loading

Loading

探索与发现

首页 Agent 工程

Agent 轨迹回放调试:把失败变成可回放资产

分类:Agent 工程
字数: (2873)
阅读: (5)
0
摘要:Agent 调试难在无法复现、故障点藏在数步之前。这篇文章讲三件具体的事:把轨迹归一化成可校验的步骤结构,用工具签名和领域策略生成可执行约束,以及用标注过的失败轨迹在 CI 里做回归回放——顺带说明为什么只盯延迟和错误率的可观测看不到这类故障。

Agent 出了错,你看日志翻了两百行,最后只能把 Prompt 改两行再跑一遍。这种循环我做过太多次。问题不在于改 Prompt 不管用,而在于从日志里根本看不出是哪一步坏掉的。

传统的调试方式假设三件事:相同的输入产生相同的执行路径、能复现、能在某一行设置断点。Agent 把这三个假设全部打掉了。同一条请求进来,模型可能先调用搜索,也可能先读本地文件;温度、上下文长度、工具的返回内容稍有变化,整条轨迹就分叉。等你发现最终答案不对,出问题的步骤往往已经在五步之前。

下面这套做法来自几个在生产里跑 Agent 的团队对外公开的方法论,核心只有一句:把轨迹当作可以被规则验证、可以被回放的产物,而不是用来给人眼扫描的日志。

同一条轨迹不该有三种格式

多数 Agent 框架都会记录轨迹,问题是记法各不相同。LangGraph 的 state、OpenClaw 之类的 CLI 智能体的对话流、自研 ReAct 循环打的 access log,字段名各异,工具调用和模型响应的结构也不一样。想在上面写一条自动化检查,先得为每种格式写一遍解析逻辑。这基本上就挡住了所有后续工作。

第一步只能是归一化。让每一步都带上同一套 schema:步骤序号、类型(推理/工具调用/检索/输出)、输入、输出、工具签名、耗时、以及状态变更的哈希。听上去像纯管道活,工程量也不小,但它是后面所有事情的前提。没有归一化的轨迹,约束检查、因果定位、回放都无从谈起。

约束是可执行规则,写少了也能抓一大半

归一化之后,可以在每一步上跑检查。约束有两个来源。

一个是工具模式本身就自带的:参数类型对不对、必填字段在不在、返回结构的格式是否符合工具约定。这类约束几乎可以从现有的 JSON Schema 或函数签名里自动生成,成本极低。

另一个是领域策略:让 Agent 在下单前必须查库存,支付 API 在一次交易中最多被调用一次,查询用户信息时不能带出手机号之外的敏感字段。这些规则没法穷举,但写一部分就能抓到大量真实故障。腾讯云文章里把排查顺序归纳为四个问题:模型有没有调用目标工具、把参数传对没有、结果是否符合格式、错误是在模型调用前发生还是在执行之后发生。这四条其实就是约束检查的雏形。

检查跑完得到一份证据日志:每条约束在哪一步通过,在哪一步被违反,具体是哪个数值、哪个字段出了问题。这样你不需要逐行读日志,就能定位到具体的一次调用。

真正关键的是最早的损坏点

这里有个反直觉的地方。Agent 在第 3 步臆造了一个不存在的工具输出,然后第 8 步触发了防护栏被拦截。你看到的是第 8 步的报错,但导致整条轨迹不可修复的时间点是第 3 步。

《AI Agent 系统化调试》把证据日志交给第二次模型处理,目的只有一个:判断引用的依赖关系,修正哪一步能让轨迹重新通往成功。这不是让模型重新回答业务问题,而是基于已经收集到的、证据支持的步骤摘要做判断属因。文中给出的数字是:与直接让模型阅读原始 trace 相比,这种方法的故障定位准确率提高约 24 个百分点。差别来自结构,模型看的是带证据的步骤摘要,而不是一锅原始日志。

