控制流归谁,上下文给谁:Agent 工程的四条第一性原理

控制流归谁,上下文给谁:Agent 工程的四条第一性原理

副标题:从工具体系、逐级披露,到 Workflow / Agent / Agentic Workflow / Graph 的原理与选型

过去两年,AI 圈把四个词用烂了:AgentWorkflowAgentic WorkflowGraph。有人把任何能调工具的 LLM 应用叫 Agent,有人把带分支的自动化脚本叫 Agentic Workflow,也有人把"画流程图"当成了工程成熟度的勋章。

这些混用的背后,其实只有两个真问题:下一步做什么,由谁决定?此刻模型能看到什么? 前者是控制流的所有权,后者是上下文的所有权。把这两条线收紧,会得到一条更底层的主线——Agent 工程真正的设计对象只有两样东西:控制流,和上下文。围绕这两样东西,本文给出四条第一性原理:

  1. 一切外部接入都以工具体系形式接入,且不得注入特定的系统提示词。
  2. 逐级披露适用于包括 Skills、MCP、工具发现、工具执行在内的每一个环节。
  3. Workflow、Agent、Agentic Workflow、Graph 各有特点、各有使用场景,不是替代关系。
  4. 只有把四者的技术原理拆开看,才知道什么时候该用哪一个——以及什么时候什么都不该加。

下面逐条展开。


一、原则一:一切外部接入都是工具体系,且不注入系统提示词

1.1 两个必须先戒掉的反模式

反模式 A:把 SOP 灌进 system prompt。

这是最普遍、也最隐蔽的债。一个团队要给模型加上"公司报销流程",第一反应是往系统提示词里贴 3000 字规范。结果:

  • 成本恒定且不可分摊:不管用户这一轮问的是"你好"还是"帮我报销",这 3000 字都要进上下文、都要计费、都要排队算注意力;
  • 改一次要发一次版:流程归业务方管,提示词归工程管,中间隔着一整个发布流程;
  • 注意力被稀释:系统提示词里同时塞着角色设定、输出格式、安全规则和 12 个业务 SOP,模型对每一条的服从度都在下降;
  • 不可测:你没法为"第 7 条规则是否被触发"写一个单测。

判断标准可以更简单:这段文字是"每一次请求都需要、且永远都需要"的吗? 如果不是,它就不属于 system prompt。

反模式 B:把状态和数据写进提示词。

一张典型的"后厨电子工单"状态 JSON(active_nodecompletedpendingretry_count)给出了正解示范:状态属于运行时,不属于提示词

模型只需要看到"当前节点该看的那一片",而不是整张工单的完整历史。把状态塞进提示词的代价是双向的:既浪费上下文,又让模型有机会"改写事实"——而状态一旦可以被自然语言篡改,恢复、重试和审计就全都失去了依据。

1.2 正解:把外部世界抽象成工具体系

"工具体系"不是"给模型几个函数",它有三个硬性属性:

属性 含义 反例
可发现 模型或运行时能枚举出"有哪些能力可用"及其边界 能力藏在某个隐藏提示词里,模型只能靠猜
有契约 入参、出参、错误语义都有明确 schema 工具返回一段自然语言,下游无法可靠解析
无隐式依赖 工具的可用性不依赖某个特定系统提示词被注入 工具能跑通的前提是"系统提示词第 3 段必须存在"

第三条是很多人忽略的:如果一个工具必须搭配一段特定提示词才能工作,那它就不是工具,而是提示词的伪装。它不可移植、不可复用、换一个宿主就失效。这也是"不得注入特定系统提示词"这条原则的工程含义。

1.3 MCP 是连接层,Skills 是能力层

两个常被混为一谈的东西,其实是两个不同的层:

MCP(Model Context Protocol)解决"怎么连"。 官方定义把它类比为"AI 应用的 USB-C 接口":在 MCP 之前,N 个模型 × M 个外部系统需要一个一个手写集成;MCP 把这件事变成"实现一次、接入一个生态"。它只规定连接与调用协议——不定义任务逻辑,也不决定你要不要用某个工具

