LangChain 如何为 Deep Agents 设计评估体系
评估(Evals)直接塑造智能体的行为。我们一直在为 Deep Agents 设计和维护评估体系,以衡量并改进其表现。Deep Agents 是一个开源、模型无关的智能体执行框架(Harness),支撑着 Fleet 和 Open SWE 等产品。评估定义了智能体的行为,因此精心设计它们至关重要。
每个评估都像一个向量,推动着智能体系统的行为变化。例如,如果一个关于高效文件读取的评估失败了,你很可能会调整系统提示或 read_file 工具的描述,直到它通过。你保留的每个评估都会随着时间的推移对整个系统施加压力。
添加评估时必须深思熟虑。盲目添加成百上千个测试的诱惑很大,但这可能导致一种“改进智能体”的错觉——你的评估套件得分很高,却可能无法准确反映生产环境中你真正关心的行为。
评估数量多 ≠ 智能体更好。相反,应该构建能反映生产环境中期望行为的针对性评估。
在构建 Deep Agents 时,我们梳理了生产环境中重要的行为,例如跨多个文件检索内容,或准确组合 5 个以上的工具调用(Tool Use)。我们没有使用聚合的基准测试任务,而是采用以下方法来管理评估:
- 决定我们希望智能体遵循哪些行为,然后研究并整理能以一种可验证的方式衡量这些行为的针对性评估。
- 为每个评估添加文档字符串,解释它_如何_衡量智能体的某项能力。这确保了每个评估都是自文档化的。我们还会为每个评估打上标签,如
tool_use,以便进行分组运行。 - 审查输出轨迹(Traces)以理解失败模式,并更新评估覆盖范围。
因为我们将每次评估运行都追踪到共享的 LangSmith 项目中,团队中的任何人都可以介入分析问题、进行修复并重新评估特定评估的价值。这为添加和维护优质评估创造了共同责任。跨多个模型和评估运行成本可能很高,因此针对性评估在改进智能体的同时也能节省资金。
本文将涵盖:
- 我们如何收集数据
- 我们如何定义指标
- 我们如何运行评估
如何收集数据
我们通过几种方式获取评估:
- 利用内部使用(Dogfooding)智能体时获得的反馈
- 从外部基准测试(如 Terminal Bench 2.0 或 BFCL)中选取部分评估,并经常针对特定智能体进行调整
- 手动编写我们自己的(手工制作的)评估和单元测试,针对我们认为重要的行为

