一个会退款、下单或删文件的 Agent 在生产环境里做错了事,开发者通常先想办法重跑。但同一段代码再次调用模型,可能得到另一组工具参数;数据库、时间和网络状态也已经变化。修复代码即使通过了这次重跑,也未必真正挡住原来的危险动作。
9 月 17 日公开的 Chronicle 试图把这场碰运气的复现改成普通回归测试。它记录模型调用、工具调用和路由选择这些容易变化的边界;事故发生后,开发者冻结上游轨迹,只在与修复有关的“切点”运行新代码。论文在六个作者构造的事故上证明了这套机制可以工作,真正有价值的变化是:过去只能查看的 Agent 轨迹,开始能直接检验一次代码修改。
不重跑模型,只重演危险动作前的输入
Chronicle 把每次边界调用保存为不可变的 envelope,其中包括输入、输出、模型版本和采样参数等元数据。一次退款事故可能被记录成三次跨越:模型决定退款参数、退款工具执行、模型生成最终回复。完整回放会返回三次已经保存的输出,不再调用模型;切点回放则冻结第一次模型调用,让更新后的退款工具接收事故当时的真实参数。
这种选择保留了两件看似矛盾的事。测试上游不再依赖一次新的模型生成,因此可以稳定重复;被修复的工具却没有被 mock 掉,新的限额、币种校验或删除门禁会真的运行。论文中的交易案例正是如此:记录里的模型把约 1000 美元的请求误读成卖出 1000 股、名义金额约 19 万美元,切点测试把这组参数交给新门禁,再断言交易被拦截。
这也解释了 Chronicle 与“全部 stub”的差别。若模型和工具都直接返回旧结果,测试无论面对有漏洞的代码还是修复后的代码,都会看到同一个危险输出。它能够忠实复现事故,却无法回答补丁是否有效。Chronicle 借用了传统 record-and-replay 固定不确定输入的思路,但目的不是复用成功经验。此前 AgentRR 将历史轨迹概括成可迁移的经验,用于执行相似任务;Chronicle 固定的是一个失败样本,用它检查某段新代码。
六个事故证明机制可用,没有证明覆盖真实生产
作者构造了退款金额误用订单号、发票币种错误、交易数量与名义金额混淆、邮件受众过宽、收款账户被替换和生产文件误删六个事故。每例都只有“模型—工具—模型”三步,共标注 18 个边界;模型边界使用确定性模拟器,不调用真实供应商。
在这套样本里,完整回放连续运行 20 次均无分歧,也没有发出模型请求。切点测试在六例中都拒绝未加门禁的代码,并接受修复版和不改变安全约束的改写。我们在论文发布前最后一个公开提交上复跑了六例和 mutation study,得到相同的核心结果:六个切点测试均为“旧代码失败、修复与无害改动通过”,全部 stub 则对三个版本一律失败。
mutation study 更能说明结果的上限。作者对六个修复工具生成 192 个一阶 mutant,切点测试杀死 51 个,全部 stub 一个也没有杀死。其余 141 个并非都安全:110 个没有被这一次事故输入触达,或改变了阈值写法却没有改变该输入的判定;另外 31 个修改了断言没有检查的输出字段。换句话说,在会改变这条记录行为的 82 个 mutant 中,切点测试覆盖了 51 个,即 62%。它能守住已经发生过的事故,不会自动把一个样本扩展成边界条件测试集。
这一限制与更广泛的 Agent 故障研究相吻合。MAST 对 1642 条多 Agent 轨迹的分析把失败归为系统设计、Agent 间失配和任务验证三大类,远比六种工具门禁更宽。Chronicle 的六例主要验证“行动前缺少检查”这一窄类问题,无法代表循环、重试、多 Agent 路由或模型本身产生错误内容时的复现率。
生产门槛在记录治理,不在 23 微秒
论文测得内存记录每次边界跨越增加 23 微秒,单条记录最多约 1.44 KB;相对一次假定 300 毫秒的模型调用,这部分耗时很小。这个数字只回答了包装函数和写入记录有多快,没有覆盖生产环境的长期存储、访问控制、脱敏审计和回放沙箱成本。
这些成本不能省略。envelope 会复制提示词、Agent 状态和工具参数,可能包含客户信息、密钥和交易数据。论文发布时的 0.4.0 代码提供常见密钥格式的 redactor,但默认列表为空,开发者必须显式开启;姓名、邮箱等上下文相关的个人信息还要自定义规则。把事故 fixture 提交到 Git 之前,团队需要先决定哪些字段能保存、谁能读取、保留多久,以及脱敏后是否仍足以支撑断言。
回放安全也取决于切点。被 stub 的删除工具不会再次执行副作用;一旦将它设为 live,新代码会真的接收旧参数并运行,因此论文明确要求破坏性工具指向沙箱。当前实现还不支持并行工具调用,流式响应只保存组装后的结果,按名称计数的检查也抓不到调用次数相同但顺序变化的重排。任何没有标注的非确定性调用都会直接逃出记录。
过度 mock 的风险并非 Agent 独有。一项覆盖 120 多万次代码提交的研究发现,在 Agent 活跃度较高的仓库中,Agent 生成测试里的 mock 提交比例中位数为 36%,人工提交为 28%;研究者同时提醒,mock 虽让测试稳定,却可能降低对真实交互的保证。Chronicle 给出的不是“少用 mock”这一口号,而是一条更具体的界线:模型和历史环境可以冻结,补丁要改变的那段代码必须执行。
它目前最适合成为事故复盘后的第二步:先从生产轨迹抽出一个最小 fixture,再把会产生副作用的切点接入沙箱,用结构化断言守住已经发生的错误。接下来真正决定 Chronicle 能否进入生产 CI 的,不是再把六例跑得更快,而是能否在真实模型、循环与并发调用中保持轨迹完整,并让多个事故样本覆盖同一门禁的边界条件。
