正在刊行长文 · Essay
2026-08-17所有内容
随机比特 · Random Bits

多 Agent 不是多写几个角色:用失败域而不是岗位名拆系统

2026-08-17AI Engineering / Systemsrbits.uk
多 Agent 不是多写几个角色:用失败域而不是岗位名拆系统

先看一个很像「AI 公司」的系统。

它有规划员、研究员、分析师、写作者和审稿人。五个 Agent 各有名字、头像和不同的系统提示词。任务一进来,规划员开工单,研究员四处搜索,分析师整理数据,写作者生成报告,审稿人负责挑错。

演示界面很热闹,像隔着玻璃看一家创业公司加班。

直到某次供应链风险报告出了问题。一个研究员碰到接口限流,在同一批查询上循环重试;主管 Agent 一直等它,其他分支早已完成却无法进入汇总;分析师从共享笔记里读到一段未完成草稿,把旧季度数据当成最新证据;审稿人只检查最终文风,没有发现其中一条关键结论来自失败分支。

两个小时后,系统还是交出了一份像模像样的报告。成本翻了几倍,时效已经错过,结论里还混进一个旧版本数字。

复盘时,每个人都在问同一个问题:到底是「研究员提示词」写坏了,还是「主管 Agent」不够聪明?

其实真正坏掉的不是某个角色,而是系统根本没有边界。五个名字背后共享同一段状态、同一组工具、同一个等待链和同一笔预算。一个 Agent 发疯,整个团队陪它加班;一个分支被污染,所有下游都把污染当共识。

这一区分很重要:角色名解决的是专业化,失败域解决的是一个错误最多能伤到哪里。

岗位拆分与失败域拆分

这是多 Agent 系统最常见的结构错觉:把组织架构画出来,就以为软件架构也出现了。

「规划员」和「审稿人」只是提示词里的身份。只要它们共享无限制上下文、能调用相同写工具、同时修改同一份状态、失败后必须整体重跑,它们就仍然属于同一个失败域。给同一个进程换五张工牌,不会自动长出五道防火墙。

多 Agent 当然不是伪命题。对高价值、可并行、信息量超过单一上下文,而且需要调用很多独立工具的任务,它能把搜索空间铺开,让多个工作单元同时探索。问题在于,很多团队只复制了「多」,没有设计「为什么彼此独立」。

判断是否该拆 Agent,先别问公司里有哪些岗位,而要连续问四个问题。

谁拥有状态?哪个单元可以修改计划、证据集和最终工件?

谁拥有能力?哪个单元只读,哪个能发信、退款、改库或发布?

谁承担故障?一个单元超时、循环、遭到脏输入或输出不完整时,哪些任务必须一起失败?

谁负责恢复?能否只重跑出错分支,还是必须从用户第一句话重新开始?

四个答案都相同,多 Agent 只是在一个更贵的单 Agent 里模拟开会。 拆分的目的不是让每一步都离线自治,而是让并行发生在可分离的地方,只在确实必要的位置共享状态。

真正可控的拆法,不是照抄岗位,而是先把运行时、规划、工作、验证和执行分开。

运行时保存任务图、状态版本、预算、超时、取消和检查点。它最好尽量确定,不负责临场写长篇战略。规划单元读取目标与策略,产出结构化依赖图,却没有业务写权限。工作单元拿到局部目标、有限上下文和有限工具,各自在独立预算内生成工件。验证单元只读证据和工件,返回机器可消费的接受或拒绝理由。真正改变外部世界的执行单元则尽量少,所有权限、确认、幂等和回执都在那里收口。

这些「单元」不一定各对应一个模型。某些路由和校验就应该是代码;某个模型也可以在两种不同权限环境里承担两段工作。关键不是屏幕上出现几个头像,而是哪种错误被哪道边界截住。

按失败域组织的多 Agent 架构

这样的架构会迫使团队承认一件不太浪漫的事:Agent 之间不应该靠自由聊天完成关键交接。

自由聊天适合探索,不适合当系统总线。上游说「我大概查完了」,下游无法知道这句话对应哪个数据版本、覆盖了哪些对象、是否因为超时只完成了一半。共享整段聊天历史看似减少信息损失,实际把每个 Agent 的噪声、注入内容和过期判断广播给所有人。

更稳妥的交接物是一份子任务契约加一个版本化工件。

契约至少要说明:任务标识和父任务,局部目标,允许读取的输入引用,允许调用的工具与资源范围,输出 Schema,token、时间和调用预算,完成期限,重试条件,取消信号,以及结果如何加入主任务。

工件则要带上来源、输入版本、生成者、完整性状态和校验结果。聚合器读取的是「已验证的证据包 v3」,不是一段叫作 final_final_really_final 的共享笔记。

一个可执行的子任务契约