我们每天都在内部使用我们的智能体。每一个错误都成为编写评估并更新智能体定义及上下文工程(Context Engineering)实践的机会。
💡
注意: 我们将 SDK 单元和集成测试(系统提示传递、中断配置、子智能体路由)与模型能力评估分开。任何模型都能通过那些测试,因此将它们计入评分不会增加任何信号。你绝对应该编写单元和集成测试,但本文仅关注模型能力评估。
内部使用智能体和阅读轨迹是评估的绝佳来源
这使得发现错误成为可能。轨迹 为我们提供了理解智能体行为的数据。因为轨迹通常很大,我们使用内置智能体如 Polly 或 Insights 来大规模分析它们。你也可以使用其他智能体(如 Claude Code 或 Deep Agents CLI)加上一种拉取轨迹的方式(如 LangSmith CLI)来做同样的事情。我们的目标是理解每个失败模式,提出修复方案,重新运行智能体,并跟踪一段时间内的进展和回归。
例如,现在很大一部分 Bug 修复 PR 是通过 Open SWE 驱动的,这是我们开源的背景编码智能体。使用它的团队会接触到许多具有不同上下文、惯例和目标的代码库,这自然会导致错误。Open SWE 的每次交互都被追踪,因此这些错误很容易变成评估,以确保同样的错误不再发生。
其他评估是从现有基准测试中提取并调整的,例如用于函数调用(Function Calling)的 BFCL。对于编码任务,我们与 Harbor 集成,在沙盒环境中运行来自 Terminal Bench 2.0 等数据集的选定任务。许多评估是从头编写的,作为观察孤立行为的针对性测试,比如测试一个 read_file 工具。
我们按测试内容对评估进行分组
对评估进行分类有助于获得智能体表现的中观视图(不是单一数字,也不是单个运行)。
💡
提示: 根据评估测试的内容来创建分类,而不是根据它们的来源。
例如,来自 FRAMES 和 BFCL 的任务可以标记为“外部基准测试”,但这不会显示它们分别如何衡量检索和工具调用。
以下是我们定义的一些类别及其测试内容:
| 类别 | 测试内容 |
|---|---|
file_operations | 文件工具(读取、写入、编辑、ls、grep、glob)、并行调用、分页 |
retrieval | 跨文件查找信息、搜索策略、多跳文档合成 |
tool_use | 选择正确的工具、链接多步骤调用、跨轮次跟踪状态 |
memory | 回忆已植入的上下文、提取隐含偏好、持久化耐用信息 |
conversation | 为模糊请求提出澄清问题、维持多轮对话并采取正确行动 |
summarization | 处理上下文溢出、触发摘要、压缩后恢复信息 |
unit_tests | SDK 管道——我们的系统提示传递、中断配置、子智能体路由、技能路径解析等是否都正常工作? |
目前,所有评估都是智能体在任务上的端到端运行。我们有意鼓励评估结构的多样性。有些任务从输入提示开始,单步即可完成;而另一些则需要 10 轮以上,由另一个模型模拟用户交互。
如何定义指标
为智能体选择模型时,我们首先关注正确性。如果一个模型无法可靠地完成我们关心的任务,其他一切都无从谈起。我们在评估上运行多个模型,并随着时间的推移改进执行框架,以解决我们发现的问题。
衡量正确性取决于测试内容。大多数内部评估使用自定义断言,例如“智能体是否并行化了工具调用?”。像 BFCL 这样的外部基准测试则使用与数据集中标准答案的精确匹配。对于正确性是语义性的评估,比如智能体是否在记忆中持久化了正确的内容,我们使用 LLM 作为评判者(LLM-as-a-judge)。
一旦有几个模型跨过了正确性门槛,我们就转向效率。在实践中,两个能解决相同任务的模型可能表现迥异。一个可能花费额外的轮次,进行不必要的工具调用,或者因为模型大小而导致任务执行速度更慢。在生产环境中,这些差异会表现为更高的延迟、更高的成本和更差的整体用户体验。
总的来说,我们为每次评估运行衡量的指标包括:
| 指标 | 定义 |
|---|---|
| 正确性(Correctness) | 模型是否正确完成了任务 |
| 步骤比率(Step ratio) | 观察到的智能体步骤 / 理想的智能体步骤 |
| 工具调用比率(Tool call ratio) | 观察到的工具调用 / 理想的工具调用 |
| 延迟比率(Latency ratio) | 观察到的延迟 / 理想的延迟 |
| 解决率(Solve rate) | 预期步骤数 / 观察到的延迟,如果任务未正确解决则得分为 0 |
解决率衡量智能体解决任务的速度,按预期步骤数进行归一化。与延迟比率类似,它捕捉了解决任务的端到端时间,包括模型往返、供应商延迟、错误转向和工具执行时间。对于可以定义理想轨迹的简单任务,解决率可能比延迟比率更容易处理,因为它只需要测量给定智能体的任务持续时间。
这为我们提供了一个简单的方法,通过针对性评估集来选择模型:
- 首先检查正确性:哪些模型在你真正关心的任务上足够准确?
- 然后比较效率:在足够好的模型中,哪一个在正确性、延迟和成本之间提供了最佳权衡?
围绕评估的有用指标示例
为了使模型比较具有可操作性,我们检查模型_如何_成功和失败。这需要一个具体的参考点,来定义超出准确性的“良好”执行是什么样子。我们使用的一个基本概念是理想轨迹(Ideal Trajectory)。这是一系列步骤,能产生正确的结果,且没有“不必要”的操作。
对于简单、范围明确的任务,变量定义得足够紧密,最优路径通常是显而易见的。对于更开放式的任务,我们使用迄今为止看到的表现最佳的模型来近似一个轨迹,然后随着模型和执行框架的改进重新审视基线。通过这种方式,观察智能体行为有助于我们完善对理想轨迹的先验认知。
考虑一个简单的请求:
“我居住地的当前时间和天气是什么?”
一个智能体的理想轨迹可能如下所示:
- 它进行最少的必要工具调用(例如,解析用户 → 解析位置 → 获取时间和天气)
- 它在可能的情况下并行化独立的工具调用
- 它生成最终答案,无需不必要的中间轮次
理想轨迹: 4 个步骤,4 次工具调用,约 8 秒