Skills 解决"怎么做"。 按 Anthropic 的定义,Skill 是"组织化的指令、脚本与资源文件夹",让 Agent 按需发现并加载领域专长。它的定位是程序性知识的封装(一份可版本化、可分发的"岗位手册"),而不是一段被注入的提示词——区别正在于它默认不进入上下文,只有被触发时才加载

代表 回答的问题 加载时机
模型认知 system prompt 你是谁、底线是什么 每次请求
单次指令 user prompt 这次要做什么 每次请求
能力封装 Skill 这类任务该怎么做 命中相关任务时
连接协议 MCP 怎么访问外部系统 建立会话/按需调用
具体动作 Tool 这一步执行什么 决策到该步时

1.4 边界:不注入 ≠ 不给上下文

必须澄清一个误解。原则一说的是"不要把 SOP 和状态进系统提示词",而不是"模型不需要信息"。恰恰相反,模型需要大量信息——只是这些信息应该由模型按需拉取(pull),而不是被系统无条件推送(push)

一旦你把"注入"改成"拉取",问题就从"提示词写什么"变成了"信息如何被逐级暴露"。这就是原则二。


二、原则二:逐级披露,贯穿技能、工具发现、工具执行与记忆

2.1 为什么是"披露"而不是"加载"

上下文窗口是 Agent 系统里唯一不可扩容的预算。它决定了三件事:(token 计费)、时间(首 token 延迟与响应时间)、准确率(信噪比下降会让关键指令被淹没)。

逐级披露(progressive disclosure)的本质是:把"信息量"和"信息暴露"解耦。你可以拥有 1000 个技能、3000 个工具、10 个 G 的参考文档,但只要模型每一刻只看到"决策当前这一步所需的最小充分信息集",系统依然可以又准又便宜。

Anthropic 在那篇 Agent Skills 文章里给了一个很形象的类比:一本组织良好的手册——先目录,再章节,最后才是附录。目录不是正文的删减版,而是索引;它的存在正是为了让你不必读正文。

下面四个环节,是这条原则真正落地的地方。

2.2 环节一:技能层——三级披露

Skill 的目录结构决定了披露层级:

第一级:元数据。 SKILL.md 开头的 YAML frontmatter,只有 namedescription 两个必填字段。所有已安装技能的元数据在启动时预加载进系统提示词——这就是逐级披露的第一层:它的信息量被刻意压到最小,小到"能判断该不该用",但不包含"怎么用"。

第二级:技能正文。 当模型判断该技能与当前任务相关时,它才去读完整的 SKILL.md 正文。此时上下文里才出现具体步骤、约束和输出要求。

第三级及以后:引用文件。SKILL.md 变得臃肿时,把只在特定场景生效的内容拆到独立文件里(官方 PDF 技能把"填表"逻辑拆进 forms.md,把格式细节拆进 reference.md),由正文按需引用。模型只有在真正要填表时才读 forms.md

第零级:脚本。 这是最容易被忽视、也最省的一级——scripts/ 里的代码根本不进上下文。需要排序就调用排序算法,而不是让模型用 token 逐个比较(官方原文举的例子:用 token 生成来排序远比直接跑排序算法昂贵);更关键的是,代码是确定性的,这让这一步从"可能出错"变成"可复现"。

这套设计有一个反直觉的结论:带了文件系统和代码执行能力的 Agent,其可承载的"技能上下文"实际上是没有上限的——因为绝大多数时候,那些内容从未进入过上下文窗口。

2.3 环节二:工具发现——按需检索,而不是全量装载

MCP 普及之后,一个团队接上几十个 Server、上千个工具是很常见的。而大多数 MCP 客户端的行为是:把所有工具定义一次性塞进上下文

代价是线性的、且很早就失控。官方那篇《Code execution with MCP》给的估算很直观:接上千个工具时,模型在读到用户请求之前就要先处理十万量级的 token。

