深度“解剖”AI Agent 可观测性

13 阅读18分钟

Harrison Chase 2026 年 8 月 26 日 07:30

There’s no stack trace, because there’s no code that failed.

栈无迹可循,盖码未尝有失也。

楔子

最近有不少热点事件都和 AI 安全密切相关,所以 Agent 的可观测性也被频繁提及。

在传统软件出错时,我们可以通过各种手段来调试代码中的 bug。但在 Agent 出错时,还需要还原的是它在运行中形成的决策轨迹。

其实除了用于排查问题之外,可观测性也和 Agent 的持续改进密切相关,因为没有系统化评估,就无法验证改进是否有效。

所以今天,就为大家分享一篇我前不久学习到的一篇质量非常高的 AI Agent 可观测性的基础概念入门小文章。

这篇文章的作者是 LangChain 联合创始人 Harrison Chase,清晰地为大家介绍了 Agent 可观测性的几个基本单元、如何按不同粒度评估 Agent,以及生产 Trace 如何成为持续改进的根基。

绝对 AI 爱好者值得一读,也很适合已经对 Agent 可观测性有所了解的老师们来温故知新。

说明:

本文中的“决策过程”只指系统能够记录的输入、输出、工具选择、状态变化和决策摘要,不涉及模型不可见的内部思维链。

部分配图,因为偷懒,所以沿用了英文原版。

欢迎大家关注 OceanBase 社区公众号 “老纪的技术唠嗑局”。在这里,我们会持续为大家更新与 #AI 和 #Data 相关的技术内容~

开篇:从调代码,到调 Agent

传统软件出了问题,你知道该怎么做:查错误日志,看堆栈跟踪,找到出错的那行代码。

但 AI Agent 改变了我们要调试的对象。一个 Agent 花两分钟走完 200 步,中途某处犯了错,这完全是另一类故障。没有堆栈跟踪,因为根本没有哪段代码执行失败,出问题的,是 Agent 的决策过程。

在现阶段,大家当然还是要靠写代码来定义 Agent,比如它有哪些工具、能访问哪些数据。你也会编写提示词和工具说明,引导 Agent 的行为。

但在 Agent 真正运行之前,你不会知道 LLM 会如何理解这些指令。 于是,事实依据从代码转向了 Trace(一次完整执行轨迹):它记录了 Agent 实际做过什么。

Agent 工程是一个反复迭代的过程 [1] ,而追踪与评估能帮你把这个闭环真正转起来。

本文即将和大家讨论:Agent 可观测性 [2] 和评估为什么从根本上不同于传统软件,我们需要哪些新的基本单元和实践,以及可观测性如何为评估提供动力,让两者再也分不开。

Agent 可观测性 ≠ 软件可观测性

在 LLM 出现之前,大多数软件都相对确定:输入相同,输出通常也相同。业务逻辑写在代码里,读代码就能大致知道系统会怎么运行。服务出了问题,日志会指出哪个函数失败,再沿着调用链回去查原因。

AI Agent 打破了这两项基本假设:系统是确定性的,代码是事实依据。

LLM 应用已经会因为自然语言的模糊性产生不同结果,Agent 又在此基础上多了一层循环:它会反复调用模型和工具,维护状态,根据新拿到的上下文调整下一步,直到自己判断任务完成。几十步还算客气,复杂 Agent 可能连续行动几百步。

传统软件、LLM 应用与 Agent 的对比

当问题发生时,你已经不是在寻找某一行执行失败的代码,而是在追问:

  • 总共 200 步,为什么第 23 步调用了 edit_file ,而不是 read_file
  • 当时的上下文里,有哪些信息影响了这个决定?
  • 这段持续两分钟的执行,究竟从哪里开始偏离预期?

传统追踪工具回答不了这些问题。一条包含 200 步的 Trace,就已经难以阅读; 传统 Trace 也不会记录每次决策背后的上下文,只会告诉你调用了哪些服务、每次调用花了多久。

Agent 评估 ≠ 软件评估

传统软件测试很直接:写一个断言,检查 output == expected_output ,通过就发布。线上再用 A/B 测试或产品指标观察业务效果。

Agent 评估 [3] 麻烦一些。它处理的经常是开放式任务,正确答案可能不止一个;最终答案即使看起来不错,中间也可能走了一条危险、昂贵或碰巧成功的路径。

评估的是决策过程,而非代码路径

传统软件有单元测试、集成测试和端到端测试,每一层都对应一段可以阅读和修改的代码路径。Agent 也需要不同层次的测试,只是检查对象换成了它的行动:

  • 单步评估 ,这一刻选对工具了吗?参数传对了吗?
  • 单轮完整评估 ,这一次任务从头到尾做得怎么样?
  • 多轮评估 ,聊了几轮以后,它还能记住前文和状态吗?

