AI Agent系统需同时建设prompt、context、harness、loop、graph五层才能稳定生产,前四层被大量投入但Graph层最易被忽视,直接决定组件调度与人工审批节点。
每一条"My agent 不 work 了"的事后分析都如出一辙:有人重写了 prompt,追加了一条约束,补充了一个示例,再发布。三次迭代之后,agent 依然无法在生产环境立足,团队已经悄悄束手无策——因为问题从来就不在 prompt 层。
从原始模型调用到一个真正可以托付业务成果的系统之间,存在五个控制层:prompt、context、harness、loop 和 graph。大多数团队只部署和instrument 了前一到两层。那些在生产环境中暴露的失败——调错了工具、同一错误反复重试、输出被路由到了错误的审核人——几乎全部发生在没人命名的那些层中。
Graph engineering 是这五层中最新的、也是最不被理解的一层:它决定了哪个组件下一步运行、何时 agent 并行工作何时串行工作,以及在什么昂贵或不可逆的操作之前必须有人签字确认。本文将逐一拆解这五层,完整还原一次生产故障的端到端诊断过程,并说明 evals 作为贯穿所有层的测量系统如何运作。
心智模型:环绕模型的五个环
MODEL CALL = prompt + context
AGENT = model call + harness + loop
SYSTEM = agents + deterministic steps + humans, connected by a graph
EVALS = evidence that every layer actually works
Prompt 和 context 距离模型最近。Harness 和 loop 将一次模型调用转化为可以行动并从中恢复的东西。Graph 将一组 agent、函数和人工checkpoint 整合为一个协调一致的系统。这五层不会相互替代——它们是同心圆式的控制机制,而非流水线上的顺序阶段,一个生产级 agent 同时使用全部五层。无论其他四层有多强,最弱的那层决定了整个系统的可靠性上限。
一次生产故障的分层诊断
以一个用来修复内部支付服务低风险缺陷的 coding agent 为例。Prompt 写得还算合理:检查问题、避免无关改动、运行测试、返回 PR 摘要。在一个干净的示例仓库上,它工作正常。在真实仓库上,它在四个截然不同的方面崩溃了:
它漏掉了一条藏在文档深处的架构决策——context 层故障。
它运行的 shell 命令作用域超出了预期——harness 层故障。
它在不改变假设的前提下反复重试同一个失败的测试——loop 层故障。
它把 pull request 发到了错误的审核路径——graph 层故障。人们的第一反应是问"怎么改进 prompt?"这个问题本身就是错的。四个故障中只有一个可以追溯到指令层——而且恰恰不是造成损害的那一个。每个故障都需要在真正负责它的那个层去修复,而不是在 system prompt 后面追加一段话。
第一层——Prompt:控制单次模型调用
Analyze the reported defect and propose the smallest safe fix.
Do not change unrelated behavior.
Return the root cause, files changed, test evidence, and residual risk.
Stop and ask for approval if the fix changes an external contract.
此处被优化的单元是一次模型交互。一条更强的 prompt 可以减少歧义,但它无法提供一份缺失的设计文档、限制一个危险的工具,或者决定谁来审核输出。在 agent 系统中,prompt 是方向盘——不是汽车本身。
第二层——Context:模型实际能看到什么
让模型总结一份 80 页合同中的风险。把整份文档丢进 context 窗口,然后取出其中关于赔偿责任、免责条款、终止条款和数据使用条款(再加上组织的风险政策),与仅把相关条款传入context,得到的答案会大相径庭。指令没有变——用来回答问题的证据变了。对这个 coding agent 来说,缺失的架构决策本质上是一个检索问题。修改 prompt 或许能遮掩一个测试用例;但修复 context 装配才能解决整类故障。
第三层——Harness:运行时边界
Harness 指的是模型调用周围的一切:工具、文件访问、shell 访问、MCP 连接、沙箱、权限、超时、日志记录、审批边界。模型可以决定"我需要运行测试"——但 harness 决定这是否可行、哪些命令在白名单中、哪个目录可见、以及什么被记录下来。MCP 标准化了 agent 连接到工具的方式;但它不决定一个 agent 是否应该拥有生产环境写权限。身份、最小权限和审批策略仍然属于宿主及其周围控制平面的职责。这通常是安全团队第一个问到的层——而那个范围过大的 shell 命令恰恰应该在这里被拦截。
第四层——Loop:重试契约
Loop engineering 掌控整个循环——行动、观察、评估、调整、重复——以及重试策略、验证器、完成条件、预算和升级规则。它与 harness 是两个截然不同的问题:
Harness 问的是:agent 能否执行这个测试?在哪个沙箱中?超时时间是多少?
Loop 问的是:一次测试失败是否触发另一次尝试?在重试之前需要改变什么?允许多少次尝试?什么算"完成"?你可能有一个完美沙箱化、完整日志记录的 harness,但仍然眼睁睁看着 agent 用全部预算反复重试同一个失败的修复方案。这个 coding agent 的反复测试失败需要的是"新假设"要求和重试上限——而不是更宽泛的文件系统访问权限。
第五层——Graph:协调整个系统
Graph Engineering 是一种构建复杂 AI agent 和多 agent 系统的操作范式,它将工作流显式建模为有状态图,而不是依赖无结构的单 agent 循环或线性 prompt 链。与其让 LLM 在一个不可预测的循环中自主决定每一个执行步骤("prompt and pray"),graph engineering 强加 architectural boundary。它将整体任务视为一个状态机,其中节点执行离散逻辑(LLM 调用、工具执行、验证),边directed 路由决策,而由 schema 定义的状态贯穿整个生命周期。
Graph engineering 控制着整个工作流的拓扑结构。节点可以是 agent、确定性函数、评估器或人工 gate;边定义了顺序、路由、分支路径、恢复路径,以及第四层的 loop 实际存在于何处。Loop 问的是"这个 agent 如何持续工作?"Graph 问的是"下一步运行哪个组件?系统如何协调?"
flowchart LR
A[Triage] --> B[Planner]
B --> C[Coding Agent]
C --> D[Deterministic Tests]
D -->|pass| E[Security Reviewer]
D -->|fail| C
E --> F{Human Approval}
F -->|approved| G[Merge]
F -->|rejected| B
这就是修复 coding agent 第四类故障的方案:代码变更→测试→安全审核→人工审批→合并之间有一条显式路由——而不是隐含地指望相关的人迟早会看到它。
LangGraph 正是将自己定位为做这件事的低层次编排运行时:混合确定性步骤和模型驱动的步骤,同时保持状态持久化、 durable 执行和人工中断。真正有价值的理念不是"画方框和箭头"——而是把一个过载的聊天会话悄悄同时做的一切(计划、研究、编写、并为自己的工作审批)拆分开来,并在失误代价变得昂贵的地方保留人工介入。
Graph 复杂度不是免费的,数据也印证了这一点:Anthropic 报告其多 agent 研究系统在内部 breadth-first research 评估中比单 agent 配置高出 90.2%——但多 agent 运行的 token 消耗大约是普通聊天交互的 15 倍。这个数字针对的是 Anthropic 的研究负载,不是通用乘数,但它精确地捕捉到了权衡:graph 只有在任务价值和并行性足以证明账单合理时才能收回其复杂度成本。选择 graph 是因为工作流确实在分支,不是因为编排框架是当前技术栈里有趣的部分。
Graph Engineering 的核心支柱
[ Shared Typed State Object (e.g., Pydantic / TypedDict) ]
|
+----------------------+----------------------+
| |
v v
[ Node: LLM / Tool / Task ] ---------> [ Conditional Edge ]
| |
+----------------------+----------------------+
|
v
[ Node: Validator / Human Checkpoint ]
贯穿图中每个执行步骤传递的显式数据结构。
Typed Schemas:精确定义变量、工具输出、消息历史和系统元数据。
Reducers:决定如何合并并行或顺序步骤中状态字段更新的函数(例如,向列表追加项 vs. 覆盖变量)。
系统内部的独立、有界步骤。节点接收当前状态,执行逻辑,并返回一个状态补丁。
Agentic Nodes:专为单一角色定制的 LLM 调用(例如,Researcher、Refiner、Evaluator)。
Deterministic Nodes:标准代码执行(API 调用、数据解析器、格式化工具)。
Validation Nodes:输出解析器和 schema 检查器,评估前置步骤。
连接节点并管理系统转换的规则。
Fixed Edges:从节点 A 到节点 B 的直接、确定性路由。
Conditional Edges:基于 LLM 输出或状态评估的动态路由(例如,如果 confidence < 0.8,则路由到 Human Review;否则路由到 Execution)。
Cyclic Paths:为迭代优化设计的循环(例如,Draft -> Evaluate -> Revise -> Evaluate)。
贯穿所有五层的隐含关注点:evals
有一条第六条线索贯穿每一层,但它不是第六个环——而是衡量其他五层的测量系统。
Prompt 是否可靠地产生了符合指令的输出?
Context 检索是否包含了关键证据,还是悄悄遗漏了?
Harness 是否允许了必要的工具同时拒绝了危险的工具?
Loop 是否在正确的原因下停止,还是在死胡同里耗尽了预算?
Graph 是否将风险情况路由到了人工,还是让它漏掉了?
OpenAI 自己的评估指南遵循同样的原则,不分层:定义期望行为,用代表性测试输入针对显式标准运行,分析结果,迭代。Evals 不是独立于五层之外的架构关注点——它们是每一层在履行其职责的证据。
术语的成熟度并不均衡。Prompt engineering 和 context engineering 已是业界公认的术语。"Agent harness"是一个真实、被认可的类别。Loop engineering 和 graph engineering 是从业者也曾称为 agent loop、workflow 和 orchestration 的更新的标签——是有用的名称,而非已经确定的术语。
边界是模糊的。Memory 可以合理地归属于 context、harness 或 loop 级的运行时状态。验证可以存在于工具边界内部、重试循环中,或自己的 graph 节点中。这是五个关注点,不是五个可以清晰分离的软件组件——不要强行把它们一一映射到文件。
这不是一个建造顺序。实际上,graph(工作流形状)往往最先被勾勒出来,然后定义 loop 和控制边界,最后调优 prompt。把它想象成围绕模型同心圆式的控制机制,而不是从上到下执行的瀑布。
五个控制层位于原始模型调用和一个可信系统之间:prompt(掌舵)、context(供讯)、harness(约束)、loop(持久化)、graph(协调)——最弱的一层决定了整个系统的可靠性上限。
按层诊断故障,而不是靠修改 prompt 来修修补补。一次路由错误的 PR、一次无限重试、一次权限过高的 shell 命令,是三个不同层中的三个不同 bug,"改进 prompt"一个也解决不了。
Graph engineering 是拓扑,不是装饰:节点是 agent、确定性步骤或人工 gate;边定义了顺序、并行、恢复,以及在何处必须有人签字。
多 agent 编排是成本权衡,不是免费升级——Anthropic 自己的研究系统需要大约 15 倍的 token 才能获得 90.2% 的质量提升,这个比例应该成为判断你的工作流是否真正需要 graph 的依据。
Evals 不是单独的一层——它们是其他五层各自在按预期工作的证明,没有它们,"AI 有点怪"是你团队能做出的最好诊断。
在你再修改一次 prompt 之前:context、harness、loop、graph 这四层中,哪一层实际上是你系统中最薄弱的环节,你又会如何得知?