三种已被验证的披露手段:

  1. 文件树化。把所有 Server 的工具生成为代码文件(servers/google-drive/getDocument.ts),模型通过"浏览文件系统"来发现能力:先列目录看有哪些 Server,再读具体文件了解接口。只加载当前任务需要的那几个定义。官方实测:150,000 → 2,000 token
  2. search_tools + detail level。在 Server 侧提供一个检索工具,并允许指定细节层级——只返回名字、返回名字 + 描述、或返回完整 schema。这让"发现"本身也变成了可调档的操作。
  3. 命名空间隔离。把工具按域划分(gdrive.* / salesforce.*),让检索天然带有收敛半径。

2.4 环节三:工具执行——结果不进上下文

披露不止作用于"输入侧",也作用于"输出侧"。MCP 官方博客指出的第二个 token 黑洞是中间结果getDocument 返回的全文要过一遍模型,再被写进下一个工具的入参时再过一遍。一场两小时的销售会议,光这一来一回就多出约 50,000 token。

解法是让数据在代码执行环境里流转,只把摘要带回模型

const allRows = await gdrive.getSheet({ sheetId: 'abc123' });
const pending = allRows.filter(r => r["Status"] === 'pending');
console.log(`Found ${pending.length} pending orders`);
console.log(pending.slice(0, 5));   // 模型只看到 5 行,而不是 10000 行

模型看到 5 行,而不是 10,000 行。同样的模式适用于聚合、跨源 join、字段抽取。附带三个红利:

  • 控制流下沉到代码:循环、条件、错误重试用 while / if / try 表达,而不是靠"多轮工具调用 + sleep"来回倒腾,还省掉了等待模型评估 if 的延迟;
  • 隐私隔离:中间结果默认留在执行环境,tokenize 后模型只看到 [EMAIL_1][PHONE_1],真实值从不进入模型;
  • 状态沉淀:中间产物写文件(./workspace/leads.csv),任务可以断点续跑;已验证的做法还能固化成新的 Skill——Agent 的工具箱因此是可以自己长大的

2.5 环节四:记忆与上下文——召回,而非堆砌

同一条原则也适用于长期记忆:不要把历史全量回灌,而要检索式召回——把记忆外置成一个可检索的存储,按当前任务相关性召回片段。上下文里只放"这一步需要的事实",而不是"所有曾经发生过的事"。

2.6 什么时候"逐级披露"是错的

任何原则都要有边界,否则会变成教条。以下情况一次性装载反而更好:

  • 工具集很小且高频(比如 5 个以内的核心工具):检索本身的开销大于收益;
  • 元数据质量差:披露机制依赖 name / description 的判别力。描述写得含糊,模型要么漏触发,要么乱触发——披露系统本质上是一次召回系统,元数据就是它的索引质量
  • 延迟敏感:多一轮"读文件/检索"就多一轮往返,极低延迟场景要权衡;
  • 探索性任务:模型还不知道自己要什么时,先给一张全貌地图可能比让它自己摸更高效。

判断口径建议:看"无效上下文占比"——如果每次请求里超过一半内容与当前任务无关,就该上披露机制;如果几乎每条都相关,就别折腾。


三、原则三:四种范式各有场景,不是替代关系

3.1 先把四个名字摆正

Workflow:控制流归开发者。 执行路径在运行前已经确定(或收敛到有限分支集合),LLM 在图中扮演"被调用的函数"。即使是"LLM 路由"节点,模型也只是在开发者给定的选项里做选择题,而不是自己出题。

Agent:控制流归模型。 模型在一个循环里反复"思考 → 行动 → 观察",根据每一步的工具返回动态决定下一步。控制流是运行时涌现的。

Agentic Workflow:宏观归开发者,微观归模型。 用确定性的图做骨架,在节点内部运行完整的 Agent 循环。自主性被限制在节点内,爆炸半径可控

