让 Claude 帮你建 eval、调 prompt,怎么不被分数骗
Anthropic 给 claude-api skill 加了 build-eval 和 hillclimb 两条命令:一条帮你出题打分,一条每轮只改一处、拿留出的题抓过拟合。客服案例里成本降到原来的五分之一,skill 自己从 66% 调到约 88%。
做 AI 应用的人迟早会碰到两件事:怎么知道它做得好不好,以及怎么让它变得更好。前一件靠 eval(评测,一批固定的题加一个打分办法),后一件靠 hillclimb(爬山,字面意思是每次改一点、看分数涨没涨、涨了就留下)。听起来简单,难在两头都很容易自己骗自己:题出得不对,分数就没意义;改得太贴着这批题,分数涨了线上却没变好。
Anthropic 的 Lance Martin 写了一篇长文,把这两件事的原则讲了一遍,然后说明 Claude Code 里的 claude-api skill 新增的两条命令怎么把这些原则变成流程:/claude-api build-eval 在你的代码库里建一套评测,/claude-api hillclimb 拿这套评测去改进你的应用,每次只改一处,还留一批从不给它看的题来抓过拟合。文章最后用两个实际案例收尾:一个把客服场景的成本压到原来的五分之一,一个把 claude-api skill 自己从 66% 调到约 88%。
下面按文章的顺序讲:先是好 eval 的样子,再是 build-eval 怎么建,然后是 hillclimb 怎么爬又怎么防过拟合,最后看两个案例。
一套好 eval 长什么样
文章给了四个特征(图 1)。
题要像生产环境里的题。 有人挑题是因为好生成、好打分,结果题目分布和真实用户遇到的完全不是一回事。评测要测的是你在乎的那类任务。
模型越强、想得越多,分数应该越高。 换更强的模型、把 effort(推理投入档位)调高,分数理应上升。如果不升,多半是题目有歧义,或者打分的 grader 校准得不对,把成绩拖住了。
最强模型也得留出空隙。 最强模型在最高 effort 下应该明显低于 100%,否则你改了什么都看不出差别。而且这个空隙不能是「不可能的题」造成的:一个常见的信号是,某道题不管重复跑多少次都全军覆没。好题的标准是,两个领域专家看了会给出同一个结论,而且 grader 检查的每一点,题目里都写明了。
每次跑的结果波动要小。 波动大,往往是题有歧义,或者 grader 对同一份输出前后判得不一样。波动也可能藏在配置里,比如 effort 其实没有被一致地应用;还有环境的影响,上一轮遗留的文件、git 历史,可能把答案直接递给了 Agent。
别只挑「今天的模型做不好」的题
文章专门警告了一种很自然的做法:把当前模型答错的题收集起来当评测。模型的能力是参差的,有的地方很强,有的地方莫名其妙地弱。你专挑它今天的弱点,量到的只是这个模型的「失败指纹」,而不是你的应用里真正难、真正有价值的部分。等下一代模型出来,这些谷底可能被整体抬平,你的评测就失去了意义(图 2)。
更好的做法是让人来判断哪些题难,并且能说出它为什么难,说不出就先别放进去。另外要放进从生产流量、bug 报告和工单里来的具体失败。但也不要只信用户流量:用户往往只会试他们预期能成的事,所以纯从流量里抽的题可能偏简单。图 2 右侧还画了一类「不应触发」的用例,也就是该不动作的场景,同样要有。
/claude-api build-eval:让 Claude 采访你,然后把评测建好
在 Claude Code 里运行这条命令,Claude 会先采访你,然后在你的代码库里把评测建出来,并且在几个关键点停下来等你批准。
先定题目:谁的数据优先
Claude 帮你找输入的顺序是这样的:
- 生产环境的对话记录,先问清楚数据保留和敏感信息的规矩;
- bug 报告和客服工单;
- 你自己手写的 5 到 10 条;
- 从代码库里合成的用例。
生产数据优先,但没有的话,它也能在你给的几个真实例子的基础上合成数据。建好之后,它会生成一个简单的页面,把每一条输入摊开给你看,等你确认。文章拿一个邮件路由应用当例子:24 封客户邮件,每封带标签,比如「账单、简单」「账单、有歧义」,Claude 在聊天里问你:这些能代表你的应用实际遇到的输入吗?有没有明显缺的,或者根本没必要放的?(图 3)
再定打分:先看能不能用代码,不行再请评委
输入定了,接着是 grader。Claude 会提议「够用的最便宜的那种」:
- 程序校验:输出范围有限时用代码判,比如完全匹配、从固定标签里选一个、JSON 符合某个格式、测试通过。
- LLM 当评委(LLM-as-judge):输出是开放式的,有很多种正确答案但质量标准明确时,默认用这种。评委是另一个模型,它读输入、输出和一份评分标准,返回分数和理由。评分标准要写成一条条可检查的陈述,而不是「1 到 5 分」这种量表。如果你手里有个基线可对比,评委就同时读两份输出,顺序随机,也不告诉它哪份是基线,让它选更好的。评委模型由你选,但不应该就是被测的那个模型。
Claude 会拿几条用例先打分,问你:有没有哪条你会打得不一样?文章特别强调,在相信一个评分器之前,一定要读一些打过分的记录,评分出错是评测配置失误里最常见的一种。
跑基线,得到什么
grader 验证过之后,skill 会告诉你评测集的规模(用例数 × 重复次数 × 模型,以及大约要跑多久),跑出基线,并给出带置信区间的分数。你拿到的东西是:用例、grader、运行器,每个用例一行 JSON 和一份完整的对话记录,还有一个朴素的页面,列出每个用例的分数并链接到它的记录(图 4)。想要图表之类更多的东西,直接跟 Claude 说,它会在旁边另建一个页面;默认这些附加页面都是静态文件,本地打开,不联网。
基线阶段的三项体检
跑基线的同时,Claude 会顺手检查三件事:
- grader:对同一份输出评两次,看结论会不会变。
- 管道:有没有超时、API 报错、答案被截断,避免把基础设施的噪声当成模型的波动。
- 空间:基线如果已经在 95% 上下或更高,skill 会警告你,此时爬山的目标应该改成成本或延迟,而不是质量。
爬山:什么值得爬,怎么不爬歪
有了一个可靠的评分办法,就可以拿它来改进应用了。爬山特别适合调整那些在成本和效果之间做权衡的参数,比如 effort、提示词。文章给了三条选靶子的经验:
改起来便宜。 在时间、花费和精力上都便宜,改错了还能撤回。很多内部项目和客户把爬山对象放在文本上,比如 prompt 和 skill,好改好撤。相反,让它在爬山过程中随意改 Agent 的 harness(模型外面那层代码:提示词、工具、调用循环)代码,可能牵扯大量代码修改。
分数变化能归因。 分数的涨跌应该确实来自你在改的那个东西。文章举的例子是 skill 触发:好几个成功的爬山项目就盯着「skill 什么时候被触发」,评测指标(触发率)直接挂在被修改的 skill 描述上。
目标要划清。 一种常见的失败,是笼统地说「帮我提升性能」,而没有想过评测本身还有多少空间。评测已经接近饱和,或者改动范围太散(比如笼统地让它去改 harness),更容易原地打转。文章说,在各种项目里表现稳定的一个目标是成本:就算评测已经饱和,你也可以让 Claude 在保持分数不掉的前提下想办法降成本。
过拟合:评测是怎么泄漏进 harness 的
再好的评测也很少和你线上真正的任务分布完全一样,所以「过拟合」很常见:系统在评测上变好,在生产流量上没有。
文章的例子是:某个评测里有些任务用 OCR(文字识别)能做得更好,但你线上的任务基本用不上 OCR。评测里的 harness 于是给应用加了个 OCR 工具,分数上去了,对线上毫无帮助。更一般地说,爬山会往 harness 里加一些专门处理你评测例子里边角情况的功能,这些加进去的东西提高评测分,却带不到生产环境(图 5)。
图上的五行,前四行是渐进的贴合:任务需要 OCR 就加工具;任务都在 /app 目录就写死 cd /app 再跑 pytest;措辞独特就把 prompt 调成贴着这些措辞;失败看多了,就一个失败打一个补丁。最后一行是最直接的泄漏:题目来自公开仓库、仓库里有答案,那 harness 就学会了直接 curl 参考解答。
三道防线
- 切分用例。 一部分是 train(训练集,爬山器可以读),另一部分是 test(测试集,从不给它看)。如果 train 分数涨了而 test 不动,那是过拟合最常见的警告信号。
- 绝不把失败内容贴进 prompt。 爬山器读了失败的对话记录,也不能把失败的内容原样贴到提示词里。这正是图 5 第四行「一个失败打一个补丁」的做法:补丁越贴着那几条具体失败,越像是把评测题抄进了 prompt,分数涨的是这批题,不是能力。
- 答案在结构上让模型拿不到。 模型有时会 reward hack(钻评测空子),直接把答案找出来。所以要让答案从结构上就在它够不着的地方。
/claude-api hillclimb:一轮一个改动,一直盯着 test
这条命令的入口是:你有一套评测,想让 Claude 沿着你的目标改进。你可以选 Claude 允许改什么:
- 你的系统提示词;
- skill 或指令文件;
- 工具描述;
- 模型选择、effort 档位和其他 API 参数;
- 你的 harness 代码。
开始之前,Claude 会问你想优化什么(比如性能,或者「性能不掉的前提下压成本」),然后把评测集随机分成 test 和 train。如果目标是成本,它会考虑几个常见的成本来源,包括提示词缓存、检查 prompt 和所选模型是否兼容、以及选模型和 effort 档位。
第一轮之前,它先检查评测的噪声(分数纯靠运气能晃多远)是不是小于你愿意采取行动的最小提升。噪声是拿基线重复跑 N 次量出来的:同一个版本跑几遍,分数本来就会晃,晃的幅度就是「噪声底」,之后任何改动的提升,得高出这个底才算数(图 6 里标的「pre-flight」就是这一步)。如果噪声比你要的提升还大,它会直说,并建议加重复次数或加用例。
每一轮怎么走
每一轮,Claude 读上一轮 train 的对话记录,提一个改动,以补丁的形式提出。它的目标是这个改动的效果能在评测噪声之上显出来:所以要从根上修那个失败的行为(改写引起它的段落,或者补一条缺的规则),而不是换个说法改一行。然后拿补丁后的版本跑评测。
这时候有个检查:如果 train 涨了而 test 没动,Claude 就怀疑是过拟合,把补丁回退;如果有退步,回退;train 和 test 都涨,才保留(图 6)。
停滞了怎么办
分数连续两三轮没变,Claude 会去读剩下的每一个 train 失败,按原因分类。如果发现没有哪个单独的修复能超过评测的噪声,它也会提前这么做,并建议加重复或加用例,而不是把轮数浪费在小到测不出来的改动上。这一步能抓到有歧义的用例、harness 错误和不同次运行之间的波动。只有真正的失败才会被放进后续的爬山轮次。
结束时你拿到什么
爬山结束,Claude 把你的代码留在「对你的目标而言 test 上表现最好」的那个版本,并给出 test 结果与基线的对比,带置信区间(图 7)。如果提升在噪声范围之内,它会明说,并建议不要合并。
两个实际案例
案例一:降成本,同时提准确率
Anthropic 在一个内部客服基准上跑了 /claude-api hillclimb,目标是降成本,同时提升表现。基准共 44 张工单,30 张用来搜索,14 张留出。起点是 Opus 4.8,默认(高)effort,在搜索集上的决策准确率 74.4%,每张工单的 token 成本 4.6 美分。
爬山先审了一遍提示词,删掉了强制的工具调用「仪式」、一个草稿步骤,以及互相矛盾的规则。接着试了 Opus 5.5 的低 effort:准确率 87.8%,超过了基线,成本降到 1.9 美分,不到起点的一半。
这里面有一部分节省来自 Opus 5.5 的定价:输入和输出 token 比 Opus 4.8 便宜 20%,缓存读取便宜 60%。因为 Opus 5.5 过了线,爬山接着往下降一档,看更便宜的模型行不行:Sonnet 5 低 effort 得分差不多,88.9%,成本约一半,1 美分左右(图 8)。
最后,Claude 改进了提示词,加了路由规则和一条退款上限的交叉引用,让 Sonnet 5 提到 98.9%,成本基本不变。在从未参与搜索的 14 张留出工单上,最终配置得分 90.5%,原配置是 78.6%,而成本是原来的五分之一左右。
值得注意的是:图 8 和前面几个数字(74.4%、87.8%、88.9%、98.9%)都是在 30 张搜索工单上读的;对外可以拿来说话的,是留出集上的 90.5% 对 78.6%。留出集只有 14 张,这个差距有多稳,文章没有给置信区间。
案例二:提升 claude-api skill 自己
第二个例子是 claude-api skill 本身。它负责指导如何使用 Anthropic 的 API 和 Claude 的通用技巧(包括本文讲的这两条子命令)。团队想确认这个 skill 能写出正确调用 API 的代码,于是基于官方文档做了一套评测。
起点是 66%。他们给爬山器开了文档和 SDK 的访问权限,让 Claude 自己找错并纠正(图 9)。Claude 发现 skill 缺了八项功能的说明,补上后升到 74%;接着找到 C# 和 Java 类型表里的错误,改完到 77%。
这一路一共跑了 24 轮。中间分数停滞两轮后,Claude 把剩下的失败按根因分类。这一步很特别:普通的一轮是针对最常见的失败改一处,而这一步不改任何东西,只把所有剩下的失败按原因分类。这个「反思」步骤有几处价值:
发现 skill 里内容明明有,但 Claude 写的仍是老的 API 写法。 这是从训练时学到的先验里冒出来的。爬山器于是在 skill 靠前的位置加了一张对照表,把 Claude 记得的旧写法引到现在的写法:比如固定 token 预算的 extended thinking(扩展思考),现在的新 Opus 模型 API 已经拒收,要换成 adaptive thinking(自适应思考);旧版的 web search 和 web fetch 工具,要换成当前版本。它还把 C# 和 Java 里「不要用固定预算思考」的警告,挪到了自适应思考示例的前面。分数升到 80%。
有些任务怎么都不涨,是评测本身有毛病的信号。 补过明显的内容缺口还是不涨的任务,往往说明题目或 grader 有问题。一道题要求写一段捕获某一种错误的代码,而 grader 却要求至少三层的错误链;Claude 把题目改了。另一个 grader 的说明和文档矛盾,用真实 API 一测,是文档对,grader 错。处理完这些,再加上更多 skill 改动,分数到了约 88%。
怎么用
文章最后给的入口很直白:
- 想为某个问题生成一套评测:运行
/claude-api build-eval。你可以给它样本(比如运行记录)来引导它。它会按文中的原则设计用例和 grader,并保证用例和 grader 都要你批准。 - 已经有评测、想让 Claude 沿着你的目标改进:运行
/claude-api hillclimb,目标可以是提升表现,或者表现不掉的前提下压成本。它会在爬的过程中查过拟合,并在第一轮之前和分数停滞时,检查评测本身的毛病,比如把看起来正确的答案判错的 grader,或者 harness 错误。
Automating eval design and hillclimbing with Claude
Principles for designing evals and hillclimbing against them without fooling yourself, and how the claude-api skill's build-eval and hillclimb commands put them to work.
Evaluations provide a signal on how your app or skill is performing on specific tasks. But designing evaluations, and improving performance on them without fooling yourself, is hard. We've added guidance for both to the claude-api skill.
With the skill, you can run /claude-api build-eval to build an evaluation inside your codebase, and run /claude-api hillclimb to improve your application against it, one change at a time, with a held-out set of examples to catch overfitting.
In this article, we highlight the principles of good eval design and hillclimbing first, then show how Claude Code with the claude-api skill applies those principles. We’ll close by showing a few examples of these commands.
EVAL DESIGN
Well designed evaluations have a few common elements (Figure 1):
- Eval tasks mirror production. Sample tasks that you care about in “production,” or the setting in which the capability or application you are testing will be used. Sometimes tasks are picked because they are easy to generate or they are easy to grade. But it’s important to ensure that the task distribution represents what you actually care about.
- Performance improves with stronger models and more thinking. More capable models and higher effort levels typically should perform better on an evaluation. If they don’t, ambiguous tasks or a miscalibrated grader often are hobbling performance.
- There is “passable” headroom at the frontier. The most capable model at the highest effort should be well below 100% on the evaluation, otherwise you can’t reliably judge how changes impact performance. Importantly, the gap should not be explained by impossible or ambiguous tasks: a common tell is that a task fails every evaluation run, regardless of the number of replicates. A good task is one where two domain experts would reach the same verdict and everything the grader checks is stated in the task.
- Low run-to-run variance. High variance is often due to poorly designed, ambiguous tasks or a grader that produces different verdicts on identical output. Variance can also hide in the configuration. For example, effort may not be applied consistently. Also, the environment can affect the results of the evaluation: leftover state from an earlier trial (a file, a git history) can hand the agent the answer.
FIG 1The four elements of a good eval
Adversarial sampling
Model capability is jagged. If you pick cases because today's model fails them, you are sampling the valleys of one model's capability surface (Figure 2). The evaluation can end up measuring that model's failure fingerprint rather than what is intrinsically hard or valuable for your application to do.

