跳到正文
Claude.dev 开发者博客· Lance Martin·· 7 天前精选AI 评分75

Claude 官方博客:用 claude-api skill 自动化 eval 设计与 hillclimbing

Automating eval design and hillclimbing with Claude

AI 导读

Anthropic 在 claude-api skill 中新增 eval 设计与 hillclimbing 指引,可在 Claude Code 中运行 /claude-api build-eval 构建评测、运行 /claude-api hillclimb 逐项改进应用。

推荐理由

原文给出 eval 设计与 hillclimbing 的可复用原则,并展示 Claude Code 中两个命令的完整工作流。

正文 · AI 翻译

评估能提供信号,反映你的应用或技能在特定任务上的表现。但设计评估,并在不欺骗自己的前提下提升其表现,并非易事。我们已在 claude-api skill 中为两者都添加了指导。

借助该技能,你可以运行 /claude-api build-eval 在你的代码库中构建评估,并运行 /claude-api hillclimb 针对它改进你的应用,一次一个改动,同时用一组留出的示例来捕捉过拟合。

在本文中,我们首先强调良好评估设计和爬山法的原则,然后展示 Claude Code 配合 claude-api 技能如何应用这些原则。最后,我们会展示这些命令的几个示例。

评估设计

设计良好的评估有几个共同要素(图 1):

  1. 评估任务要反映生产环境。 采样你在“生产环境”中关心的任务,也就是你所测试的能力或应用将被使用的场景。有时任务被选中是因为它们容易生成或容易评分。但重要的是确保任务分布代表你真正关心的内容。
  2. 性能随更强的模型和更多的思考而提升。能力更强的模型和更高的努力程度通常应在评估中表现更好。如果不是这样,那么模糊的任务或校准不当的评分器往往在拖累性能。
  3. 前沿存在“可通过”的提升空间。能力最强的模型在最高努力程度下,在评估中的表现应远低于 100%,否则你无法可靠地判断改动如何影响性能。重要的是,这一差距不应由不可能或模糊的任务来解释:一个常见的迹象是,无论重复多少次,某个任务在每次评估运行中都失败。好的任务是两位领域专家会得出相同结论,且评分器检查的一切都在任务中有所陈述。
  4. 运行间方差低。高方差通常源于设计不佳、模糊的任务,或对相同输出给出不同判定的评分器。方差也可能隐藏在配置中。例如,努力程度可能未被一致地应用。此外,环境也会影响评估结果:早先试验遗留的状态(一个文件、一段 git 历史)可能把答案直接交给智能体。

按消耗的 token 计分

三种模型规模、三种努力程度设置,示意

图 1良好评估的四个要素

对抗性采样

模型能力参差不齐。如果你因为今天的模型在这些案例上失败而挑选它们,你就是在采样某个模型能力曲面的低谷(图 2)。评估最终可能衡量的是那个模型的失败指纹,而非对你的应用而言本质上困难或有价值的内容。

Two panels plotting capability across task space, each with today’s model as a jagged curve and the next model as a smoother curve above it. On the left, cases sampled where today’s model fails sit only in its valleys; on the right, cases a person judged hard are spread across peaks and valleys, with a few should-not-fire cases.
图 2对抗性采样

挑选困难案例,是因为人类判定它们困难:一个有用的测试是,在纳入某个任务之前,你能够说出它为什么困难。纳入来自生产流量、缺陷报告或工单的、你应用中的具体失败案例。然而,不要盲目信任用户流量:用户有时会尝试他们预期能奏效的东西,因此严格从用户流量中抽取的任务分布可能偏向简单。

/CLAUDE-API BUILD-EVAL

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

设计示例

Claude 会按以下顺序帮助你采样输入以构建评估:

  1. 生产环境记录,在询问保留和敏感数据之后。
  2. 错误报告和支持工单。
  3. 你手写的五到十个案例。
  4. 从你的代码库合成的案例。

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

