跳到主要内容

无人负责的对话:问责制如何在智能体移交链中消散

· 阅读需 10 分钟
Tian Pan
Software Engineer

一个支持请求发送了进来:“我的订阅被扣了两次费,请取消其中一个并退款。”一个路由代理将其归类为计费问题并进行了移交。一位计费专员查看了账户,确认了两笔扣费,并将退款操作移交给了一个工具调用子代理。该子代理执行了一次退款,随后一个总结代理给客户回信:“搞定了——你的重复扣费已退还。”每一个步骤单独看都是正确的。但实际上客户被扣了三次费,而不是两次。其中一笔重复扣费仍在他们的卡上,而总结代理无从得知这一点,因为当对话传导到它那里时,“ 2 ”这个数字已经在上游的四个步骤中固化成了事实。

让我们进行一次复盘。这是谁的 Bug?路由代理分类正确。计费专员读取了它收到的两笔扣费。工具代理准确地按照指令进行了退款。总结代理进行了准确的总结。单独调出每个代理的 Trace,每一个都通过了。系统失败了,但没有任何组件出错。这就是“无主对话”,它是多代理架构中定义性的操作性失败——不是模型太笨,而是责任在移交链条中不断扩散,直到没有任何一个代理需要对用户实际体验到的结果负责。

我们已经知道结局会如何,因为我们在组织架构中见过类似的情况。一个请求进入公司,在四个团队之间来回跳转,每个团队都完成了自己的部分,但结果却是错的——复盘的结论是“流程”失败了,这是企业中表达“没人负责”的一种委婉说法。多代理系统在软件中重现了同样的病理,速度更快,且可见度更低。最近研究中一个令人不安的发现是,这并不是你可以通过更好的 Prompt 就能磨平的粗糙边缘。伯克利的 MAST 研究对七个多代理框架中的 1,600 多个执行 Trace 进行了标注,发现失败率在 41% 到 87% 之间——而这些失败中的大多数是“交互”的属性,而不是任何单个代理的问题。你无法通过让每个参与者变得更聪明来修复交互失败。

步骤级正确性并非对话级正确性

这种陷阱是一种听起来很严谨的范畴错误。你测试每个代理。路由代理在你的评估集上达到了 98% 的分类准确率。计费专员正确回答了问题。退款工具通过了单元测试。你满怀信心地发布了产品,因为每个部分都经过了测量且显示正常。然后,生产环境给了你一个没有任何单个部分需要负责的结果。

真正重要的区别在于“步骤级正确性”——给定输入,该代理是否做了正确的事——与“对话级正确性”——用户是否得到了他们想要的结果——之间。这是不同的属性,后者并不能分解为前者。一个代理可以根据其输入做出正确的反应,但如果输入本身就是错的,它会自信地在错误的基础上继续构建,因为它的上下文里没有任何信息告诉它基础并不牢靠。 MAST 的分类学将 14 种记录在案的失败模式分为三类,其结构很有启发性:规范问题(约 42% )、代理间对齐失调(约 37% )以及任务验证(约 21% )。大约五分之四的失败发生在“接缝处”——即工作如何在代理之间定义和传递——而不是代理本身。

这正是生产环境中最危险的部分:每一个失败都返回了 HTTP 200 。对于“总结代理相信了一个两步之前就错了的数字”这种情况,是没有堆栈追踪的。一个微妙的、错误的中间输出完整地穿过流水线,下游的每个代理都将其视为事实。错误并没有在步骤之间抵消——它在静默中累积,没有告警,因为从每个代理的局部视角来看,一切正常。你的仪表盘是绿色的。你的客户并非如此。

移交像职能孤岛一样扩散责任

为什么增加代理会让所有权变得更糟而不是更好?因为移交是一个上下文会发生损耗的地方,而且没有人从契约上对跨越移交后留下的内容负责。

当路由代理移交给计费专员时,它传递的是意图的压缩摘要,而不是完整的对话。当专员移交给工具代理时,它传递的是进一步压缩的指令。每一个边界都是对用户实际请求的一次有损重新编码,而且——关键在于——每个代理都针对其“局部”任务进行优化,而不是“全局”结果。与微服务不同(在微服务中,团队 A 通过类型化的契约调用团队 B,如果模式不匹配会大声报错),代理间的移交依赖于自然语言。规划代理向下游代理发送的模糊简述不会抛出错误。它只会被看似合理但错误地解释,然后执行继续。

