实操 · CLAUDE

CLAUDE发布日期 2026-09-28 · 阅读约 13 分钟

使用 Claude 自动化评测设计与迭代优化

> 评测设计与迭代优化的原则,以及如何在不自欺的前提下依据评测进行迭代优化;并介绍 `claude-api` Skill 的 `build-eval` 和 `hillclimb` 命令如何将这些原则付诸实践。

原作者/来源:claude.dev

原文链接:https://claude.dev/blog/automating-eval-design-and-hillclimbing/

评测设计与迭代优化的原则,以及如何在不自欺的前提下依据评测进行迭代优化;并介绍 claude-api Skill 的 build-eval 和 hillclimb 命令如何将这些原则付诸实践。

  • 阅读时长:12 分钟

评测能为你的应用或 Skill 在特定任务上的表现提供信号。但设计评测,以及在不自欺的前提下提升评测表现,都很难。我们已在 claude-api Skill 中加入了这两方面的指导。有了这个 Skill,你可以运行 /claude-api build-eval,在你的代码库中构建一套评测;也可以运行 /claude-api hillclimb,每次只做一项更改,针对这套评测改进你的应用,并用一组留出样例来发现过拟合。

本文先介绍优秀评测设计和迭代优化的原则,然后展示 Claude Code 如何借助 claude-api Skill 运用这些原则。最后,我们会展示这些命令的一些示例。

评测设计

设计良好的评测通常包含几个共同要素(图 1):

  1. 评测任务应映射到生产场景。 选取你在“生产环境”中关心的任务,也就是你正在测试的能力或应用将被使用的场景。有时,人们会因为某些任务容易生成或容易评分而选中它们。但重要的是,确保任务分布能够代表你真正关心的内容。
  2. 更强的模型和更多思考应带来更好的表现。 能力更强的模型和更高的 effort 等级通常应当在评测中表现更好。如果没有,含糊的任务或校准不当的评分器往往会拖累表现。
  3. 前沿模型应有“可提升”的空间。 能力最强的模型在最高 effort 设置下的评测得分应明显低于 100%,否则你就无法可靠地判断更改会如何影响表现。重要的是,这个差距不应由不可能完成或含糊不清的任务造成:一个常见信号是,某项任务无论重复评测多少次,每次都会失败。一项好的任务应当满足:两位领域专家会得出相同判定,而且评分器要检查的所有内容都已在任务中说明。
  4. 多次运行之间的方差应较低。 高方差通常来自设计不佳、含糊不清的任务,或者会对相同输出给出不同判定的评分器。配置中也可能隐藏着方差。例如,effort 可能没有被一致地应用。此外,运行环境也会影响评测结果:先前试验留下的状态(某个文件、Git 历史)可能会把答案直接交给智能体。

根据 token 消耗量评估得分

原文图 1

图表说明: 三种模型规模在三种 effort 设置下的示意图。

  • 完美得分
  • effort 较低 / effort 中等 / effort 较高
  • 每次尝试的操作 token 数(对数刻度)
  • 纵轴:得分
  • 前沿模型 / 中等规模模型 / 较小模型
  • 1:能力更强的模型得分更高
  • 2:effort 越高,得分越高
  • 3:低于完美得分的提升空间
  • 4:多次运行之间的方差较低

图 1: 优秀评测的四个要素

对抗性采样

模型能力的表现并不平滑。如果你因为当下的模型无法通过某些案例而挑选它们,你实际上是在对某个模型能力曲面的低谷进行采样(图 2)。这样一来,评测最终测量的可能是该模型特有的失败指纹,而不是你的应用本身要完成的事情在内在层面有多难或多有价值。

原文图 2

图 2:对抗性采样。 左图标题:在模型失败处采样;右图标题:由人判断难度。纵轴:能力;横轴:任务空间。曲线标注:下一代模型、当前模型。图例:评测案例、不应触发的案例。

选择难例,是因为人判断它们很难:一个有用的检验方法是,在纳入某项任务之前,你能够说清它为什么难。纳入那些来自生产流量、错误报告或工单、并且是你的应用中特定失败的案例。不过,不要盲目信任用户流量:用户有时只会尝试他们预期能够奏效的事情,因此严格从用户流量中抽取的任务分布可能会偏简单。

/claude-api build-eval

