多智能体协作的故障常出在编排层
作者复盘多智能体并行工作中的三类故障:共享进度板被覆盖、审查误判权限违规,以及数据库约束放过无效数据。文章指出,协作可靠性需要系统设计保障,单靠调整提示词难以解决。
AI 深度解读
多个 AI Agent 并行干活,一个研究、一个实现、一个审查,看起来已经有了团队分工。但作者遇到的三次真实故障,都出在协作机制上:进度板被覆盖,审查员误报越权,数据库约束放过无效数据。
作者的核心判断是:多 Agent 编排首先是系统设计问题。任务怎么分只是开始,共享状态归谁写、审查能看到哪些权限、约束究竟拦住什么,才决定这套流程能不能可靠交付。这几个案例值得读,因为它们也会出现在普通的并发服务和开发流水线里。
四条工作流,为什么会被一次更新抹掉
作者的工作方式是:多个执行 Agent 并行推进不同任务,再由审查 Agent 检查输出,最后由编排者汇总、裁决并交付。共享任务板为每个编排者保存一个元素,里面记录四条并行工作流和整体进展。这套机制正常运行了数周。
问题发生在一次研究任务中。一个负责文案的子 Agent,自行调用了任务板的更新函数,而且使用了编排者的 ID。这个 API 按 ID 找到元素后,会整体替换内容。结果,四条工作流变成了子 Agent 自己的一条,其余三条和全局进展一起消失。
没有报错,也没有冲突提示。最后一次写入直接覆盖了之前的状态。
共享同一个 ID,再配上整体替换接口,就已经具备了静默覆盖的条件。
作者随后加了三条规则:子 Agent 只返回结果,由编排者集中保存;确实需要直接写入时,使用自己的命名空间 ID,例如 orchestrator-sub-N;编排者每次合并结果后,都重新读取自己的任务板元素,检查内容是否被覆盖。
这里要分清两层作用。单写者或独立 ID 用于减少写入冲突,合并后的回读用于发现异常。回读能帮助发现丢失,却不能自动找回已经被覆盖的内容。
审查报得越多,真的代表越安全吗
第二次故障看起来甚至像一次成功:两张实现任务卡并行执行,审查 Agent 交叉检查,报出了一大批「权限违规」。
作者说,这一批报告全部是误报。
原因是,每个审查员只知道自己那张任务卡的操作白名单。另一张卡执行的操作虽然已经获得授权,却不在它掌握的名单里,于是合法工作被判成了越权。
这不是多加一句「请认真审查」能解决的。审查员缺少判断所需的信息,再认真也只能依据局部规则得出错误结论。
作者的修正是,在审查提示中明确列出所有并行任务卡的白名单,并把最终裁决放回编排者层面。执行任务可以拆开,判断权限时却必须知道被审查工作对应的授权范围。
对日常 AI 编程来说,这个案例提醒我们:审查发现的「问题数」不能直接当成质量指标。误报太多,会消耗处理精力,也可能让人逐渐忽略后续告警。先确认审查依据是否完整,再讨论审查有多严格。
数据库 CHECK 为什么会放过空对象
第三次故障来自数据库语义。作者给一个 JSONB 字段添加了下面的约束,希望 status 只能是 active 或 archived:
CHECK ((data->>'status') IN ('active', 'archived'))
要留意的是 data->>'status':字段缺失,或数据是标量而非对象时,这个取值表达式会得到 NULL。
接下来才是陷阱。SQL 中,NULL IN (...) 的结果是 UNKNOWN,不是 FALSE。而 CHECK 只拒绝结果为 FALSE 的记录,UNKNOWN 可以通过。
因此,空对象 {} 也能入库。作者不是只做了推理,而是实际插入了一条,验证了这个漏洞。
修复后的约束显式要求取值非空:
CHECK (data->>'status' IS NOT NULL AND (data->>'status') IN ('active', 'archived'))
关键是新增的 IS NOT NULL,它让缺失的状态值无法再借助 UNKNOWN 通过检查。
作者还补了一条契约测试:尝试插入 {},并断言数据库拒绝。这样做是为了防止后续维护者或 Agent 认为条件冗余,又把约束「简化」回去。
约束是否可靠,要看边界输入能否被挡住,不能只看表达式像不像正确答案。
原文还建议检查缺失键、标量、空值,以及那些逻辑上「没有明确为假」的输入。不过,明确描述的插入实测只有 {},其他情况没有逐项给出测试记录。
我的判断
这篇最有价值的地方,是把故障定位到了组件之间的契约。任务板确实执行了替换,审查员确实遵循了手里的白名单,数据库也确实遵循了 SQL 规则。单个组件按设计工作,组合起来仍然可能出错。
但作者最后说「Agent 已经准备好了」,证据还不够。三个案例能说明协作机制存在缺陷,无法证明模型能力已经不是瓶颈。原文没有提供任务成功率、修复前后的故障率,也没有与单 Agent 或人工审查做对照。因此,整体结论应当视为工程经验,而不是经过对照实验验证的普遍判断。
具体方案也有适用边界。集中写入容易理解,但会让编排者承担更多汇总工作;独立 ID 可以避免覆盖同一个元素,却仍需要定义如何合并结果。如果业务必须多人修改同一份状态,就还要考虑版本检查或冲突检测,原文没有展开。
「所有审查员都拿到所有白名单」适合作者描述的小规模并行任务。任务多起来以后,更可取的目标是让审查员拿到判断当前产物所需的完整授权信息。信息完整与上下文无限膨胀,并不是一回事。
相比继续打磨提示词,这些修正更接近普通软件工程:明确写入边界,补齐判断依据,用测试固定约束。提示词可以传达规则,但关键规则是否生效,还需要接口和数据库共同保证。
能拿来做什么
-
在前端或 Node 项目里并行使用多个 Agent 时,先明确共享进度、汇总文件由谁写。可以让子 Agent 返回结构化结果,再由一个编排入口统一保存;需要各自落盘时,分配独立 ID 或文件路径。
-
给审查 Agent 的任务说明补上被审查工作的授权范围,包括允许修改的目录和允许执行的操作。遇到越权报告,先核对它是否掌握了对应任务卡的权限,再决定是否拦截。
-
如果 Node 服务把业务状态存进 JSONB,就用
{}、缺失键和标量实际验证数据库约束,并覆盖空值情况。把应当拒绝的输入写进测试,避免后续迁移或 AI 修改让约束退化。 -
每次汇总并行结果后,重新读取关键共享状态,核对各条工作流是否仍然存在。把回读当成验收动作,同时保留明确的写入边界。