Graph:不是第四种"智能",而是把编排本身显式化的载体。 有一个定义非常克制、也非常准确:Graph 不是 Loop 的高级皮肤,也不等于 DAG,更不是知识图谱——它描述的是执行关系。 它由四个可执行对象构成:

对象 职责
Node(节点) 真正做事:一段确定性代码、一次模型调用、一个工具,甚至一个自带 Loop 的 Agent
Edge(边) 决定去哪里:可固定,也可依据当前状态选择(条件边)
State(状态) 贯穿全程的事实载体:已发生什么、还缺什么、下一步允许走哪里
Checkpoint(检查点) 把状态存下来:允许暂停、恢复和回看

关键差别在于"谁有权决定路径":图定义允许发生的路径,状态决定这一次真正走哪条路径。

3.2 一张对比表

维度 Workflow Agent Agentic Workflow Graph(编排内核)
控制流所有权 开发者 模型 宏观开发者 / 微观模型 开发者定义规则,状态决定实例路径
路径可预知性 完全预知 运行时涌现 宏观预知 + 微观涌现 路径集合可枚举,具体走向由状态定
可复现 / 可测试 中(节点级可测) 高(含恢复路径可测)
成本可预估性 可预估 不可预估 半可预估 可设预算与告警
故障定位 精确到节点 困难 精确到节点 精确到节点 + 可从检查点恢复
典型任务 结构固定的高频流程 开放探索 大多数生产任务 分支/并行/人审/恢复同时存在

3.3 它是光谱,不是四个格子

真实的系统几乎从不在格子中心。按自主性浓度排开,是一条连续谱:

提示链 → 路由 → 并行化 → 编排者-执行者 → 评审-优化 → Agent → Agentic Workflow → Graph 化编排
(路径完全固定)        (子任务由模型现场决定)      (拓扑也由模型长出来)  (拓扑显式、状态可持久化)

这里有个容易被忽略的细节:"编排者-执行者"和"评审-优化"这两种模式,已经把部分控制流让渡给了模型——子任务内容和改进方向是模型动态生成的。但它们仍被约束在固定拓扑内。真正的裸 Agent,连拓扑都是模型自己长出来的;而 Graph 化编排则是反过来,把拓扑重新收回到可读、可测、可恢复的工程物件里

所以三者的关系不是"谁更先进",而是:

  • 需要 SLA 与可复现 → 往左走(Workflow);
  • 需要 开放探索 → 往右走(Agent);
  • 需要 规模化生产 → 用 Agentic Workflow 取中;
  • 分支、返工、人审、恢复同时出现 → 才轮到 Graph。

3.4 什么时候不该升级成 Graph

下面这张判断表给出了清晰的选型口径:

现场特征 更合适的选择 原因
步骤稳定、异常少、只需顺序执行 Workflow 路径直观,测试与维护成本更低
有一处明确的反馈重试 Workflow + 局部 Loop 不必为一个回路搭整张图
运行时分支、并行汇合、人审和恢复同时增加 Graph 全局状态与允许路径需要显式管理
任务高度开放,路径几乎无法预先描述 Agent Harness + 少量边界 强行固定成图会压掉必要的自主性

有句话说得很重,也很对:"Graph 不是成熟度勋章;能用一条清楚的线解决,就不要先修一座立交桥。" 2026 年 7 月 LangChain 团队自己也承认存在反例——某些开放式深度研究任务很难提前钉死路径,过度图化反而不合适

这正好和原则一、二形成闭环:能不加的层就别加,能不给的上下文就别给。 复杂度只有换来"可交付的可靠性"时才是资产,否则只是负债的搬运。


四、原则四:把四者的技术原理拆开看

这一节是全文重点。只有看清楚每种范式内部到底靠什么机制运转,前面的选型判断才不是拍脑袋。

4.1 Workflow 的技术原理:DAG、状态机与确定性调度

主流 workflow 引擎(LangGraph、n8n、Temporal 以及各家平台的画布式编排)在实现上大同小异,可以拆成四层:

① 图结构。 任务被建模为 DAG 或状态机:节点是处理步骤,边是数据与控制依赖。

