发布时间:2026-07-12
标签:AI Agent|LLM|Benchmark|质量评测|工程实践


系列导航

上一篇:AI Agent 工程实践(17):Agent 为什么需要可观测性(Observability)
下一篇: AI Agent 工程实践(19):从 Demo 到生产环境——AI Agent 的工程 Checklist

本文是 [AI Agent 工程实践] 系列的第 18 篇(第二季 · 工程实现)。


上周我改了一行 Prompt——把"请详细回答"改成了"请简洁回答"。

感觉上,Agent 回答变快了。"优化成功",我在 commit message 里写道。

三天后我发现,这行改动让代码审查任务的漏检率从 12% 涨到了 28%——Agent 变"简洁"了,但也跳过了关键检查项。"感觉好了"和"真的好了",差了一个 Benchmark。

我说的是 Benchmark Agent,不是 Benchmark 模型。前者回答"改完之后 Agent 变好了吗",后者回答"哪个模型分高"。你改了一行 Prompt,Agent 变好了还是变差了——没有 Benchmark,你永远不知道。


本文你将学到

✓ Benchmark Agent 和 Benchmark 模型的本质区别——前者是持续交付,后者是选型
✓ Agent Benchmark 的核心链路:Task → Expected → Result → Score
✓ 四个关键指标:Success Rate / Cost / Time / Tool Calls
✓ 如何把 Benchmark 做成 CI/CD——每次改动自动跑、自动对比

适合阅读

✓ 经常调 Prompt / Rule / Tool、但靠"感觉"判断效果的人
✓ 想让 Agent 的质量像代码一样可回归测试的人
✓ 不知道"Agent 改完是变好还是变坏"的人


问题背景

99% 的 Benchmark 文章在讲同一件事:哪个模型更好。 MMLU 几分、HumanEval 几分、这个榜那个榜。

但 Agent 开发者真正需要的不是"选模型时的决策依据"——模型选完之后,问题才刚开始。你每天在做的操作是:

  • 改了 core/00-must.md 的一条规则
  • 加了一个新的 heavy 文件
  • 调整了 Router 的 priority 配置
  • 换了一个 Tool 的实现

每次改动后,Agent 是变好了还是变坏了? 这个问题,MMLU 回答不了,HumanEval 也回答不了。因为它们在测"裸模型",不是在测"你的 Agent 这个具体系统"。

Benchmark Agent 不是做一次,是每次改动后都做——这才是真正的 CI/CD for Agent。 它回答的不是"GPT-5 比 GPT-4 好多少",而是"你今天的 commit 让 Agent 的质量涨了还是跌了"。


错误尝试

第一次:靠"感觉"判断质量

改完 Prompt,自己跑几个 case,觉得"好像不错"就上线。

结果:很多退化是统计意义上才可见的——成功率从 92% 降到 88%,跑 5 个 case 根本看不出来,跑 50 个才能发现。感觉是 Benchmark 的敌人——感觉好的时候,往往指标在变差。

第二次:只测最终输出对错

搭了一套自动评测:给 Agent 一个任务,比对输出是否和预期一致。对就是对,错就是错。

结果:Agent 的输出"对了",但多了 3 次不必要的 Tool 调用,延迟从 5 秒变成了 18 秒,token 消耗翻了一倍。用户不会告诉你"答案对了但太慢了"——他们直接不用了。只看 Success Rate 的 Benchmark,和只看血压的心脏检查一样——漏了一半的指标。

两次尝试指向同一个教训:Benchmark 需要多维度 + 回归对比 + 统计显著。 不是"跑 5 个 case 看看",而是"每次改动后对同一组标准任务跑分、和历史版本对比、多维指标综合判断"。


关键观察

我把"Agent 上线后退化的 case"做了根因追溯:

退化类型 改动操作 单看 Success Rate 能发现吗 占比
成功率下降 改了一条 Rule ✅ 能 30%
延迟暴涨 加了一个 Tool 调用 ❌ 不能(Success 反升) 25%
成本翻倍 改了 Router 配置 ❌ 不能 25%
Tool 调用冗余 改了 Planner ❌ 不能 20%

pie title Agent 退化的可检测性(只看 Success Rate)
    "Success Rate 能发现" : 30
    "延迟暴涨(Success Rate 看不出)" : 25
    "成本翻倍(Success Rate 看不出)" : 25
    "Tool 冗余(Success Rate 看不出)" : 20

你改了一行 Prompt,Agent 变好了还是变差了——没有 Benchmark,你永远不知道。

70% 的质量退化,Success Rate 看不出来。你需要四维指标同时跑——少一维就有一个盲区。


最终方案:Agent Benchmark 四维体系

核心链路:Task → Expected → Result → Score

Benchmark 的本质就是"标准任务 + 预期输出 + 多维评分 + 回归对比"。 少任何一环,就是盲测。

四个指标的全部含义

指标 测什么 为什么不能只看它 怎么算
Success Rate 输出是否正确 覆盖不了效率和成本退化 正确数 / 总任务数
Cost Token 消耗 单独看没意义——便宜的废品还是废品 input_tokens × 单价 + output_tokens × 单价
Time 端到端延迟 快没用的答案也是没用 从 Task 进入到 Result 输出的总耗时
Tool Calls 调用效率 "答案对了但调了 10 次 Tool"是浪费 任务完成用的 Tool 调用次数

四维不是四个独立的分数,是综合评判。 我的产出公式是:

综合分 = Success Rate × 0.5 + (1 - Cost/预算) × 0.2 + (1 - Time/阈值) × 0.2 + (1 - ToolCalls/上限) × 0.1