生产环境会不断送来新题目

在传统软件里,大多数正确性问题可以通过离线测试发现,包括单元测试、集成测试和预发布环境测试。你仍会借助金丝雀发布和功能开关在生产环境中测试,但目的主要是捕捉此前漏掉的边缘情况和集成问题。

到了 Agent 这里,生产环境扮演着另一种角色。每条自然语言输入都不一样,你无法预判用户会如何表达请求,也无法穷举所有边缘情况。

生产 Trace 会暴露那些你根本想不到的失败模式,也会帮你理解:在真实用户交互中,“正确行为”究竟长什么样。

这会彻底改变你看待评估的方式: 生产环境不只是用来捕捉漏网的 Bug,更是你发现“离线阶段应该测什么”的地方。 生产 Trace 会变成测试用例,你的评估套件也会从真实案例中持续生长,而不是只靠人为设计的场景。

Agent 可观测性的基本单元

Agent 可观测性常用三个基本单元来记录行为:

  • Run(一次执行步骤) :单个执行步骤,例如一次带有输入和输出的 LLM 调用
  • Trace(一次完整执行轨迹) :一次完整的 Agent 执行,包含所有 Run 及其相互关系
  • Thread(跨多轮会话) :将一段时间内的多条 Trace 归入同一场多轮对话

这些概念与传统可观测性中的 Trace、Span 等概念一脉相承,不过记录重点变了。传统可观测性关心服务调用和耗时, Agent 可观测性记录的是决策上下文,需要留下当时的输入、工具、状态和行动结果。

Run:记录 LLM 在单个步骤里做了什么

一个 Run [4] 记录单个执行步骤。以一次 LLM 调用为例,它会留下完整提示词、相关指令、可用工具、上下文和模型输出。

调试和评估都会用到这份 Run。

调试时,它帮你还原 Agent 在那一步拿到了哪些信息、手里有哪些工具,以及最后选了什么动作。

评估时,你可以直接对这一步写断言:工具选对了吗?参数有没有填错?

Trace:记录行动轨迹

一条 Trace 会把本次执行里的 Run 全部连接起来。每一步送进模型的信息、所有工具调用及其参数和返回结果、步骤之间的嵌套关系,都在这条轨迹里。

Agent Trace 往往比传统分布式 Trace 大得多,普通分布式 Trace 可能只有几百字节,复杂的长时间运行 Agent 则可能产生数百兆字节的 Trace。之所以这么大,是因为调试一次决策需要的不只是耗时,还包括上下文和状态。

Thread:多轮对话的上下文

单条 Trace 只记录一次 Agent 执行,可很多 Agent 会和用户连续交互。一条 Thread [5] 会把同一场会话中的多次执行(多条 Trace)归在一起,保留三类信息: 完整的多轮上下文,记忆、文件等状态如何变化,以及这场对话持续了多久

假设一个编程 Agent 前 10 轮都表现正常,第 11 轮突然开始犯错。只看第 11 轮的 Trace,它调用的工具甚至很合理。把整个 Thread 打开后才发现,第 6 轮时,它往记忆里写进了一个错误假设。这个假设一路留到第 11 轮,终于把后续行为带偏。

第 11 轮只是问题爆出来的地方,原因早在第 6 轮就出现了。没有完整 Thread,这类跨轮累积的问题很容易被误判成一次偶发故障。

三层记录,对应三层评估

Agent 的行为要运行后才会显现,而 Run、Trace、Thread 正好记录了三种不同范围的行为。要检查这些行为,评估也分成三个范围:

  • 单步评估检查 Run,看 Agent 在某个具体步骤做对决定了吗?
  • 单轮完整评估检查 Trace,看 Agent 正确执行了整个任务吗?
  • 多轮评估检查 Thread,看 Agent 能否在一段会话中维持上下文和状态。

单步评估:给决策做“单元测试”

有时你只想检查一个具体决策,不想让 Agent 从头到尾再跑一遍。比如,某个场景下它应该选择哪个工具,或者工具参数应该怎么填。

这很像给 Agent 的一次选择写单元测试:准备好当时的对话历史、可用工具和任务状态,只让它执行一步,再检查结果。

拿日程安排 Agent 举个例子。用户说:“把我和 Harrison 的会议安排在明天上午。”Agent 手里有三个工具: find_meeting_timesschedule_meetingsend_email

这条测试只做三件事:

  1. 还原用户消息和当时可用的工具;
  2. 让 Agent 生成下一步动作;
  3. 检查它选择的是 find_meeting_times ,而不是直接调用 schedule_meeting

为什么需要 Run :单步测试经常来自真实生产环境中的故障案例。要复现它,你必须拿到出错步骤之前 Agent 的精确状态,因为详细的 Run 记录通常是还原这份状态最直接的依据。

