我说你把面试过程尽量还原给我。
他答得很细。前两轮都过了——项目、JVM、并发,答得都不错。
三面是架构面。面试官先让他讲手上那个 AI 项目,他讲了大概十分钟——四个 Agent:理解意图、检索知识库、生成回答、质量校验,串起来跑。
讲完,面试官开始往下挖。一共四个回合:
第一问检索那个 Agent 如果超时了,你们怎么处理?他答:重试一次,还失败就走兜底话术。
第二问重试的时候,前面意图理解的结果还要重跑一遍吗?他愣了一下:应该不用吧,我们是缓存下来的。
第三问把最后的质量校验改成三路并行,准确性、合规性、可读性各一路,改动大吗?他答:那得改不少代码,现在流程是写死的。
第四问想让不同类型的咨询走不同链路,账单走财务 Agent、技术走技术 Agent,现在这套能支持吗?他答:可以加 if-else。
四个回合,他每一问都答了,没有一句接不上。
但面试官心里已经有判断了。最后他说了一句:你搭的不是多 Agent 系统,是一条写死的流水线。
复盘的时候我把这四个回合记下来,发现它们指向的是同一件事。
他挂的不是知识盲区。五种编排模式——链式、并行、路由、层级、反思——他都能说出来,自己项目用的哪一种也清楚,还能讲两句为什么选它。
他缺的是这些模式为什么存在,以及在什么条件下该换成另一个。
换句话说:他知道工具箱里有什么,但没想过工具箱是拿来干什么的。
这一层,叫编排层。
编排模式解决的是「Agent 怎么连」,编排层解决的是「任务怎么走」。
前者是拓扑,后者是策略。
复盘完之后,我把这四个回合的问题往上抽了一层,拿去问身边做 AI 应用的团队——
第一个 Agent 挂了,链路怎么恢复?
A 的中间结果传到 E,还剩多少有效信息?
换一类任务进来,编排逻辑要不要改代码?
三个都能答上来的,不多。
这篇文章,就是那次复盘的完整版。大部分多 Agent 项目不是在选错模式上翻车的,是在编排层这一层翻车的。
1.多 Agent 系统 ≠ 多 Agent 编排
这两个词经常被混着用,但它们是两件事。
多 Agent 系统描述的是「有几个 Agent」。三个 Agent 互相调用,就是多 Agent 系统了。门槛很低,低到只要你愿意,写三个类就能自称。
多 Agent 编排描述的是另一组问题:在什么条件下、用哪种协作方式、以什么顺序、传递什么状态、失败之后怎么办。
举个不恰当但好记的类比。乐队里多坐几个人,不叫交响乐。有指挥、有谱子、知道第二乐章该谁进,才叫交响乐。
多出来的那几个 Agent,就是多坐的那几个人。谱子和指挥,才是编排。
怎么判断自己有没有编排层?看三个特征:
特征 | 落地表现 |
动态性 | 同一套代码,能根据任务状态切换到不同的协作策略,而不是换任务就改 if-else |
状态显式 | 状态如何产生、如何流转、如何裁剪,是写在代码里的,不是藏在某个 Agent 的 prompt 里 |
失败可恢复 | 局部失败后重规划或降级,而不是把整条任务从头再跑一遍 |
三个都占了,才谈得上编排。少一个,本质上就是「多个 Agent 各干各的」。
2.五种模式,一张表过完
先把地基铺上。多 Agent 编排的协作模式,收敛下来就五种,一张表能说完。
模式 | 一句话 | 选型条件 | 核心代价 |
链式 | A→B→C 顺序传递,像流水线 | 任务有严格先后依赖,且环节不超过 5 步 | 脆弱:断一环全停;越靠后信息越少 |
并行 | 子任务同时下发,汇总节点收敛 | 子任务之间无依赖,且需要多维度整合 | 汇总 Agent 就是输出上限;Token 成倍消耗 |
路由 | 先识别类型,再对口分派专家 | 任务类型边界清晰 | 判错就派错;跨类型需求无解 |
层级 | 树形管控,编排器管编排器 | 项目分阶段、复杂度高,且阶段内部仍需协作 | 延迟随层数上升;极易过度设计 |
反思 | 执行-评审-迭代闭环 | 质量要求极高,且用户能接受等待 | 轮次不可控;评审标准偏了会越改越差 |
五种模式画成拓扑,差别一眼能看出来:
这张表能撑住你 80% 的选型。但请注意,它回答的是「怎么连」。
而系统跑不通,往往是因为下面这四件事。
3.真正难的是这四件事
这四条,选型表里一个字都不会写,但它们才是你上线之后每天要面对的东西。
3.1 上下文在传递中衰减
链式编排最容易被忽略的问题,不是慢,是信息衰减。
A 产出一份 3000 token 的分析,B 拿到之后总结成 800 token,C 再压缩到 200 token。等到 D 要用的那个关键数字,可能在 C 那一步就被当作「细节」扔掉了。
层级编排更明显。每一层抽象都在做有损压缩,压三四层之后,底层的事实已经变形了。
这个问题的本质是:你让 Agent 互相传「对话」,而不是传「状态」。
工程上的解法是黑板模式(Blackboard)。所有 Agent 读写同一个共享状态区,谁需要什么自己取,而不是把上游的整段上下文往下灌。
public class OrchestrationContext { // 所有 Agent 共享的状态区 private final Map<String, Object> blackboard = new ConcurrentHashMap<>(); // 产出写入黑板,key 用「阶段.字段」命名,避免撞车 public void put(String key, Object value) { blackboard.put(key, value); } // 需要什么取什么,不做整段上下文传递 public <T> Optional<T> get(String key, Class<T> type) { return Optional.ofNullable(blackboard.get(key)).map(type::cast); } // 关键:给 LLM 的是「按阶段裁剪过的视图」,不是全量状态 public String viewFor(String stage) { return VIEW_SPEC.get(stage).stream() .map(k -> k + ": " + blackboard.get(k)) .collect(Collectors.joining("\n")); } }区别就在最后那个viewFor。
上游把全量状态写进黑板,但每个阶段只能看到自己该看的那几个字段。既避免了链式传递的信息衰减,也顺手解决了上下文窗口被无关内容占满的问题。
坑黑板别做成大杂烩。字段命名一定要带阶段前缀,否则三个人并行开发,一星期后没人知道这个 key 是谁写的、还能不能删。
3.2 失败之后是重跑,还是重规划
这是区分「有编排层」和「没编排层」最直接的一道题。
没编排层:第 7 个 Agent 报错了,异常往上抛,整个任务失败。用户看到「系统繁忙,请重试」,然后从头再跑一遍。前面 6 个 Agent 的钱,白花了。
有编排层:第 7 个 Agent 报错了,编排层知道前面 6 步的产出已经落在黑板里,于是尝试换一个 Agent 兜底、或者降级输出、或者只重跑第 7 步。
要做到这一点,需要两个前提:状态可序列化,步骤尽量幂等。做不到这两条,你的「重试」就只能是从头再来。
所以编排层的主循环长这样:
public TaskResult run(Task task) { OrchestrationContext ctx = new OrchestrationContext(); TaskState state = TaskState.ROUTE; while (state != TaskState.DONE && state != TaskState.FAILED) { if (budget.exhausted()) { // 预算兜底 state = TaskState.DEGRADE; continue; } try { state = nodes.get(state).execute(ctx); // 节点返回下一个状态 } catch (AgentException e) { state = compensate(state, e); // 局部失败 -> 重规划 } budget.consume(ctx.deltaUsage()); } return TaskResult.of(state, ctx); }这个循环里有两个设计值得单独说:execute返回的是「下一个状态」而不是「结果」——状态推进权在编排层手里,Agent 没法自己乱跑;compensate把异常转成状态跳转,失败就成了流程的一部分,而不是流程的终点。
3.3 成本必须有预算概念
并行编排 Token 翻 N 倍,这个大家都知道。真正失控的是反思编排。
「不达标就打回重写」听着很美,但它是个开环。评审 Agent 的标准只要稍微严一点,迭代就停不下来。我见过一个内容生成的场景,一个任务反复改了 11 轮,最后产出的质量还不如第 3 轮。
编排层必须给任务挂预算,而且得是三重的:Token 预算、时长预算、迭代轮次上限。任何一项触顶,强制走降级出口——返回当前最优结果,而不是继续烧。
预算触顶后的降级策略,也是要提前设计的:是返回半成品,还是返回上一轮结果,还是转人工?这三种在业务上的体验完全不同。
3.4 可观测性:多 Agent 的日志是线团
单 Agent 出问题,看日志就行。多 Agent 出问题,你面对的是几路日志交织在一起的线团,而且每路都是一个 LLM 的输入输出。
最低限度,你得能回答四个问题:
这次任务走了哪条路径?(状态流转轨迹)
每一步花了多少钱、多少时间?
哪一步失败了,失败时黑板里有什么?
同一个任务重跑一次,路径会不会不一样?
最后一条尤其重要。LLM 的输出有随机性,路径不稳定意味着你的系统行为不可复现。这也是为什么很多团队最后会走回「关键节点用规则兜底、只在明确的环节放 LLM」——不是不信任模型,是要保住可复现性。
4.编排层的三种落地形态
道理说完,说说怎么落地。编排层不是非得引入什么框架,它有三种形态,复杂度递增。
形态一:硬编码状态机
就是枚举 + switch。状态不超过 5 个、分支不超过 10 条的时候,这是最省事也最好调试的方案。别看不起它,很多跑得稳的系统就这么写的。
但它有个明确的崩点:状态一多,状态转移的合法性就得靠人脑维护,漏一个分支就是线上事故。
形态二:图结构编排
把状态机画成一张图:节点是 Agent,边是转移条件。图引擎帮你做拓扑校验、并行调度、断点恢复。LangGraph 这类框架走的就是这条路,自研一套也不复杂。
适合协作关系复杂、需要动态并行的场景。
形态三:声明式编排
编排逻辑从代码里抽出来,用 YAML 或 DSL 描述。好处很实在:业务规则变了不用发版,改配置就行。
orchestration: order-exception steps: - id: classify agent: router next: STOCK_OUT: [checkStock, buildCompensation] PAY_TIMEOUT: [queryPayment, retryOrRefund] RISK_BLOCK: [riskReview] - id: checkStock agent: inventory parallel: [checkRisk, loadUserProfile] # 同组并行 - id: buildCompensation agent: planner review: quality-checker # 反思:评审不过打回 maxRetries: 2 budget: maxTokens: 120000 maxSeconds: 60代价是调试变难了。逻辑不在代码里,断点打不进去,出问题只能靠链路追踪反查。
选择标准状态少于 5 个用形态一,别过度设计;协作关系会持续变复杂,直接上形态二;只有「业务规则频繁变、却又不值得发版」这一个理由,才值得付形态三的调试成本。
5.一个完整的例子:订单异常怎么编排
拿电商的订单异常处理来串一遍。这个场景好在,它天然有分类、有并行、有串行、有质量要求,五种模式里能用到四种。
场景是这样的:用户下单之后,订单卡住了。可能的原因有一堆——库存不足、支付超时、地址异常、风控拦截。
把这四种模式串起来,整条链路是这样:
路由异常分类 Agent 先判断类型,分派到不同的处理链路。这一步不能省,否则所有异常都走同一条又长又慢的路。
并行库存、风控、用户画像三个查询同时发起。它们之间没有依赖,串行跑纯属浪费。汇总节点收敛成一份「异常上下文」。
链式补偿方案生成 → 人工审核 → 执行。这三步有严格先后依赖,而且只有三步,链式最合适。
反思补偿话术生成之后,交给评审 Agent 检查——金额算得对不对、措辞会不会引发投诉。不达标打回重写,但轮次上限卡死 2 轮。
你会注意到,编排层在这里的角色不是「调用 Agent」,而是「决定此刻该用哪种协作方式」。
风控拦截的订单,压根不需要走补偿方案生成,直接从风险评估跳到人工介入。库存不足的订单,话术要往「调货」方向走而不是「退款」方向走。这些决策都不属于任何一个 Agent,只属于编排层。
模式是静态的,任务状态是动态的。
真实系统里,同一个任务在推进过程中会需要换协作方式。能在运行中做出这个切换的,才是编排器;做不到的,只是调度器。
6.选型:一套顺序,一句口诀
最后落到可执行的东西上。选型别一上来就比框架,先过下面这个顺序:
第一问:任务之间有依赖吗?有严格先后 → 链式;完全独立 → 并行。
第二问:需要多维度整合吗?需要 → 并行 + 汇总;只需要一类专业能力 → 考虑路由。
第三问:复杂度是分阶段的吗?是,且阶段内部还要协作 → 层级。否则别上,这是最容易过度设计的一档。
第四问:质量要求高到需要返工吗?是,且用户能等 → 反思,但必须配轮次上限。
第五问:预算够吗?并行翻倍、反思无上限,算不清就先降级方案。
如果嫌长,记这五句就行——
先后有依赖,链式。
子任务独立,并行。
类型有区分,路由。
复杂分阶段,层级。
追求高质感,反思。
但还是要补一句:真实生产环境里,几乎没有系统只单用一种模式。
模式是零散的积木。会用积木搭出什么,取决于编排层怎么决策。
写在最后
复盘到最后,那位读者问了我一个问题:那我下一轮面试,该怎么答这一题?
我说你把回答分成两层。
第一层说模式:链式、并行、路由、层级、反思,我们系统里用到了哪几种、为什么选它。这一层证明你知道工具箱里有什么。
第二层说编排层:状态放在哪、失败怎么兜、预算怎么卡、路径怎么追。这一层证明你能把工具箱用起来。
只答第一层,是名词解释;答到第二层,才是架构设计。
写这篇文章的过程中,我自己最大的收获也是把这两个词分开看了:模式和编排层。
模式是可以背的,网上一搜一大把,五种十种都有人总结。编排层是设计出来的,它取决于你的任务长什么样、失败成本有多高、预算有多少。
AI 可以帮你完成单个 Agent 的代码调用,但做架构决策、场景选型、风险兜底,才是技术人不可替代的那部分价值。
死板的代码可以被 AI 替代,灵活的架构思维,才是我们的核心竞争力。