Pick hard cases because a human judged them hard: a useful test is to be able to say why a task is hard before you include it. Include cases that are specific failures in your application derived from production traffic, bug reports, or tickets. However, don’t blindly trust user traffic: users sometimes try what they expect to work, so a task distribution drawn strictly from user traffic may skew easy.
/CLAUDE-API BUILD-EVAL
The build-eval command in the claude-api skill turns these principles into a guided workflow. When you run /claude-api build-eval in Claude Code, Claude interviews you, builds the eval inside your codebase, and pauses for approval at specific points.
Designing examples
Claude helps you sample inputs to build evaluations in this order:
- Production transcripts, after asking about retention and sensitive data.
- Bug reports and support tickets.
- Five to ten cases you write by hand.
- Cases synthesized from your codebase.
The skill prioritizes production traffic, but it can also generate synthetic data anchored in a few real examples that you provide. The skill instructs Claude to generate a simple page that shows you every input and waits until you confirm them. As an illustration, below we show an example set of inputs for an e-mail router application that the skill may ask the user to review (Figure 3).

Validating the grader
After the inputs, Claude proposes the cheapest grader that fits your application’s output:
- Programmatic verification: If the output possibilities are constrained, it uses a code based check (exact match, a label from a fixed set, JSON that matches a schema, tests that pass).
- LLM-as-judge: It will default to this type of check if the output space is open-ended, with many valid answers but clear quality criteria. In this case, a second model reads the input, the output and a rubric written as checkable claims (not a 1-to-5 scale), and returns a score with its reasoning. If you have a baseline to compare against, the judge instead reads both inputs in random order, without being told which is the baseline, and picks the better one. You pick the judge model, and it should not be the model you are testing.
Claude grades a handful of cases and asks whether you would have scored any of them differently (Figure 4). In general, it is important to read a sample of scored transcripts before believing your evaluator; scoring failures are among the most common ways an evaluation is misconfigured.
When you’ve validated the grader, the skill tells you the size of the evaluation set (cases × repeats × model, and roughly how long it will take), runs the baseline, and prints the score with a confidence interval. What you get back: the cases, the grader, the runner, one JSON line and one full transcript per case, and a plain page that lists each case's score with a link to its transcript. If you want more than that page shows (e.g., a chart), just ask and Claude will build it as an extra page next to it. By default, these extra pages are static files that open locally and load nothing from the network.