单步评估效率很高,也能捕获具体决策点上的回归问题。实践中,大约一半的 Agent 测试套件会使用这类单步测试:它们可以隔离并验证特定决策行为,又不必承担完整运行 Agent 的开销。

单轮完整评估:端到端检查行动轨迹

另一些任务不能只看一步。你得把一整条 Trace 从头看到尾,检查行动轨迹、最终回复和状态变化。

行动轨迹 ,Agent 有没有调用必要的工具?比如一个编程 Agent 修 Bug,通常需要调用 read_fileedit_filerun_tests 。具体顺序可以有变化,但缺了其中某一步就值得检查。

最终回复 ,答案是否正确、是否真的帮到了用户?调研和编程任务通常不只有一条合法路径,最后交付的质量可能比固定的工具顺序更重要。

状态变化 ,Agent 有没有把正确内容写进文件、记忆或其他产物?嘴上说“已经保存”和文件里真的多了一条记录,是两回事。

要验证 Agent 是否记住了一项用户偏好,可以连续检查三处:

  1. 行动轨迹里,它是否对记忆文件调用了 edit_file
  2. 最终回复里,它是否向用户确认了更新;
  3. 实际状态里,记忆文件是否真的写进了这条偏好。

每条断言依赖 Trace 中不同部分的数据。不记录完整行动轨迹和状态变化,你就无法评估这些维度。

多轮评估:还原真实的对话流程,问题才会露面

有些 Agent 行为只会在多轮交互后显现。Agent 可能前 5 轮都能正确维持上下文,到第 6 轮却出了问题;也可能单独处理每条请求都没毛病,一旦请求层层承接,就开始招架不住。

多轮评估验证的是 Thread,也就是包含多次 Agent 执行的对话会话。你要测试 Agent 能否正确累积上下文、跨轮维护状态,以及处理建立在前文之上的对话流程。

比如测试一项编程语言偏好:

  • 第 1 轮:用户表达一项偏好(“比起 JavaScript,我更喜欢 Python”)
  • 第 2 轮:用户提出一个承接上文的问题(“给我看个例子”)
  • 第 3 轮:测试偏好是否仍然有效(“为这个写段脚本”)

Agent 应该在第 2、3 轮都提供 Python 示例,而不是 JavaScript。这要求它跨轮维持上下文。

难点在于,如何让多轮测试始终“跑在轨道上”。如果 Agent 在第 1 轮就偏离预期,你硬编码的第 2 轮输入可能立刻变得不合时宜。应该在每轮结束后用条件逻辑检查 Agent 输出,一旦跑偏就尽早失败。

多轮评估需要用 Thread 把多次 Agent 执行(多条 Trace)归入同一场对话。多轮测试失败时,你需要查看包含全部轮次的 Thread,才能弄清哪里出了问题、问题又是从何时开始的。

如何选择 Agent 评估的粒度?

没有一种粒度能包办所有问题。

Trace 级评估最容易准备输入。 这些输入本来就是要交给 Agent 的任务,收集和设计都相对直接。难的是预期输出,开放式任务很难写成一个简单断言。很多团队会先把 Agent 批量跑起来,评分暂时还得靠人。

Run 级评估最容易自动评分。 一次模型调用、一次工具选择,通常用代码就能判断。不过,Agent 的工具和内部结构还在频繁调整时,这些测试也很容易过期。整体架构稳定以后再大量建设,维护起来更省心。

Thread 级评估最难。 你得设计一串彼此承接的输入,还要保证 Agent 每一轮都走在测试能够继续的方向上。评分同样不好自动化,因此目前最少见。

大多数生产级 Agent 会把几种粒度组合起来:用单轮完整测试覆盖核心工作流,用单步测试防范生产环境中已经暴露的失败模式,再用多轮测试检查有状态的交互。

Agent 评估应该什么时候做?

Agent 的行为在真正运行于生产环境之前不会完全显现,因此, 评估 Agent 的时机也不同于传统软件

离线评估 ,相当于发布前运行单元测试。你需要先收集一个输入数据集,还可以选择准备标准答案,用来与 Agent 输出比较。根据 Agent 在这套数据上运行和接受评估的成本,你可以每次提交都执行,也可以只在发布到生产环境前执行。如果要频繁进行离线评估,最好设置某种缓存,避免不必要的模型调用。

说明:大多数人谈到“评估”时,主要指的就是离线评估。

在线评估 ,既然不实际运行就不知道 Agent 表现如何,你可能会希望在 Agent 使用生产数据运行时,直接开展“在线”评估。按照定义,这类评估器必须是“无参考答案(reference-free) [6] ”的。在线评估器通常会在生产数据写入时运行。