The skill’s review page for an inbox-routing eval with 24 inputs, listing each case’s email text with tags such as billing, easy and ambiguous. Beside it, Claude asks in chat whether the inputs are representative, and the user answers yes.
图 3该技能生成的示例输入审阅

验证评分器

在输入之后,Claude 会提出最适合你应用输出的最廉价评分器:

  • 程序化验证:如果输出可能性受限,它会使用基于代码的检查(精确匹配、来自固定集合的标签、符合 schema 的 JSON、通过的测试)。
  • LLM 作为评判者:如果输出空间是开放式的,有许多有效答案但有明确的质量标准,它会默认使用这种检查。在这种情况下,第二个模型读取输入、输出以及一份写成可检查断言(而非 1 到 5 分制)的评分标准,并返回分数及其推理。如果你有可比较的基线,评判者则会以随机顺序读取两个输入,不被告知哪个是基线,并选出更好的那个。你选择评判者模型,它不应是你正在测试的模型。

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

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

The skill’s results page for the inbox-routing eval: a baseline scoring 0.681 mean correct across 24 cases, then a table of per-case scores with a link to each repetition. A rep link opens that case’s raw JSON trace, shown alongside.
图 4生成的结果页面示意图,其中包含为每个输入建议的评分。

诊断检查

在上述基线运行期间,Claude 会检查若干事项:

  • 评分器:Claude 对同一输出运行评分器两次,并报告判定是否发生变化。
  • 管道:Claude 检查超时、API 错误和被截断的答案,以确保基础设施噪声不会被当作模型方差。
  • 余量:如果基线得分已经约为 95% 或更高,该技能会警告用户,并提示爬山应旨在探索成本或延迟,而非质量。

爬山

现在你已经有了一种可靠的方法来评估你的应用在任务上的表现,你可以尝试改进它。爬山是调整努力程度或提示等参数的有效方法,这些参数会在成本与性能之间权衡。关于选择在哪里应用它,有一些通用建议:

  • 低成本迭代 - 修改你用于爬山优化的目标层面应当是低成本的(在时间、成本和精力方面)。许多内部项目和客户都将爬山优化聚焦于文本,例如提示词和技能。这些内容易于修改和回滚。相比之下,在爬山优化过程中对智能体框架进行开放式修改可能涉及大量代码变更。
  • 可归因性 - 评估分数的变化应当可归因于你在爬山优化过程中所修改的层面。例如,若干成功的爬山优化应用都聚焦于技能触发。评估指标(技能的触发率)与被修改的技能描述直接耦合。
  • 范围明确的目标 - 一种常见的失败模式是提出开放式的性能改进请求,而未仔细考虑评估中可用的提升空间;接近饱和的评估或范围界定不清的层面(例如,开放式地要求更新框架)更有可能陷入停滞。在各种项目中,一个普遍有效的目标是成本:即使评估已经饱和,你也可以要求 Claude 在保持性能持平的同时寻找降低成本的方法。

过拟合

即使是精心设计的评估,也很少能完全匹配你在生产环境中真正关心的任务分布。因此,对评估的“过拟合”是一个常见问题,会导致系统在评估上的表现优于在生产流量上的表现。

评估有多种方式可能“泄漏”到你的框架中(即模型周围的代码,包括提示词、工具以及调用 Claude 的循环)。例如,假设某个评估任务能从 OCR 中获益,但 OCR 在你的生产任务中很少有用。评估框架可能会向你的应用添加一个 OCR 工具,从而提升基准测试成绩,但对生产没有任何影响。更广泛地说,爬山优化可能会向该框架添加一些特性,以应对你所选定的特定评估示例中的边缘情况。这些框架新增内容会提高你的评估分数,但不会转化为生产环境的改进(图 5)。