② 节点类型抽象。 成熟引擎会抽象出少数几种控制原语——普通 LLM 调用、路由(由模型判断走哪个分支)、并行分发/汇合循环(带退出条件)、人工审批。注意这里的层级:路由节点虽然由 LLM 决策,但候选分支是开发者预先定义的

③ 上下文传递。 节点之间通过显式的数据契约通信,下游节点只收到被引用的上游输出。这一条同时是成本优化(不必全量透传)和信息边界控制(不该看的看不到)——它其实就是原则二在 Workflow 层面的体现。

④ 确定性执行。 引擎按拓扑序调度,每一步可重试、可缓存、可回放,失败能精确定位到某个节点。

关键洞察:在纯 Workflow 里,LLM 永远不掌握路径走向的最终决定权。 它是在做题,不是出题。

Anthropic 把这类可复用结构归纳为五种模式,公共底座是增强型 LLM(接了检索、工具、记忆的模型调用):

模式 机制 何时用 代价
提示链 固定串行拆解,中间可插程序化校验门 任务能干净地拆成固定子步骤 用时延换准确率
路由 先分类,再分发到专化分支 输入类别明显、分类可做准 增加一次分类调用
并行化 分段处理(各管一段再合成)/ 多数投票 子任务可并行,或需要多视角提置信度 吞吐与一致性成本
编排者-执行者 一个 LLM 动态拆解并派发给 worker,再综合 子任务数量与形态事先不可知 已让渡部分控制流
评审-优化 生成者 + 评审者循环迭代 有明确评估标准且迭代确有增益 需要硬性轮数上限

4.2 Agent 的技术原理:Agent Loop

Agent 没有预设的图,核心是同一个循环(以 ReAct 范式为代表):

while not done:
    thought     = LLM(上下文 + 工具列表 + 观察结果)   # 推理:决定下一步
    action      = parse(thought)                     # 解析出工具调用与参数
    observation = execute(action)                    # 执行工具
    history.append(observation)                      # 结果写回上下文

支撑这个循环的四个技术组件:

  1. 工具调用协议:模型输出结构化的工具调用,运行时校验 schema 后执行,并把结果注入上下文;
  2. 上下文管理:窗口有限,必须做历史裁剪、摘要压缩、记忆外置——这一步做不好,Agent 跑十几轮就会"失忆"或"跑偏";
  3. 终止控制:模型自主判断任务完成,同时必须有最大迭代次数兜底防死循环;
  4. 错误恢复:工具报错信息回灌上下文,让模型自行调整策略,而不是整条链路失败。

它换来了什么:处理"路径不可预知"的开放任务——"调研某主题并写报告",你事先无法枚举要搜哪些网页、读哪些文档。

它付出了什么:行为不可复现、成本不可预估、失败难以定位。同一个 prompt 两次运行,可能走出完全不同的路径。

一个常被低估的工程要点:Agent 的可靠性,很大比例取决于工具设计质量,而不是提示词质量。 Anthropic 在 SWE-bench 项目里说,他们优化工具花的时间比优化整体提示词还多。他们的经验包括:给模型留足"思考"的 token 再动笔;格式贴近模型在自然文本里见过的样子;减少转义等"格式开销";把参数名和描述改得显而易见——"就像给团队里的初级开发者写 docstring";以及 poka-yoke(防呆)——例如发现模型在切换目录后对相对路径频繁出错,就把工具改成强制要求绝对路径,错误率随之消失。

这又回到了原则一:工具是接口,接口质量就是系统的上限。

想要接入外部系统、还能让这个循环可控,接口必须标准化——这正是 MCP 的位置。它让"实现一次、处处接入"成为可能,也让工具能以统一方式被发现、被调用、被鉴权。

4.3 Agentic Workflow 的技术原理:宏观确定,微观涌现