claude-api Skill 中的 build-eval 命令会把这些原则转化为一套引导式工作流。当你在 Claude Code 中运行 /claude-api build-eval 时,Claude 会采访你,在你的代码库中构建评测,并在特定节点暂停,等待你批准。

设计样例

Claude 会按以下顺序帮助你抽取输入,以构建评测:

  1. 生产环境对话记录;在此之前会询问数据保留和敏感数据方面的问题。
  2. 错误报告和支持工单。
  3. 你手写的五到十个案例。
  4. 根据你的代码库合成的案例。

这个 Skill 会优先使用生产流量,但也可以基于你提供的少量真实案例生成合成数据。Skill 会指示 Claude 生成一个简单页面,展示每一条输入,并等待你确认。作为示例,下面展示了一组用于电子邮件路由应用的输入;Skill 可能会要求用户审核这组输入(图 3)。

原文图 3

图 3:由 Skill 生成的示例输入审核界面。 图中显示的是 inbox-routing 的 24 条输入,每个案例各有一个区块,包含邮件应用收到的邮件及其元数据。可见的示例包括:

  • c01(标签:账单、简单):“我的卡在 3 号被扣了 48 美元,但我的套餐每月应该是 24 美元。你能查一下发生了什么,并退还差额吗?”
  • c02(标签:账单、简单):“我需要上个月付款的发票用于报销。在哪里可以下载?”
  • c03(标签:账单、含糊):“我结账时应用崩溃了,现在账单上显示有两笔扣款。请处理一下。”
  • c04(标签:账单、含糊):“我该如何从按月计费切换为按年计费?当前月份剩下的天数会折算抵扣吗?”
  • 其余为 c05 至 c24(共 24 个案例)。

Claude 的对话消息:“以下是我提议使用的 24 条输入。请快速浏览一下。它们能代表你的应用实际会遇到的情况吗?有没有明显缺失的案例,或者其中有不重要的案例?”用户回复:“是”。

校验评分器

输入样例之后,Claude 会为你的应用输出建议一个成本最低且适用的评分器:

程序化校验: 如果输出的可能性受到限制,它会使用基于代码的检查(精确匹配、从固定集合中选取标签、符合某个 Schema 的 JSON,或能够通过的测试)。

LLM-as-judge: 如果输出空间是开放式的,有许多有效答案,但质量标准明确,它默认会采用这种检查方式。在这种情况下,第二个模型会读取输入、输出和一份以可检查主张编写的评分标准(而不是 1 到 5 分量表),然后返回分数及其推理过程。如果你有基线可供比较,裁判模型会以随机顺序读取两个输入,不会被告知哪个是基线,并选出更好的一个。由你选择裁判模型;它不应是你正在测试的模型。

Claude 会为若干案例评分,并询问你是否会对其中任何案例给出不同分数(图 4)。一般来说,在相信评测器之前,阅读一部分已经评分的对话记录很重要;评分失败是评测配置错误最常见的原因之一。

原文图 4

图 4:结果页面示意图,其中为每项输入给出了建议评分。

图中示例页面标题为 inbox-routing,列出了变体、案例、平均正确率和失败尝试等信息;右侧显示一条运行记录的 JSON。案例使用账单、简单或含糊等标签,并展示基线分数及相应提示词。

验证评分器之后,Skill 会告诉你评测集的规模(案例数 × 重复次数 × 模型数,以及大致所需时间),运行基线,并打印带置信区间的分数。你会得到:案例、评分器、运行器、每个案例一行 JSON,以及每个案例的一份完整对话记录;此外还有一个简洁页面,列出每个案例的分数,并附上其对话记录链接。如果你想查看该页面之外的内容(例如图表),只要提出要求,Claude 就会在旁边额外构建一个页面。默认情况下,这些额外页面是静态文件,可在本地打开,不会从网络加载任何内容。

诊断检查

在上述基线运行期间,Claude 会检查多项内容:

评分器: Claude 会用同一份输出运行评分器两次,并报告判定是否发生变化。

运行链路: Claude 会检查超时、API 错误和回答被截断的情况,确保基础设施噪声不会被误当作模型方差。

提升空间: 如果基线得分已经约为 95% 或更高,Skill 会警告用户,并提醒迭代优化的目标应是探索成本或延迟,而不是质量。