The benchmark’s traits on the left, each shaping a matching addition to the harness on the right: a task mix that needs OCR adds an OCR tool, tasks in /app add “always cd /app, run pytest”, distinctive phrasings get a tuned prompt, and failures you’ve read get one patch each. A dashed arrow marks the outright leak: a public repo with answers lets the harness curl the reference solution.
图 5框架过拟合的常见原因。

有三件事可以帮助解决这个问题:

  • 拆分用例。使用一个爬山优化器可以读取的训练集,以及一个从未见过的测试集。如果训练集分数提高而测试集分数持平,那么这就是一个常见的过拟合警示信号。
  • 切勿将失败案例粘贴到提示词中。如果爬山优化器读取了失败的记录,它绝不应将失败内容粘贴到提示词中。
  • 在结构上让答案处于模型无法触及的范围。模型有时会通过直接找到评估答案来进行“奖励黑客”。

如下所述,claude-api 技能会为你应用这些原则。

/CLAUDE-API HILLCLIMB

claude-api 技能中的 hillclimb 命令将这些原则转化为一个引导式工作流。当你在 Claude Code 中运行 /claude-api hillclimb 时,Claude 会针对给定的评估进行迭代改进。你可以选择它能够做出哪些更改,包括:

  • 你的系统提示词
  • 技能或指令文件
  • 工具描述
  • 模型选择、努力程度以及其他 API 参数
  • 你的框架代码

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

在第一轮之前,Claude 会检查评估的噪声(仅凭偶然因素分数能波动的幅度)是否小于你会采取行动的最小改进幅度;如果不是,它会说明这一点,并建议增加重复次数或测试用例。

每一轮,Claude 都会阅读上一轮训练集的记录,并作为补丁提出一项更改。它每轮的目标是做出一种效果能超出评估噪声的更改:它从根源上修复失败行为(例如重写导致问题的部分,或添加缺失的规则),而不是改写某一行。然后它运行带有该补丁更改的评估。此时,Claude 会执行一项检查:如果 train 集有所改善,但 test 集持平,Claude 会怀疑过拟合,并回退该补丁。如果出现退化,Claude 会回退。如果训练集和测试集都有改善,它会保留该补丁(图 6)。

The hillclimbing loop: the thing being edited, such as a prompt, feeds a fixed model and harness that is scored on a held-out test split and a train split. An analyzer reads only the train failures and proposes one diff per round; the diff is kept when train and test both rise, and reverted when only train rises or either score drops.
图 6爬山器所使用的过程。

当分数连续两到三轮停滞时,Claude 会阅读每个剩余的失败训练用例,并按原因分类。如果没有任何单一修复能带来超过评估噪声的收益,它也会提前这样做,并建议增加重复次数或测试用例,而不是把轮次花在太小而无法衡量的更改上。这一步可以捕捉到模糊的评估用例、测试框架错误或运行间差异。

只有合理的失败才会被纳入更多的爬山轮次。

当爬山完成后,Claude 会将你的代码保留在针对你的目标在测试集上表现最好的版本。它会报告相对于基线的测试结果,并给出置信区间(图 7)。如果收益在噪声范围内,它会说明这一点,并建议不要合并。

The inbox-routing results page after hillclimbing, comparing three variants on train and test scores. Variant v1, which defines each queue and adds a tie-break rule, is marked best at 0.875 on both; v2, which adds two worked examples, was reverted because train went up while test stayed flat.
图 7爬山后生成的报告示意图。

示例

用于降低成本的爬山

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

爬山首先审查了提示,移除了强制性的工具调用仪式、一个草稿步骤以及相互矛盾的规则。然后它尝试了低努力程度的 Opus 5.5。这以 87.8% 的成绩越过了基线准确率门槛,并将成本降至每个工单 1.9 美分,不到起始成本的一半。