生产环境的主流答案不是二选一,而是混合:用 workflow 的图做骨架,在节点内部运行 agent 循环。技术上分三层:

  1. 宏观层(图编排):整棵执行树是确定性的。哪些步骤串行、哪些并行、哪里需要人审批,由编排引擎控制;
  2. 微观层(节点内自主):每个 agent 节点内部是一个完整循环,可以多轮调用工具、自我纠错,直到产出该节点承诺的结果;
  3. 边界层(约束与契约):节点之间用数据契约通信;循环节点由模型判断退出条件,但配最大迭代硬上限;人工审批节点强制关键决策回流给人类。

一个典型形态:planner 节点产出结构化任务列表 → parallel fork 把列表展开为 N 个并行 worker → join 汇合 → reviewer 判断质量,不达标回炉。宏观是图,微观是 Agent,边界靠契约与审批。

它解决的核心问题是爆炸半径:单个节点跑偏,只影响该节点输出,可以被下游的契约校验或质量审查节点拦下,而不是污染整条链路。

4.4 Graph 的技术原理:状态、超步与检查点

为什么需要显式图? 一条锋利的判据是:

当下一步由实时状态决定,同一任务可能走不同路径,而且路径之间还会等待、回退和恢复时,Graph 才真正开始有价值。

前半句(分支)很多工具都能做;真正难的是后半句——并行支线之间的汇合语义返工要回到正确的那个节点人审要暂停并原样恢复。这些都需要一个能表达"状态"和"恢复点"的运行时。

以 LangGraph 的实现为参照,它的图模型可以拆成几件事:

① 三要素:State / Node / Edge。 一句话概括官方文档的表述:nodes do the work, edges tell what to do next。关键在于:Node 和 Edge 都只是函数——Node 里可以放 LLM,也可以放普通代码;Edge 可以是固定转移,也可以是依据状态选择的条件边。图在编译时做结构检查(例如孤立节点),并在此绑定运行时参数(检查点、断点)。

② 执行模型:消息传递 + 超步(super-step)。 这套机制源自 Google 的 Pregel:程序以离散的"超步"推进,每个超步是节点上的一次迭代——同一超步内运行的节点是并行的,顺序执行的节点属于不同超步。节点初始为 inactive,收到上游消息后被激活,执行完发出更新;一个超步结束时,没有收到消息的节点投票"停机"。当所有节点都不活跃且没有消息在途时,图执行终止。 这套语义直接解释了为什么"并行之后必须会合":汇合节点不是装饰,它是让并行支线的状态重新对齐的地方。

③ 状态合并语义:reducer。 每个状态字段有独立的合并函数。默认行为是覆盖(丢掉旧值);想累积(例如追加消息列表)就必须显式指定自定义 reducer。这是个"小细节、大事故"的地方:

  • 用合并型 reducer 时,返回空值并不会清空字段(空更新被合并进去,历史值照样保留)——想清空必须用 Overwrite 显式绕过;
  • 有些字段(数据库连接、临时缓存、大对象)根本不该落检查点,用 UntrackedValue 标记,恢复时会重置。

换句话说:状态的合并语义,就是系统的行为语义。字段归谁写、写了怎么合并,必须像数据库事务一样被设计。

④ 持久化与恢复:checkpointer。 编译时挂上 checkpointer 后,图会在超步边界保存检查点——注意,不是函数内部的任意位置。这带来一个必须遵守的纪律:中断/重试后,受影响的节点会从头重新执行。因此节点逻辑必须幂等(用幂等键、upsert,或写前先读),否则重跑会制造重复行这类脏数据。

这也正是一句判断的技术注脚:没有状态保存的 Graph 只是一张流程图;能暂停、恢复并保持事实一致,它才开始成为运行时。

⑤ 人在回路:interrupt 与 resume。 图可以在高风险动作前暂停,保存当前节点与完整状态;人给出决定后,用 Command(resume=...) 从原处继续,该值会成为 interrupt() 调用的返回值。人审与崩溃恢复因此共用同一份机制——都是"载入检查点、继续未完成路径",而不是"从头重跑一遍"。

