跳到主要内容

AI Agent 系统化调试:从凭空猜测到根因分析

· 阅读需 10 分钟
Tian Pan
Software Engineer

当 AI Agent 在生产环境中失败时,你很少能准确知道它是何时出错的。你看到的只是最终输出——一个幻觉答案、一个跳过的步骤,或者一个参数错误的工具调用——但实际的失败可能发生在三个步骤之前。这是软件工程尚未解决的核心调试问题:Agent 以一系列决策的形式执行,当你意识到出问题时,证据已经埋藏在交织的 LLM 调用、工具调用和状态变更的长轨迹中。

传统的调试假设确定性。你可以重现 bug,设置断点,检查状态。Agent 调试同时打破了这三个假设。相同的输入可以产生不同的执行路径。重现失败需要捕获发生那一刻的精确上下文、模型温度和外部状态。而且在实时推理循环中“设置断点”甚至不是大多数 Agent 框架所支持的功能。

凭猜测进行调试的隐藏成本

当 Agent 表现异常时,大多数团队首先会阅读日志。他们滚动查看轨迹,形成假设,调整提示词(Prompt),然后再次运行。这对于极短的 Agent 有效。但在任何有意义的规模上,这都行不通。

在多步 Agent 中,问题会成倍增加。分析了数百个失败 Agent 轨迹的研究人员一致发现,根本原因很早就出现了,但其影响要到很久以后才会显现。一个在第 2 步误解了用户意图的 Agent 可能会正确执行后续的三个步骤,然后才产生错误的最终答案。如果没有步骤级的归因,查看输出的开发者会归咎于最后一次 LLM 调用——而那次调用实际上是正常的。

有九类经常出现的故障类别涵盖了大多数生产环境中的 Agent 失败:

  • 计划执行失败(Plan adherence failures) — Agent 跳过了要求的步骤,或者在计划中臆造了额外的步骤
  • 信息捏造(Information invention) — 幻觉出的事实、引用,或从未发生过的工具输出
  • 无效工具调用(Invalid tool invocations) — 使用格式错误的参数、错误的类型或缺失必填字段来调用工具
  • 误读输出(Misinterpreted outputs) — 正确接收了工具结果,但从中提取了错误的值
  • 意图与计划不匹配(Intent-plan misalignment) — Agent 生成的计划实际上并未解决用户提出的问题
  • 用户意图不明(Under-specified user intent) — Agent 对模糊的请求做出假设,而不是进行澄清
  • 不支持的请求(Unsupported requests) — 尝试完成超出 Agent 范围的任务,且通常表现得很自信
  • 触发防护栏(Triggered guardrails) — 安全或政策过滤器在执行中途阻断了轨迹
  • 系统故障(System failures) — Agent 未能正确处理的超时、API 错误、频率限制

前两个——计划执行和信息捏造——始终是最常见的,也是最难自动检测的,因为它们需要理解意图,而不仅仅是语法。

轨迹分析:将执行视为可测试的产物

使系统化调试变得可行的转变是:将 Agent 的执行轨迹视为可以根据规则验证的一等公民产物,而不只是由人工检查。

轨迹是 Agent 经历的完整状态序列:初始请求、每个推理步骤、每个工具调用及其输入和输出,以及最终结果。大多数 Agent 框架已经记录了这些数据。问题在于它们以异构格式存储——不同的字段名称、工具调用与 LLM 响应的不同结构——这使得自动化分析变得困难。

任何系统化方法的第一步都是轨迹归一化(trajectory normalization):将原始日志转换为统一的表示形式,其中每个步骤都具有相同的模式(Schema)。这听起来很乏味,但它开启了后续的一切。一旦有了归一化的轨迹,你就可以对其编写自动化检查。

这些检查采取**可执行约束(executable constraints)**的形式,来源于两个方面:

  1. 工具模式(Tool schemas) — 每个工具都有一个签名。参数应与其声明的类型匹配。必填字段应当存在。返回值应符合文档格式。这些约束几乎可以从你现有的模式定义中免费生成。

  2. 领域策略(Domain policies) — 表现为可测试条件的业务规则、安全要求和工作流不变性。“Agent 在下单前必须检查库存。”“Agent 在每次交易中调用支付 API 的次数不得超过一次。”这些很难枚举完整,但即使是部分清单也能捕获很大一部分实际故障。

在轨迹中逐步检查这些约束会生成证据日志(evidence log):记录每个约束在何处得到满足或被违反,以及导致违反的具体数值。这就是让调试变快的原因——与其阅读 200 行日志,不如直接看到是哪一步产生了无效的工具调用,以及哪个参数出错了。

关键故障步骤

并非所有的约束违反都是等同的。智能体(Agent)可能因为在第 3 步虚构了信息,从而在第 8 步触发了护栏(guardrail)。导致故障的步骤与显现故障的步骤是不同的。

