跳转到主要内容

Agent 调试器没有断点:为什么追踪优先工作流正在取代单步执行

阅读需 2 分钟Tian PanTian Pan

当你第一次尝试像调试服务那样调试 Agent 时,你会发现以往的肌肉记忆完全派不上用场。你设置了一个假设的断点——虽然 IDE 中没有面板可以放置它,但你在脑海中想象了一个——就在 planner 选错工具的那一步。你使用相同的输入重新运行。这一次,planner 选择了正确的工具。你再次运行。它又选了一个你从未见过的第三种工具。Bug 是真实存在的,你的同事今天早上复现了两次,而你用了十五年的调试器突然间变成了博物馆里的陈列品。

这里失效的心智模型并不是“使用调试器”,而是背后更深层的假设:即一个程序在给定相同输入的情况下,会产生相同的执行过程。现代调试器中的每一项功能——断点、单步跳过 (step-over)、观测表达式 (watch expressions)、条件断点、热重载——都是建立在这种确定性之上的。你暂停执行是因为暂停是有意义的。你向前单步执行是因为下一步是可预知的。你检查一个变量是因为它的值是一个事实,而不是从某种分布中随机抽取的结果。

Agent 在每一个关键层面上都违背了确定性。生产环境中的 Temperature 不会设为 0,因为在长尾场景下,0 会扼杀创造力。工具输出取决于外部系统的实时状态。检索索引随着文档的增加而变化。API 背后的模型本身也是一个移动的目标——微小的修订在发布时并没有与语义化版本号对齐的变更日志。结果就是,“设置断点并重新运行”无法复现问题,开发者调试的前三十分钟往往毫无收获。

取代单步执行的工作流并不是一个更快的 IDE。它是一种不同的形态:Trace 优先、基于回放,并具备确定性代码工具箱中不存在的功能。以下是 Agent 调试技术栈必须提供的四项功能、它们在实践中的样子,以及迫使团队构建这些功能的失效模式。

时间轴拖动 (Timeline Scrubbing) 取代单步跳过 (Step-Over)

工程师打开 Agent Trace 时,最先想要的功能就是能像视频编辑拖动时间轴一样滚动查看运行过程。一个包含 50 步的 Agent 执行过程可能包含一千个 span——工具调用、模型调用、检索查询、状态转换、内存写入——而 Bug 可能就发生在第 37 步。单步跳过会强迫他们逐个经过前面的步骤。而时间轴视图让他们可以抓住播放头,拖动它,并在两秒钟内定位到正确的 span。

让这项功能变得至关重要的是 Agent Trace 的形态,它几乎从来不是线性的。一个现代 Agent 的运行过程是一个包含并行工具调用、条件分支和嵌套子 Agent 的有向无环图 (DAG)。生产环境的 Trace 通常包含两千个 span,其中故障可能发生在四个工具调用的深度,如果没有时间轴视图,手动翻阅日志会将事故处理时间从几分钟拉长到几小时。

最关键的实现细节在于哪些内容被呈现在时间轴的顶层,哪些内容被隐藏在子面板中。工具调用和推理 span 属于主时间轴,因为它们是决策发生的地方。Token 级别的流式传输、重试尝试和缓存查找则属于折叠的子 span,因为十有八九它们都是干扰噪音。那些把所有内容都展示出来的团队,最终得到的虽然是一个结构完整的、但实际上无法阅读的时间轴——你必须缩放跳过 300 个 token 增量,才能找到 planner 选错工具的那一刻。

分支对比 (Branch Comparison) 取代条件断点 (Conditional Breakpoints)

当一个确定性的 Bug 让你措手不及,下一步通常是设置条件断点:当变量处于某种状态时停止,然后进行排查。Agent 的对应操作在结构上是不同的。你不需要检查一次执行——你需要检查多次,问题在于哪个变化维度才是真正关键的。

分支对比功能让你能将两三个 Trace 并排放在一起,然后追问:有什么不同。不同的 prompt、不同的模型、不同的检索结果、不同的工具参数、不同的推理链。最常出现的模式是:模型调用了同一个工具,但参数有细微差别,工具返回了细微差别的结果,于是下游决策发生了逆转。如果没有对比视图,这看起来就像是“Agent 很不稳定”;有了它,这就变成了一系列微小扰动导致的确定性链路。

一个不那么显见的要求是,对比只有在 Trace 是可对比 (diffable) 的情况下才有效,这意味着它们必须共享足够的结构,使得“运行 A 中的这个 span”能映射到“运行 B 中的这个 span”。自由格式的日志不支持这一点——两次具有不同推理链的运行会产生形状不同的树,而对比引擎需要知道如何按角色而不是按索引来对齐 span。

这是在以后的评估套件 (eval suites) 中会得到回报的规范:如果你的 Trace 是可对比的,你还可以计算跨模型版本的单个 span 增量,这就是你捕捉那些在聚合指标中无法体现的回归问题的方法。

会员专享

余下内容仅对会员开放。

会员可读完整内容 —— 每一个公开发布的观点背后,那些框架、决策与推理的全貌。

  • 完整文章,包含未公开存档的部分
  • 可落地的工作框架,附带权衡与决策依据
  • 新文章抢先看,先于公开发布

随时取消 · 一次订阅,畅读全部

参考资料

保持联系,关注我获取更多内容

阅读需 12 分钟

Agent 飞行记录仪:在第一次事故发生前必须捕获的字段

当 Agent 脱轨时,大多数团队拥有的取证记录都是徒劳的。这里列出了飞行记录仪在第一次事故发生前必须捕获的字段,以及与之配套的存储、采样和隐私规范。

insider
ai-engineering
阅读需 9 分钟

你从未构建过的智能体反馈闭环

每一个点踩、每一次无声的放弃、每一次重新表述的问题,都是一个免费的带标签失败案例 —— 而大多数团队却将其丢弃。本文介绍如何构建从用户信号到分诊失败再到永久评估案例的流水线。

insider
ai-engineering
阅读需 12 分钟

智能体动作空间的可达性分析:为你从未测试过的分支提供评测覆盖

你的工具目录加上规划器构成了一个可达的执行计划图,而你的评测(Evals)可能从未覆盖过这些路径。借鉴编译器的可达性分析方法,找出那些可能最先由事故频道(Incident Channel)发现的隐藏分支。

insider
ai-engineering
阅读需 9 分钟

Agent 流水线的分布式追踪:为什么你的 APM 工具形同虚设

标准 APM 工具在多步骤 Agent 流水线上会失效。以下是 AI Agent 专用可观测性的真正需求——以及三个能在用户察觉之前预判 Agent 劣化的关键指标。

insider
ai-engineering
阅读需 10 分钟

被反向代理剥离的 SSE Keep-Alive,以及你支付了两次费用的 Prompt

LLM 流式响应看起来像是从模型到用户的通畅管道 —— 直到一次 35 秒的工具调用导致反向代理断开连接,你的客户端针对无状态 API 重试整个 Prompt,最终用户的账单为同一个响应支付了两次费用。

insider
ai-engineering