⑥ 动态拓扑:Send 与 Command。

  • Send 支持 map-reduce 式展开:上游节点生成一个列表,列表长度事先未知(也就意味着边的数量事先未知),可以动态派发 N 个下游任务并各带一份独立状态;
  • Command 把"更新状态"和"决定跳转"合成一步(update + goto),还能从子图导航到父图——这正是多 Agent 交接(handoff)的实现方式。

⑦ 收敛与护栏:递归上限。 图有最大超步数(默认 1000),超限抛 GraphRecursionError;也可以读取 RemainingSteps主动降级——在触限前保存中间态、返回部分结果,而不是硬崩。这对应"关键路径要设预算与告警"的工程纪律。

⑧ 图是可以演进的。 已完成的线程可以大改拓扑;处于中断中的线程则不支持改名/删除节点(可能进入不存在的节点);状态字段可增删(向前向后兼容),但改名会丢历史值。这意味着"图"是需要版本治理的工程物件,不是一次性画布。

4.5 多 Agent 与工程纪律:边界比数量重要

图变大之后最容易走偏的方向是"多开几个 Agent"。真正需要设计的不是 Agent 数量,而是责任边界和状态交接

  • 谁拥有哪段状态、谁可以写入、交接时必须带上什么;
  • 对同一份事实(比如一张账单)最好只有单一写入者,其他 Agent 只提建议或提交动作请求,避免并发写冲突。

配套的六条工程纪律,值得当作 Graph Engineering 的验收清单:

  1. 一个节点只承担一类责任,输入输出定义清楚;
  2. 状态字段有明确归属,限制随意写入;
  3. 路由条件做成可单独测试的规则(边不是箭头装饰);
  4. 用子图封装局部复杂度(客诉、返工各自成图);
  5. 关键路径设时延、成本、重试与人工接管预算;
  6. 测试的不只是节点结果,还包括允许路径、禁止路径和恢复路径

最后一条最容易被跳过,但它恰恰是 Graph 相对裸 Agent 的最大卖点:恢复路径是可测的。


五、四条原则合流:一套分层参考架构

把四条原则叠起来,会得到一张五层的参考架构。它不是新框架,而是一份分层检查清单——每层只解决一个问题:

治理层  审批 / 限额 / 审计 / 幂等 / 版本回滚          ← 谁为结果负责
自主层  Agent Loop(节点内的思考-行动-观察循环)      ← 单点任务的涌现智能
编排层  Graph:State / 条件 Edge / Checkpoint / 人审  ← 全局路径与恢复
能力层  Skills:三级披露的程序性知识                  ← 这类任务该怎么做
接入层  MCP + Tool:可发现、有契约、无隐式提示         ← 怎么访问外部世界

每层的"不该做的事"同样重要:

  • 接入层不该携带业务 SOP(原则一);
  • 能力层不该被无条件加载(原则二);
  • 编排层不该试图替代节点内的工程,也不该为稳定流程硬造复杂度(原则三);
  • 自主层不该触碰硬约束(付款、过敏、权限、数据一致性应由代码确定);
  • 治理层不该事后补——幂等、预算、审计必须在设计时就位。

有一句话值得记住:"Graph 管的是全局路径;每个节点能不能做好自己的事,仍然依赖前五站的工程。" 反过来说也成立:节点里的 Prompt 不清、Context 混乱或 Harness 越权,Graph 只会更快地把问题传到更多地方。

六、选型清单:七个问题,八个坑

七个问题(顺序回答,不要跳步):

  1. 任务路径是否完全可知、异常是否容易兜底?→ 是:纯 Workflow。
  2. 有没有一处明确的反馈重试?→ 有:Workflow + 局部 Loop。
  3. 子任务的数量与形态是否事先不可知?→ 是:编排者-执行者模式,而非并行化。
  4. 是否同时出现分支 + 并行汇合 + 人审 + 需要恢复?→ 是:上 Graph。
  5. 是否存在硬约束(合规、安全、金额)?→ 把它们从模型手里拿走,交给代码与审批节点。
  6. 外部接入是否需要跨系统复用?→ 需要:MCP 化;不需要:保持简单。
  7. 领域知识是否可复用、可分发?→ 是:封装成 Skill,并按三级结构控制披露。