Diagnostic checks
During the baseline runs mentioned above, Claude checks a number of things:
- Grader: Claude runs the grader twice on the same output, and reports whether the verdict changed.
- Plumbing: Claude checks for timeouts, API errors, and cut-off answers to ensure infrastructure noise doesn't pass as model variance.
- Headroom: if the baseline already scores about 95% or higher, the skill warns the user and alerts that the hillclimb should aim to explore cost or latency rather than quality.
HILLCLIMBING
Now that you have a reliable means of grading your application’s performance on a task, you can try to improve it. Hillclimbing is an effective way to tune parameters like effort or prompts, which trade-off cost and performance. Some general tips for choosing where to apply it:
- Cheap iteration - It should be inexpensive (in terms of time, cost, and effort) to modify whatever surface you are focused on for hillclimbing. Many internal efforts and customers have focused hillclimbing on text, such as prompts and skills. These are easy to change and revert. In contrast, open-ended modifications to an agent harness during hillclimbing may involve extensive code changes.
- Attributable - Changes in the score on your evaluation should be attributable to the surface you are modifying during hillclimbing. For example, several successful applications of hillclimbing have focused on skill triggering. The evaluation metric (the trigger rate for the skill) is directly coupled to the skill description that is being modified.
- Well-scoped objective - One common failure mode is an open-ended request to improve performance without careful consideration of the headroom available in the evaluation; an evaluation that’s near saturation or a poorly scoped surface (e.g., an open-ended request to update the harness) is more likely to stall. One generally strong objective across various efforts is cost: even if an evaluation is saturated, you can ask Claude to find ways to reduce cost while keeping performance at parity.
Overfitting
Even a well-designed evaluation rarely matches the exact task distribution you care about in production. As a result, "overfitting" to an evaluation is a common problem and results in a system that performs better on an evaluation than on production traffic.
There are many ways an evaluation can "leak" into your harness (the code around the model, including prompts, tools, and loop that calls Claude). For example, consider an evaluation task that benefits from OCR, but OCR is rarely beneficial in your production tasks. The evaluation harness might add an OCR tool to your application, which improves on the benchmark without any impact on production. More broadly, hillclimbing may add features to that harness that address edge cases in the particular evaluation examples you’ve chosen. These harness additions improve your evaluation score, but don’t translate to improvements in production (Figure 5).