迭代优化

现在,你已经有了一种可靠方法来评估应用在某项任务上的表现,可以尝试改进它。迭代优化是调整 effort 或提示词等参数的有效方式;这些参数会在成本与表现之间进行权衡。以下是一些关于如何选择迭代优化对象的一般建议:

迭代成本低: 从时间、成本和精力来看,你聚焦进行迭代优化的对象应当容易修改。许多内部项目和客户都把迭代优化聚焦在文本上,例如提示词和技能。这些内容容易更改,也容易回滚。相比之下,在迭代优化期间对智能体运行框架进行开放式修改,可能需要大量代码更改。

效果可归因: 评测分数的变化应当能够归因于你在迭代优化过程中修改的对象。例如,几次成功的迭代优化都聚焦于技能触发。评测指标(技能触发率)与正在修改的技能描述直接相关。

目标范围明确: 一种常见的失败模式是,在没有仔细考虑评测中尚有多少提升空间的情况下,提出开放式的提升表现请求;如果评测已接近饱和,或优化对象的范围界定不佳(例如,开放式地要求更新运行框架),就更容易停滞。在各种工作中,成本通常是一个很好的目标:即便评测已接近饱和,你仍可以要求 Claude 在保持表现不变的同时设法降低成本。

过拟合

即便是设计良好的评测,也很少会与生产环境中你所关心的确切任务分布完全一致。因此,对评测“过拟合”是个常见问题,会导致系统在评测上的表现优于在生产流量上的表现。

评测可能通过许多途径“泄漏”进你的运行框架(模型周围的代码,包括提示词、工具,以及调用 Claude 的循环)。例如,设想有一项评测任务会受益于 OCR,但 OCR 在你的生产任务中很少有用。评测运行框架可能会为你的应用加入一个 OCR 工具;这会让它在基准测试中表现更好,却不会对生产环境产生任何影响。更广泛地说,迭代优化可能会为运行框架添加功能,以处理你所选评测样例中的特定边缘情况。这些运行框架的补充会提高评测得分,却不会转化为生产环境中的改进(图 5)。

原文图 5

图 5:运行框架过拟合的常见原因。 图示左侧为“基准测试”:任务组合需要 OCR、任务位于 /app、独特措辞、你读过的失败案例、公开仓库中含有答案。箭头表示这些因素“塑造了运行框架”。右侧为“运行框架”:加入 OCR 工具、总是切换到 /app 并运行 pytest、针对这些措辞调整提示词、每个失败只打一个补丁、用 curl 获取参考答案。虚线表示直接泄漏。

以下三种做法可以帮助解决这个问题:

拆分案例。 使用一组迭代优化器可以读取的训练集,以及一组它永远看不到的测试集。如果训练集得分有所提高,而测试集得分保持不变,这通常是过拟合的警示信号。

绝不要把失败内容粘贴进提示词。 如果迭代优化器会读取失败的对话记录,就绝不能把失败内容粘贴进提示词。

在结构上让模型无法触及答案。 模型有时会通过直接找出评测答案来“奖励作弊”。

如下所述,claude-api Skill 会替你应用这些原则。

/claude-api hillclimb

claude-api Skill 中的 hillclimb 命令会把这些原则转化为一套引导式工作流。当你在 Claude Code 中运行 /claude-api hillclimb 时,Claude 会针对给定评测进行迭代改进。你可以选择它能够修改的内容,包括:

  • 你的系统提示词
  • 技能或指令文件
  • 工具描述
  • 模型选择、effort 等级和其他 API 参数
  • 你的运行框架代码

开始之前,Claude 会询问你想优化什么(例如提升表现,或在保持表现的同时降低成本),然后将评测集随机拆分成测试集和训练集。若目标是降低成本,它会考虑几个常见的成本驱动因素,包括提示缓存、审查提示词与所选模型的兼容性,以及选择模型和 effort 设置。

第一轮开始之前,Claude 会检查评测噪声(分数仅因偶然因素可能产生多大波动)是否小于你会采取行动的最小提升幅度;如果不是,它会说明这一点,并建议增加重复次数或案例数量。