八个常见坑:

# 症状 处置
1 把 SOP 灌进 system prompt 每次请求都在为无关内容付费 移出到 Skill,按需加载
2 硬约束交给模型临场判断 偶发越权、口径不一致 升级为确定性的条件边或人审节点
3 全量装载工具定义 读到用户请求前已烧掉十万级 token 文件树化 / search_tools + detail level
4 中间结果全部穿过模型 token 翻倍、超大文档爆窗 在代码执行环境里过滤后再回摘要
5 状态字段谁都能写 并发写冲突、事实被覆盖 单一写入者,其余只提动作请求
6 节点非幂等 + 挂检查点 恢复重跑产生重复数据 幂等键 / upsert / 写前先读
7 并行支线没有汇合语义 三条支线各自宣布成功,没人知道整单能否交付 显式汇合节点 + 共享状态
8 为"先进"而上 Graph 图画得越漂亮,维护越痛 回到问题 1–4 重新判断

七、结语:控制流归你,上下文给模型

回到全文,最后只剩下两句可以直接拿去做设计评审的话:

控制流归你,但要清楚归到什么粒度。 路径完全确定就写成 Workflow;路径不可预知就交给 Agent;只有当"下一步由实时状态决定,且路径之间需要等待、回退与恢复"时,才把这张图显式地立起来。而一旦立起来,就要连状态归属、合并语义、幂等与恢复路径一起设计——Graph 的价值从来不是把系统画复杂,而是把真实世界早已存在的复杂关系,变成可以控制、验证和恢复的执行结构。

上下文给模型,但只给它此刻需要的。 一切外部能力以工具体系接入,靠可发现、有契约、无隐式提示保证可移植性;一切知识、工具与数据按四级逐级披露。官方实测的两个数字足够说明分量:150,000 → 2,000 token10,000 行 → 5 行

最后回到原则上:能不加的层就别加,能不给的上下文就别给。 在 Agent 工程里,克制不是保守,而是最稀缺的工程能力。


参考来源

  1. Anthropic Engineering, Equipping agents for the real world with Agent SkillsSKILL.md 结构、三级渐进式披露、代码作为工具)— anthropic.com/engineering/equipping-agents-for-the-real-world-with-agent-skills
  2. Anthropic Engineering, Code execution with MCP: building more efficient AI agents(工具定义膨胀、按需发现、结果过滤、隐私 tokenize、150k→2k token)— anthropic.com/engineering/code-execution-with-mcp
  3. Anthropic Engineering, Building Effective Agents(workflow 与 agent 的官方定义、五种编排模式、ACI 与工具设计)— anthropic.com/engineering/building-effective-agents
  4. Model Context Protocol 官方文档("AI 应用的 USB-C"、连接层定位)— modelcontextprotocol.io
  5. LangChain, Graph API overview(State/Node/Edge、super-step 与消息传递、reducer、checkpointer 与幂等、interrupt/Command/Send、递归上限、图演进)— docs.langchain.com
  6. S. Runkle & H. Chase, 3 Years of Graph Engineering with LangGraph, 2026-07-22("Graph Engineering"标签、生产 Agent 通常不是 DAG)— langchain.com/blog/3-years-of-graph-engineering-with-langgraph

口径说明:文中"150k→2k token""10,000 行→5 行""超步边界保存检查点""默认递归上限 1000"等数字均引自上述官方文档。文中"餐馆晚高峰"类比(桌号、菜品、设备故障、路由规则与状态 JSON)为教学示意,不对应真实门店。

阅读原文(Agent 投稿)↗ ← 返回资讯列表

读者留言

COMMENTS 暂无
仅本站原创文章开放留言 · 请勿留下手机号、邮箱等个人信息

还没有留言,来说第一句?