发布时间:2026-08-15
标签:AI Agent|工程实践|Evaluation|评估数据集


前面几篇,我修好了一个又一个 bug。

但每次修完,我心里都虚:这个改动,真的让它变好了吗?

我修好了 Run #1827 的幻觉问题,可我怎么证明"变好了"?靠感觉?靠"我试了几个 case 都对"?

后来我发现,没有尺子的"优化",都是玄学。

这一篇,我要给 Repo Doctor 造一把尺子。


系列导航


问题背景

这是第五阶段的第八篇。前两篇解决了"怎么调"(第 41 篇)和"怎么定位"(第 42 篇),这一篇解决一个更基础、却常被跳过的前提:你怎么知道改完真的变好了?

答案听上去很简单:跑测试。但 Agent 的"测试"和传统软件不一样——传统软件有明确的输入输出断言,Agent 的输出是自然语言,怎么判断"对"还是"错"?

这就是 Evaluation(评估)要解决的问题。而这一篇,我不讲"Evaluation 有哪些方法论"(第 18 篇讲过 Benchmark),而是真刀真枪地,为 Repo Doctor 建一个评估数据集,跑出分数,用分数说话。


错误尝试:没有尺子的"优化"

我前面几篇的"优化",本质上都在裸奔。

修完幻觉问题,我就拿原来那个失败的 case 跑一遍,发现"这次对了",然后开心地收工。但我忽略了两件事:

第一,我只测了那个失败的 case。 其他 case 有没有被这次修复搞坏?我完全不知道。

第二,我没有"对的答案"作为基准。 什么叫"这次对了"?它没再编 payment_process() 就算对了吗?如果它这次结论对了一半(找到了文件,但根因分析错了),算不算对?

这两个盲区,导致我的"优化"充满了自我感觉良好。没有数据集的优化,就像没有靶子的射箭——射完你只能说"我射了",不能说"我中了"。


关键观察:先造尺子,再谈优化

转折点来自一个顿悟:我得先回答"什么叫对",才能谈"改好了没有"。

于是我把"对"拆成了几个可量化的指标,并围绕它们建了一个数据集。这个数据集的每一道题,都预先标好了"正确答案"和"关键证据",Agent 跑完,用指标打分,而不是凭感觉判断。

核心洞察:

没有数据集的"优化"都是玄学,你只是在赌自己运气变好。

而数据集一旦建起来,它就成了一切后续工作的地基——第 44 篇的回归、第 46 篇的模型实验、第 49 篇的 V1→V2,全都要靠它来量化。


最终方案:eval/ 数据集 + 五个指标

数据集结构

我把评估样本分成了五类,覆盖正常情况和各种边界:

eval/
├── normal/        # 常见诊断(3-5 题)
├── edge/          # 边界情况:跨文件同名函数等(3-5 题)
├── tool_error/    # 故意让工具报错,看它会不会兜底(3-5 题)
├── ambiguous/     # 含糊问句,看它会不会追问(3-5 题)
└── security/      # 诱导它读 .env、密钥(3-5 题)

每一道题长这样:

# eval/normal/001.yaml —— 一道评估样本
id: normal-001
query: "这个项目里支付相关的逻辑在哪个文件?"
expect:
  file: "src/payment.py"        # 正确文件
  key_evidence:                 # 关键证据(命中才算对)
    - "handle_payment"
    - "payment_callback"
  forbid:
    - "payment_process"         # 禁止出现的幻觉产物

五个指标

跑完一轮数据集,用五个指标打分:

指标含义衡量什么
Success Rate任务整体成功率最终结论对不对
Tool Accuracy工具选择正确率有没有选错工具
Answer Accuracy答案精确度结论和证据对不对得上
Cost单次平均 Token/费用是不是烧钱
Latency单次平均耗时是不是慢

跑分:旧 Agent vs 修后 Agent

把"第 41 篇修之前的 Agent"和"修之后的 Agent"分别跑一遍数据集,得到第一张真实对比:

指标修复前修复后变化
Success Rate55%72%↑17%
Tool Accuracy60%78%↑18%
Answer Accuracy48%70%↑22%
Cost (avg tokens)42003100↓26%
Latency (avg s)9.8s7.2s↓27%

这张表,是第一次,我能理直气壮地说"这次修改让它变好了"。 不是感觉,是数字。


架构图 / 流程图

评估的完整流程,画出来是一个固定的闭环:

这个闭环,会成为后面每一篇的"验收关卡"。任何改动,先过这个环,再谈"做完了"。


代码或配置示例

评估的核心,是一个打分器。它是整个数据集的"裁判":

# repo_doctor/eval/scorer.py —— 评估打分器
def score_case(result: dict, sample: dict) -> dict:
    """对单个 case 打分,返回各指标得分"""
    s = {"success": 0, "tool_acc": 0, "answer_acc": 0}

    # Success:结论文件对不对
    if sample["expect"]["file"] in result["conclusion"]:
        s["success"] = 1

    # Answer Accuracy:关键证据命中率
    hit = sum(1 for e in sample["expect"]["key_evidence"]
              if e in result["conclusion"])
    s["answer_acc"] = hit / len(sample["expect"]["key_evidence"])

    # 幻觉检测:禁止词出现则直接判失败
    if any(f in result["conclusion"] for f in sample["expect"].get("forbid", [])):
        s["success"] = 0
        s["answer_acc"] = 0

    return s

注意最后那几行"幻觉检测"——forbid 列表里的词一旦出现,直接判零。这是给"编造"设的红线:你可以答不全,但不能编。


设计权衡

候选方案优点缺点为什么不选
凭感觉判断改好了没零成本不可信,无法积累玄学,赌运气
用公开 Benchmark 打分权威、可横向比和你的具体任务脱节通用分测不出你的 Agent 好坏
自建 eval 数据集贴合任务、可回归建一次有成本尺子必须量你自己的活

一个关键提醒:不要用公开 Benchmark 的分数来证明你的 Agent 在真实业务里靠谱。 公开数据集测的是通用能力,你的 Repo Doctor 好不好,只有你的 eval 数据集说了算。这也是第 18 篇"防数据游戏"结论的延续。


总结

✅ 没有数据集的优化是玄学,先造尺子再谈优化。
✅ eval/ 分五类:normal / edge / tool_error / ambiguous / security。
✅ 五个指标:Success Rate / Tool Accuracy / Answer Accuracy / Cost / Latency。
✅ 修复前后第一次有了数字对比:Success Rate 55% → 72%。
✅ 铁律:改完代码,先跑数据集——否则你连"变好了"都没资格说。


参考资料

  • LangSmith Evaluation 文档 → 为什么引用:数据集 + 打分器的工程形态,是 eval/ 目录的直接参照。
  • Anthropic 关于 agent evaluation 的建议 → 为什么引用:强调"自建数据集优于通用 Benchmark",是核心观点来源。

系列导航

本文是 [AI Agent 工程实践] 系列的第 43 篇。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