每一轮中,Claude 会读取上一轮的训练集对话记录,并以补丁形式提出一项更改。它会让每轮更改的效果有机会超出评测噪声:它会从根本上修复失败行为(例如重写导致问题的部分,或补充一条缺失规则),而不是改写某一行措辞。然后,它会用打过补丁的更改运行评测。此时 Claude 会进行检查:如果训练集有所改善,但测试集没有变化,Claude 就会怀疑存在过拟合,并回滚补丁。如果出现性能回退,Claude 会回滚。如果训练集和测试集都有改善,它就会保留补丁(图 6)。

原文图 6

图 6:迭代优化器使用的流程。 图中流程标签:

  • 优化对象: 我们要编辑的内容(例如提示词)。每轮提出一个补丁。
  • 应用: 模型与运行框架保持不变。
  • 评测: 测试拆分集为留出集,不向迭代优化器展示,每轮评分;训练拆分集展示各案例通过或失败。预运行阶段通过基线及 N 次重复运行估算噪声范围。
  • 决策: 训练集和测试集都提升,则保留补丁;训练集提升而测试集持平,则怀疑过拟合并回滚;任一方回退,则回滚。
  • 分析器: 读取训练集失败案例并形成假设;测试拆分集仍保持不可见。分析器读取训练集对话记录和分数,聚焦失败案例。

如果分数连续两三轮停滞,Claude 会读取每一项尚未解决的训练集失败案例,并按原因分类。如果没有任何单项修复能带来超过评测噪声的提升,它也会提前执行这一操作,并建议增加重复次数或案例数量,而不是把轮次浪费在小到无法测量的更改上。这一步可以发现含糊的评测案例、运行框架错误或多次运行之间的方差。

只有合理的失败案例才会进入后续迭代优化轮次。迭代优化完成后,Claude 会让你的代码保持在针对既定目标、在测试集上表现最佳的版本。它会报告测试集相对于基线的结果及置信区间(图 7)。如果提升幅度处于噪声范围内,它会说明这一点,并建议不要合并。

原文图 7

图 7:迭代优化完成后生成的报告示意图。 示例报告展示了 inbox-routing 的三个变体和 24 个案例,并列出 baseline、v1、v2 的更改、模型、平均正确率、测试均值、案例数、截断数和失败尝试数。最佳版本 v1 的更改是“定义每个队列并添加平局时的决胜规则”;v2 添加了两个完整示例,但因训练集提高、测试集持平而被回滚。下方表格列出案例编号、拆分集、标签、各版本分数和提示词;示例案例包括账单类的简单、含糊和困难案例。

示例

为降低成本而进行迭代优化

我们在一个内部客户支持基准测试上运行了 /claude-api hillclimb,目标是降低成本并提升表现。基准测试包含 44 个工单,其中 30 个用于搜索,14 个作为留出集。它从 Opus 4.8 的默认(high)effort 设置开始,在搜索工单上的决策准确率为 74.4%,每个工单的 token 成本为 4.6 美分。

迭代优化器首先审查了提示词,删除了强制性的工具调用流程、一项草稿步骤以及相互矛盾的规则。然后,它尝试在 low effort 下使用 Opus 5.5。它以 87.8% 的准确率超过了基线准确率门槛,并将每个工单的成本降到了 1.9 美分,不到起始成本的一半。

部分节省来自 Opus 5.5 的定价:输入和输出 token 的成本比 Opus 4.8 低 20%,缓存读取的成本低 60%。由于 Opus 5.5 达到了门槛,迭代优化器接着下调一个模型档位,检查成本更低的模型是否也能达到门槛。low effort 下的 Sonnet 5 得分大致相同,为 88.9%,成本约为一半,即每个工单 1 美分(图 8)。

原文图 8

图表标题: 客户支持基准测试。沿着采用的路径排列的四种配置。

  • 纵轴:搜索工单上的决策准确率
  • 横轴:每个工单的成本(对数刻度)
  • 起始准确率
  • 1:Opus 4.8,high effort——基线,准确率 74.4%,成本 4.6 美分
  • 2:Opus 5.5,low effort——审查后的提示词,准确率 87.8%,成本 1.9 美分
  • 3:Sonnet 5,low effort——相同提示词,准确率 88.9%,成本 1 美分
  • 4:Sonnet 5,low effort——改进后的提示词,准确率 98.9%,成本 1 美分

图 8:以成本为重点的迭代优化。

