Agent 编排:工作流、自主与混合(Agent Orchestration)
所属:01-fundamentals / 04-agent-architecture
面试权重:★★★
来源:《深入理解 AI Agent:设计原理与工程实践》第 1 章「Harness 工程 / 编排模式:工作流与自主」(李博杰),另引第 10 章「多 Agent 协作」;框架对比表同出处。五种工作流模式(提示链 / 路由 / 并行化 / 编排者-工作者 / 评估者-优化器)的命名取自 Anthropic《Building Effective Agents》(书第 1 章脚注所引),书中只给了「工作流 = 预定义代码路径」的定义与订票、文生图两个例子,未逐一命名这五种模式,此处标渠道,未做一手考证
相关知识点:agent-react.md(单体的 ReAct 循环与循环控制:Thought→Action→Observation、最大步数/预算、无进展检测 —— 本篇不复述循环本身)、multi-agent.md(多 Agent 的收益判据与拓扑:supervisor / router / 判据层与机制层、LangGraph 共享状态、handoff)、13-multi-agent-coordination.md(协作的机制层:数据平面 / 控制平面 / 冲突治理三层)、../07-distributed-systems/state-machine.md(跨机器后的持久化执行:状态机与 checkpoint)
一句话#
编排(orchestration)回答的是:一条任务从入口到出口,路径是谁定的、在哪定的。 书里的判断顺序是从简单到复杂 —— 先考虑单次 LLM 调用;能用提示与上下文示例解决就别上 Agent 系统;需要多步且能清晰分解成固定子任务就用工作流;只有需要动态决策与灵活路径才用自主 Agent。而 Agent 系统本质是用延迟和成本换任务性能,这笔交换值不值,是这道题真正的考点。
为什么重要(面试角度)#
- 它考的是「架构判断力」而不是名词量。 面试官想听的不是「工作流和自主 Agent 的区别是……」,而是你能不能在动手前选对形态。「该用一个提示解决的事别上多 Agent」这句话答得出来,比会背五种工作流模式更值钱。
- 这是对你项目的正面提问。 你在 Race Bot 里做的是 Agentic Workflow(外层固定骨架)、在 Writing Copilot 里做的是 LangGraph 上的多智能体(编排层 + 共享状态) —— 两条都是真实经验,会被顺着往项目里挖。这一篇给你把「路径是谁定的」讲清楚的坐标系。
- 混合形态是分层点。 大多数人只会答「要么工作流、要么自主 Agent」;能答出「先由自主 Agent 把工作流写出来,再由工作流确定性执行」的人立刻分层,而且这条正好接上第 10 章的 Claude Code Workflow 工具实例。
- 它是通篇的总入口。 单体的循环在
agent-react.md、多 Agent 的判据与拓扑在multi-agent.md、协作机制在13-multi-agent-coordination.md—— 这一篇讲的是它们之上那一层:路径怎么定。
⚠️ 边界声明:Race Bot 的编排式工作流与 Writing Copilot 的 LangGraph 多智能体是你的一手经验,可以讲。框架横向对比不是 —— 你只用过 LangGraph 一家,书里那张表(Codex Harness / n8n / Dify / CrewAI / OpenClaw…)是书里的口径,其余框架你没有实际选型过,面试用「按这张表我会这么选」的口径讲,不要讲成「我用过这些框架」。大规模分布式编排同理,见本篇 §8。
核心内容#
1. 先给判断顺序:默认不上 Agent#
书里给的原则很直接:从简单到复杂。
| 顺序 | 形态 | 什么时候停在这一档 |
|---|---|---|
| 1 | 单次 LLM 调用 | 优化提示词与上下文示例就能解决 —— 就停在这里,不要引入 Agent 系统 |
| 2 | 工作流 | 需要多步处理,且能清晰分解为固定子任务 |
| 3 | 自主 Agent | 步骤依赖中间结果、事先无法枚举,必须动态决策才用 |
还有一句定义性的表述要记住:Agent 系统通常是用延迟和成本换取更好的任务性能,所以要权衡这笔交换值不值 —— 不是「更自主就更好」。
反面例子(书里给的,能直接引)。 为「从百万条聊天记录中提炼个人记忆」设计 Agent,很容易迅速画出一条看似严谨的流水线:切分对话片段 → 提取 → 证据核验 → 身份解析 → 记忆整理 → 合并复核,再建事实图、覆盖账本、不可变版本。每个部件单看都有道理,组合起来却很低效、不可靠:因为复杂工作流的执行拓扑是固定的,遇到新例外就继续加节点,架构越来越复杂、通用性越来越差,而模型原本能按上下文做的语义判断,反而被工作流写死了。
书把这种取舍概括成 Manus 那句「Less structure, more intelligence.」:先给一个能力足够的 Agent 清晰的目标、必要的上下文和可组合的工具,用自然语言告诉它如何查证、比较、处理冲突;程序只固化必须始终成立的边界(权限、不得覆盖原始材料、原子发布)。只有业务约束本身要求,或评测反复暴露出某类稳定失败时,才把对应步骤升级成专门的验证器、独立 Agent 或确定性流程。好的结构不是替 Agent 预演全部思考,而是守住边界、把边界内的决策空间还给模型。
Anthropic 三原则里的第一条也是这个:保持简单 —— 直接的 API 调用优于复杂的框架,清晰的代码优于聪明的抽象,因为每多一层抽象都会成为以后调试时新的盲区。
2. 工作流模式逐个拆#
工作流 = 通过预定义的代码路径来编排 LLM 和工具,执行路径是确定性的、由开发者预先设计,LLM 只在每个节点内部负责理解和生成(定义出自书第 1 章)。书给的最简单例子是文生图:提示词改写 → 图片生成 两个固定节点,改写那一步的 LLM 做的是「把人话翻译成生图模型听得懂的格式」—— 书把这种给工具能力短板打补丁的 Harness 代码叫适配层。
下面五种模式是工程里最常见的工作流骨架。命名取 Anthropic《Building Effective Agents》(书脚注所引,书中未逐一命名):
| 模式 | 形态 | 什么时候用 | 代价 |
|---|---|---|---|
| 提示链(prompt chaining) | 固定顺序的步骤,前一步输出是后一步输入 | 任务能清晰分解为固定子任务,且每步都能在上一步输出上做中间校验 | 延迟按步累加;路径写死,不能按中间结果改道 |
| 路由(routing) | 先分类,再分发到专用处理 | 请求类型互斥,各类需要不同的工具链/提示 | 判断错 = 整条链错;需要置信度阈值与低置信兜底 |
| 并行化(parallelization) | ① 分片(sectioning):拆成独立子任务并行;② 投票(voting):同一任务跑多次取多数 / 取优 | 分片:子任务互不依赖、结果可归并;投票:需要高置信、结果可比较 | 分片:要有归并逻辑,且要防共因失效;投票:花钱换方差 |
| 编排者-工作者(orchestrator-workers) | 由一个 LLM 动态分解任务并分派给工作者 | 子任务的数量与内容事先无法枚举 | 编排者本身是单点;它的上下文会累积所有子结果 |
| 评估者-优化器(evaluator-optimizer) | 生成者产出 → 评估者给反馈 → 循环改进 | 有明确可判的评价标准,且评判比生成容易 | 多轮调用推高成本;评估者若没有外部证据,容易越修越错 |
两条要展开说清楚的边界:
- 投票 / 辩论不等于「多个脑子」。 同一模型 + 相似上下文产生的多条结论不能自动当作独立证据;书第 10 章引的研究(Tran & Kiela, 2026)在多跳推理上对比单 Agent 与五种多 Agent 架构,思考 token 预算对齐后单 Agent 持平甚至更好,并给了信息论解释(辩论中多个 Agent 处理的是完全相同的文本信息,串行转述只可能丢信息)。真正有效的「多次」要么是独立采样再聚合(自一致性 / 多数投票),要么利用生成与验证的难度不对称。 判据见
multi-agent.md的判据层:协作是否引入了单个 Agent 拿不到的新信息。 - 评估者-优化器必须有外部证据,否则退化成不可靠的自审。 GPT-4 在没有外部反馈时自审,把对的改错的次数多于把错的改对的 —— 详细证据见
multi-agent.md。给评估者接上测试执行结果 / 渲染截图 / 外部工具验证,它才真正有效。
与
multi-agent.md的分工:那一篇从拓扑视角讲 supervisor / router / pipeline;这一篇从编排模式视角讲同几件事。实现上 supervisor 不神秘 —— 它就是一个「读状态 → 决定下一个节点 → 写状态」的节点,去掉包装就是一个分类器加一段调度代码(见multi-agent.md)。所以别把两篇的内容互相当成新知识重复讲。
3. 工作流的两个真实优势(书里的口径)#
书明确给了工作流的两个核心优势,都不在「省成本」上:
- 严格的流程控制。 关键步骤不被跳过或乱序执行,「付款前不能预订」这类业务规则由代码强制执行,不依赖 LLM 的判断。这是合规场景的硬要求 —— 把正确性建立在代码上,而不是建立在模型「记得住」上。
- 安全性。 因为执行路径确定,提示注入或模型犯错最多只能影响当前节点内部的处理,无法让 Agent 跳到不该执行的分支 —— 攻击面被限制在单个节点内。
局限也要一起说:缺乏变通性。 出现预设流程未覆盖的情况(比如用户在付款环节临时想改签、或航班取消需要推荐替代方案),固定节点路径无法灵活应对,只能走预设的异常分支,或把控制权交还给人类。
4. 自主 Agent:路径由环境反馈实时决定#
自主 Agent 与工作流的核心区别只有一条:执行路径不是预先定义的,而是 Agent 根据环境反馈实时决定的。 仍以订票为例,自主 Agent 不预定义四个节点:它会自行决定先搜索航班 → 发现要登录 → 先核实身份 → 回来搜索 → 发现最便宜的航班要转机 → 主动询问用户 → 按用户答复调整条件……
书里的几个要点:
- 自主 Agent 需要自主规划能力,还要能识别失败、调整策略,而不只是出错时停下。
- 自主性不等于无限制 —— 必须有显式的停止条件,否则容易陷入死循环或过度执行。书给的退出条件是:调用最终输出工具、模型返回没有任何工具调用的响应、遇到错误、达到最大轮数。
- 适用场景:开放式、难以预测所需步骤数的问题 —— Coding Agent 解 SWE-bench、Computer Use、需要迭代搜索与分析的研究任务。
- 代价:更高的成本 + 复合错误风险。部署时要在沙盒中充分测试、设置护栏与监控,并在关键决策点考虑加入人机协作检查点。
循环内部的机制(ReAct 的 Thought/Action/Observation、最大步数与预算、无进展检测、终止后返回什么)见
agent-react.md。本篇只说编排视角:路径的决策权在模型手里,而且必须给它一个出口。
5. 混合形态:这一篇的高分点#
工作流与自主 Agent 并非非此即彼。书给了两种混合方式。
混合方式一:按环节分工。 关键的、有严格合规要求的流程用工作流确保可靠性,需要灵活决策的部分切换到自主模式。以订票客服系统为例(书中参考答法):主体用工作流四节点「身份核实 → 搜索 → 付款 → 预订」保证「付款前不能预订」等合规顺序、把注入攻击面限制在单节点;而开放性环节(理解需求、改签、航班取消后的替代方案推荐)切换为自主 Agent;高风险操作(大额付款、退款)加人工确认。书里提到 n8n 这类工具允许在同一个系统里同时使用工作流节点和自主 Agent 节点。
混合方式二(更值钱):先由自主 Agent 把工作流写出来,再由工作流去执行。 这是书第 1 章提出、第 10 章展开的形态:
Agent 读完任务后自行决定拓扑并生成一段编排代码;代码一旦生成,执行阶段就退回工作流的确定性。
它解决一个具体痛点:管理者模式里,管理者始终待在循环中 —— 每派发一个子任务都要模型做一次决策,上下文随调用次数增长。 换成本方式后,「决定拓扑」只发生一次,后续的每一次调度都是确定性的代码。既保留了自主 Agent 面对未知任务的灵活性,又不必让模型在每次调度上都参与决策。
书第 10 章给的实例是 Claude Code 内置的 Workflow 工具:它给 Agent 提供 agent()、parallel()、pipeline() 几个原语,每个 agent() 是拥有独立上下文的子 Agent,schema 约定它只返回结构化结论而非完整轨迹。例如「为一篇技术稿件核实七组事实」——先按方向并行调研,再对每条发现逐条独立核实,最后统一汇总(pipeline 编排两个阶段 + parallel 展开逐条核实)。
判据一句话:把「决定拓扑」和「按拓扑执行」拆到两个时间点 —— 前者作一次性的、可审查的决策,后者是确定性的、可缓存的执行。任务的拓扑是否稳定,决定这条值不值得用:拓扑每次都不同就退化成方式一的自主模式;拓扑一旦定下来就能重复用,这条最划算。
6. 编排的工程要素#
不管哪种形态,一条编排落地的工程问题就这几件,每件给一句话判据:
| 要素 | 一句话判据 |
|---|---|
| 任务分解 | 子任务是否有独立的成功判据 —— 有才值得拆出来单独验收 |
| 路由与分发 | 分类的置信度能不能判断;低置信时有没有兜底(澄清追问,而不是硬走错分支) |
| 状态在节点间怎么传 | 参数传递(结构化、类型确定)还是共享状态(单一事实来源、可序列化、可恢复)—— 见 multi-agent.md 的 LangGraph 共享状态讨论 |
| 失败与补偿 | 有没有一个能回到上一稳定状态的检查点;不可逆操作的补偿动作是否显式定义 |
| 幂等 | 节点重跑一次会不会产生重复副作用 —— 写操作要么本身幂等,要么靠操作标识 / 补偿 |
| 并发与限流 | 瓶颈在哪一项(模型并发 / 稀疏资源);并发上限是防一两个节点打满全部配额 |
| 可观测 | 哪一步慢、哪一步贵能不能单独看出来(链路追踪记录每个节点的输入输出) |
状态传递这一条要单独记住一句话(它是错误级联的根源):进程之间传字节是逐位保真的,Agent 之间传语义每转述一次都是有损重编码(见 13-multi-agent-coordination.md)。所以 handoff 走结构化字段、不走自然语言总结 —— 有 schema 才可校验、可评测。可观测性在多节点编排里从加分项变成必需品:单 Agent 的轨迹是一条线,多节点编排的失败点可能在任意节点,没有每节点的输入输出就无法定位(机制层见 13-multi-agent-coordination.md)。
7. 框架对比:讲定位差异,不讲参数#
书第 1 章给了一张选型表。它按「核心定位 + 编排模式 + 开发方式」分档,比参数罗列有用得多:
| 分档 | 代表 | 定位 | 编排模式 | 开发方式 |
|---|---|---|---|---|
| 代码优先的通用框架 | LangChain / LangGraph | 通用 LLM 应用框架 | 工作流 + 自主 | 代码优先 |
| 低代码可视化 | n8n | 可视化工作流自动化 | 工作流 + 自主 | 拖拽 |
| Dify | LLM 应用开发平台 | 工作流 + 对话式 | 可视化 + API | |
| 任务运行时 / SDK | Codex Harness | Codex 的开源 Agent 运行时 | 自主 | 代码优先,可嵌入 |
| Claude Agent SDK | 生产级 Agent 开发框架 | 自主 | 代码优先 | |
| Pi | 极简 Coding Agent 框架 | 自主 | 代码优先 | |
| 角色化多 Agent | CrewAI | 角色化多 Agent 编排 | Multi-Agent 协作 | 代码优先 |
| 其他 | OpenClaw / DeepSeek Harness | 个人 Agent / 自进化框架 | 自主 + 事件驱动 / 插件 | 配置 + 代码 / 代码优先 |
怎么讲定位差异(这才是这道题要的):
- 第一档(LangGraph)给你显式的图 + 共享状态,控制流可枚举、可测试、可画出来 —— 你在 Writing Copilot 里用的就是这一档的真实经验。代价是你要自己设计 state schema。
- 第二档(n8n / Dify)把编排交给拖拽,适合业务自动化与非技术团队;代价是控制流藏在框架的画布后面。
- 第三档(Codex Harness / Claude Agent SDK / Pi)是自带自主循环的运行时 —— 你不自己写编排,框架替你跑循环,你只定义工具与边界。
- 第四档(CrewAI)是角色化多 Agent 的封装。
书明确给了选型的总判据:关键考量不在于框架本身的复杂度,而在于它能否用尽可能少的抽象层让你专注于业务逻辑;而且框架发展迅速,学会某个具体框架的用法并不重要。呼应 §1:每多一层抽象都是以后调试时新的盲区。
⚠️ 这一节是书里的表格口径。你实际用过的是 LangGraph 一家(Writing Copilot);其余框架的定位差异属于「我知道它们各自站在哪一档」,不是「我选过型」。
这张表只回答「站在哪一档」。 每个工具到底属于框架 / 运行时 / Harness / 持久化执行引擎的哪一类、各自的核心抽象是什么、以及怎么选型(含面经直接题里的 Eino),见 ./16-agent-runtime-tools.md。一句话联系:这一篇的七件工程要素(§6)就是运行时替你兜的那几件事,所以「要不要上运行时」的判据,和「这七件你打不打算自己写」是同一个问题。
8. 把线接到分布式:跨机器之后,问题换了#
前面所有讨论都默认编排在单机 / 单进程内。一旦编排跨进程、跨机器、要重启后继续,问题就从「谁定路径」变成「路径执行到一半,机器挂了怎么办」—— 后者是 07-distributed-systems/ 那一套:
| 单机编排里的工程要素 | 跨机器后的问题 | 去哪一篇 |
|---|---|---|
| 失败与补偿、检查点 | 状态机与持久化执行:把任务建模成显式状态机,每步落地成可恢复的 checkpoint | ../07-distributed-systems/state-machine.md |
| 路由与分发、并发与限流 | 任务队列 / 发布订阅:解耦、背压、死信、投递语义 | ../07-distributed-systems/queue-pubsub.md |
| 幂等、失败重试 | 超时 / 重试 / 幂等:部分失败、消息重投、重跑不产生重复副作用 | ../07-distributed-systems/timeout-retry-idempotency.md |
| 失败与补偿(不可逆操作) | 事务 / WAL / Saga / 补偿 | ../07-distributed-systems/transaction-wal.md |
一句话收口:单机内的编排问题是「谁定路径」,跨机器之后是「路径执行到一半、部分失败怎么继续」 —— 后者要面对部分失败、消息重复投递、状态一致性这些单机里不存在的问题。这也是这一篇存在的理由:它讲的是入口,出口在 07-distributed-systems/。
常见面试问法#
Q:什么时候用工作流,什么时候用自主 Agent? A:先按「从简单到复杂」的顺序排除:先考虑单次 LLM 调用,优化提示与上下文示例能解决就别上 Agent 系统;需要多步且能清晰分解成固定子任务,就用工作流;只有步骤依赖中间结果、事先无法枚举,必须动态决策时,才用自主 Agent。要记住 Agent 系统本质是用延迟和成本换任务性能,不是更自主就更好。书里的反面例子:给「从百万条聊天记录提炼记忆」一上来画六七个 Agent 的流水线,每个部件都合理、组合起来很低效 —— 因为固定拓扑遇到新例外只会不断加节点,把模型本来能做的语义判断写死了。
Q:工作流比自主 Agent 好在哪? A:书里的口径是两点,都不在省钱上。 ① 严格的流程控制:「付款前不能预订」这类规则由代码强制执行,不依赖 LLM 判断;② 安全性:执行路径确定,所以提示注入或模型犯错最多影响当前节点内部,无法跳到不该执行的分支,攻击面被限制在单节点内。代价是缺乏变通性 —— 流程未覆盖的情况只能走预设异常分支或交还人类。所以生产系统常用混合:合规流程走工作流,开放环节切自主模式。
Q:除了「一部分工作流、一部分自主」,还有什么混合方式?
A:「先由自主 Agent 把工作流写出来,再由工作流去执行」 —— Agent 读完任务自行决定拓扑并生成编排代码,代码生成后执行阶段退回确定性。它解决的问题是:管理者模式下管理者始终待在循环里,每派发一个子任务就要模型决策一次、上下文随调用次数增长;换成本方式后**「决定拓扑」只发生一次**。书第 10 章的实例是 Claude Code 的 Workflow 工具(agent() / parallel() / pipeline(),每个 agent() 独立上下文、只返回结构化结论)。判据是任务的拓扑稳不稳定:每次都不同就退化成自主模式,稳定可复用才划算。
Q:一条编排在工程上要处理哪些事? A:七件,每件一句话判据:任务分解(子任务有没有独立成功判据)、路由与分发(分类置信度可判吗、低置信有兜底吗)、状态怎么传(参数传递还是共享状态;Agent 间传语义每转述一次都是有损的,所以 handoff 走结构化字段)、失败与补偿(有没有回到上一稳定状态的检查点)、幂等(节点重跑会不会重复副作用)、并发与限流(瓶颈在哪、并发上限防打满配额)、可观测(哪一步慢、哪一步贵能不能单独看出来)。多节点编排没有可观测性等于不可运维 —— 单 Agent 的轨迹是一条线,多节点的失败点在任意节点。
Q:你的编排什么时候会从「单机」变成「分布式问题」?
A:一旦跨进程、跨机器、要重启后继续,问题就从「谁定路径」变成「路径执行到一半挂了怎么办」。 这时要面对部分失败、消息重复投递、状态一致性 —— 单机里不存在的问题。对应到三块:状态机与持久化执行(每步 checkpoint)、任务队列(解耦与背压)、超时重试幂等(重跑不重复副作用)。判据是:任务能不能在一次进程生命周期内跑完 —— 能,就还是编排问题;不能,就要 07-distributed-systems/ 那套。
易错点#
| 易错说法 | 问题 | 应该说 |
|---|---|---|
| 「更自主 = 更好,直接上自主 Agent」 | 默认反了 | 从简单到复杂:先单次调用 → 工作流 → 只有必须动态决策才用自主 Agent。Agent 系统是用延迟和成本换任务性能 |
| 「复杂工作流一定比简单方案强」 | 固定拓扑的代价 | 书里的反面例子:每个部件都合理、组合起来很低效;新例外只会不断加节点,把模型的语义判断写死了 |
| 「工作流的优势是省钱」 | 答偏了 | 书里的口径是流程控制(合规规则由代码强制)+ 安全性(攻击面限在单节点) |
| 「自主 Agent 不需要停止条件,它会自己完成」 | 漏了硬约束 | 必须有显式停止条件:调用最终输出工具 / 返回无工具调用的响应 / 遇到错误 / 达到最大轮数 |
| 「工作流和自主 Agent 只能二选一」 | 漏了混合 | 按环节分工(合规走工作流、开放环节切自主)+ Agent 写工作流、工作流再执行 |
| 「多个 Agent 辩论 = 更强的判断」 | 同源信息 | 思考预算对齐后单 Agent 持平甚至更好(Tran & Kiela, 2026);相似上下文的结论不能当独立证据 |
| 「让模型自审就能提升质量」 | 自审不可靠 | 无外部反馈时 GPT-4 自审把对的改错的多于把错的改对的;评估者要接测试 / 截图 / 工具验证 |
| 「handoff 用自然语言总结就行」 | 有损重编码 | 传字节逐位保真,传语义每转述一次有损;handoff 走结构化字段才可校验、可评测 |
| 「节点重试没问题」 | 漏了幂等 | 节点重跑会不会产生重复副作用 —— 写操作要么幂等,要么靠操作标识 / 补偿 |
| 「先上七个 Agent 再说」 | 违反从简原则 | 先做最小可用形态,只在评测反复暴露某类稳定失败时才升级为独立 Agent / 确定性流程 |
| 「选框架看谁功能多」 | 判据错 | 书里:看它能否用尽可能少的抽象层让你专注业务逻辑;每多一层抽象都是调试盲区 |
| 「编排跨机器只是部署问题」 | 换了问题 | 跨机器后是部分失败 / 消息重投 / 状态一致性,要状态机、队列、幂等三件套 |
| 把框架对比讲成「我都用过」 | 触碰仓库硬规矩 | 书里的表格口径;你的一手经验只有 Race Bot 的编排式工作流与 Writing Copilot 的 LangGraph |
自测#
1. 有人要做一个「从百万条聊天记录提炼个人记忆」的系统,方案是六七个 Agent 串成的流水线(切分 → 提取 → 证据核验 → 身份解析 → 记忆整理 → 合并复核)。你按书里的原则怎么评价?
答案
这正是书里那个反面例子。 评价分三点:
- 它违反了「从简单到复杂」的顺序。 先该问:单次调用 + 好的提示与上下文示例能不能解决?不能的话,这个任务能不能清晰分解为固定子任务?如果能,也只是工作流,不该一上来铺六个 Agent。
- 固定拓扑是它真正的病根。 书里的原话是:每个部件单看都有道理,组合起来却很低效、不可靠 —— 因为复杂工作流的执行拓扑是固定的,遇到新例外,系统很容易继续增加节点,架构越来越复杂,通用性却越来越差;而模型原本能根据上下文处理的语义判断,反而被工作流写死了。
- 正确的方向是「减少结构、保留判断」。 书引 Manus「Less structure, more intelligence.」:给一个能力足够的 Agent 清晰的目标、必要的上下文和可组合的工具,用自然语言告诉它如何查证、比较、处理冲突;程序只固化必须始终成立的边界(权限、不得覆盖原始材料、原子发布)。只有业务约束本身要求,或评测反复暴露出某类稳定失败时,才把对应步骤升级为专门的验证器、独立 Agent 或确定性流程。
可以补一句:这不是说这个任务不能拆,而是拆的依据应该是「子任务有独立成功判据 / 独立评测价值」,不是「流程图看起来严谨」。
2. 一个订票客服系统:「付款前不能预订」是硬合规要求,但用户经常临时改签、或航班取消要推荐替代方案。你会怎么设计?
答案
混合设计,而且这是书里参考答法的标准形态:
- 主体走工作流四节点:身份核实 → 搜索 → 付款 → 预订。理由是工作流的两个优势正好对上这个需求:① 流程控制 —— 「付款前不能预订」由代码强制执行,不依赖 LLM 判断;② 安全性 —— 执行路径确定,提示注入或模型犯错最多影响当前节点内部,无法跳到不该执行的分支,攻击面被限制在单节点内。
- 开放性环节切自主 Agent:理解需求、改签、航班取消后的替代方案推荐 —— 这些步骤依赖中间结果、事先无法枚举,正是自主 Agent 的适用场景(路径由环境反馈实时决定)。
- 高风险操作加人工确认:大额付款、退款这类不可逆操作,加人机协作检查点。
- 两侧都要有停止条件与兜底:自主那一侧必须有显式停止条件(书给的退出条件:调用最终输出工具 / 返回无工具调用 / 遇到错误 / 达到最大轮数);工作流那一侧要定义流程未覆盖时「走预设异常分支还是交还人类」。
- 实现上:书里提到 n8n 这类工具允许在同一个系统中同时使用工作流节点和自主 Agent 节点。
为什么不能全用自主 Agent:那样「付款前不能预订」就依赖模型判断而不是代码,合规性没有保证,而且攻击面从一个节点扩散到整条链。
3. 「先由自主 Agent 把工作流写出来,再由工作流去执行」是什么意思?它比让 Agent 一直待循环里好在哪?什么任务不适合它?
答案
含义(书第 1 章提出、第 10 章展开):Agent 读完任务后自行决定拓扑并生成一段编排代码;代码一旦生成,执行阶段就退回工作流的确定性。 书第 10 章的实例是 Claude Code 的 Workflow 工具,提供 agent() / parallel() / pipeline() 原语,每个 agent() 是拥有独立上下文的子 Agent,schema 约定只返回结构化结论而非完整轨迹。
好在哪:它解决管理者模式的痛点 —— 管理者始终待在循环中,每派发一个子任务都要模型做一次决策,上下文随调用次数增长。换成本方式后,「决定拓扑」只发生一次,之后的每次调度都是确定性代码。既保留自主 Agent 面对未知任务的灵活性,又不必让模型在每一次调度上参与决策。
判据一句话:把「决定拓扑」和「按拓扑执行」拆到两个时间点 —— 前者作一次性的、可审查的决策,后者是确定性的、可缓存的执行。
什么任务不适合:拓扑本身不稳定、每次都要重新决定的任务(比如开放式研究、需求天天变的探索性工作)—— 那样生成的代码只用一次就废,等于白付了生成代价,不如直接让自主 Agent 跑。只有拓扑一旦定下来就能重复用时,这条才划算。
4. 一条三段式编排(检索 → 生成 → 校验)要上生产。除了「能不能跑通」,你还要考虑哪些事?
答案
按 §6 的七件工程要素过一遍,重点答状态、幂等、可观测三条:
- 任务分解 / 路由与分发:三段的边界是否清晰(每段有独立成功判据);如果有分类,低置信时有没有兜底(澄清追问,而不是硬走错分支)。
- 状态在节点间怎么传(重点):参数传递还是共享状态 —— 共享状态是「单一事实来源」,可序列化因而支持持久化与恢复(LangGraph 的做法),代价是状态容易膨胀、易出隐式耦合(
multi-agent.md)。并且记住:Agent 间传语义每转述一次都是有损重编码,所以段与段之间走结构化字段,不走自然语言总结。 - 失败与补偿:有没有一个能回到上一稳定状态的检查点;校验段发现的错误是「让生成段重来」还是「走补偿」,要显式定义。
- 幂等(重点):节点重跑会不会产生重复副作用。检索、生成这类只读 / 可重复的没问题;如果某段有写操作,要么本身幂等,要么靠操作标识 / 补偿 —— 否则重试就是重复执行。
- 并发与限流:瓶颈在哪一项(模型并发 / 稀疏资源);并发上限防一两个节点打满全部配额。
- 可观测(重点):哪一步慢、哪一步贵能不能单独看出来。多节点编排没有可观测性等于不可运维 —— 单 Agent 轨迹是一条线,多段的失败点在任意段。
再补一句边界:如果这三段是跨进程、跨机器、要重启后继续的,那就不只是编排问题,要引入 07-distributed-systems/ 的状态机、队列与幂等三件套(见 §8)。
5. 面试官说「我们的编排现在跑在一台机器上,挺好的,为什么要考虑分布式」—— 你怎么答?
答案
先承认前提正确,再指出什么时候会变。 判据是:任务能不能在一次进程生命周期内跑完。能,单机编排就够了,不要为了分布式而分布式(这正好呼应书里「保持简单」的原则 —— 直接的方案优于复杂的抽象)。
一旦跨进程、跨机器、或要重启后继续,问题就换了:从「谁定路径」变成「路径执行到一半挂了怎么办」。这时会遇到单机里不存在的三类问题:部分失败(不是全成或全败,而是做了一半)、消息重复投递(重试导致同一节点被执行两次)、状态一致性(状态分散在多处、恢复时要核对)。
对应三块:
- 状态机与持久化执行 —— 把任务建模成显式状态机,每步落地成可恢复的 checkpoint(
../07-distributed-systems/state-machine.md)。 - 任务队列 / 发布订阅 —— 节点间解耦、背压、死信(
../07-distributed-systems/queue-pubsub.md)。 - 超时 / 重试 / 幂等 —— 重跑不产生重复副作用;这一步其实在单机就该做好,跨机器只是让它的必要性变得不可回避(
../07-distributed-systems/timeout-retry-idempotency.md)。
收口:单机内的编排问题是「谁定路径」,跨机器之后是「路径执行到一半、部分失败怎么继续」。 所以不是「要不要分布式」,而是先问任务的生命周期能不能被一个进程包住。