契约的作用不是把 Agent 写死,而是把自由留在边界里面。研究员可以选择不同关键词、不同搜索顺序和不同证据组合,但不能偷偷扩大数据范围;写作者可以改变结构,却不能把未验证草稿升级成事实;审稿人可以做语义判断,却不能顺手修改原始证据来让文章通过。

状态也要有明确所有者。

最简单的办法是把共享状态做成单写多读的黑板:运行时负责版本和并发控制,工作单元只能提交新工件,不能覆盖别人的历史;计划更新产生新版本,旧分支要么显式迁移,要么在旧版本上完成后被隔离。这样出现冲突时,系统知道是谁基于哪个版本做了什么,而不是让最后一次写入把前面的历史抹掉。

接下来是最容易把多 Agent 拖成慢 Agent 的 join,也就是「等谁回来再继续」。

不是所有分支都值得等齐。合规检查和授权证据缺一个都不能执行,可以用 all;三路独立核验可以用 quorum;多条搜索路径只需要一个满足质量门槛的结果,可以用 first-valid。一个可选背景分支超时,不应自动拖死主任务;一个强依赖分支失败,也不能被汇总器用流畅语言悄悄补齐。

重试同样要局部化。限流和短暂网络失败可以在预算内退避;输入本身有毒、权限错误、Schema 确定不匹配,重复十次只会把事故打印十份。取消信号要向下传播,但已经发出的邮件和已经写入的订单不会因为父任务取消就自动消失,仍要依靠回执、幂等或补偿处理。

最慢分支、最脏分支和最贵分支,都应该有自己的舱门。

故障如何被局部隔离

失败域设计还有一个经常被忽略的价值:它让团队终于能回答「到底是谁把事情搞坏了」。

只看最终报告得分,多 Agent 系统会遇到典型的信用分配难题。研究员找到了关键证据,写作者却删掉了它,最终低分无法直接归因;两个 Agent 重复搜索,结果质量不变但成本翻倍,全局质量分看不出浪费;验证器拦住一份错误工件,虽然增加了延迟,却可能避免了更大的事故。

因此除了全局成功率,还要给每个边界留下局部证据:子任务是否满足契约,输出是否被下游接受,覆盖是否和其他分支重复,触发了多少重试与降级,消耗了多少预算,被拒绝后有没有带来可复现的修复,以及某个分支失效时波及了多少兄弟任务。

这些指标不是为了给 Agent 排绩效,而是为了定位系统的因果链。没有局部证据,全局 82 分只会让五个角色一起参加提示词团建。

落地时,不需要先重写整个编排平台。挑二十个真实任务,保留现在的单 Agent 方案,再搭两组对照。

A 组由一个 Agent 从头做到尾。B 组按规划员、研究员、写作者和审稿人拆开,但共享上下文与资源。C 组不追求更多角色,只增加结构化工件、局部预算、状态版本、受控 join 和收口的写入口。

然后给三组注入同样的故障:一个搜索分支持续限流,一份证据带有误导指令,一个工作单元变成慢节点,父任务中途取消,一次写操作返回未知状态。

比较的也不能只有最终质量。还要看 P95 延迟、token 与工具成本、重复工作率、故障波及分支数、重复副作用、局部恢复率,以及下游拒绝能否定位到具体输入版本。

这个实验不是为了预设 C 组一定更聪明。它要回答的是:在质量相近时,哪种结构能把失败限制得更小、恢复得更便宜、解释得更清楚。

三组架构的最小故障实验

准备上线前,还可以做一次很朴素的验收。

上线门槛应要求每个子任务都有明确输入、输出、工具范围和预算;共享状态有唯一所有者与版本;每种 join 写清缺失分支的语义;超时、重试和取消沿依赖图传播;验证贴着真正产生副作用的工具;单个 worker 失败后可以局部恢复;旧版本任务不被新部署中途改写;全局失败能够下钻到具体工件和调用。

如果这些问题没有答案,继续增加 Agent 只会增加事故现场的目击者。

回到开头那家五人「AI 公司」。真正的修复不是给研究员补一句「遇到限流请冷静」,也不是再招聘一个「项目经理 Agent」。

它需要把研究分支放进独立预算,把未完成工件标成不可汇总,让慢节点不再绑架无关分支,让验证器只读证据,让写操作经过唯一受控入口。此后研究员仍然可能失败,但它的失败只会停在自己的舱室里。

多 Agent 的价值,从来不在于让屏幕上看起来有一支团队。

而在于系统终于知道:谁能做什么,谁拥有哪段状态,一处进水时该关上哪扇门。

作者|随机比特

随机比特公众号二维码
公众号 · 随机比特
从 AI 工具热闹里拆工程真相

写边界、控制面、上下文、成本与安全。