其中一部分节省来自 Opus 5.5 的定价:输入和输出 token 的成本比 Opus 4.8 低 20%,缓存读取成本低 60%。由于 Opus 5.5 越过了门槛,爬山随后降低一个层级,检查更便宜的模型是否也能越过门槛。低努力程度的 Sonnet 5 得分大致相同,为 88.9%,成本约为一半,每个工单 1 美分(图 8)。

客户支持基准

所采用路径上的四种配置

图 8以成本为重点的爬山。

最后,Claude 通过路由规则和退款上限交叉引用改进了提示词,使 Sonnet 5 在成本大致相同的情况下达到 98.9%。在搜索从未见过的 14 张留出工单上,最终配置得分为 90.5%,而原始设置仅为 78.6%,成本约为其五分之一。

通过爬山法提升性能

另一个例子是我们的 claude-api 技能,它提供了使用我们 API 的指导以及与 Claude 协作的通用技巧(包括本文讨论的子命令)。我们希望确保我们的技能能够正确实现使用我们 API 的代码,并基于我们的文档构建了一个评估集来测试该技能。

在我们的评估中,该技能初始得分为 66%。我们让爬山器访问文档和我们的 SDK,使 Claude 能够识别错误并自行纠正(图 9)。Claude 发现该技能缺少对八项功能的覆盖。

在技能中为它们添加章节后,性能提升至 74%。随后它又发现了 C# 和 Java 类型表中的错误,将性能提升至 77%。

claude-api 技能评估

分三个阶段从 66.1% 提升至 87.9%

图 9以性能为重点的爬山法。

在得分连续两轮停滞之后,Claude 分析了剩余的失败案例,并按根本原因对它们进行了分类。普通轮次会针对最常见的失败做一次编辑。而这一步不做任何编辑;它只是按原因对每一个剩余失败进行排序。这一反思步骤在几个方面都很有用:

  • 通过反思一组失败案例,爬山器发现技能内容虽然存在,但 Claude 只是在编写较旧的 API 形式(例如,来自其训练先验)。为解决这个问题,爬山器在技能顶部附近添加了一个表格,引导 Claude 从它记住的形式转向当前形式:例如,从使用固定 token 预算的扩展思考(API 现在在最近的 Opus 模型上已拒绝这种方式)转向自适应思考,以及从旧版本的网页搜索和网页抓取工具转向当前版本。它还将针对固定预算思考的 C# 和 Java 警告移到了各自的自适应思考示例之上。这将性能提升至 80%。
  • 那些尽管填补了明显的内容空白却始终没有提升性能的任务,表明示例或评分器存在缺陷。有一个任务要求编写捕获一种错误类型的代码,而它的评分器却想要至少三种的链条。Claude 重新表述了该任务。另一个评分器的说明与我们的文档相矛盾,而测试真实 API 表明文档是正确的。解决这些问题,再加上更多的技能编辑,将性能提升至约 88%。

开始使用

注意:先运行 claude update。claude-api 技能随 Claude Code 一起提供,因此更新即可获得这些命令的最新版本。

代码Shell

claude update

然后,在 Claude Code 中:

提示词

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

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

如果你想为特定问题生成评估集,请运行 /claude-api build-eval。你可以通过提供对示例(例如,追踪记录)的访问来引导它。Claude 将运用本文中分享的指导来设计示例和评分器,并确保你批准这些示例和评分器。

如果你有评估集,并希望 Claude 在你的目标指导下对此进行改进(例如更好的性能,或在保持性能的同时降低成本),请运行 /claude-api hillclimb。Claude 将采用本文中分享的指导,在爬坡过程中检查过拟合,并检查评估本身的错误,例如将看起来正确的答案标记为错误的评分器或测试框架错误,这些检查既在第一轮之前进行,也在分数停滞时进行。

特别感谢 Misha Khalman 在技能开发方面的贡献。感谢 Misha Khalman、Michael Segner、Matt Bell、Matt Thanabalan 和 Punit Shah 的审阅、贡献和产品支持。

来源:Claude.dev 开发者博客 · claude.dev