最后,Claude 通过加入路由规则和关于退款上限的交叉引用改进了提示词,使 Sonnet 5 在成本大致不变的情况下达到了 98.9%。在搜索过程中从未见过的 14 个留出工单上,最终配置的得分为 90.5%,而原始配置为 78.6%;成本约为原来的五分之一。

为提升表现而进行迭代优化

另一个例子是我们的 claude-api Skill,它提供有关如何使用我们 API 的指导,以及使用 Claude 的一般建议(包括本文讨论的子命令)。我们希望确保 Skill 能正确实现使用我们 API 的代码,因此我们基于文档构建了一套评测集来测试该 Skill。

在这套评测上,该 Skill 的初始得分为 66%。我们让迭代优化器能够访问文档和 SDK,以便 Claude 找出错误并自行纠正(图 9)。Claude 发现该 Skill 缺少对八项功能的覆盖。

在 Skill 中为这些功能添加章节后,表现提高到了 74%。之后它又发现了 C# 和 Java 类型表中的错误,使表现提高到了 77%。

原文图 9

图表标题: claude-api Skill 评测。经过三个阶段的工作,得分从 66.1% 提升到 87.9%。

  • 纵轴:通过率
  • 横轴:迭代优化轮次(第 0 轮为基线)
  • 第 0 轮:66.1%;第 6 轮:74.3%;第 9 轮:74.0%;第 11 轮:77.5%;第 13 轮:77.2%;第 17 轮:80.1%;第 22 轮:84.0%;第 24 轮:87.9%
  • 阶段 1:添加缺失章节和类型表
  • 阶段 2:修正 Skill 指导 Claude 编写代码的方式
  • 阶段 3:修正评分器,并进一步修改 Skill

图 9:以提升表现为重点的迭代优化。

分数连续两轮停滞后,Claude 分析了剩余失败案例,并按根本原因归类。常规轮次会针对最常见的失败做一项编辑;这一步不做任何编辑,只按原因整理所有剩余失败。这个反思步骤在几个方面都很有用:

  • 通过对一组失败案例进行整体反思,迭代优化器发现 Skill 中已经包含相关内容,但 Claude 只是写出了较旧的 API 形式(例如来自其训练先验的形式)。为解决这个问题,迭代优化器在 Skill 靠前的位置添加了一张表,引导 Claude 从它记得的形式转向当前形式:例如,从固定 token 预算的扩展思考转向自适应思考——API 现在会在较新的 Opus 模型上拒绝前一种方式;还从旧版 Web 搜索和 Web 抓取工具转向当前版本。它还把 C# 和 Java 中反对固定预算思考的警告,移到了自适应思考示例之前。这使表现提高到了 80%。

尽管补上了明显的内容缺口,表现却始终没有改善的任务,说明案例或评分器可能存在问题。一项任务要求编写能捕获一种错误类型的代码,而它的评分器却要求至少包含三种错误类型的链条。Claude 改写了这项任务。另一个评分器的指令与我们的文档相矛盾;测试真实 API 后证明文档是正确的。解决这些问题并进一步修改 Skill 后,表现提高到了约 88%。

开始使用

注意: 先运行 claude update。claude-api Skill 随 Claude Code 一同发布,因此更新即可获得这些命令的最新版本。

claude update

然后,在 Claude Code 中运行:

/claude-api build-eval
/claude-api hillclimb

通过 claude-api Skill,可以直接在 Claude Code 中使用这些子命令:

如果你想为某个特定问题生成评测集,请运行 /claude-api build-eval。你可以通过提供示例(例如 traces)的访问权限来引导它。Claude 会运用本文分享的指导来设计样例和评分器,并确保你批准这些样例和评分器。

如果你已有一套评测并希望 Claude 根据你的目标(例如提升表现,或在保持表现的同时降低成本)进行改进,请运行 /claude-api hillclimb。Claude 会运用本文分享的指导,在迭代优化过程中检查过拟合,并检查评测本身是否存在错误,例如评分器把看起来正确的答案判错,或运行框架出错;这些检查会在第一轮开始之前进行,也会在分数停滞时再次进行。

特别感谢 Misha Khalman 对 Skill 开发的贡献。

感谢 Misha Khalman、Michael Segner、Matt Bell、Matt Thanabalan 和 Punit Shah 提供审阅、贡献和产品支持。