Three things can help address this:
- Split the cases. Use a train set that the hillclimber may read and a test set that is never seen. If the train set scores improve while the test set scores stay flat, then that is a common overfitting warning sign.
- Never paste failures into the prompt. If the hillclimber reads the failing transcripts, it should never paste the failure content into the prompt.
- Keep the answers structurally out of the model's reach. Models can sometimes “reward hack” by directly finding answers to evaluations.
As discussed below, the claude-api skill applies these principles for you.
/CLAUDE-API HILLCLIMB
The hillclimb command in the claude-api skill turns these principles into a guided workflow. When you run /claude-api hillclimb in Claude Code, Claude iterates to improve against a given evaluation. You choose what changes it can make including:
- Your system prompt
- Skills or instruction files
- Tool descriptions
- Model choice, effort level, and other API parameters
- Your harness code
Before it starts, Claude asks what you want to optimize (e.g., performance, or cost while performance holds) and then splits the evaluation set at random into test and train. With a cost goal, it considers a few common cost drivers, including prompt caching, auditing the prompt for compatibility with the selected model, and picking the model and effort setting.
Before the first round, Claude checks that the eval's noise (how far the score can move by chance alone) is smaller than the smallest improvement you'd act on; if it isn't, it says so and suggests more repetitions or cases.
Each round, Claude reads the previous round’s train transcripts and proposes one change as a patch. It aims each round at a change whose effect can show above the eval's noise: it fixes the failing behavior at its root (e.g., rewrites the section that causes it or adds a missing rule) rather than rewording a line. It then runs evaluation with the patched change. At this point, Claude applies a check: if the train set improves but the test set is flat, Claude suspects overfitting and reverts the patch. If there is a regression, Claude reverts. If train and test sets improve, it keeps the patch (Figure 6).