这正是组织孤岛的激励结构。每个团队都根据自己的 SLA 进行衡量,因此每个团队都优化自己的那一小块,让跨团队的结果成为别人的问题。更多的专业化并无帮助——它将请求分散到更多的边界,而每一个新边界都是意图泄漏和所有权消失的新场所。生产环境移交图中最常被提及的失败模式是无限循环:A 移交给 B,B 移交给 C,C 又移交回 A,每个代理都在不断重新规划,因为没有一个代理负责达成“完成”这一目标。专业化本应带来可靠性。超过一定程度后,它带来的却是扩散。

真正起作用的问责原语

这些观点并非反对多智能体系统。其核心在于:如果你将工作分发(fan out)出去,就必须有意识地重新集中责任——这不会自动发生。以下三个原语承担了大部分工作。

一个始终端到端负责的单一所有者智能体。 必须有人为用户体验到的最终结果负责,而不是仅对某个步骤负责。具体来说:一个监督者智能体(supervisor agent)在整个对话生命周期内持有原始的、未经压缩的用户请求,将其分发给专家智能体,并根据 用户实际要求的内容 验证它们的返回结果,而不是仅根据它委派的内容。当工具智能体报告“已退款一笔费用”时,所有者智能体应记得用户说的是“两次”,注意到算术逻辑不通,并重新开启任务。所有权意味着责任止于一个能看到完整结果的智能体,而不仅仅是看到它自己那一环。如果你拓扑结构中的任何智能体都做不到这一点,那么你面临的不是一个可以通过提示词(prompt)解决的问责缺口,而是一个缺失的角色。

每个移交边界处的明确契约。 借鉴委派理论(delegation theory):一次移交应包含任务、授予的权限、预期的工作产出以及该工作的验收标准。契约不应是“处理一下计费问题”,而是:退还所有符合此交易特征的费用;你的退款限额为争议金额;返回每笔已处理退款的数量和 ID;成功标准是退款数量等于重复扣款数量。现在,边界处有了一个可以 显式报错(fail loudly) 的断言,而不是一个被默默解读的指令。你正在将自然语言的“感觉”换成更接近类型化接口(typed interface)的东西——这正是微服务最初变得可调试的原因。

一个跨越扇出的结果级追踪(trace)。 为整个对话分配一个关联 ID(correlation ID),并将其串联到每一次智能体调用、工具调用和移交中,使整个过程可以重建为从初始查询到最终响应的单一追踪(trace)——而不是你在凌晨 2 点手动重新组装的一堆断碎日志。这是分布式系统可观测性在智能体领域的应用:一个追踪,多个跨度(span),且父子关系在每次移交中得以保留。其重点不仅仅是更快的调试,而是该追踪成为了你可以附加 对话级 判定结果的人造制品。你终于可以把“这次完整的交互成功了吗?”作为一个一等公民式的问题来提问,因为终于有一个单一对象代表了整个交互。

为你真正会执行的事后分析而设计

识别你是否存在此类问题的征兆是有一种特定的、令人沮丧的事后分析(postmortem):结果是错误的,你回放了每个智能体的表现,发现每个智能体都是正确的。如果这种会议听起来很熟悉,那么解决方案不是对单个组件进行另一次评估(eval),而是在向图中添加下一个专家智能体之前,先问三个问题。

哪一个智能体为用户体验到的结果负责——它能真正看到那个结果,还是只能看到它自己那一环?每次移交时的明确契约是什么,违反契约是会显式报错还是被默默解读?当这次对话出现问题时,是会有一个代表整个交互的单一追踪,还是会有四套看起来都正常的日志?

专业化确实有用;错误在于假设它是免费的。你添加的每一个智能体都会分摊工作,除非你刻意重新集中责任,否则它也会分摊所有权,直到在用户关心的层面不再剩下任何责任。在生产环境中经得起考验的系统,并不是那些智能体最多或路由最巧妙的系统。而是那些无论工作如何扇出,始终有一个智能体对用户收到的实际回答负责的系统。

References:Let's stay in touch and Follow me for more thoughts and updates