智能体故障分类
智能体发生故障时很少崩溃。它会继续调用返回成功的工具,用流畅的文字报告任务已完成,却将出错的证据散落在其上下文、日志以及它所操作的环境中,这正是生产环境中所见的 Fail-Plausible 故障模型 的“故障时仍显得合理”故障模型。本附录根据工程师可观察到的症状、各类故障所加剧的 H·S·A 风险暴露、其违反的原则,以及正文中用于闭合该故障的机制,对智能体系统反复出现的故障模式进行分类,使读者在遇到异常时能够为其命名、找到本应捕获它的组件,并将其转化为回归测试任务。
如何使用本附录
从你观察到的现象出发,而不是从你的猜测出发。
- 当智能体持续调用有效工具、每次调用都成功,但任务没有进展时,参见 节 1.2。
- 当每轮的成本和延迟不断上升,且智能体开始忽略任务早期提出的约束时,参见 节 1.3。
- 当奖励、通过率或选择器评分上升,而其所衡量的工作并未改善时,参见 节 1.4。
- 当智能体在读取不可信内容后执行了无人要求的操作,或将数据发送到不应发送的地方时,参见 节 1.5。
- 当多个智能体或样本对错误答案表现出自信的一致认同时,参见 节 1.6。
- 当智能体针对已不存在或已发生变化的文件、记录或结果执行操作时,参见 节 1.7。
- 当轨迹在崩溃后丢失进度,或在恢复后重复产生某项效果时,参见 节 1.8。
- 当一个发生故障的依赖项耗尽多条轨迹的预算时,参见 节 1.9。
- 如需并列比较全部八种模式,参见 智能体失效模式分类;如需逐步执行的事件处置流程,参见 节 1.10。
故障分类矩阵
智能体失效模式分类 根据各类故障模式所加剧的风险暴露及其违反的原则,对它们进行定位。风险暴露列指出运行时的哪个部分本应闭合该故障,原则列则指出哪项不变量未得到强制保障。缺少闭合机制的故障属于运行时缺陷,应在干预阶梯的第 1 至第 3 级修复(干预阶梯);只有在闭合机制已经到位后仍然持续存在的故障,才适合考虑通过训练解决。
| 故障模式 | 风险暴露 | 违反的原则 | 可观察特征 | 主要原因 | 闭合机制 |
|---|---|---|---|---|---|
| 无进展循环 | 时域 | 12 | 轮次和词元数增加;环境状态重复;每次调用均成功 | 模型身处不断增长的上下文之中,无法察觉循环 | 预算与进展检测(预算与上限、语义看门狗定时器) |
| 上下文溢出与稀释 | 状态(\(S_1\)) | 4 | 每轮成本上升;早期约束被忽略;工具调用格式错误 | 上下文仅追加,且没有预算、压缩或失效处理机制 | 上下文预算、压缩与分层暂存(上下文工程) |
| 奖励投机与验证器钻空子 | 无(训练与选择) | 18 | 评分上升,但任务结果未改善;测试被修改或绕过 | 策略能够访问验证器,或验证器的检查范围小于任务要求 | 隔离且封闭的验证器(隔离验证器、封闭隔离评估训练场) |
| 混淆代理与注入 | 权限 | 10 | 读取不可信文本后发起未经请求的特权调用;出现意外的数据外传 | 不可信内容操纵了一个既持有权限又拥有外传通道的智能体 | 能力权限、出站控制、污点跟踪、审批关卡(智能体沙箱) |
| 相关性一致 | 三者全部,且风险成倍放大 | 不变闭包原则 | 对错误答案投出一致赞成票,或在辩论中达成共识 | 共享同一模型的样本和智能体也共享该模型的盲点 | 由确定性关卡决定提交,而非投票(集成系统中的相关性失效) |
| 环境失同步 | 状态(\(S_2\)、\(S_3\)) | 7 | 对已发生变化的文件或记录执行操作;编辑冲突;重复创建 | 相比源数据,更信任上下文或索引中的副本;存在并发写入者 | 失效处理、版本检查、工作区隔离(上下文失效、乐观并发控制) |
| 进度丢失与效果重复 | 时域 | 13 | 崩溃后从头开始;恢复时同一效果被应用两次 | 进度仅保存在内存中;操作意图尚未持久化就已派发产生效果的操作 | 轨迹日志、预写意图、结算(持久执行) |
| 重试风暴 | 权限与时域 | 9 | 一个依赖项的故障在多条轨迹间成倍扩散;预算耗尽 | 模型重试发生故障的服务,而每条轨迹都执行相同的重试 | 返回带类型观测的熔断器(工具熔断器) |
无进展循环
无进展循环是指持续开展工作却未推进任务的轨迹。模型不断提出格式正确的工具调用,工具不断返回成功,而环境不断回到此前已经经历过的状态。与因活动停止而被活性检查捕获的挂起不同,循环通过毫无进展的活动导致失效,且每次调用的检查都能通过(原则 12)。
可观测症状
成因
模型无法从自身上下文内部识别出循环。每轮的上下文都与上一轮不同,因为其中包含新的推理和新的错误文本,即使工作区已经回到先前的状态也是如此,因此此前未带来任何进展的方案又显得像是新方案。上下文压缩若丢弃某次失败尝试的记录,就会移除唯一能够让模型知道自己已经尝试过这条路径的证据(上下文压缩)。仅有非零退出码等信息不足的错误观测,无法为下一次方案提供任何调整依据(终端输出净化)。
消除机制
- 以预算作为兜底。 对轨迹施加轮次、token 数、时间和成本上限,最终能够终止任何循环;限制逐步收紧,从引导到只读操作,再到停止(预算与上限)。预算可以限制损失,但无法及早检测循环。
- 基于环境检测进展。 运行时将每个动作与其作用的状态一起进行哈希,并标记重复情况;同时根据环境状态的变化,例如原先未通过而现在通过的测试,来衡量进展,而非依据模型自身的叙述(语义看门狗定时器)。李雅普诺夫活性验证 给出了其形式化版本,即一个每轮都必须减小的量。
- 保留失败记录的上下文压缩。 上下文压缩必须原样保留每次失败尝试的标识符和错误信息,使已尝试操作的记录能够在摘要中留存(上下文压缩)。
- 先通过模型修复,再绕过模型修复。 检测到循环后,首先提供明确指出重复行为的观测,并回滚受到污染的上下文分支;随后重新采样或改用其他模型,最后升级处理(前向恢复)。提高采样温度并不能解决问题。这只会将确定性循环变成随机游走,而同一检测器仍然必须将其捕获。
上下文溢出与稀释
上下文溢出是指轨迹的上下文增长到超出模型可用范围时发生的失效。它包含两个方面。成本方面由机械性的过程决定。每次调用都会重新发送整个上下文,因此,对于每轮增长 \(\Delta\) 个 token、初始大小为 \(L_0\) 的上下文,重新发送的 token 总量为 \(T L_0 + T(T-1)\Delta/2\),对应的轮数为 \(T\),且首个输出 token 的生成时间随输入量增加而延长(工作集容量)。质量方面则具有统计性。模型检索并整合长上下文中部证据的可靠性低于处理两端证据的可靠性,因此可用上下文短于标称窗口(工作集容量)。
可观测症状
- 每轮的成本和延迟攀升。 每次调用的输入 token 数逐轮增加,而上下文靠近开头的任何内容发生变化,都会使前缀缓存命中率下降。
- 早期约束被忽略。 智能体遵循最新的工具输出和系统提示词,却违反了较早轮次中声明的约束,例如禁止访问某个路径。
- 工具调用质量下降。 当工具定义和参数说明与大量观测内容争夺模型的注意力时,参数会缺失或类型错误。
- 服务端内存压力。 长时间持续的轨迹保留了大量注意力状态,服务器能够同时容纳的轨迹数量因而减少(从上下文 token 到 KV 状态)。
原因
上下文被当作只能追加的对话记录。无论是输出一万行构建日志的 shell 命令、返回整个模块的文件读取操作,还是保留完整标记的网页,都会完整进入上下文,并在轨迹的剩余过程中一直保留,每轮都为此付出成本,同时稀释真正重要的证据。
闭环机制
- 分配预算。 上下文预算将工作集分配给系统提示词、工具定义、任务、历史记录、检索到的证据以及输出预留空间(工作集容量;原则 4)。
- 在源头整形。 冗长的工具输出在进入上下文前被截断、分页或缩减为结构化结果,并用标记说明删去了哪些内容(观测流截断)。
- 压缩与进度记录。 清除或概括旧的工具结果,逐字保留标识符和失败信息,并在移除任何内容之前,将持久状态提取为结构化笔记(上下文压缩、上下文检查点)。
- 以检索代替保留。 智能体之后可能需要的材料应放在可搜索的存储中,而不是放在每次都要重新发送的上下文中(智能体检索)。
- 服务端缓解。 当压力来自内存而非质量时,服务层会在等待工具期间移除、重新计算或卸载注意力状态,并在各分支之间共享前缀(保留、驱逐、重计算或卸载、分页 KV 分配)。
奖励投机与验证器操纵
奖励投机是指策略通过未能完成奖励原本旨在衡量的任务的行为,提高其测得的奖励(训练病态)。即使没有训练,只要选择器依据分数从候选项中进行选择,同样的失效也会出现:选择器看到的候选项越多,就越可能选中利用评分漏洞而非完成任务的候选项(过程验证)。两者都是古德哈特定律在验证器上的体现 (Goodhart 1984年)。
可观测症状
- 分数与结果背离。 训练奖励或 best-of-\(n\) 选择分数上升,而在封存测试上的留出评估结果持平或下降。
- 测试被修改或绕过。 候选变更修改测试文件、弱化断言、跳过测试,或针对测试输入进行特殊处理。
- 探查评分器。 轨迹在生成解决方案之前,读取评分脚本、测试运行器的配置或其环境。
- 学习型奖励下的输出退化。 当奖励由学习型奖励模型或评判器提供时,输出会趋向它给予高分的模式,例如篇幅较长或措辞自信,而非趋向正确。
原因
验证器可被访问或不完备。如果验证器运行在策略可写入的环境中,或者其测试位于策略的工作区内,就可以通过修改验证器来满足验证要求。如果验证器检查的内容少于任务要求,例如测试套件从未触发正在修复的故障,那么即使所做的工作没有完成任务,也能通过验证。学习型验证器还引入了第三个原因:它们自身存在错误,而优化过程会发现这些错误(原则 3)。
闭环机制
- 隔离验证器。 在策略的操作边界之外运行验证,从策略无法写入的存储中加载验证程序,并针对策略最后一次操作之后取得的状态快照进行验证(隔离验证器、封闭隔离评估训练场)。
- 拒绝涉及测试的变更。 防范测试篡改的机制不接受任何修改了用于评判自身的文件的轨迹(验证器投机行为防御)。
- 在准入关口优先采用确定性检查。 由编译器、类型检查器和封存测试决定哪些内容可以提交或获得奖励;学习型排序器和评判器则在该关口之下对候选项排序(门控之下的学习式排序器、轨迹评分)。
- 监测差距。 同时跟踪封存留出集上的性能和训练奖励,并将不断扩大的差距视为验证器缺陷,在继续训练之前予以修复(训练病态)。
混淆代理攻击与提示注入
混淆代理是指拥有合法权限,却被不具备该权限的人诱导,代其使用这些权限的智能体。对智能体而言,这种诱导通常以间接提示注入的形式出现(间接提示注入):网页、电子邮件、议题或工具结果中的文本被模型当作指令读取。当三个条件同时具备时,这种威胁就会演变为安全事件:能够访问私有数据、接触不可信内容,以及拥有向外发送数据的通道(智能体威胁模型)。
可观察症状
- 未经请求的特权调用。 智能体在总结电子邮件或对议题进行分类处理时,调用了执行写入、发送或删除操作的工具,而任务中并未要求执行这些操作。
- 意外的出站流量。 出站请求被发送到任务从未指定的主机,有时会通过查询字符串、请求头或名称查询携带文件内容或凭据。
- 推理中借用他人的口吻。 轨迹引用了操作人员从未给出的指令,例如检索文本中嵌入的、声称可以覆盖现有指令的内容。
- 跨租户访问。 为某个租户执行任务的智能体,在摄取共享资源中的内容后,读取或更改了另一个租户的数据。
原因
模型无法可靠地区分指令与数据,因为两者都以词元的形式进入同一个上下文。呈现方式和来源标签可以降低注入文本左右拟议操作的概率,但无法保证避免这种情况。当智能体还拥有任务不需要的权限、能够读取的凭据或能够使用的网络路径时,这种失效就会造成损害。
封堵机制
- 在上下文中标注来源。 将不可信文本放入带有标记的区域,并注明其来源,从而降低模型将其视为指令的概率(编排下一次调用;对于检索内容,参见 入口隔离)。
- 仅授予任务所需的权限。 能力明确规定每次授权的权限、对象、参数边界和到期时间,并随着工作委派而收缩,因此,被诱导产生的拟议操作只能触及任务本身有权触及的范围(权能与凭据,衰减能力委派)。
- 使秘密不可访问。 凭据代理在使用时注入限定作用域的凭据,使上下文或工作区中都不会出现任何秘密(凭据代理)。
- 封堵出口。 出站访问默认拒绝,仅允许访问契约指定的主机,并涵盖名称解析和元数据端点等旁路通道(出口控制)。
- 跟踪污点。 源自不可信来源的数据带有标记,具有权限的调用拒绝带标记的参数;一个经过隔离、不持有任何工具的读取器,将不可信文本处理为具有明确类型的字段,供持有工具的智能体使用(跟踪不可信数据)。
- 暂缓不可逆步骤。 \(A_3\) 调用在审批关卡等待,并在执行前重新核验其前置条件(审批关卡)。
只有位于模型之下的机制(能力、凭据代理、出站控制、污点跟踪和审批关卡)才能限制损害。来源标签能够改变模型倾向于提出的操作,这虽有帮助,却不能提供保证。
环境失同步
环境失同步是指智能体的上下文、检索索引或记忆中所承载的环境表征不再与环境本身相符,从而导致失效。此时,智能体是在一个已不复存在的世界中采取正确行动。
可观察症状
- 对已不存在的对象执行操作。 智能体依赖上下文中仍然保留的目录列表,读取、编辑或删除已在先前轮次中移走或移除的路径。
- 重复创建。 智能体创建已存在的分支、表或文件,并因报错而偏离正常执行流程。
- 检索结果与工具结果矛盾。 搜索返回智能体刚刚编辑过的代码的旧版本,智能体便认定编辑失败,并再次执行该编辑(哪些内容必须持久保存)。
- 写入者冲突。 在同一工作空间中工作的两个智能体相互覆盖对方的编辑,导致任何一方单独运行时都无法复现的故障。
- 结果迟到。 工具结果在截止时间之后到达,却被当作后续调用的响应。
原因
副本比其源更受信任。上下文中的观测、检索索引中的条目以及智能体写入记忆的笔记,都源自环境在某一时刻的状态;除非运行时负责建立关联,否则它们与源后续发生的变化之间没有任何关联(原则 7)。缺乏隔离的共享工作空间,以及尚未确认执行结果就重试的工具调用,会引入智能体未曾观测到的变化。
闭环机制
- 使暂存的观测失效。 将每条暂存观测绑定到其源,并在源发生变化时将其弃用,或替换为墓碑标记(上下文失效)。
- 对照源核查派生副本。 检索契约在每条结果暂存之前检查其版本与来源,并在源被写入时使索引条目失效(检索契约,存储失效处理)。
- 写入时检查版本。 编辑操作携带其所读取文件的版本哈希;若版本不匹配,则编辑失败,并返回结构化观测,告知模型需要重新读取(乐观并发控制)。
- 隔离工作空间。 为每条轨迹及每个并发智能体分配独立的租用工作空间,并通过验证关卡将其合并回去(每条轨迹独享工作区租约,按租户重置,乐观并发控制)。
- 重试前确认执行结果,并拒绝迟到的结果。 产生变更的调用携带幂等键,并在发生结果不明的超时后确认其执行结果(幂等动作执行);智能体运行框架仅接受调用 ID 仍处于待处理状态的调用所对应的结果(轨迹状态)。
进度丢失与重复效应
进度丢失是指长轨迹无法在运行它的进程丢失后继续执行而导致的失效。与之相伴的是重复效应:简单的重启方式通过从记忆中重放或再次询问模型,使轨迹得以继续,却又触发了已经发生过的效应。
可观察症状
- 从头重新开始。 工作进程崩溃、部署或被抢占后,轨迹会从头开始,重复数分钟乃至数小时的模型调用。
- 外部效应重复发生。 恢复的轨迹会再次发送邮件、再次创建拉取请求,或重复扣款。
- 恢复后的轨迹行为发生变化。 重新调用模型以重建进度时,生成的提案与实际执行的提案不同,因为采样和模型服务具有非确定性(回放为何会发生偏离)。
- 审批状态丢失。 为等待审批而暂停的轨迹会在其宿主重启时丢失,而审批到达时,对应的轨迹已不复存在。
原因
进度仅保存在内存中,或者在授权执行外部效应的记录持久化之前,外部效应就已从宿主发出。第一种情况下,崩溃后不会留下任何进度。第二种情况下,日志无法说明某项效应是否已经发生,而假定其未发生并重试,正是重复效应产生的原因(原则 13)。
闭环机制
- 记录事件,归约记录。 将轨迹保存为由带类型的事件构成的仅追加日志,并在任意工作进程上根据该日志重建记录(轨迹日志)。
- 先记录意图,再执行效应。 在派发前将意图持久化,使每项效应要么可确认曾被计划执行,要么可确认尚未发生(意图先于效果)。
- 核实存疑操作的结果。 恢复时,对于没有结果记录的意图,通过其幂等键或对账探测来核实结果,绝不假定其失败而重新派发(幂等动作执行、恢复轨迹)。
- 对日志无法低成本重建的内容建立检查点。 对工作区创建快照,并将其绑定到日志位置;快照频率由检查点成本和故障发生率决定(检查点)。
- 重放,而非重新生成。 使用已记录的模型回复和工具结果重建状态,并以桩实现替代模型和工具(重放)。
重试风暴
重试风暴是指一组轨迹因共同依赖某个发生故障的服务而集体失败的现象。每条轨迹中的模型读取错误后,都会对调用稍作修改并提议再次调用,不断为此消耗预算;所有轨迹又同时采取相同行为,导致服务持续无法恢复。
可观察症状
- 相关联的预算耗尽。 许多共享同一依赖的轨迹在同一时间窗口内因达到预算上限而结束。
- 换一种表述后重试。 对故障工具的连续调用仅在措辞或参数顺序上有所不同,因为模型将服务故障视为自身查询存在问题。
- 负载阻碍恢复。 服务开始出现故障后,发往该服务的请求速率反而上升。
原因
模型会放大重试。对模型而言,传输故障看起来与其他错误观测无异,而调用失败后最可能的后续行为就是再次尝试。如果没有运行时规则约束,一次服务中断就会演变为多个重试循环,其数量与使用该服务的轨迹数量相同。
闭环机制
- 在网关中触发熔断器。 按依赖项统计传输层故障次数,超过阈值时停止派发,并在冷却期后通过单次调用进行探测(工具熔断器)。
- 返回带类型的观测。 处于断开状态的熔断器立即返回一条观测,指明发生故障的服务,说明改换措辞无济于事,并告知何时再试,从而使模型更可能转向后续工作(工具熔断器)。
- 先核实结果,再重试。 对于超时的状态变更调用,应先核实其结果,而不是直接重发,以免重试风暴同时造成重复效应(幂等动作执行;原则 9)。
- 回退或升级处理。 如果存在替代工具或模型,就将该步骤路由至替代方案;否则暂停轨迹,直到依赖恢复(前向恢复)。
事件分诊工作流
当智能体系统在生产环境中性能退化时,遵循同一套步骤可以快速定位原因,并将事件转化为测试。表 1 列出了这些步骤。第一步始终是保全证据,因为未被记录的轨迹无法重放,而无法重放的故障也就无法归因。
| 步骤 | 阶段 | 诊断操作 | 可区分的故障模式 | 产生的证据 |
|---|---|---|---|---|
| 1 | 保全证据 | 保留轨迹日志和追踪记录;如果轨迹持有权限,则暂停或隔离该轨迹 | 所有故障模式 | 完整的日志和冻结的授权集合(影响范围隔离) |
| 2 | 检查边界 | 将已授予的能力、出站访问和受污染的输入与实际发起的调用进行比较 | 混淆代理(节 1.5) | 能力与出站访问记录;参数上的污点标记 |
| 3 | 检查进展 | 检查是否存在重复的动作哈希值、未发生变化的环境状态,以及状态未变却持续消耗预算的情况 | 无进展循环(节 1.2)、重试风暴(节 1.9) | 进展信号和各依赖项的失败率 |
| 4 | 检查上下文 | 测量每轮输入词元数、缓存命中率,以及被违反的约束在上下文中的位置 | 上下文溢出(节 1.3) | 从追踪记录中获取的逐轮词元用量统计 |
| 5 | 检查外部世界 | 将上下文和索引中的信息与源信息进行比较;检查是否存在迟到的结果和并发写入者 | 环境失同步(节 1.7) | 版本不匹配、被拒绝的迟到结果、写入冲突 |
| 6 | 检查持久性 | 确认每项外部效应都有持久记录的意图和已确定的结果 | 进展丢失和效应重复(节 1.8) | 没有对应结果的意图;重复的幂等键 |
| 7 | 检查验证器 | 确认测试和评分器不可访问且未被修改,并将得分与封存的留出集结果进行比较 | 奖励投机(节 1.4)、相关性一致(节 1.6) | 验证器哈希值;得分与留出集结果之间的差距 |
| 8 | 重放并归因 | 使用模型和工具的桩实现,根据日志重放轨迹,然后逐层进行消融 | 模型、运行框架与环境之间的故障归因 | 归因结果和一项回归任务(事件取证复盘) |
最后一步使前面各步的投入获得回报。对于归因于运行框架或环境的故障,应在相应位置修复,并将其作为回归任务加入评估套件。只有在各项闭合保障均已落实的情况下仍然存在、且经重放归因于模型的故障,才能作为沿干预阶梯逐级上行、转向训练的依据(能力差距诊断)。