Success Rate 占 50% 权重(答案对不对最重要),但 Cost / Time / Tool Calls 各占其余 50%——一个慢到不可接受的 Agent,和答错的 Agent 一样不能用。

Benchmark 作为 CI/CD

真正的价值不在"测一次",在"每次改动都测、每次和历史对比":

def benchmark_regression(agent_v2, test_suite, baseline):
    """每次 commit 后自动跑,和历史版本对比"""
    v2_scores = run_benchmark(agent_v2, test_suite)

    report = {
        "success_rate": (v2_scores.sr, baseline.sr, v2_scores.sr - baseline.sr),
        "cost": (v2_scores.cost, baseline.cost, v2_scores.cost - baseline.cost),
        "time": (v2_scores.time, baseline.time, v2_scores.time - baseline.time),
        "tool_calls": (v2_scores.tc, baseline.tc, v2_scores.tc - baseline.tc),
    }

    # 如果任一指标退化超过阈值,CI 报红
    degraded = any(delta < -THRESHOLD for _, _, delta in report.values())
    return "FAIL" if degraded else "PASS"

Agent 的 CI/CD 不是"代码能跑就行",是"质量没跌就行"。


架构图 / 流程图

Benchmark 驱动的 Agent 迭代闭环

关键:不是"上线前手动测一下"——是每次 commit 自动跑、自动对比、退化自动阻止。这和第 04 篇 Review 闭环、第 15 篇 RAG Evaluate 闭环是同一种思想:反馈系统必须自动化,靠人做不了。


代码或配置示例

标准 Benchmark 任务集定义

# benchmark/suite.yaml
tasks:
  - id: code_review_01
    task: "审查这段 Python 代码的安全性"
    expected:
      must_contain: ["SQL 注入风险", "建议使用参数化查询"]
      must_not_contain: ["看起来不错", "没有明显问题"]
  - id: db_query_01
    task: "查询 user_id=42 的订单状态"
    expected:
      must_return: "shipped"
      max_tool_calls: 2
  - id: report_gen_01
    task: "根据过去 10 条订单生成周报"
    expected:
      must_contain: ["总订单数", "完成率"]
      max_time_ms: 8000

Benchmark 执行引擎

def run_benchmark(agent, suite: list) -> BenchmarkScore:
    results = []
    for test in suite:
        start = now()
        result = agent.run(test.task)         # Trace 自动记录(17 篇)
        elapsed = (now() - start).ms

        # 四维评分
        sr = 1.0 if evaluate(result, test.expected) else 0.0
        cost = result.total_tokens * TOKEN_PRICE
        tc = result.tool_calls_count

        results.append({"sr": sr, "cost": cost, "time": elapsed, "tc": tc})

    # 汇总:所有任务的各维度取平均值
    return BenchmarkScore(
        sr=np.mean([r["sr"] for r in results]),
        cost=np.mean([r["cost"] for r in results]),
        time=np.mean([r["time"] for r in results]),
        tc=np.mean([r["tc"] for r in results]),
    )

和 17 篇的 Trace 无缝衔接:每跑一次 Benchmark 都是一次完整的 Trace 记录。Benchmark 不只产出一个分数,还产出了每次运行的完整调用链——分数跌了,Trace 告诉你哪个 Span 出了变化。


设计权衡

候选方案 优点 缺点 为什么不选
靠感觉评测 零成本 完全不可靠 感觉骗人
只看 Success Rate 简单直观 漏 70% 的退化 效率/成本退化看不见
人工评测(每次手测) 最准 不可持续 规模一大人就崩
自动 Benchmark + CI 回归 持续可对比、多维覆盖 需维护标准任务集 选择理由:唯一把质量变成可量化、可自动化的工程实践的方案

Benchmark 的任务集需要持续维护。 标准任务集不是"写完一次永远不变"——新功能上线要加新 case,过时的 case 要淘汰。这本身也是一个治理问题,和第 15 篇 RAG 知识治理同源:测试集本身也有生命周期。


总结

✅ Benchmark Agent ≠ Benchmark 模型——前者是持续交付的 CI/CD,后者是选型依据。
✅ 核心链路:Task → Expected → Result → Score → 和历史 baseline 回归对比。
✅ 四维指标缺一不可——Success Rate / Cost / Time / Tool Calls。只看 SR 会漏掉 70% 的退化。
✅ Benchmark 必须做成 CI/CD——每次 commit 自动跑、自动对比、退化自动阻止合并。
✅ 测试集本身也需要治理——新 case 持续加、旧 case 淘汰更新。


参考资料

  • 第 17 篇:Agent Observability → Trace 是 Benchmark 的数据源,每次 Run 生成完整 Trace
  • 第 15 篇:RAG 知识治理 → 测试集的治理与知识治理同构
  • 第 04 篇:Review 闭环 → Benchmark 是 Review 的量化工具
  • RAGAS / LangSmith Evaluation → Agent 自动评测的工程参考实现
  • ML CI/CD (MLOps) → 模型回归测试的最佳实践,Agent Benchmark CI 的思想来源

系列导航

上一篇:AI Agent 工程实践(17):Agent 为什么需要可观测性(Observability)
下一篇: AI Agent 工程实践(19):从 Demo 到生产环境——AI Agent 的工程 Checklist

本文是 [AI Agent 工程实践] 系列的第 18 篇(第二季 · 工程实现)。

Logo

中国智能体开发者社区,聚焦智能体与大模型开发,提供前沿资讯、实用工具链、开源项目及行业案例。通过技术沙龙、开发者大赛等活动,促进经验交流与协作,助力开发者快速构建创新智能应用。

更多推荐