摘要
一句话总结 智能体可观测性通过记录非确定性的推理过程(运行、追踪、线程),实现了从“调试代码”到“调试推理”的根本转变,是驱动智能体多维度评估与持续迭代的核心基础。
核心要点
- 调试对象的范式转移:传统软件调试依赖确定性代码和堆栈跟踪,而智能体调试的核心是“推理过程”,事实来源从代码转移到了展示实际行为的“追踪(Traces)”上。
- 可观测性的三大基本要素:
- 运行(Runs):捕获单次 LLM 调用(单步执行)的完整提示词、工具和上下文,用于单步调试和断言。
- 追踪(Traces):捕获完整的智能体执行轨迹(全回合),包含所有运行、工具调用及嵌套结构。
- 线程(Threads):捕获多轮对话上下文,记录随时间推移的交互、状态演变和记忆更新。
- 评估核心的改变:智能体评估测试的是“推理”而非“代码路径”,需验证智能体在单步决策、端到端轨迹以及多轮上下文中的表现。
- 生产环境的新角色:生产环境不仅用于捕获遗漏的 Bug,更是主要的“老师”;生产环境的真实追踪记录会转化为离线测试用例,定义“正确的行为”。
- 评估粒度与可观测性一一对应:
- 单步评估(对应 Runs):类似单元测试,验证特定决策点(如工具选择),易于自动化评分。
- 全回合评估(对应 Traces):验证端到端轨迹、最终响应和状态变化,易于获取输入但难以自动验证输出。
- 多轮评估(对应 Threads):验证真实对话流和上下文积累。
- 多阶段评估策略:智能体评估需要结合离线评估(发布前测试)、在线评估(生产数据无参考运行)和即席评估(对海量追踪数据进行探索性分析)。
- 追踪驱动评估闭环:追踪数据构成了统一的基础,直接驱动手动调试、离线评估数据集的生成、在线监控(如 LLM 作为裁判)以及 AI 辅助的即席洞察。
风险与不足(原文明确提及)
- 传统工具的局限性:传统的追踪工具仅记录服务调用和耗时,无法捕获智能体决策背后的推理上下文,且无法处理动辄数百步的庞大轨迹。
- 数据规模挑战:智能体的追踪数据量极大,复杂任务的追踪数据可能高达数百兆字节,超出人工手动检查的极限,必须依赖 AI 辅助分析。
- 单步评估的脆弱性:如果智能体的内部结构(如可用工具、调用顺序)频繁变化,单步评估(运行级别)会很快过时,建议在架构稳定后再构建。
- 多轮评估的实现难度:多轮评估(线程级别)最难有效实现和自动评分,一旦智能体在早期回合偏离预期,后续硬编码的测试输入就会失效。
正文
如果不了解智能体(Agent)的推理过程,你就无法构建可靠的智能体;如果没有系统的评估,你也无法验证改进的效果。
核心观点:
- 在实际运行之前,你无法预知智能体会做什么——这意味着智能体的可观测性与传统软件的可观测性截然不同,且更为重要。
- 智能体通常执行复杂的开放式任务,因此评估它们的方式也与评估传统软件不同。
- 由于追踪(Traces)记录了智能体行为的产生过程,它们以多种方式为评估提供了核心动力。
在传统软件中,当出现问题时,你知道该怎么做:查看错误日志,检查堆栈跟踪,找到出错的那行代码。但是,AI 智能体改变了我们调试的对象。当一个智能体花了耗时两分钟、执行了 200 个步骤来完成一项任务,并在中途犯了错误时,这是一种完全不同的错误类型。这里没有堆栈跟踪——因为没有失败的代码。真正失败的是智能体的推理。
从调试代码到调试推理
你仍然需要编写代码来定义你的智能体,例如:存在哪些工具、有哪些可用数据。你编写提示词(Prompts)和工具描述来引导智能体的行为,但在实际运行之前,你无法知道大语言模型(LLM)将如何理解这些指令。因此,事实的来源从“代码”转移到了展示智能体实际行为的“追踪(Traces)”上。
智能体工程是一个迭代的过程,而追踪与评估正是你形成闭环的方式。智能体的可观测性和评估与传统软件有着本质的区别,我们需要新的基本要素和实践方法,而可观测性与评估之间密不可分的联系正是驱动这一切的基础。
智能体可观测性 ≠ 软件可观测性
在 LLM 出现之前,软件在很大程度上是确定性的——给定相同的输入,就会得到相同的输出。逻辑被固化在代码中。你可以通过阅读代码准确知道系统的行为方式。当出现问题时,日志会指出哪个服务或函数失败了,然后你可以回到代码中找出原因并修复它。
AI 智能体打破了确定性以及“代码即事实来源”的假设。当我们从传统软件转向 LLM 应用,再转向智能体时,每一步都引入了更多的微不确定性。普通的 LLM 应用带着上下文对 LLM 进行单次调用,引入了自然语言固有的“模糊性”,但仍局限于一次调用。
然而,智能体会循环调用 LLM 和工具,直到它们判定任务完成——并且可以在几十或几百个步骤中进行推理,调用工具、维护状态,并根据上下文调整行为。在构建智能体时,你试图在代码和提示词中规定应用逻辑。但在实际运行 LLM 之前,你并不知道这些逻辑会产生什么结果。
当出现问题时,你不再是寻找出错的某一行代码。相反,你需要问:
- 为什么智能体在 200 步中的第 23 步决定调用
edit_file而不是read_file? - 是什么上下文和提示词指令促成了这个决定?
- 在这个耗时两分钟、长达 200 步的轨迹中,智能体是在哪里偏离轨道的?
传统的追踪工具无法回答这些问题。一个 200 步的追踪记录对人类来说太庞大了,而且传统的追踪工具无法捕获每个决策背后的推理上下文;它们只记录调用了哪些服务以及每次调用耗时多久。
智能体评估 ≠ 软件评估
传统的软件测试依赖于确定性的断言:编写测试来检查 output == expected_output,验证通过后即可发布。在线评估(A/B 测试、产品分析)则单独衡量业务影响。评估智能体与评估软件在以下几个关键方面有所不同:
1. 你测试的是推理,而不是代码路径
传统软件在不同粒度(单元、集成、端到端)上进行测试,测试的是你可以阅读和修改的确定性代码路径。智能体也需要在不同粒度上进行测试,但你测试的不再是代码路径,而是推理:
- 单步(Single-step):智能体在这一刻做出了正确的决定吗?
- 全回合(Full-turn):智能体在端到端执行中表现良好吗?
- 多轮(Multi-turn):智能体在整个对话过程中是否保持了上下文?
2. 生产环境成为你主要的“老师”
在传统软件中,你可以通过离线测试(单元测试、集成测试、预发布环境)捕获大部分正确性问题。你仍然会通过金丝雀部署和功能标志在生产环境中进行测试,但目标是捕获遗漏的边缘情况和集成问题。
对于智能体来说,生产环境扮演着不同的角色。因为每一个自然语言输入都是独一无二的,你无法预见用户会如何表达请求,或者存在哪些边缘情况。生产环境的追踪记录会揭示你无法预测的故障模式,并帮助你了解在真实用户交互中“正确的行为”到底是什么样的。
这改变了你对评估的看法:生产环境不仅仅是你捕获遗漏 Bug 的地方。它是你发现离线测试应该测什么的地方。生产环境的追踪记录变成了测试用例,你的评估套件会随着真实世界的例子不断增长,而不仅仅是人为设计的场景。
智能体可观测性的三大基本要素
智能体可观测性使用三个核心要素来捕获非确定性的推理过程:
- 运行(Runs):单个执行步骤(一次 LLM 调用及其输入/输出)。
- 追踪(Traces):完整的智能体执行过程,展示所有运行及其相互关系。
- 线程(Threads):多轮对话,将随时间推移的多个追踪记录分组。
这些要素使用了与传统可观测性相同的概念(如 traces、spans),但它们捕获的是推理上下文,而不是服务调用和耗时。
运行(Runs):捕获 LLM 在单步中的行为
一次运行捕获一个执行步骤。这对于记录 LLM 在特定时间点的行为最为有用。它捕获了 LLM 调用的完整提示词,包括所有指令、使用的工具和上下文。
这些运行具有双重用途:
- 用于调试:准确查看智能体在任何步骤中的思考过程。提示词里有什么?有哪些可用工具?为什么它选择了这个动作?
- 用于评估:针对这次运行编写断言。智能体调用了正确的工具吗?参数正确吗?
追踪(Traces):捕获轨迹
追踪通过将发生的所有运行链接在一起,捕获完整的智能体执行过程。一个推理追踪包含:
- 每一步输入模型的所有信息(由构成追踪的各个运行捕获)。
- 所有工具调用及其参数和结果。
- 展示步骤之间如何关联的嵌套结构。
智能体的追踪数据是海量的。典型的分布式追踪可能只有几百字节,而智能体追踪的规模可能要大几个数量级。对于复杂、长时间运行的智能体,追踪数据可能达到数百兆字节。这种上下文对于调试和评估智能体的推理是必不可少的。
线程(Threads):多轮对话上下文
单个追踪捕获一次智能体执行,但智能体通常在涉及与用户或系统多次交互的会话中运行。线程将多个智能体执行(追踪)分组到一个对话会话中,保留了:
- 多轮上下文:用户与智能体之间按时间顺序排列的所有交互。
- 状态演变:智能体的记忆、文件或其他工件在不同回合中是如何变化的。
- 时间跨度:对话可能持续几分钟、几小时甚至几天。
假设你在调试一个编程智能体,它在前 10 个回合表现良好,但在第 11 个回合突然开始犯错。孤立地看第 11 回合的追踪,可能显示智能体调用了一个合理的工具。但当你检查完整的线程时,你会发现在第 6 回合,智能体用一个错误的假设更新了它的记忆,到了第 11 回合,这个糟糕的上下文已经累积成了包含 Bug 的行为。
线程对于理解智能体行为如何随时间演变,以及上下文如何在交互中积累(或退化)至关重要。
可观测性如何影响智能体评估
智能体的行为只有在运行时才会显现,并且只能通过可观测性(运行、追踪和线程)来捕获。这意味着要评估行为,你需要评估你的可观测性数据。这引出了两个关键问题:
- 你在什么粒度上评估智能体?是在运行、追踪还是线程级别?
- 你在什么时候评估智能体?如果行为只有在运行智能体时才会显现,你能像评估软件一样离线评估它们吗?
在不同粒度上评估智能体
你可以在不同的粒度上评估智能体,这些粒度与可观测性要素 1:1 对应。你评估的内容决定了你需要哪个要素:
1. 单步评估:决策的单元测试 有时,你需要验证特定的决策点,而无需运行整个智能体。你可能想看看智能体在特定场景下是否选择了正确的工具,或者是否使用了正确的参数。
这就像是智能体推理的单元测试:设置一个特定的状态(对话历史、可用工具、当前任务),让智能体运行一步,并断言它做出了正确的决定。单步评估验证的是运行(Runs),即单个 LLM 调用。
示例:测试日历智能体的工具选择 日程安排智能体需要在安排会议之前找到空闲时间。你想验证它是否先检查了空闲时间,而不是立即尝试创建会议:
- 设置状态:对话历史 = 用户说“安排明天早上与 Harrison 的会议”,可用工具 =
[find_meeting_times, schedule_meeting, send_email] - 运行一步:智能体生成下一个动作
- 断言:智能体选择了
find_meeting_times(而不是schedule_meeting)
为什么需要运行(Runs):单步测试通常来自生产环境中报错的真实案例。为了重现这些案例,你需要智能体在该步骤之前的确切状态。详细的运行捕获是获取这些状态的唯一途径。单步评估效率高,能捕获单个决策点的回归问题。
2. 全回合评估:端到端轨迹评估 其他时候,你需要查看完整的智能体执行过程。全回合评估验证的是追踪(Traces),即包含所有运行的完整智能体执行,并允许你在多个维度进行测试:
- 轨迹:智能体是否调用了必要的工具?对于修复 Bug 的编程智能体,你可能会断言:“智能体应该调用
read_file,然后调用edit_file,最后调用run_tests。” - 最终响应:输出是否正确且有用?对于研究或编程等开放式任务,最终答案的质量通常比采取的具体路径更重要。
- 状态变化:智能体是否创建了正确的工件?对于编程智能体,你会检查它编写的文件;对于具有记忆的智能体,你会检查它是否存储了正确的信息。
每个断言都需要追踪的不同部分。如果不捕获完整的轨迹和状态变化,就无法评估这些维度。
3. 多轮评估:真实的对话流 有些智能体行为只有在多个回合中才会显现。智能体可能在前 5 个回合正确维护了上下文,但在第 6 个回合失败;或者能很好地处理单个请求,但在请求相互依赖时陷入困境。
多轮评估验证的是线程(Threads),即包含多个智能体执行的对话会话。你测试智能体是否正确积累了上下文、在回合之间保持了状态,并处理了基于先前交流的对话流。
挑战在于让多轮测试保持在正轨上。如果智能体在第 1 回合偏离了预期路径,你硬编码的第 2 回合输入可能就失去了意义。需要使用条件逻辑在每个回合后检查智能体的输出,如果偏离轨道则尽早判定失败。当多轮测试失败时,你需要展示所有回合的线程来了解哪里出了问题。
如何选择评估粒度
选择评估粒度没有唯一正确的方法。以下是一些常见的经验法则:
- 追踪级别(全回合):通常最容易想出输入数据。但很难想出预期的输出或通过编程方式验证它们的方法。你可能会自动化运行这些数据点,但不自动评分。
- 运行级别(单步):最容易完全自动化评分。这只是单个模型调用,通常可以通过检查调用了哪些工具来评估。注意:如果智能体内部结构(可用工具、调用顺序)频繁变化,这些评估可能会很快过时。通常建议在智能体架构相对稳定后再构建这些测试。
- 线程级别(多轮):最难有效实现。它们涉及一系列输入,且通常只有在智能体在输入之间表现出特定行为时才有意义。它们也很难自动评估,这是最不常见的评估类型。
大多数生产环境中的智能体结合使用这三种方式:核心工作流使用全回合测试,生产环境中发现的已知故障模式使用单步测试,有状态的交互使用多轮测试。
何时评估智能体
智能体的行为直到在生产环境中运行才会完全显现,这意味着评估智能体的时机也与传统软件不同。
- 离线评估:相当于发布前运行单元测试。你需要收集一个输入数据集(可选包含用于对比的真实输出)。根据成本,你可以在每次提交时运行,或仅在推送到生产环境前运行。频繁运行需要设置缓存。
- 在线评估:因为运行前不知道表现如何,你可能希望在智能体处理生产数据时“在线”运行评估。这些评估器通常需要是“无参考(reference free)”的,并在摄取生产数据时运行。
- 即席评估:智能体的输入和行为非常无边界,你并不总是提前知道要测试什么。如果生产环境中有大量追踪数据,你可能希望在摄取后对它们进行测试。这种探索性数据分析对于理解智能体至关重要。
关键的转变是:离线评估是必要的,但还不够。在生产环境中评估智能体非常重要,因为你无法预见用户与智能体交互的所有方式。
智能体可观测性如何为评估提供动力
你为可观测性生成的追踪记录,正是驱动你进行评估的追踪记录,它们构成了一个统一的基础。
追踪 → 手动调试 当你在本地针对即席查询运行智能体并手动检查结果时——这仍然是一种(手动)评估形式!追踪记录为这种工作流提供了动力,因为它们允许你深入到过程的每一步,准确找出哪里出了问题。
追踪 → 离线评估数据集 生产环境的追踪记录会自动成为你的评估数据集。例如,当用户报告 Bug 时,你可以在追踪记录中看到:确切的对话历史和上下文、智能体在每一步的决定,以及具体在哪里出了错。 工作流示例:用户报告错误行为 → 找到生产追踪记录 → 提取失败点的状态 → 从该确切状态创建测试用例 → 修复并验证。
追踪 → 在线评估 为调试生成的相同追踪记录,也为持续的生产验证提供了动力。在线评估运行在你已经捕获的追踪记录上。你可以对每个追踪记录运行检查,或进行策略性抽样:
- 轨迹检查:标记异常的工具调用模式。
- 效率监控:检测性能下降趋势。
- 质量评分:在生产输出上运行“LLM作为裁判(LLM-as-judge)”。
- 故障警报:在用户报告之前发现错误。
追踪 → 即席洞察 当一个追踪记录包含超过 100,000 行数据,或者一个线程跨越几十个回合时,手动检查变得不可能。这时 AI 辅助分析可以帮助你查询追踪和线程,从而:
- 发现跨多个智能体执行的使用模式。
- 识别常见的故障模式和低效问题。
- 解释特定决策:“为什么智能体在这一步调用了这个工具?”
- 对比成功与失败的执行以寻找规律。
例如,如果一个智能体采取了低效的路径,AI 助手可以识别出智能体对同一个文件多次调用了 read_file,而不是将内容存储在上下文中。修复方法可能只是一个简单的提示词调整(而手动发现这种模式可能需要几个小时)。
对智能体开发团队的启示
交付可靠智能体的团队已经接受了从“调试代码”到“调试推理”的转变。传统软件将追踪(用于调试)和测试(用于验证)分离开来。现在,由于我们正在调试跨越长时间运行、有状态过程的非确定性推理,这些实践正在融合。你需要推理追踪来评估智能体行为,你也需要系统的评估来理解追踪记录。
从第一天起就将这两种实践结合起来的团队,才能真正交付行之有效的智能体。