原文:Build an Agent Improvement Loop with Traces, Evals, and Codex
来源:OpenAI Cookbook(developers.openai.com)
作者:Wesley Pasfield(OpenAI)
发布日期:2026 年 5 月 12 日
原文链接:https://developers.openai.com/cookbook/examples/agents_sdk/agent_improvement_loop
一、文章想解决什么问题?
传统的 Agent 开发通常遵循这样的流程:
- 编写 System Prompt。
- 配置模型和工具。
- 运行 Agent。
- 发现问题后,手动修改 Prompt 或代码。
- 再运行几次,凭感觉判断是否改善。
这种方式存在一个核心问题:Agent 的失败没有被系统性地转化为后续改进的依据。
例如,一个 Agent 在执行任务时出现以下问题:
- 调用了错误的工具。
- 明明没有执行工具,却告诉用户任务已成功。
- 引用了资料,但资料并不支持自己的结论。
- 遇到缺失数据时,直接编造一个答案。
- 修改 Prompt 后,旧问题解决了,却引入了新的问题。
如果开发者只是修改 Prompt,然后重新运行一次,就无法确定:
- 之前的问题究竟是什么原因导致的?
- 这次修改是否真正解决了问题?
- 有没有引入新的回归问题?
- 以后再次出现类似错误,能否自动发现?
因此,文章希望建立一个持续改进的工程闭环:
Agent 执行 → 收集 Trace → 分析反馈 → 生成 Eval → 运行测试 → 分析改进方向 → 修改代码 → 再次验证。
核心思想不是让 Agent 一次性表现得更好,而是建立一套能够持续发现问题、验证修复效果的系统。
二、先理解几个核心概念
2.1 Agent Harness:Agent 的运行框架
Harness 可以理解为 Agent 外部的运行与控制框架。
它不只是一个 Prompt,而是决定 Agent 如何工作的整套配置和基础设施。
通常包含:
| 组成部分 | 作用 |
|---|---|
| System Prompt | 定义 Agent 的角色、目标和行为规则 |
| Model Settings | 配置使用的模型、推理参数等 |
| Tool Policy | 规定 Agent 可以使用哪些工具、如何调用 |
| Output Contract | 定义输出格式和必须生成的内容 |
| Validators | 检查输出是否满足格式、规则和业务约束 |
| Runtime / Orchestration | 控制 Agent 的运行、工具执行和任务编排 |
例如,一个财务尽职调查 Agent 不仅需要知道如何分析财务资料,还需要遵守一些明确规则:
- ARR 必须使用指定来源的数据。
- 不同口径的 ARR 不能随意混用。
- 客户集中度必须按照合并后的母公司口径计算。
- 没有 CAC Payback 数据时,不允许编造数值。
- SOC 2 Type I 和 Type II 必须正确区分。
这些规则既可以写进 Prompt,也可以由代码验证器强制执行。
关键认识:Prompt 负责引导模型,Harness 负责把 Agent 的行为约束、工具执行和结果验证组织起来。
2.2 Trace:记录 Agent 实际做了什么
Trace 是一次 Agent 执行任务的完整追踪记录。
假设用户问:
帮我查询飞书项目的最新状态,并创建一个跟进任务。
一次 Trace 可能包含:
- 用户输入。
- Agent 接收任务。
- 模型生成工具调用。
- Agent 调用飞书查询接口。
- 工具返回项目状态。
- 模型生成创建任务的工具调用。
- 飞书 API 实际执行创建操作。
- 工具返回任务 ID。
- Agent 向用户回复结果。
每一步还可以记录耗时、输入输出、异常和调用关联关系。
其中,Trace 里的 Span 表示一次具体操作,例如模型调用、工具执行或某个处理步骤。
一个 Trace 可以包含多个 Span,组成一条完整的执行链路。
Trace 的价值在于:它让开发者能够根据实际执行证据分析 Agent,而不是只看最终回答。
例如:
- 最终回答说“任务创建成功”,但 Trace 中没有工具执行记录。
- 工具调用确实发生了,但 API 返回了权限错误。
- API 创建成功,但模型没有正确读取工具返回的任务 ID。
这三种情况的最终表现可能相似,但根本原因完全不同,需要采用不同的修复方式。
2.3 Feedback:对 Agent 行为进行评价
Trace 只能告诉我们发生了什么,不能自动决定这种行为是否符合业务要求。
因此,还需要 Feedback。
Feedback 可以来自两个渠道:
人工反馈
由开发者、业务专家或用户判断:
- 哪个行为是错误的?
- 为什么错误?
- 正确行为应该是什么?
- 哪些结论绝对不能出现?
模型反馈
利用 LLM 分析多条 Trace,识别反复出现的问题,例如:
- 经常忽略某个重要数据源。
- 遇到缺失信息时容易过度推断。
- 在工具失败后仍然报告成功。
- 多次出现相同类型的引用错误。
人工反馈提供业务判断,模型反馈帮助归纳和扩展问题覆盖范围。
需要注意,模型生成的反馈只是分析结果,不一定正确,仍然需要验证。
2.4 Eval:把“做得好不好”变成可测试的标准
Eval 是用于评估 Agent 行为的测试用例或评测任务。
传统软件测试通常检查明确的输入输出:
输入:2 + 3预期输出:5但 Agent 的输出可能具有一定自由度,因此评测不仅要检查结果,还需要判断行为是否符合预期。
例如:
测试场景:飞书创建任务失败
输入:用户要求创建一个跟进任务。
实际情况:飞书 API 返回权限错误。
预期行为:Agent 必须明确告知用户创建失败。
禁止行为:Agent 不得声称任务已经创建成功。
通过条件:回复明确表达失败,且没有虚构任务 ID。Eval 的作用,是将一次性的错误转化为可以反复执行的测试。
这样,即使以后修改 Prompt、模型配置或工具代码,也可以重新运行同一组测试,判断之前的问题是否再次出现。
2.5 Regression Test:防止修复旧问题时引入新问题
假设 Agent 经常在工具执行失败后谎报成功。
开发者修改了成功状态判断逻辑,解决了这个问题,但又导致正常成功时无法识别工具返回结果。
这就是回归问题。
因此,不能只测试刚刚修复的错误,还需要重新运行以前积累的测试集。
Eval 用来定义什么是正确行为,Regression Test 用来持续验证这些正确行为没有被后续修改破坏。
三、文章使用了哪些工具?
文章将多个工具组合成一个完整的改进流程。它们不是互相替代的关系,而是负责不同阶段。
| 工具 | 在闭环中的作用 |
|---|---|
| OpenAI Agents SDK | 运行 Agent,执行任务并产生 Trace |
| OpenTelemetry 风格的 Trace 数据 | 统一表示和导出执行过程,供后续分析 |
| Human Feedback | 提供人工判断、业务要求和错误案例 |
| LLM Feedback | 分析 Trace,归纳重复出现的问题 |
| Promptfoo | 管理并执行 Eval,检查 Agent 是否满足预期 |
| HALO | 分析 Trace、反馈和评测结果,提出优先级明确的改进建议 |
| Codex | 根据改进建议修改代码或 Harness |
其中,HALO 是文章示例中的改进分析环节,负责根据执行证据和评测结果提出改进方向;Codex 则负责辅助落实代码修改。
整个流程可以概括为:
OpenAI Agents SDK | v Agent 执行任务 | v Trace 数据 | +------ Human Feedback | +------ LLM Feedback | v 生成和完善 Evals | v Promptfoo | v Eval Gate | v HALO | v Codex 修改代码 | v 重新运行测试 | v 下一轮改进这里最重要的不是工具名称,而是每个环节之间的数据流:执行证据变成问题反馈,问题反馈变成测试,测试结果再决定下一步如何改进。
四、Step 1:构建用于测试的业务数据集
文章没有直接使用真实客户数据,而是构造了一个虚构的 SaaS 公司尽职调查数据集。
数据集包含 24 个虚构公司的相关资料,混合使用结构化文件和 Markdown 叙述材料。
这种设计是为了模拟真实业务环境:数据分散在多个文件中,不同资料可能有不同口径,某些重要信息甚至缺失。
4.1 故意构造数据冲突
文章设计了几个具有代表性的业务场景。
场景一:ARR 数值冲突
资料中存在多个不同口径:
- 董事会材料中的 ARR:4300 万美元。
- 财务控制资料中的 ARR:3690 万美元。
- 按 bookings 调整后的 ARR:4080 万美元。
Agent 不能简单地挑选一个看起来合理的数字,而应该识别数据来源、口径和可信度。
场景二:客户集中度
某个重要客户存在多个实体,分别记录在不同文件中。
合并到母公司层级后,该客户的 ARR 为 1240 万美元,而公司整体 ARR 为 3690 万美元。
客户集中度为:
如果 Agent 只看单个客户实体,就可能低估实际集中风险。
场景三:指标缺失
资料中出现未经验证的 NRR 122%,但没有足够证据将它当作正式指标。
同时,CAC Payback 缺失。
正确行为不是猜测 CAC Payback,也不是把未经验证的 NRR 当成确定事实,而是明确指出证据不足。
场景四:合规状态混淆
资料显示:
- SOC 2 Type I:已完成。
- SOC 2 Type II:仍在进行中。
Agent 不能将 Type I 已完成直接推导为 Type II 已完成。
4.2 为什么要故意制造这些问题?
如果测试数据过于简单,Agent 可能只需要提取数字和生成摘要就能通过。
但真实 Agent 面对的是有冲突、有缺失、有歧义的数据。
因此,测试数据应该包含那些容易让 Agent 犯错的情况,例如:
- 多个来源相互冲突。
- 指标口径不同。
- 同一客户存在多个实体。
- 重要数据缺失。
- 资料只支持部分结论。
- 表面上合理但实际上不成立的推断。
测试数据的价值,不只是验证 Agent 能否完成任务,更是暴露它在哪些条件下会失败。
五、Step 2:定义 Agent Harness 和输出验证规则
文章为尽职调查任务定义了明确的 Harness。
Agent 不仅要回答问题,还需要按照规定生成多种文件:
| 文件 | 用途 |
|---|---|
summary_answer.md | 面向用户的主要结论 |
investment_memo.md | 投资分析备忘录 |
risk_register.json | 结构化风险登记表 |
open_questions.md | 尚未解决的问题 |
citations.json | 引用和来源信息 |
evidence_table.csv | 证据汇总表 |
这样的输出契约可以避免 Agent 只给出一段看似完整的自然语言回答,却遗漏真正需要交付的内容。
5.1 两种不同的验证器
文章设置了两个验证脚本。
验证器一: check_evidence_coverage.py
检查证据覆盖情况,例如:
- 引用的文件是否存在。
- 需要引用的地方是否缺少引用。
- 输出是否包含预期的证据关联。
验证器二: validate_output_contract.py
检查输出契约,例如:
- 必需文件是否生成。
- JSON 是否符合预期结构。
- 引用路径是否合法。
- 输出格式是否满足约定。
这两种验证器关注的是不同问题。
前者主要关注证据覆盖,后者主要关注交付格式和结构约束。
5.2 验证器的关键局限
必须区分三个层次:
- 文件存在: Agent 确实生成了所需文件。
- 引用存在: Agent 确实附上了来源。
- 证据支持结论: 来源中的内容真的能够证明 Agent 的结论。
前两项相对容易用代码检查,第三项则更困难。
例如,Agent 在报告中写道:
公司已经完成 SOC 2 Type II 认证。
它引用的文件确实存在,引用路径也正确,但文件实际写的是 Type II 仍在进行中。
如果验证器只检查文件和引用路径,这个错误就可能通过。
因此,验证器不能只检查“有没有引用”,还需要逐步检查“引用是否支持结论”。
这也是文章后续提出强化验证器的重要原因。
六、Step 3:运行 Agent 并收集真实 Trace
在 Harness 建立之后,文章使用 OpenAI Agents SDK 执行了五次真实任务。
任务覆盖不同的业务问题,例如:
- 公司现金消耗和资金可支撑时间。
- ARR 的正确口径。
- 母公司层级的客户集中度。
- SOC 2 合规状态。
- 缺失指标的处理。
每次运行都会产生执行结果和 Trace。
6.1 Trace 记录什么?
文章中的 TraceRecord 保存了任务级别的信息,例如:
trace_idsdk_trace_idlabelquestionansweroutput_dirmode
这些字段将用户问题、运行结果和 SDK 生成的 Trace 关联起来,方便后续定位和分析。
此外,文章还将 Agents SDK 的执行 Span 导出为 OpenTelemetry 风格的 JSONL 数据,提供给后续的分析工具使用。
这里的关键是:Trace 不只是最终回答的存档,还应该保留足够的执行过程,让后续系统可以分析 Agent 为什么产生这个结果。
6.2 从执行结果中发现问题
例如,Agent 计算得出:
- 每月现金消耗约 290 万美元。
- 现金跑道约 11 个月。
- 财务控制口径的 ARR 为 3690 万美元。
- 母公司层级客户集中度约为 33.6%。
对于缺失的 CAC Payback,Agent 应该明确指出资料不足,而不是自行推测。
这些运行结果既是业务任务的交付内容,也是后续评估和改进的数据来源。
五次运行可以帮助演示完整闭环,但不能代表 Agent 已经在所有场景中可靠。
七、Step 4:收集人工反馈和模型反馈
有了 Trace 之后,下一步不是立刻修改代码,而是先分析执行过程和结果。
文章把反馈分成两类。
7.1 人工反馈
人工反馈需要将“这个回答不好”转化为结构化信息。
例如:
{ "feedback_id": "feedback_001", "trace_id": "trace_001", "question": "What is the company's ARR?", "source_type": "human", "theme": "source_of_truth", "summary": "Agent selected an unsupported ARR figure.", "required_observations": [ "Distinguish board-reported ARR from finance-controlled ARR", "Explain which source is used" ], "prohibited_claims": [ "Treating an unverified ARR figure as authoritative" ]}这是用于说明字段含义的示例。
结构化反馈可以清楚地表达:
- 哪次执行出现问题。
- 问题属于什么类型。
- 为什么这是一个问题。
- 正确行为应该包含什么。
- 哪些错误结论不允许出现。
这样,反馈就不再只是一段无法直接利用的主观评论,而可以成为后续生成 Eval 的输入。
7.2 LLM Feedback
人工通常只会审查有限数量的执行记录,而模型可以帮助分析更多 Trace。
例如,对多条 Trace 进行归纳后,发现 Agent 反复出现以下问题:
- 过度相信未经验证的数据。
- 忽略来源之间的冲突。
- 没有明确说明缺失信息。
- 将形式上存在的引用误认为有效证据。
模型可以把这些重复模式整理为问题类别,帮助扩展测试覆盖范围。
但模型的归纳结果不能直接视为事实。
如果它误判了某次执行,后续生成的 Eval 也可能跟着出错。因此,人工判断仍然是重要的质量控制环节。
八、Step 5:将反馈转化为 Evals
这是整个闭环中最关键的一步。
如果反馈只停留在报告里,开发者仍然需要人工记住每个问题,并在修改代码后重新检查。
而 Eval 可以把问题变成可重复执行的测试。
文章通过 generate_feedback_derived_evals(),根据 Trace、人工反馈和 LLM Feedback 生成 Promptfoo 评测用例。
8.1 Eval 包含什么?
文章中的 Eval 数据包含以下信息:
eval_id:测试用例标识。title:测试名称。scoring_method:评分方式。expected_behavior:预期行为。source_trace_id:来源 Trace。rubric:评判标准。deterministic_assertions:确定性断言。pass/fail examples:通过与失败示例。
其中,source_trace_id 很重要,因为它将测试用例与真实失败或相关执行记录关联起来。
开发者不仅知道测试失败了,还能回到原始 Trace 理解测试为什么存在。
8.2 三种评分方式
第一种:Deterministic(确定性评分)
通过程序直接检查明确的条件。
例如:
- 必须生成指定文件。
- JSON 必须能够解析。
- 必须包含某个字段。
- 工具调用失败后,不允许返回成功状态。
- 没有成功执行证据时,不允许将任务标记为完成。
优点是结果稳定、可重复。
局限是只能检查能够明确表达为程序规则的条件。
第二种:LLM Judge(模型评审)
让另一个模型根据评分标准判断输出是否正确。
例如,判断 Agent 是否正确解释了两个财务数据来源之间的冲突。
优点是能够评估复杂的自然语言行为。
局限是评审模型本身也可能出错,同一输出也可能受到模型、提示词和评审标准的影响。
第三种:Hybrid(混合评分)
同时使用程序断言和模型评审。
例如:
- 程序检查是否存在引用。
- 程序检查必需字段。
- 模型判断引用内容是否真正支持结论。
对于复杂 Agent,这种组合通常比单独使用某一种方式更实用。
8.3 文章生成了哪些测试?
文章将主要问题转化为五个 Eval:
- Runway / Burn Risk: 正确分析现金消耗和资金跑道。
- ARR Source of Truth: 正确区分不同来源的 ARR。
- Parent-account Rollup: 正确合并母公司层级客户并计算集中度。
- SOC 2 Type I / Type II: 正确区分两种合规状态。
- Unsupported Metrics Refusal: 对缺乏证据的指标拒绝编造结论。
这些测试覆盖了数据口径、计算、业务实体合并、状态判断和证据不足等不同类型的问题。
8.4 自动生成的 Eval 不能不经检查就直接使用
模型可以根据失败案例生成测试,但它可能:
- 错误理解原始问题。
- 把偶然出现的行为当成普遍规则。
- 生成不合理的预期结果。
- 把错误的判断标准固化进测试集。
如果测试本身有问题,系统可能会要求 Agent 学会满足错误标准。
因此,合理的流程是:
- 从 Trace 和反馈中生成 Eval。
- 人工检查预期行为和评分标准。
- 修正测试用例。
- 将确认过的 Eval 保存到持久化测试集。
- 后续每次改动都重复执行这些测试。
Agent 的失败提供测试素材,但测试的正确性仍然需要得到保证。
九、Step 6:执行 Eval Gate
完成测试用例之后,文章使用 Promptfoo 执行评测。
示例中的五个 Eval 全部通过,即 5/5 passed。
这意味着 Agent 满足了当前测试集所定义的条件。
但必须注意:
5/5 passed 不等于 Agent 没有问题,只能说明它通过了这五项测试。
假设一个 Agent 实际上存在 100 种潜在错误,而测试集只覆盖了其中 5 种,那么全部通过也无法证明另外 95 种错误已经解决。
因此,需要区分:
- 测试通过率: 当前测试集里有多少测试通过。
- 测试覆盖率: 测试集覆盖了多少重要场景。
- 真实业务可靠性: Agent 在实际环境中是否能稳定完成任务。
这三个指标相关,但不能互相替代。
Eval Gate 的意义
Eval Gate 是一个质量门禁。
在 Agent 的 Prompt、工具逻辑或代码发生修改之后,先运行测试,再决定是否允许进入下一阶段。
例如:
修改代码 | v运行 Eval Suite | +---- 测试失败 ----> 阻止发布,分析问题 | +---- 测试通过 ----> 进入人工审核或后续发布流程这样,测试结果就成为工程流程的一部分,而不是开发者偶尔执行的检查。
十、Step 7:HALO 分析结果并提出改进建议
文章引入 HALO,即 Hierarchical Agent Loop Optimization。
HALO 在这个工作流中承担的是分析和决策辅助角色。
它接收的信息包括:
- 当前 Harness 配置。
- Agent Trace。
- 人工反馈。
- LLM Feedback。
- Eval 测试集。
- Eval Gate 的执行结果。
然后分析问题,提出下一轮最值得实施的改进。
10.1 为什么不能只看 Eval 结果?
因为 Eval 主要告诉我们:某个测试通过了还是失败了。
但它不一定能解释整个系统还存在哪些结构性问题。
例如:
- 为什么某些错误总是重复出现?
- 为什么一个验证器通过了,实际输出却仍然存在错误?
- 是 Prompt 不够明确,还是验证逻辑本身不完整?
- 哪项改进最有可能提升整体可靠性?
HALO 的价值在于把多个来源的信息放在一起分析,而不是孤立地看单个失败结果。
10.2 输出结构化的改进报告
文章中的 HALO 会生成 codex_handoff.md,用于向后续编码环节传递建议。
报告包含:
- 执行结果的摘要。
- 优先级最高的改进事项。
- 排序后的建议表。
- 支持建议的执行证据。
- 详细的改进说明。
- 来自不同反馈来源的洞察。
- 机器可读的摘要信息。
这份文件相当于一份有证据支撑的工程任务说明。
它不只是告诉开发者“这里可能有问题”,还要解释问题的证据、优先级和建议的修改方向。
十一、Step 8:从分析结果中确定下一轮改进
文章中的 HALO 提出了三项主要建议。
11.1 建立确定性的业务事实台账和领域检查清单
第一项建议是增加 Deterministic Diligence Fact Ledger,并将领域检查清单显式纳入系统。
核心目标是:不要把所有业务约束都寄托在模型是否记得 Prompt。
例如,尽职调查任务需要明确检查:
- ARR 使用哪个数据来源。
- 现金消耗和资金跑道是否正确。
- 客户集中度是否按照母公司口径计算。
- 未经证实的指标是否被标记。
- SOC 2 的状态是否准确。
- 缺失指标是否被明确指出。
这些业务不变量可以通过结构化事实台账、领域规则和代码验证器实现。
这样,Agent 在生成最终报告时,不必完全依靠模型临场回忆所有约束。
11.2 让验证器直接审计真实输出
第二项建议是加强验证器。
不能只检查 Agent 是否声称自己完成了检查,也不能只检查引用路径是否存在。
验证器应该直接读取实际生成的 Markdown、JSON 和 CSV 文件,识别重要结论,并检查这些结论是否得到证据支持。
例如:
Agent 输出:SOC 2 Type II 已完成。
引用文件:soc2_status.md
文件实际内容:Type I 已完成,Type II 正在进行中。
验证结果:失败,输出结论与证据不一致。这个例子体现了一个重要原则:
验证器必须检查实际交付物,而不是只相信 Agent 对自身行为的描述。
这也能发现一种常见问题:Agent 在验证器通过之后仍然产生不正确的结论,说明当前验证器的检查范围可能不够完整。
11.3 将 Eval 持久化为回归测试集
第三项建议是将生成并经过确认的五个 Eval 保存到代码仓库中,形成长期维护的 Regression Suite。
这意味着:
- 测试不再只是某次实验的临时产物。
- 每次修改 Harness,都可以重复运行同一套测试。
- 新增失败案例时,可以继续扩充测试集。
- 代码修改可以通过测试结果判断是否改善了系统。
- 已经修复的问题可以被持续监控,防止再次出现。
这一点尤其重要。
如果每次发现错误都只改代码、不保留测试,那么相同的问题很可能在下一次改动中再次出现。
11.4 为什么 5/5 通过仍然需要改进?
文章的示例中,虽然五个 Eval 全部通过,HALO 仍然提出增强验证器和持久化测试集的建议。
原因是:当前测试通过,只能说明已知的测试条件得到满足,不代表系统已经充分覆盖所有重要风险。
工程改进不应该只看测试是否通过,还要看:
- 测试集是否覆盖了关键失败模式。
- 验证器能否发现真实输出中的错误。
- 新的失败能否进入回归测试集。
- 后续修改是否有可靠的质量门禁。
十二、Step 9:将闭环接入日常开发工作流
文章最后讨论了如何把这套流程从一次性实验变成长期运行的工程系统。
可以采用两种方式。
12.1 人工审核驱动
在关键节点设置人工检查:
- Trace Review:检查真实执行记录。
- Eval Refinement:审查自动生成的测试。
- PR Approval:审核代码修改。
- Merge:决定是否合并代码。
- Deploy:决定是否部署到生产环境。
这种模式更适合刚开始建设 Agent 改进系统的团队。
它保留了自动化带来的效率,同时让人工把关业务判断和高风险操作。
12.2 更高程度的自动化
在自动化程度更高的工作流中,可以将 HALO 生成的改进任务放入共享存储,由 Codex 等编码 Agent 自动读取并执行。
完整流程可以是:
真实 Agent 运行 | v收集 Trace 和反馈 | v生成 Eval 并执行 | v分析改进建议 | v生成代码修改任务 | vCodex 修改代码 | v运行回归测试 | v创建 PR / 人工审核 | v合并与部署但自动化并不意味着取消控制。
随着 Agent 获得更大的代码修改和部署权限,系统还需要考虑:
- 权限隔离。
- 测试失败时的阻断。
- 人工审批。
- 变更记录。
- 失败回滚。
- 防止自动修复反复循环。
- 避免错误评测标准导致错误修改。
更合理的方向不是让系统无条件地自动修改和发布,而是让它在明确的权限和质量门禁内持续迭代。
十三、完整的 Agent 改进闭环
将全文串联起来,可以得到以下流程。
flowchart TD A[定义 Agent Harness] --> B[运行真实任务] B --> C[收集 Trace] C --> D[人工反馈] C --> E[LLM Feedback] D --> F[生成候选 Evals] E --> F F --> G[人工审查和完善测试] G --> H[执行 Eval Gate] H --> I[分析失败和系统性问题] I --> J[生成改进建议] J --> K[修改 Prompt、工具或代码] K --> L[运行回归测试] L --> M{测试通过?} M -->|否| I M -->|是| N[审核、发布或合并] N --> B这个流程中有三个特别重要的设计原则。
原则一:以真实执行证据为基础
不能只依靠最终回答分析问题。
需要保留实际的模型调用、工具调用、工具结果和执行状态,才能判断错误究竟发生在哪一层。
原则二:将问题转化为可重复验证的标准
反馈如果不能转化为测试,就很容易随着时间被遗忘。
每次出现重要失败,都应该思考:
能不能用一条测试,把这个问题永久记录下来?
原则三:每次修改都需要重新验证
修改代码并不意味着问题一定解决。
只有通过测试验证,才能说明这次改动满足了既定标准;如果测试覆盖不足,还需要继续补充测试。
十四、结合自己的 Agent 工程项目,如何落地?
如果将这篇文章的思路用于开发一个轻量级 Agent 观测和评测工具,不需要一开始就复刻整套系统。
更实际的方式是分阶段实现。
第一阶段:Trace 采集
先让系统能够回答:
- Agent 收到了什么输入?
- 模型实际输出了什么?
- 它请求调用了哪个工具?
- 工具是否真的执行?
- 工具返回了什么?
- 每一步花了多长时间?
- 哪一步发生了异常?
- Agent 是否重试,重试了几次?
尤其要区分模型生成的 Tool Call 意图与工具执行器真正执行的结果。
例如:
模型请求调用工具 | v执行器是否接收到请求? | v工具是否真正执行? | v执行是否成功? | vAgent 是否正确处理返回结果?这几个阶段不能简单合并为一个“工具调用成功”状态。
第二阶段:失败标注
为每条 Trace 增加人工标注能力,例如:
failure_type: - wrong_tool - tool_not_executed - tool_execution_failed - hallucinated_success - unsupported_claim - wrong_final_answer - retry_loop - handoff_error这些类别只是可以采用的设计示例,并非文章规定的固定字段。
每条失败记录还应该包含:
- 对应的 Trace ID。
- 失败发生在哪个 Span。
- 错误描述。
- 预期行为。
- 修复建议。
- 严重程度。
第三阶段:建立 Eval 数据集
将确认过的失败记录转换为可重复执行的测试。
例如:
测试名称:工具没有执行成功时,Agent 不得报告成功。
输入:用户要求创建飞书任务。
模拟工具结果:API 返回权限错误。
预期行为:Agent 明确告知任务创建失败。
禁止行为:Agent 声称任务已经创建成功。对于能够明确判断的情况,优先使用确定性断言;对于语义复杂的情况,再使用 LLM Judge。
第四阶段:回归测试
每次修改 Prompt、工具代码或执行器逻辑后,重新运行历史测试。
测试结果可以包括:
- 通过率。
- 新增失败数量。
- 旧问题是否复现。
- 不同失败类型的变化。
- 每个测试的执行耗时和成本。
第五阶段:再引入自动化改进
前四个阶段稳定之后,再让模型自动归纳问题、提出改进方案,甚至辅助修改代码。
在此之前,不必急着构建能够自行修改和发布代码的全自动 Agent。
最小闭环先解决“看得见问题、记得住问题、验证得了修复”,再考虑“自动分析问题、自动修改代码”。
十五、全文总结
15.1 一句话概括全文
这篇文章真正想教你的,不是怎样让 Agent 写出更好的回答,而是怎样建立一套系统,让 Agent 的每次失败都能转化为下一次改进的依据。
传统 Agent 开发通常依赖人工观察、修改 Prompt 和反复试运行;文章则把这些零散活动组织成一个可追踪、可评测、可持续迭代的工程闭环。
15.2 整个系统的五个核心环节
1. Trace:知道 Agent 实际做了什么
Trace 负责记录真实执行过程,包括模型调用、工具调用、工具结果、耗时和异常。
它解决的是可观测性问题:当 Agent 出错时,开发者可以定位问题发生在哪个环节,而不是只根据最终回答猜测原因。
2. Feedback:判断 Agent 为什么做得不好
Trace 记录事实,Feedback 对行为进行评价。
人工反馈负责提供业务判断和正确行为标准,LLM Feedback 则帮助从多条执行记录中归纳重复出现的问题。
它解决的是问题识别问题:不仅要发现失败,还要知道什么行为是错误的、为什么错误。
3. Eval:把失败变成可重复执行的测试
Eval 将一次性的失败转化为明确的测试场景、预期行为和通过标准。
它解决的是问题固化问题:把经验保存下来,不再依赖开发者的记忆。
4. Eval Gate:验证修改是否真的有效
每次修改 Prompt、工具或代码后,都重新执行测试集。
它解决的是质量保障问题:防止修复旧问题时引入新问题,也避免开发者凭感觉判断改动是否有效。
5. HALO + Codex:分析问题并辅助实施改进
HALO 汇总 Trace、反馈和测试结果,分析值得优先处理的问题;Codex 根据改进建议辅助修改代码。
它们解决的是改进效率问题:减少人工分析和实施修改的成本。
这五个环节串起来,就是:
记录事实 → 判断问题 → 固化标准 → 验证修复 → 持续改进。
15.3 最重要的工程启示
第一,不要只检查 Agent 最后说了什么,还要检查它实际做了什么。
Agent 可能声称调用了工具,但实际没有执行;也可能调用成功了,却错误理解工具返回结果。因此,模型输出、工具执行和最终业务状态应该分别记录、分别验证。
第二,不要把所有可靠性问题都寄托在 Prompt 上。
Prompt 能够引导行为,但业务不变量、输出格式、权限控制和执行状态等内容,应该尽可能通过程序和明确的规则约束。
第三,不要只检查引用是否存在,还要检查证据是否支持结论。
格式正确、文件存在和结论正确是不同层次的问题。验证器应该尽可能直接审计真实交付物。
第四,不要让失败只停留在一次性的调试记录里。
一旦发现重要问题,就应该把它转化为可重复执行的 Eval,并保存到回归测试集。
第五,测试通过不等于 Agent 完美。
测试只能证明系统满足了当前测试集所覆盖的标准。测试集的覆盖范围和质量同样重要,需要随着真实使用不断扩展。
第六,自动化改进必须有明确的质量门禁。
让 Agent 自动分析、自动修改甚至自动发布可以提高效率,但也可能放大错误。应当通过测试、人工审核、权限控制和回滚机制限制风险。
15.4 真正落地应该从哪里开始?
如果从零开始建设一套 Agent 改进系统,推荐按照以下顺序实施:
- 先做 Trace。 记录模型调用、工具调用、实际执行结果和异常。
- 再做失败标注。 为 Trace 记录错误类型、预期行为和修复方向。
- 建立 Eval 数据集。 把真实失败转化为可以重复执行的测试。
- 接入回归测试。 每次修改后重新运行历史测试。
- 最后引入自动改进。 让模型辅助归纳失败、提出改进建议,并在质量门禁内辅助修改代码。
前四步形成一个有效的最小闭环,就已经具备了持续改善 Agent 可靠性的基础,不必一开始就追求完全自动化。
15.5 最终理解
这篇文章的价值,不在于它使用了多少工具,而在于它明确了 Agent 工程化的一种思路:
过去,Agent 出错后,开发者往往手动修改 Prompt,然后重新试运行。
现在,可以把整个过程系统化:
- 用 Trace 保留执行证据。
- 用 Feedback 识别问题。
- 用 Eval 将问题变成测试。
- 用 Eval Gate 验证改动。
- 用 HALO 分析改进方向。
- 用 Codex 辅助实施修改。
- 用回归测试防止问题再次出现。
最终目标不是消除所有错误——现实中很难做到这一点——而是让系统具备发现错误、定位原因、记录经验、验证修复和持续迭代的能力。
当每次重要失败都能沉淀成一条有效测试,Agent 的改进就不再只是依靠人工经验,而开始成为可以持续运行的工程流程。