该文分类出九类最常见的故障:计划执行失败、信息捏造、无效工具调用、误读输出、意图与计划不匹配、用户意图不明确、超范围请求、触发防护栏、系统故障。其中计划和凭空编造信息两类出现频率最高,也最难自动检测,因为它们考察的是意图理解。

回放的正确用法是回归,而不是扮演

有了标签完整的失败轨迹库,就可以做回放。这里容易产生一个误解:以为回放能完整重现问题。

实际做不到。模型的推理轨迹是概率性的,工具的结果也会因外部状态而变,就算把请求和上下文完整拿回来,也不会走出一模一样的一步。因此回放的价值应当缩小到执行运行规则:能够拉起真实的工具与真实接口,实际运行的是逻辑与检查,不必追求再现同一条思考过程。

比较务实的用法是把它接进 CI。上线任何 Prompt、工具 schema 或流程调整之前,先对一大批标注过的失败轨迹跑一遍,确认两件事:原来的故障有没有被解决,新的约束违反有没有被引进来。这不能拦住所有新问题,但不引入先前的缺陷。

在生产里看到的核心循环只有五步:记录规范的步骤级轨迹,跑自动化约束检查并留下证据,把失败轨迹标上故障类别和关键故障步骤,把标签输入测试回流数据里积攒成一个增长的数据集,再在变更之前回放验证。

它不够快,但三个月后你会看到两条线慢慢分开:一条是不断积累校验集的系统,另一条是每周从生产里被新问题打击一次的系统。

只关注延迟、错误率你会发现不了这些错

常见的错误是把任务日志打到已有的可观测平台上就以为完事。问题在于,一个返回 HTTP 200 的 LLM 响应里完全可能包含伪造的事实;在类型上合法的工具调用,可能在语义上并不正确的;Agent 每一步可能都成功完成,却在次序上出问题。这些问题埋不住延迟计和错误率曲线。

该文给出的数据是:2026 年初在生产上跑 Agent 的团队里约 89% 有某种形式的可观测性,但只有 52% 有验证行为质量的量评估流水。这个序列就是多数问题潜伏的地方。

如果把层次拆开看:有 span 结构的 trace 是面,OpenTelemetry 的 GenAI semantic conventions 已经提供了 gen_ai.system、gen_ai.request.model、gen_ai.usage.input_tokens 这类通用属性;采样上多数系统只记录最终回复,因为 token 开销,折中办法是中间状态只记哈希,只对失败的轨迹保留完整输入输出;推理 trace 与操作日志分两路存储,一个记录意图,一个记录动作,两者都有用,但混在一条流里两边都难读;自动化约束检查接进 CI,这是唯一容易被迫推进的决定。

大厂已经在怎么做

阿里云 AgentLoop 围绕采集、分析、评估、回测、优化做了完整的一圈。采集上做法很直接:支持 Dify、LangChain、LangGraph、AgentScope,以及 OpenClaw、Claude Code、Codex、Cursor 这些客户端,不需要改代码、嵌 SDK;内部用一种叫 ATIF 的轨迹交换格式做结构化,然后用 Pipeline 把一次小时级窗口内的数千行轨迹清洗成可计分的样本。评估层用 Agent-as-a-Judge,内置二十多个业务场景评估器。上游还有 OpenAI Agents SDK 把 LLM 调用、工具、handoff、防护栏、自定义事件都计入 trace;Apifox 的例子则是在 IDE 里直接看执行追踪,工具没调用、参数传错、返回异常,分别看到。

这些东西解决的不是用哪种工具,而是你能不能把一次失败真正回到工作台上。我认为最容易忽视的前置条件仍然是那个:愿不愿意先把日志写入格式规范工作当成工程,而不是等人出了问题再说。因为多数 Agent 的故障并不会出现在指标周围。

转载请注明出处: 皮哈皮阿

本文的链接地址: https://blog.phpat.com/agent-engineering/617.html

手机扫码阅读

微信或手机浏览器扫一扫,随时随地随心阅读与分享

您可能对以下文章感兴趣
1 / 1
预览图