现在将其与一个技术上正确但效率较低的轨迹进行比较。
低效轨迹: 6 个步骤,5 次工具调用,约 14 秒。

正确但低效的轨迹: 6 个智能体步骤,5 次工具调用,包含一次不必要的工具调用,并且没有并行化工具调用。
上面的例子是示意性的:一个 REPL 可能更快地解决这个特定任务,但更简单的工具调用版本使概念更容易解释。
两次运行都是正确的,但第二次运行增加了延迟和成本,并创造了更多失败的机会。
这种框架让我们能够评估评估的正确性和效率。我们维护和更新指标,将运行提炼成可测量的数字,用于比较实验。
根据上面的例子,低效但正确的运行将得分如下:
| 指标 | 定义 | 示例值 | 解释 |
|---|---|---|---|
| 正确性(Correctness) | 模型是否正确完成了任务 | 1 | 运行成功 |
| 步骤比率(Step ratio) | 观察到的智能体步骤 / 理想的智能体步骤 | 6 / 4 = 1.5 | 比理想情况多 50% 的智能体步骤;数值越低越好 |
| 工具调用比率(Tool call ratio) | 观察到的工具调用 / 理想的工具调用 | 5 / 4 = 1.25 | 比理想情况多 25% 的工具调用;数值越低越好 |
| 延迟比率(Latency ratio) | 观察到的延迟 / 理想的延迟 | 14 / 8 = 1.75 | 比理想情况慢 75%;数值越低越好 |
| 解决率(Solve rate) | 预期步骤数 / 观察到的延迟,如果任务未正确解决则得分为 0 | 4 / 14 = 0.29 预期步骤每秒 | 通过预期轨迹的进度更快;数值越高越好 |
如何运行评估
我们使用 pytest 和 GitHub Actions 在 CI 中运行评估,以便更改在干净、可重现的环境中运行。每个评估都会创建一个具有给定模型的 Deep Agent 实例,为其提供任务,并计算正确性和效率指标。
我们也可以使用标签运行评估的子集,以节省成本并衡量针对性实验。例如,如果构建一个需要大量本地文件处理和合成的智能体,我们可能会专注于标记为 file_operations 和 tool_use 的子集。
export LANGSMITH_API_KEY="lsv2_..."
uv run pytest tests/evals --eval-category file_operations --eval-category tool_use --model baseten:nvidia/zai-org/GLM-5
我们的评估架构和实现已在 Deep Agents 仓库 中开源。
下一步计划
我们正在扩展评估套件,并围绕开源 LLM 做更多工作!我们期待很快分享以下内容:
- 开源模型与闭源前沿模型在各个评估类别上的表现对比
- 评估作为实时自动改进智能体任务表现的机制
- 公开分享我们如何随时间维护、减少和扩展每个智能体的评估
Deep Agents 是完全开源的。试试看,告诉我们你的想法!我们很乐意帮助团队构建优秀的智能体和评估体系。
觉得有用?分享给更多人