基于Evaluation的AI Agent开发实践全景指南
基于 Evaluation 的 AI Agent 开发实践全景指南
如果你不能测量它,你就不能改进它。Agent 时代这句话被放大了十倍——一个看似 80 分的 Prompt 改动,可能在 Benchmark 上反而下降 5 分;一个 7B 的小模型,用对评测 + RL 后能在具体任务上超过 GPT-4o。
过去一年(2025-2026)AI Agent 领域最深刻的变化,不是某个新框架或新模型的出现,而是开发范式的迁移:从"凭感觉调 Prompt"变成"以 Evaluation 为仪表盘驾驶开发"。前面几篇文章分别介绍过 Harbor(Terminal-Bench 2.0 的 Harness)、AgentFlow(Flow-GRPO 训练 Agent)、codebase-memory-mcp(让 Agent 理解代码库)等工具链——这些单点工具合在一起,就是今天业界主流的"Evaluation-First Agent 开发模式"。
本文把这些碎片拼成一张完整实践地图:面向一个具体 Agent(无论是代码 Agent、写作 Agent、还是客服 Agent),如何从零开始搭建评测 → 迭代 → 优化 → 训练 的完整闭环。
本文提纲
- 为什么需要 Evaluation-First:Prompt 工程已经不够用了
- 第一步:选择或搭建一个合适的 Benchmark
- 第二步:搭建可复现的 Harness 运行时
- 第三步:建立度量体系,知道每个分数背后意味着什么
- 第四步:用 Evaluation 驾驶迭代(Baseline → Ablation → Pareto)
- 第五步:从评测到训练:SFT 和 RL 的数据闭环
- 第六步:落地到团队工程流程:CI、发布、回归
- 常见陷阱与反模式
- 30 条从 0 到 1 落地 Checklist
一、为什么需要 Evaluation-First:Prompt 工程已经不够用了
传统 Agent 开发的典型循环是这样的:
改一下 Prompt → 手动跑 3 个例子 → 感觉不错 → 发布 → 线上一堆 case 挂了 → 紧急打补丁
这在小场景还能撑,一旦 Agent 上规模(比如代码 Agent 覆盖 1000 个库、RAG Agent 回答 10 万份文档),问题立刻爆发:
- 手动测试严重不充分:手工跑 20 个 case 就能覆盖的场景,在真实世界面前几乎等于 0
- 改动的副作用不可见:改了 Prompt 想解决 A 问题,结果 B 场景反而从 90 分降到 75 分,没人知道
- 经验无法积累:调 Prompt 的"直觉"在不同团队成员之间不能传递,换一个人一切重来
- 无法做 RL:没有 Reward 信号就没有训练数据,Agent 永远停留在 "聪明一点的 Prompt Chaining" 阶段
Evaluation-First 模式把这个循环反过来:
MERMAID_BLOCK_0
核心心智模型的改变:
| 传统 Prompt 开发 | Evaluation-First 开发 |
|---|---|
| 改动后靠"例子看起来对" | 改动后看 Benchmark 总分 + 每个子集分 + 分桶分析 |
| "这个改动挺好的" | "这个改动在子集 A +3.1 分,子集 B -0.4 分,总 +1.2 分,95% CI 不包含 0,接受" |
| 靠直觉挑 case | 靠 Ablation 消融找真正起作用的组件 |
| 经验存在人脑子里 | 经验存在 Benchmark 历史记录 + 改动日志里 |
| 训练是"以后再说" | 轨迹导出格式在搭 Harness 那天就定好,随时可以开始训练 |
二、第一步:选择或搭建一个合适的 Benchmark
Benchmark 不是越大越好。选错 Benchmark 的代价是——你花几个月优化到接近满分,上线表现还是一塌糊涂。
2.1 先决定用现成 Benchmark 还是自建
| 任务类型 | 现成 Benchmark 推荐 | 什么时候需要自建 |
|---|---|---|
| 代码 Agent | Terminal-Bench 2.0(Stanford/Laude)、SWE-Bench Lite、SWE-Bench Verified、Aider Polyglot、Mini-SWE | 你的代码工作流严重依赖特定内部工具链 |
| 通用工具使用 Agent | GAIA、ToolBench、Tool-E | 私有 API、行业领域专用工具 |
| RAG / 问答 Agent | MMLU-Pro、GPQA-Diamond、HotpotQA、2Wiki、Musique | 行业内部知识(医疗/法律/金融) |
| GUI / Computer-Use Agent | AgentBench GUI Subset、WebArena、VisualWebArena | 内部桌面应用、专有 SaaS |
| 数学/逻辑 Agent | AIME 2024、AMC 23、Game of 24、MATH-500 | 一般不需要自建 |
| 多步复杂规划 | ALFWorld、ALICE-Bench、SciWorld | 你的任务有独特的子目标顺序依赖 |
判断"要不要自建"的黄金标准:拿现成 Benchmark 上 3 个你最关心的内部真实 case 回注进去——如果 Agent 在 Benchmark 上的得分排名和在内部 case 的表现排名不一致,就说明需要自建。
2.2 自建 Benchmark 的任务设计四原则
- 任务之间必须相互独立:一个任务的状态不能影响其他任务。这就是为什么 Harbor / Terminal-Bench 每个任务都跑在独立 Docker 容器里。
- Verifier 必须是确定性 + 代码化的:禁止人工打分进入主指标。人工判断只用于"失败原因归类"这种辅助分析。
- 难度分布要覆盖真实场景:Easy / Medium / Hard = 3:5:2 比较健康。全是 Medium 的 Benchmark 分数每年 +20% 没意义。
- 数据集要版本化且不可变:
my-bench@1.0、my-bench@2.0,升级时保留旧版本,分数必须跨版本可比。
最实用的做法是 "80% 公共 Benchmark + 20% 私有黄金集":公共集负责覆盖面和横向对比,私有集保证对齐内部真实需求。私有黄金集不要搞太大——100 道高质量 case 已经足够抓住 90% 的回归。
2.3 Verifier 设计
一个靠谱的 Verifier 比任务本身还重要。常用模式:
| Verifier 类型 | 实现方式 | 典型场景 |
|---|---|---|
| 文件/输出模式匹配 | 检查 /logs/verifier/reward.txt 是否 1,或特定文件内容是否等于预期 |
代码类、构建任务 |
| 单元测试驱动 | 运行 pytest tests/test_x.py,统计 pass rate |
SWE-Bench 风格 |
| Binary 判断 | 成功/失败二分类 | Terminal-Bench 风格 |
| 代码比对(有风险) | AST 相似度、功能等价性验证 | 编程题 |
| LLM-as-judge(有风险) | 让另一个 LLM 给打分,一般用于开放式输出 | 写作、报告、摘要 |
Verifier 反模式:开放式任务用 LLM judge 做主指标——judge 的一致性往往比被测 Agent 还低,分数是假的。建议:LLM judge 只用于失败原因分类,不用做主 reward。
三、第二步:搭建可复现的 Harness 运行时
Benchmark 只是"考纲",真正跑实验的是 Harness(运行时框架)。
3.1 Harness 必须具备的六大能力
参考 Harbor Framework 的设计,一个工业化 Harness 至少要覆盖这六件事:
MERMAID_BLOCK_1
| 能力 | 为什么重要 | 没做好的后果 |
|---|---|---|
| 沙箱隔离 | 任务之间互不污染、Agent 可以随意执行命令 | 前面的挂了的任务让后面的也挂,分数虚高/虚低 |
| 确定性 | 同一个 seed + 同一版本能跑出同样结果 | "这个分数和上次不一样"导致没人信 Benchmark |
| 并行调度 | 1000 tasks 串行跑要一周 | 研发速度被 Benchmark 拖死 |
| 轨迹采集 | 直接导出做 SFT/RL | 需要做第二步数据管道 |
| 结构化日志 | cost、latency、API 失败率一目了然 | "为什么这次这么贵"无法回答 |
| 失败重试 | 区分环境故障和 Agent 真正失败 | 20% 的任务因为 API 超时拿了 0 分 |
3.2 Harness 选型推荐
| 你的情况 | 推荐 |
|---|---|
| 代码 Agent、Terminal-Bench / SWE-Bench 体系 | Harbor Framework(前面文章详细拆解过)——数据集、Agent、Model、Environment 4 层解耦,生态最成熟 |
| 自定义 RL Agent 训练循环 | 自己写轻量 harness 接 Verl / OpenRLHF——当你要跑 on-policy Flow-GRPO 那种训练闭环 |
| 简单评测、几十条任务 | 纯 Python + pytest 就够了,不要过度工程化 |
| 超大规模分布式评测(>10000 tasks) | 自建 + Modal/Daytona/Runloop 工作队列 |
3.3 可复现性清单
每次 Benchmark 运行时都必须把下面这组元数据和结果一起存下来:
- 代码仓库 commit SHA
- Harness 版本号
- Agent 包版本或 commit
- 模型全名(包括 provider)
- 所有 Prompt 模板的内容哈希
- 工具集版本 / MCP server 列表与版本
- 环境镜像 ID(Docker image sha256)
- Random seed
- API endpoint 配置
- Verifier 版本号
缺任何一个,未来的你都无法回答"为什么 6 月那版分数高 5 分"这个问题。
四、第三步:建立度量体系,知道每个分数背后意味着什么
很多团队的评测报告只展示一个数字:"我们在 X 上达到了 84.2 分"。这种数字几乎没有可操作价值。
4.1 从一维分数到多维指标
一个工程可用的 Agent 度量体系至少分 5 个维度:
| 维度 | 典型指标 | 为什么要看 |
|---|---|---|
| 正确性 | Pass rate、Partial reward、EM/F1 | 主指标,但不是全部 |
| 成本 | 每任务平均 API cost、每千任务 total cost | 上线不能亏 |
| 速度 | Mean / P95 latency、平均 step 数、平均 token 消耗 | 用户体验天花板 |
| 可靠性 | 成功率 / 崩溃率 / 超时率 / 幻觉率 | 稳定性决定能否进生产 |
| 安全合规 | PII 泄露率、禁止动作触发率、越狱成功率 | 越红的红线越要早测 |
一个典型的发布决策不是"正确性涨了",而是下面这种综合判断:
正确性从 76.1 → 78.3(+2.2),但每任务平均 cost 从 \$0.14 → \$0.38(+170%),P95 latency 从 120s → 210s。所以不接受这次改动,除非同时有成本优化方案。
4.2 分桶分析:找到真正的改进点
把总分按属性切分才是迭代的燃料。常见分桶方式:
- 按难度桶:Easy / Medium / Hard
- 按任务类型桶:代码 Agent 的"文件编辑"、"环境配置"、"模型训练"、"服务搭建"……
- 按失败原因桶:工具调用错误 / 规划路径失误 / Verifier 误判 / 环境问题 / API 超时
- 按 Prompt 版本桶:v1 vs v2 vs v3 的跨版本对比
- 按模型家族桶:Opus vs Sonnet vs Gemini vs DeepSeek
举个真实例子。团队在 Terminal-Bench 上从 62 分涨到 65 分,看起来不错,但分桶一看:
- Medium 任务从 58 → 64(涨了 6 分,主贡献)
- Hard 任务从 21 → 18(掉了 3 分,没人注意)
这就是为什么做硬任务的同事反馈"感觉最近变差了"——总分涨了,但 hardest 的子集跌了,他们恰恰主要在 hardest 子集工作。
4.3 置信区间与统计显著性
你不希望用"看起来更好"做决策。标准做法:
- 对同一个 (Agent, Model, Dataset) 组合,跑 N 次重复(N≥3,一般取 5),报告 Mean ± 95% CI。
- 判断"改动有效"的标准是:旧版本最高分 < 新版本最低分(或做 Welch t-test / Mann-Whitney U test 看 p < 0.05)
- 小规模改动(±1-2 分、CI 重叠)不要急着合并,它大概率是噪声而不是真正提升
五、第四步:用 Evaluation 驾驶迭代
有了 Benchmark + Harness + 度量,现在让评测真正"驱动"开发。
5.1 Baseline 先行
第一次跑任何改动之前,先建立基线(Baseline):
baseline-001:
agent_version: v0.1.0
model: deepseek/deepseek-v4-pro
dataset: internal-gold-v1
score: 58.3 +/- 1.2 (95% CI)
cost_per_task: 0.084 USD
p95_latency: 98 s
所有后续改动都和这个 baseline 比,而不是和上一次实验比。 这避免了"漂移"——每次一点点 +0.2/-0.1,累积 6 个月后发现原地踏步。
5.2 Ablation(消融实验)替代拍脑袋
你怀疑 Prompt 里有三句话起作用,应该怎么做?
不是把三句话一起删掉看效果——那你还是不知道具体哪句在起作用。正确做法是消融矩阵:
| 变体 | 系统 Prompt 里的组件 | 分数 | Delta |
|---|---|---|---|
| Baseline | A + B + C 全放 | 58.3 | 0 |
| Ablate A | 只放 B + C | 57.9 | -0.4(统计不显著) |
| Ablate B | 只放 A + C | 48.2 | -10.1 |
| Ablate C | 只放 A + B | 56.7 | -1.6(显著) |
结论:B 是真正起作用的组件;A 几乎没用;C 有小帮助。然后你的下一步不是"保留三句",而是"把 B 做更深,A 可以删掉省 token"。
5.3 找 Pareto 前沿,不要只追最高正确率
当你改动涉及 cost/latency/safety tradeoff 时,单一的分数会误导人。把每一个候选版本画在 (score, cost) 二维散点图上,连接 Pareto 前沿——那些"没有任何其他版本在不牺牲任一维度的情况下完全优于它"的点。
Pareto 前沿上的版本是唯一值得保留候选的。前沿外的点(比如"分数比别人低、cost 还比别人高"的点)直接丢弃,不要浪费讨论时间。
5.4 失败复盘 → Targeted Fix
评测不仅告诉你分数,更告诉你哪些具体 case 挂了。工程化流程:
1. 从失败列表里按失败原因聚类(比如 37% 是"找不到环境里的 pip")
2. 针对这个聚类做一次 Targeted Fix(比如加一句 Prompt 提醒、或给环境预装)
3. 只重跑失败聚类的任务 + 回归跑全量
4. 如果 Fix 在聚类上有效、在全量上不下降,就接受
这比"换个模型试试"的 shotgun 打法效率高一个数量级。
六、第五步:从评测到训练:SFT 和 RL 的数据闭环
当迭代进入平台期、单靠 Prompt 再也提不动,Evaluation 的终极价值显现——评测轨迹就是训练数据。
6.1 评测 → SFT:把"对的行为"当示教数据
任何评测系统,只要采集了轨迹,就能导出 SFT 数据:
ATIF Trajectory ----[export SFT format]----> supervised-finetune.jsonl
但不是所有通过的 case 都要喂进 SFT。推荐采样策略:
| SFT 数据来源 | 配比 | 说明 |
|---|---|---|
| 通过的 hard task 轨迹 | 40% | 含金量最高,Agent 在难任务上做了正确推理链 |
| 失败但人工修正的轨迹 | 30% | negative + positive 成对给,修正版更有效 |
| 通过的 medium task | 20% | 保证基础能力覆盖 |
| Oracle 轨迹(参考答案) | 10% | 作为"正确方式"的锚点 |
训练前做两步清洗:
1. 去重:MinHash 相似度 0.9 以上的任务对,只留一条
2. 过滤死步骤:Agent 重复问同样问题、冗余 tool call 的 step 要标成 negative 或干脆删掉
6.2 评测 → RL:把 reward 直接变成优化信号
这是 AgentFlow / Flow-GRPO 那篇文章讲的核心思路——训练就在 Agent 运行时里做:
MERMAID_BLOCK_2
注意 Checkpoint Phase 是必不可少的——训练后必须在独立的 Hold-out Set 上再跑一遍评测,确认:
- 分数确实涨了(不是过拟合 train set)
- 没有在不重要的子集上"虚涨"(分桶分析)
- 没有出现 safety/cost 退化
RL 训练的常见失败模式:Reward hacking——Agent 学会了"糊弄 Verifier"而不是"真正解决问题"。比如 Verifier 只检查文件最后一行,Agent 就只写最后一行而跳过前面所有过程。对策:
- Verifier 加更多检查点(多阶段、多角度)
- 定期用 LLM-as-judge 做抽检(不做主指标,做警钟)
- 训练前后跑 Hard 子集的变化,Reward hacking 在 hard task 上通常是负的
6.3 训练后重新进入 Eval 循环
训练产出的新 Agent 不是终点——它是下一轮 Evaluation 的起点。重新建 baseline,重新做消融,重新跑失败分析,继续循环。这就是为什么 Evaluation 是"仪表盘"——它不只开一次,而是全程陪着你。
七、第六步:落地到团队工程流程
把 Evaluation 从"个人习惯"变成"团队流程"。
7.1 CI 里的 Gate
- PR Gate:任何改 Agent 的 PR,都必须触发小型 smoke benchmark(10-20 tasks,10 分钟内跑完)。Smoke 分数下降超过阈值(比如 -3%),直接阻止合并。
- Nightly Gate:每天晚上跑完整 benchmark,把结果贴到 Slack/飞书群。连续两天下降就开 Issue 跟进。
- Release Gate:正式发布前必须过 Full benchmark + Safety suite + Cost audit。
7.2 数据与结果的中心存储
用 Harbor 的 Supabase 存储、Harbor Hub 分享、或者自建一个简单的 JSONL/S3 存储都行。关键是:
- 每次实验自动记录(手动复制粘贴的结果 3 个月后一定会丢)
- 按 (dataset version, agent version, model, prompt sha, seed) 多维可查询
- 支持一键画对比图:score timeline、bucket breakdown、pareto frontier
7.3 角色与流程配套
| 团队角色 | 对应的 Evaluation 职责 |
|---|---|
| Prompt / Agent 工程师 | 改动前先跑 baseline,改动后提交对比报告,消融分析附到 PR |
| 训练工程师 | 新 checkpoint 提交时附带 Hold-out 分数 + 成本/时延审计 |
| 研究工程师 | 新方法论文验证需至少在 2 个 Benchmark 上和当前 SOTA 对比 |
| Tech Lead / 经理 | 每周看 1 次 Nightly 趋势和 Pareto 前沿变化,决定发布窗口 |
| QA / SRE | 维护私有黄金集,真实生产 case 定期回灌 |
八、常见陷阱与反模式
陷阱 1:只追一个 Benchmark 的分数,上线翻车
征兆:团队把 Benchmark 分数作为单一 KPI;几个月里分数涨了 20 分,但线上用户反馈没变好。
解药:20% 私有黄金集 + 定期生产 case 回灌 + 线上 A/B 测试和离线分数的相关性审计。Benchmark 分数和线上 CTR/solve rate 相关系数 < 0.7 就该换 Benchmark。
陷阱 2:数据泄露 / Test Set Contamination
征兆:一个新模型从 60 分直接跳到 90 分,但换个任务集立刻掉回 60 分。
解药:
- 私有黄金集任何人都不能把 case 放进训练数据(权限隔离)
- 公共数据集定期换版本(SWE-Bench Verified 就是为了对抗这个)
- 训练前做 n-gram overlap 检查,和 test set 重复的样本剔除
陷阱 3:用 LLM-as-judge 做主 reward
征兆:同一个任务跑两次,reward 0.9 和 0.5 都出现,方差巨大。
解药:LLM-as-judge 最多用于失败原因聚类 / 开放式内容的辅助检查,做主 reward 必须用代码化、确定性的 verifier。
陷阱 4:改 Prompt 不存版本,分数变化无法追溯
征兆:"上周这个 case 明明过的"——但没人知道上周 Prompt 是啥。
解药:Prompt 模板代码化,每次改都进 git,且 sha256 记录进评测元数据。
陷阱 5:RL 过拟合训练分布
征兆:训练 reward 一路飙升,但 hold-out 分数不涨甚至下降。
解药:
- 每个 checkpoint 必过独立 hold-out
- KL penalty 调大(Flow-GRPO 里的 β)
- 多任务混合训练,不要只在单一 benchmark reward 上训
- 如果是 self-play 风格,定期 reset 采样池
陷阱 6:把"更聪明的模型"当万能药
征兆:分数低就换更大的模型,然后就满意了,不做进一步分析。
解药:任何模型升级都要做分桶 + 成本审计。很多时候 7B + 评测 + RL 训练出来的 Agent,在具体任务上的 (score, cost) 组合比 Opus 级别模型在 Pareto 前沿上更优。
陷阱 7:没人看失败 case,只看总分
征兆:团队每周例会只讨论总分的变化曲线,没人点进 1000 个失败 case 看一眼。
解药:每周一次 30 分钟 Failure Review,固定议程:随机抽 5 个失败 case 看轨迹,讨论 Verifier 是否误判、Prompt 应该补什么、环境缺什么。坚持 8 周,你会看到分数自己在涨。
九、30 条从 0 到 1 落地 Checklist
基础设置(第 1-2 周)
- [ ] 选好 1 个主公共 Benchmark(和你的任务类型对应)
- [ ] 采集 50-100 条内部真实 case 做私有黄金集,每条都写确定性 Verifier
- [ ] 定好
dataset@version命名规则,版本不可变 - [ ] 选好 Harness:代码 Agent → Harbor Framework;其他 → 按推荐表选
- [ ] 沙箱环境跑通(本地 Docker 即可,并发先 4)
- [ ] 定义 5 维度度量表(score/cost/latency/reliability/safety)
- [ ] 跑一次 Baseline,把 5 维度数字 + CI 存进中心存储
迭代机制(第 3-6 周)
- [ ] Prompt 模板代码化并纳入 git
- [ ] 元数据 10 项(commit/harness/model/prompt-sha/image-sha/seed/…)自动记录
- [ ] Ablation 模板:任何改动 PR 附消融表
- [ ] PR Smoke Gate:<10 分钟的小子集评测,> -3% 降分拒绝
- [ ] Nightly Full Benchmark:自动贴结果到群聊
- [ ] 分桶分析:难度桶、任务类型桶、失败原因桶
- [ ] Pareto 前沿图定期生成
- [ ] 每周一次 Failure Review(固定议程、固定节奏)
数据闭环(第 7 周起)
- [ ] Harness 支持导出 ATIF 轨迹
- [ ] SFT 导出命令:
harbor traces export --fmt sft - [ ] SFT 数据集清洗:MinHash 去重 + 死步骤过滤
- [ ] 建立独立 Hold-out Set(至少和训练集不重叠)
- [ ] RL 训练管线打通(Flow-GRPO / GRPO / PPO 三选一)
- [ ] 每个训练 checkpoint 自动过 Hold-out + 成本审计
- [ ] Reward hacking 监控:Hard 子集分数变化
- [ ] 训练产出 Agent 重新建立 Baseline,进入下一循环
团队与流程(持续)
- [ ] 角色分工到位:Engineer/TrainEng/ResEng/TL/QA 各自职责明确
- [ ] 发布 Release Gate 三条线过(Full/Safety/Cost)
- [ ] Benchmark 相关性每季度审计一次(和线上 A/B 比)
- [ ] 私有黄金集每季度新增 10-20 条(从生产 bad case 回灌)
- [ ] 中心存储至少保留 90 天历史,支持多维查询
- [ ] 新成员入职第一课:怎么读评测报告、怎么跑 baseline
- [ ] 年度大版本:重新过一遍 Harness / Benchmark / Verifier 三件套是否依然合适
作者: itech001
来源: 公众号:AI人工智能时代(the-ai-era)
网站: https://www.theaiera.top/
关注每日最新AI新闻和技术博客,主页有更多的文章的AI 技术参考:https://www.theaiera.top
本文首发于 AI人工智能时代,转载请注明出处。

浙公网安备 33010602011771号