临时分析式评估 ,Agent 的输入和行为边界都很宽,所以你不一定能提前知道自己想测什么。如果生产环境已经积累了大量 Trace,你可能会希望在数据写入完成后,再回头测试它们。这类探索性数据分析对于理解 Agent 至关重要。Insights Agent [7] 这类系统,就是为这种探索式分析准备的。

关键变化在这里: 离线评估必不可少,却并不够。 在生产环境中评估 Agent 同样重要,因为你无法预见用户会用多少种方式与它交互。

Agent 可观测性如何驱动 Agent 评估?

你为 AI 可观测性 [8] 生成的 Trace,正是为评估 [9] 提供动力的同一批 Trace。

两者共享同一套基础。

Trace → 人工调试

在本地拿几个临时问题运行 Agent,再逐步检查结果,本身就是一种人工评估。Trace 把每一步的输入、动作和结果放在一起,你才能看出它从哪里开始偏。

Trace → 离线评估数据集

经过筛选、脱敏、清理和必要标注后,生产 Trace 可以沉淀为评估数据集。比如用户报告一个 Bug 后,你可以从 Trace 中看到:精确的对话历史和上下文、Agent 在每一步做了什么决定,以及它具体在哪里出了错。

下面是一套示例工作流:

  1. 用户报告错误行为
  2. 找到对应的生产 Trace
  3. 提取故障点当时的状态
  4. 用这一精确状态创建测试用例
  5. 修复并验证

这样一来,你的离线评估测试套件就能直接由真实数据点构成。

Trace → 在线评估

同一批 Trace 也能承担生产环境里的持续检查。没必要让人逐条阅读,可以全量运行规则,也可以按策略抽样:

  • 行动轨迹检查 ,标记异常的工具调用模式;
  • 效率监控 ,发现耗时或资源消耗持续变差;
  • 质量评分 ,用 LLM 评审(LLM-as-a-Judge)为生产输出打分;
  • 故障告警 ,尽量在用户主动报错前发现问题。

这些检查持续运行后,开发阶段表现正常的 Agent,上线后有没有慢慢跑偏,也能及时看到。

最后:Agent 可观测性,究竟意味着什么?

能够稳定交付 Agent 的团队,都已经逐渐接受了从“调试代码”到“调试决策过程”的转变。

传统软件把追踪(用于调试)和测试(用于验证)分开,如今,我们调试的是贯穿长时间运行、有状态流程的非确定性决策。

你既需要可记录的决策与执行轨迹来评估 Agent 行为,也需要系统化评估来读懂海量 Trace。只有从第一天起就把“追踪”和“测试”结合起来的团队,最终才能交付真正可用的 Agent 产品。

(原文完)

加餐

PowerContext [10] —— 不止于记忆

Agent 犯错,很多场景都是因为上下文给错了。所以我们做了一个开源项目,叫 PowerContext,是面向人机协作的上下文运行层。它的主要目标就是将 Agent 推进的工作沉淀为:可理解、可交接、可延续的项目上下文。

PowerContext 会保存值得复用的信息,对大多数人来说,最直接的价值就是: 换一次对话、甚至换一个 Agent,不用重新交代全部背景。

放在 Agent 可观测性中,Trace 会告诉我们它做了什么,而 PowerContext 可以用于管理它做决定前看到的内容:原始资料(Source)从哪里来,哪些信息被整理成长期记忆(Memory),本次任务实际拿到了哪份资料包(PreparedContext),以及更换会话或 Agent 时交接了什么(Handoff)。如果再通过一些可观测标准把这些记录串起来,排查问题时就能分清,是模型判断失误,还是资料、记忆或交接出了问题。简单来说, 一条错误的信息进入上下文,然后引发 Agent 犯错后,PowerContext 能够快速帮你找到错误信息的来源。

除此以外,PowerContext 还为 Codex、Claude Code、DeepSeek Harness 和 Hermes Agent 提供了官方插件。欢迎大家试用,也欢迎大家参与项目共建!

PowerContext 项目地址:github.com/oceanbase/p…

参考资料

[1]

Agent 工程是一个反复迭代的过程: blog.langchain.com/agent-engin…

[2]

Agent 可观测性: www.langchain.com/resources/a…

[3]

Agent 评估: www.langchain.com/resources/a…

[4]

Run: docs.langchain.com/langsmith/o…

[5]

Thread: docs.langchain.com/langsmith/t…

[6]

无参考答案(reference-free): docs.langchain.com/langsmith/e…

[7]

Insights Agent: docs.langchain.com/langsmith/i…

[8]

AI 可观测性: www.langchain.com/resources/a…

[9]

评估: www.langchain.com/resources/l…

[10]

PowerContext: github.com/oceanbase/p…

往期内容推荐

了解更多

添加社区小助手,加入微信交流群~