寻找关键故障步骤 —— 即轨迹变得不可修复的最早时间点 —— 是调试的核心问题。这不仅仅需要约束检查,还需要理解跨步骤的因果关系。

一种有效的方法是:对证据日志进行第二次 LLM 处理,目的不是生成新答案,而是对因果链进行推理。哪一次违反导致了后续的违反?如果修正哪一步,就能导向成功的轨迹?这并不是要求模型去猜测 —— 而是要求它基于已经收集的结构化证据进行推理。这种分析的质量直接取决于证据日志的质量。

对该方法的研究表明,与仅要求模型阅读原始追踪(trace)并识别错误的基准方法相比,故障定位准确率提高了约 24 个百分点。区别在于结构:模型是对经过验证、有证据支持的步骤摘要进行推理,而不是原始日志文本。

智能体调试的实践可观测性

即使没有正式的诊断框架,也有一些具体的实践可以让生产环境中的智能体变得可调试:

基于跨度(span)的结构化追踪是基础。每一个 LLM 调用、工具调用和检索操作都应该是一个具有标准化属性的可追踪跨度。OpenTelemetry 的 GenAI 语义约定现在为此提供了一个通用模式:gen_ai.systemgen_ai.request.modelgen_ai.usage.input_tokensgen_ai.usage.output_tokens 以及特定于工具的扩展。当你所有的框架都使用相同的模式时,你就可以编写适用于各种智能体架构的分析工具。

捕获每一步的输入和输出,而不仅仅是最终结果。这听起来显而易见,但出于成本考虑,许多生产系统只记录最终的 LLM 响应。Token 级别的日志记录很昂贵。中间方案是记录每个中间状态的哈希值 —— 足以检测步骤何时发生异常变化 —— 并且仅针对失败的轨迹保留完整的输入/输出。

将推理追踪与操作日志分离。智能体的推理(思维链、计划生成)和操作执行(工具调用、API 请求)有不同的调试需求。推理追踪告诉你智能体的意图;操作日志告诉你它做了什么。两者都是必需的,将它们混合在单个日志流中会使两者都难以分析。

存储轨迹以便回放。失败的轨迹是一个测试产物。如果你可以存储完整的输入上下文和工具响应,你就可以针对修改后的提示词(prompt)或更新的工具模式(schema)回放精确的执行过程,而无需等待生产环境中再次出现相同的情况。这在更改智能体行为时对于捕获回归问题特别有价值。

将自动化约束检查构建到你的 CI 流水线中。如果你有领域策略约束,请在部署更改之前针对你的基准轨迹运行它们。这不会捕获所有故障,但会捕获你之前遇到过的故障。

为什么标准的日志扫描不起作用

将智能体日志传导到现有的可观测性工具(如 Datadog、Grafana 或你已经在使用的任何工具)并认为大功告成,这很有诱惑力。这适用于基础设施层面的指标:延迟、错误率、Token 成本。但它不适用于智能体调试中最关键的一类故障。

LLM 的可观测性从根本上说是语义上的,而不是语法上的。来自 LLM API 的成功 HTTP 200 响应可能包含幻觉事实。具有有效参数类型的工具调用对于当前步骤来说在语义上可能仍然是错误的。智能体可能成功完成了每一个操作,但顺序错了。这些故障都不会出现在延迟仪表板或错误率图表中。

这就是为什么该领域正趋向于集成评估的可观测性:这些系统不仅监控指标,还主动评估智能体的行为是否正确。截至 2026 年初,在生产环境中运行智能体的团队中,约有 89% 实施了某种形式的可观测性 —— 但只有 52% 拥有验证行为质量的评估流水线。这一差距正是大多数智能体故障潜伏的地方。

系统化调试在实践中是什么样的

构建生产级智能体系统的团队应该致力于实现这种调试循环:

  1. 记录每条轨迹,采用规范化的步骤级结构,捕获每一步的输入、输出和工具签名。
  2. 自动化约束检查针对每条轨迹运行,并标出带有证据的违反情况。
  3. 为失败的轨迹贴上标签,注明故障类别(来自上述分类法)和识别出的关键故障步骤。
  4. 这些标签反馈到评估流水线中,创建一个不断增长的已标注故障数据集,可用于测试更改是否真正解决了问题。
  5. 在任何智能体部署之前,回放已标注的故障数据集,并验证已知故障是否已解决,且没有引入新的约束违反。

这个循环并不华丽。它要求对日志结构保持严谨,投入精力编写约束,并将故障视为学习产物,而非一次性事件。但它就是随时间推移变得越来越可靠的智能体系统与在生产环境中不断给你“制造意外”的系统之间的区别。

智能体调试之所以困难,是因为智能体具有概率性、有状态,且在长跨度内运行。答案不是等待更好的模型 —— 而是构建系统化的基础设施,使故障变得清晰可见。一旦故障变得清晰可见,它就是可以修复的。

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