When the score stalls for two or three rounds, Claude reads each remaining train failure and sorts it by cause. It does the same early if no single fix could gain more than the eval's noise, and suggests more repetitions or cases, rather than spending rounds on changes too small to measure. This step can catch ambiguous evaluation cases, harness errors, or run-to-run variance.
Only legitimate failures are included in more hillclimbing rounds.
When hillclimbing completes, Claude leaves your code at the version that did best on the test set for your goal. It reports the test result against the baseline with confidence intervals (Figure 7). If the gain is within noise, it says so and recommends against merging.

EXAMPLES
Hillclimbing for cost reduction
We ran /claude-api hillclimb on an internal customer support benchmark with the goal of reducing cost and improving performance. The benchmark included 44 tickets, with 30 used for the search and 14 held out. It started on Opus 4.8 at default (high) effort settings with 74.4% decision accuracy on the search tickets and a token cost of 4.6 cents per ticket.
The hillclimb first audited the prompt, removing mandatory tool-call rituals, a scratchpad step, and contradictory rules. Then it tried Opus 5.5 on low effort. This cleared the baseline accuracy bar at 87.8% and cut cost to 1.9 cents per ticket, less than half the starting cost.
Part of that saving comes from Opus 5.5's pricing: input and output tokens cost 20% less than on Opus 4.8, and cache reads cost 60% less. Because Opus 5.5 cleared the bar, the hillclimb then stepped down a tier to check whether a cheaper model could clear it too. Sonnet 5 on low effort scored about the same, 88.9%, at about half the cost, 1 cent per ticket (Figure 8).
FIG 8Cost-focused hillclimbing.
Finally, Claude improved the prompt with routing rules and a refund-cap cross-reference, bringing Sonnet 5 to 98.9% at about the same cost. On the 14 held-out tickets that the search never saw, the final configuration scored 90.5% against the original setup's 78.6%, at about one fifth of the cost.
Hillclimbing for performance improvement
Another example is our claude-api skill, which provides guidance on using our APIs and general tips for working with Claude (including the sub-commands discussed in this article). We want to ensure our skill can correctly implement code that uses our APIs, and we built an evaluation set derived from our documentation to test the skill.
On our evaluation, the skill started at 66%. We gave the hillclimber access to documentation and our SDKs, allowing Claude to identify errors and self-correct them (Figure 9). Claude found that the skill was missing coverage of eight features.
Adding sections for them in the skill improved performance to 74%. It then found errors in C# and Java type tables, boosting performance to 77%.
FIG 9Performance-focused hillclimbing.
After the score stalled for two rounds, Claude analyzed the remaining failures and bucketed them by root-cause. A normal round makes one edit for the most common failure. This step makes no edit; it only sorts every remaining failure by cause. This reflection step was useful in a few ways:
- Reflecting across a collection of failures, the hillclimber found that the skill content was present but Claude was simply writing older API shapes (e.g., from its trained priors). To address, the hillclimber added a table near the top of the skill that guided Claude from the forms it remembered to the current ones: for example, from extended thinking with a fixed token budget, which the API now rejects on recent Opus models, to adaptive thinking, and from older versions of the web search and web fetch tools to the current ones. It also moved the C# and Java warnings against fixed-budget thinking above their adaptive-thinking examples. This improved performance to 80%.
- Tasks that never improved in performance despite addressing obvious content gaps are tells that the example or grader is flawed. One task asked for code that catches one error type, while its grader wanted a chain of at least three. Claude reworded the task. Another grader's instructions contradicted our docs, and testing the real API showed the docs were right. Addressing these, along with more skill edits, brought performance to ~88%.
GETTING STARTED
Note: Run claude update first. The claude-api skill ships inside Claude Code, so updating gets you the latest version of these commands.
CODEShell
claude updateThen, in Claude Code:
PROMPT
/claude-api build-eval
/claude-api hillclimbThese sub-commands can be used directly in Claude Code via the claude-api skill:
Run /claude-api build-eval if you want to generate an evaluation set for a particular problem. You can steer it by providing access to examples (e.g., traces). Claude will employ the guidance shared in this article to design the examples and grader, and ensure you approve the examples and the grader.
Run /claude-api hillclimb if you have an evaluation and want Claude to improve on this, guided by your goal (e.g., better performance, or lower cost while performance holds). Claude will employ the guidance shared in this article to check for overfitting while climbing and check for bugs in the eval itself, such as a grader that marks a correct-looking answer wrong or a harness error, both before the first round and whenever the score stalls.
With special thanks to Misha Khalman for skill development. With thanks to Misha Khalman, Michael Segner, Matt Bell, Matt Thanabalan, and Punit Shah for reviews, contributions, and product support.
