0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

PR: NECイノベーションコミュニティ
技術で挑む価値づくり

Claude で eval の設計と「どう改善を重ねるか」を自動化する `/claude-api build-eval` と `hillclimb` とは?「自分をだまさない」改善ループの原則

0
Last updated at Posted at 2026-10-14

グラレコ

eval の設計と、どう改善を重ねるかの要点をまとめたグラレコ

上のグラレコは、この記事で扱う内容を1枚にまとめたものです。よい eval の4条件、build-eval の流れ、採点方法の選び方、hillclimb のループ、過学習対策、停滞したときの分類までを並べています。本文で1つずつ見ていくので、まずは全体の地図としてご覧ください 🗺️

はじめに

Anthropic の claude.dev ブログに、2026年9月28日付で「Automating eval design and hillclimbing with Claude」という記事が公開されました。著者は Lance Martin さんで、Playbooks カテゴリの記事です。

内容は大きく2つに分かれます。1つは、評価(eval)をどう設計するか、そしてその eval に対してどう改善を重ねるか という原則の話です。もう1つは、その原則を Claude Code に組み込んだ claude-api スキルの2つのサブコマンド、/claude-api build-eval と /claude-api hillclimb の紹介です。

記事の副題には「without fooling yourself(自分をだまさずに)」という言葉が入っています。eval のスコアは、少し油断すると「上がったように見えるだけ」の数字になります。この記事のテーマは、その落とし穴を避けながら改善を自動化する方法です 🧭

この記事では、元記事の内容に加えて、Claude Code に同梱されている claude-api スキル本体のガイド(build-eval.md と eval-hillclimb.md)も読み込み、コマンドが実際にどんな手順で動くのかまで整理します。

この記事でわかること 📌

  • よい eval に共通する4つの条件と、「敵対的サンプリング」の落とし穴
  • /claude-api build-eval が入力を集め、採点方法を決め、ベースラインを取るまでの流れ
  • 採点方法(コード判定・LLM ジャッジ・ペア比較)の選び方と、採点そのものの検証方法
  • 改善を重ねるのに向いている対象と、過学習を防ぐ3つの方法
  • /claude-api hillclimb の1ラウンドの中身と、変更を残すか戻すかの判定ルール
  • コスト削減(4.6¢ → 1¢)と性能改善(66% → 88%)の2つの事例

想定読者は、Claude API や Claude Code でアプリ・エージェント・スキルを作っていて、「プロンプトを直したけれど、本当に良くなったのかよくわからない」と感じている開発者の方です。eval をまだ作ったことがない方にも、最初の1本を作る手順として役立つ内容になっています。

全体像:2つのコマンドの役割 🗺️

最初に、2つのコマンドの関係を図にしておきます。以下の図は、eval を作ってから改善を終えるまでの大きな流れを示しています。

ポイントは、物差しを作る工程(build-eval)と、物差しを使って改善する工程(hillclimb)が分かれていることです。hillclimb のガイドには「eval が無いならここで止まり、build-eval に回す」と明記されていて、物差しなしで改善を始めることはありません。

コマンド 入力 出力 主な承認ポイント
/claude-api build-eval 評価したいフロー、本番ログやチケットなどの素材 入力セット、採点器(grader)、実行スクリプト(runner)、ベースラインのスコア、結果ページ 入力セットの承認、採点方法の承認
/claude-api hillclimb 実行できる eval と、最適化したい目標 改善後のコード(test で最良だった版)、信頼区間つきのレポート 改善の計画(変更してよい範囲・止める条件)

どちらも Claude Code の claude-api スキルに含まれています。スキルは Claude Code に同梱されているので、claude update で最新版にすれば使えるようになります(使い方は最後の「始め方」で紹介します)。


第1部:よい eval の4条件 🧪

元記事は、よく設計された eval には共通する要素があるとして、4つの条件を挙げています。

# 条件 意味 うまくいっていないときのサイン
1 本番に似たタスク 実際にその機能が使われる場面(production)から、気にしているタスクをサンプリングする 「作りやすい」「採点しやすい」という理由でタスクを選んでいる
2 強いモデル・高い effort ほど高得点 能力の高いモデルや、effort を上げた設定のほうがスコアが良くなる 強いモデルでも伸びない。タスクが曖昧か、採点がずれている可能性が高い
3 フロンティアに「届きうる余白」がある 最強モデル・最大 effort でも 100% を十分下回っている どのモデルでも、何回繰り返しても必ず失敗するタスクがある
4 実行ごとのばらつきが小さい 同じ設定で何度回しても、スコアがあまり動かない 曖昧なタスク、同じ出力に違う判定を出す採点器、設定の適用漏れ、環境の残りかす

以下の図は、元記事の Figure 1 の考え方を簡略化して描いたものです。モデルの大きさと effort を変えたときに、スコアがどう並ぶのが「健全な eval」なのかを示しています。

上から順に、強いモデルほど高く(条件2)、同じモデルでも effort を上げるほど高く(条件2)、それでも満点との間に余白がある(条件3)、という並びが理想です。元記事の図では、各点の上下のブレが小さいこと(条件4)もあわせて示されています。

「余白」が大事な理由

条件3は見落としやすいのですが、ここがいちばん効いてきます。最強の設定で 100% 近く取れてしまう eval では、何かを変えたときにスコアが上がったのか下がったのかを判断できません。

ただし元記事は、余白が「解けない問題」や「曖昧な問題」で説明できてはいけないとも書いています。わかりやすいサインは、何回繰り返しても毎回失敗するタスクがあることです。元記事は、よいタスクの基準を次のように表現しています。

A good task is one where two domain experts would reach the same verdict and everything the grader checks is stated in the task.

(よいタスクとは、2人の専門家が同じ判定に至り、採点器がチェックすることがすべてタスク内に書かれているものです。)

「採点器がチェックすることは、すべてタスクに書いておく」という一文は、地味ですが実務でよく引っかかるポイントです。採点基準にだけ書いてある隠れた要件があると、モデルはそれを知りようがないので、いくら賢くても失敗します。

ばらつきは「設定」と「環境」にも潜む

条件4のばらつきについて、元記事は原因を3つ挙げています。

  • 曖昧なタスク、または同じ出力に違う判定を出す採点器
  • 設定の不一致:たとえば effort が一貫して適用されていない
  • 環境の残りかす:前の試行で残ったファイルや git の履歴が、エージェントに答えを渡してしまう

3つ目は、コーディングエージェントの eval を作るときに特に注意したい点です(前の試行が書いたファイルを次の試行がそのまま読んで正解してしまう、というのは笑い話ではなく普通に起きます)。

敵対的サンプリングの落とし穴 ⚠️

元記事がわざわざ1節を割いているのが「adversarial sampling(敵対的サンプリング)」です。

モデルの能力は、元記事の言葉を借りると「jagged(ギザギザ)」です。得意な領域と苦手な領域が、でこぼこに入り組んでいます。このとき「今のモデルが失敗するケース」を選んで eval を作ると、そのモデルの能力の谷間だけをサンプリングすることになります。

以下の図は、その流れを示しています。

上の流れ(赤)では、eval が測っているのは「そのモデルの失敗の指紋(failure fingerprint)」であって、アプリにとって本当に難しいことや価値のあることではありません。

元記事の処方箋は、人間が難しいと判断したから選ぶことです。具体的な基準として「含める前に、なぜ難しいのかを説明できること」が挙げられています。そのうえで、本番トラフィック、バグ報告、チケットから得た「自分のアプリ特有の失敗」も含めます。

ただし、ユーザーのトラフィックをそのまま信じすぎるのも危険です。ユーザーは「たぶん動くだろう」と思うことを試すので、トラフィックだけから作ったタスク分布は簡単な方に偏りがちだと元記事は指摘しています。


第2部:/claude-api build-eval で eval を作る 🛠️

ここからは、原則をワークフローにした build-eval の中身を見ていきます。Claude Code で /claude-api build-eval を実行すると、Claude がインタビュー形式で質問し、eval をコードベースの中に組み立て、決められたポイントで承認を待ちます。

スキルのガイドでは、eval を次の3つの組み合わせとして定義しています。

  1. 入力例のセット
  2. 各入力に対してアプリを動かす方法(runner)
  3. 各出力を採点する方法(grader)

ガイドは「特定のフレームワークを押しつけない」とはっきり書いていて、runner は既存のリポジトリの流儀に合わせます。scripts/ に Click の CLI が並んでいるならその1つとして、全部 pytest ならテストとして作る、という方針です。

全体の流れ

以下の図は、スキルのガイドに書かれている build-eval の手順を、承認ゲートとあわせて示したものです。

黄色の2つが、ガイドが「必ず必要」と位置づけている承認(sign-off)です。ガイドには「沈黙ではなく、明確な yes を待つ」と書かれていて、やり取りが何往復にもなった場合は、最終版をもう一度まとめて確認し直すよう指示されています。

それ以外の質問は、Claude が推奨案を先頭に「(Recommended)」付きで並べ、ユーザーはクリックで選べる形になっています。デフォルトを信頼する人はサクサク進められ、こだわりがある人はその箇所だけ上書きできる、というバランスです。

Step 0:評価するものを1つに絞る

ガイドの最初の質問は「何を評価したいのか、どの機能か」です。1つのアプリには、分類器、要約、エージェントループなど評価したいものが10個くらい簡単に出てきますが、ガイドは 1フローにつき1つの eval を原則にしています。「大統一ベンチマーク」は作りません。

このステップでは、Claude がアプリのエントリポイント(ユーザー入力を受けて出力を返す関数やエンドポイント)を読み、使っているモデル、呼び出し先のプロバイダ、システムプロンプト、ツール、出力の形を把握します。データベースや検索インデックスのような外部の状態に依存する場合は、再現できるようにフィクスチャやテスト用インスタンスが必要になる点もここで確認します。

Step 1:入力の集め方には優先順位がある

元記事とスキルのガイドは、入力を次の順番で探すとしています。

優先 入力の出どころ 忠実度 注意点
1 本番のトランスクリプト・ログ 最も高い 保持期間ポリシーや個人情報の扱いを先に確認する
2 バグ報告・サポートチケット 高い 「ここがおかしい」と言われた例は特に価値が高い
3 ユーザーが手で書く5〜10件 中くらい 思いつきやすいものに偏るので、種として扱う
4 コードベースから合成 最も低い 実例3〜5件と「何が難しいか」の説明を先にもらってから合成する

1番目の本番ログについて、ガイドは「今使えるか」だけでなく「使い続けられるか」を確認するよう求めています。保持期間ポリシーで消さなければならないデータや、リポジトリに置けない個人情報を含むデータで eval を作ると、次の四半期にもう一度回せません。その場合の選択肢として、ガイドは3つを挙げています。

  • リポジトリには ID だけ を保存し、実行時に runner が本物の入力を取りにいく
  • ユーザー自身にサンプルを抽出・匿名化してもらう
  • 実際の入力を、形と難しさを保ったまま合成データに書き換える(書き換え後をユーザーに見せる)

4番目の合成について、ガイドは「何もないところから合成しない」と強調しています。実例なしで作った eval は単純すぎるものになりがちで、後から軌道修正するほうがケースを書くよりも手間がかかる、という理由です。

入力は何件くらい必要か 🔢

ガイドの目安は、最初の eval で 15〜100件 です。15件未満だと不安定なケースが1つあるだけでスコアが大きく揺れ、100件を大きく超えるとユーザーが全部に目を通さなくなり、承認の意味が薄れます。

さらに、後で改善を重ねるつもりなら、「検出したい改善幅」から件数を逆算するよう書かれています。合格率のような二値の指標では、ノイズの幅(eval-hillclimb.md の表現では 95% 信頼区間の半幅)はおよそ 1/sqrt(n·reps) です。

ケース数 × 反復回数 信頼区間の半幅(目安) 筆者の補足
25件 × 2回 約 ±14 ポイント 10ポイント程度の改善は誤差に埋もれやすい
50件 × 2回 約 ±10 ポイント それでも10ポイントの改善を確実に見分けるには余裕がない

(25件×2回の値は build-eval.md、50件×2回の値は eval-hillclimb.md に載っています。実際の判定は、2つの実行の「差」の信頼区間で行います。)

この数字を、「この程度改善したら採用したい」という幅と並べてユーザーに見せる、というのがガイドの指示です。何ラウンドもお金をかけて回した後に「そもそもこの eval では改善が見えなかった」と気づくのがいちばん高くつく、と書かれています(これは本当にそのとおりで、件数の見積もりは最初にやっておくのが安上がりです)。

入力を「全部」見せて承認をもらう

入力を集めたら、Claude はそれを要約ではなく 全件 ユーザーに見せます。元記事の Figure 3 では、メールのルーティングアプリを例に、入力の一覧ページが紹介されています。

スキルのガイドを読むと、この一覧の見せ方にも気配りがあります。基本は Markdown のファイルで、表(id・tags・expected・添付ファイルのパス)と、ケースごとの本文を並べます。ユーザーが普段使っているビューアやノートブックがあれば、そちらに合わせます。

興味深いのは、その場で HTML を手書きしない と明記されている点です。入力は本番ログやチケットから来ているので、中身は信頼できないテキストです。それを自作の HTML に埋め込むと、サポートチケットに紛れていた <script> がレビュー担当者のブラウザで動いてしまうおそれがあります。HTML で見せる場合は、エスケープとサンドボックス化をしてくれるスキル同梱のレポートビルダーを通す、という設計になっています 🔒

Step 2:採点方法は「出力の形」で選ぶ

入力が決まったら、次は採点方法です。元記事は「アプリの出力に合う、いちばん安い採点方法」を Claude が提案すると説明しています。以下の図は、スキルのガイドに書かれている選び方を判断フローにしたものです。

それぞれの採点方法について、ガイドが決めているデフォルトを表にまとめました。

採点方法 向いている出力 ガイドが決めているデフォルト
コードで判定 ラベル、数値、構造化データ、テストの合否 エージェントの場合はトランスクリプトではなく 作業後の状態 を見る(テストが通るか、差分が意図したファイルだけか、何もしていないのに成功を主張していないか)
ペア比較 移行や v1 対 v2 のように、比べること自体が目的の場合 A/B の並びを毎回ランダムにする。tie(引き分け)や both_bad(両方ダメ)も選べるようにする。両方の候補を信頼できないデータとして扱う(元記事も、どちらがベースラインかをジャッジに伝えないと説明している)
LLM ジャッジ(ルーブリック) 正解が1つではないが、品質の基準ははっきりしている自由記述 ルーブリックは「1〜5点で評価」ではなく、チェックできる主張 として書く。ジャッジの出力は structured outputs で受け取る
人手のスポット採点 法務文書の論理の妥当性のように、ルーブリックが書きにくいもの 少数の厳選ケースを人が採点する。その分、eval を回せる頻度が下がることを明示する

LLM ジャッジについて、元記事は大事な一文を添えています。

You pick the judge model, and it should not be the model you are testing.

(ジャッジのモデルはあなたが選びます。そして、テスト対象のモデルにしてはいけません。)

ガイドでは、毎回の PR で回すなら安くて速い claude-haiku-4-5、中間なら claude-sonnet-5-5、基準が微妙で弱いジャッジでは見落としそうなら claude-opus-5-5、という選択肢が示されています。どれにするかはユーザーに聞き、勝手に決めないことになっています。

ルーブリックを「チェックできる主張」で書くというのは、たとえば次のような書き方です。

❌ 有用性を1〜5で評価してください
✅ 回答はコンテキスト中のソースを少なくとも1つ引用している
✅ 回答は存在しない API パラメータを作り出していない

もう1つ、ペア比較で後から改善を重ねるつもりなら、ベースラインの出力を一度だけ保存して固定する ことも書かれています。基準の出力を毎回作り直すと、「勝率」の意味がラウンドごとにこっそり変わってしまうからです。

採点方法を検証する:「あなたなら違う点をつけましたか?」

採点方法の候補ができたら、Claude はいくつかのケースを実際に採点し、ユーザーに見せて質問します。スキルのガイドに書かれている質問文はこうです。

Would you have scored any of these differently?

(この中に、あなたなら違う点をつけたものはありますか?)

1件でも「はい」なら、ルーブリックはまだ完成していません。ユーザーの判断と採点器の判定が揃うまで、修正しては新しい採点例を見せる、を繰り返します。

元記事はこの工程の理由として、Anthropic のエンジニアリングブログ「Demystifying evals for AI agents」を引きながら、採点のミスは eval の設定ミスとして最もよくあるものの1つ だと述べています。採点器を信じる前に、採点済みのトランスクリプトを実際に読む、というのが基本姿勢です。

Step 3:runner を作り、お金を払う前に試す

採点方法が決まったら、Claude は runner(eval の実行スクリプト)を作ります。ガイドには、runner に最初から持たせるべき性質がまとまっています。後から足すと高くつくものばかりです。

性質 ねらい
ケースが終わるたびに結果を書き出す 途中でクラッシュしても、終わった分は失わない
(ケース, 反復)単位で再開できる 再実行で重複した行や、採点とトランスクリプトが別の呼び出しから来た行を作らない
1ケースあたりの実時間の上限 ストリーミングが keepalive を送り続けてハングしても、枠を取り戻せる
HTTPステータス429・過負荷時のジッター付きバックオフ 再試行の回数を記録し、見えないところでコストが膨らまないようにする
失敗の種類を記録する 拒否・ハーネスやサーバーのエラー・タイムアウト・本当の失敗を区別する
応答の model を確認する 要求したモデルと違うモデルが返ってきたら、その試行を大きな声で失敗させる

そのうえで、本番の実行(お金がかかる実行)の前に、次のようなチェックを行います。

  • オラクルとヌル:正解そのものを流して約100%、空の出力や定数を流して約0% になるか
  • ジャッジのいじわるテスト:空文字列、「わかりません」、別の質問への自信満々な答えを、すべて不合格にできるか
  • API エラーの扱い:わざと起こしたエラーが、grade: 0 ではなく status: error として記録されるか

確認が済んだら、Claude は「N 件 × R 回を <モデル> で、およそ Z 分」と実行内容を伝え、yes をもらってから本番を回します。ここで言う Z 分は試運転の実測から計算した値で、勘で見積もることはしません。

診断チェック:ベースラインの途中で見ているもの 🩺

元記事は、ベースライン実行中に Claude が確認していることを3つ挙げています。

2つ目の「配管」は、インフラのノイズがモデルのばらつきに見えてしまうのを防ぐためのチェックです。3つ目の「余白」は第1部の条件3と対応していて、ベースラインがすでに約95%以上なら、品質を上げる余地はほとんどないので、改善を重ねる対象は品質ではなくコストやレイテンシにすべきだと警告してくれます。

手元に残るもの 📦

build-eval が終わると、次のものが手元に残ります。元記事によると、ケース、採点器、runner、ケースごとの JSON 1行と完全なトランスクリプト、そして各ケースのスコアとトランスクリプトへのリンクを並べたシンプルなページです。

スキルのガイドでは、既定の置き場所は次のような構成になっています。

.claude/hillclimb/<flow>/
├── _state.json          # 指標の定義・train/test の分割などの状態
├── baseline/
│   ├── results.jsonl    # ケース×反復ごとに1行(採点・usage・model など)
│   ├── errors.jsonl     # 採点まで行かなかった失敗の記録
│   └── traces/
│       └── <id>_rep0.json  # そのケースの完全な会話
└── report.html          # 結果ページ(レポートビルダーが生成)

report.html 以上のもの(たとえばグラフ)が欲しければ、頼めば Claude が隣に追加のページを作ってくれます。元記事によると、こうした追加ページは既定ではローカルで開く静的ファイルで、ネットワークから何も読み込みません。

最後に、ガイドは eval をリポジトリにコミットするかどうかも聞いてきます。推奨は「runner・入力・採点器と .claude/hillclimb/<flow>/ を、traces/ を除いてコミットする」です。eval は次のモデル、次の四半期のトラフィック、次のプロンプト改修のときにもう一度回せてこそ価値がある、という考え方です。


第3部:どう改善を重ねるか、の原則 ⛰️

信頼できる物差しができたら、いよいよ改善です。元記事は、eval に対して改善を重ねることを「effort やプロンプトのように、コストと性能のトレードオフに効くパラメータを調整する有効な方法」と位置づけたうえで、どこに適用するかの目安を3つ挙げています。

目安 意味 元記事の例
安く試せる(Cheap iteration) 変更する対象を、時間・コスト・手間の面で安く変えたり戻したりできる プロンプトやスキルのようなテキストは変えやすく戻しやすい。ハーネスへの自由な変更は大きなコード変更になりがち
効果を帰属できる(Attributable) スコアの変化を、変更した対象のせいだと言える スキルのトリガー率を指標にして、スキルの description を変える。指標と変更対象が直結している
目標の範囲が明確(Well-scoped) 余白を考えずに「とにかく性能を上げて」と頼まない 飽和した eval や「ハーネスを自由に直して」は停滞しやすい。eval が飽和していても、性能を保ったままコストを下げる目標は立てられる

3つ目の「コスト」という目標は、元記事が「さまざまな取り組みを通じて概して強い目標」と評価しているものです。品質の余白がなくても、同じ品質のまま安くする余地は残っていることが多い、ということですね 💰

過学習:eval が「ハーネスに漏れる」

改善を重ねるときに最も気をつけたいのが過学習(overfitting)です。どんなに丁寧に作った eval でも、本番で気にしているタスク分布と完全には一致しません。その結果、eval では良く見えるのに、本番のトラフィックではそうでもないシステムができあがります。

元記事は、eval がハーネス(プロンプト、ツール、Claude を呼ぶループなど、モデルの周りのコード)に「漏れる」例として、OCR の話を挙げています。

もっと広く言えば、改善を重ねる過程では「選んだ eval の例の端っこのケース」に対処する機能が、ハーネスにどんどん足されていきがちです。そうした追加は eval のスコアは上げますが、本番の改善にはつながりません。

元記事は、これを防ぐ方法として3つを挙げています。

  1. ケースを分ける:改善する側が読んでよい train セットと、決して見ない test セットに分けます。train のスコアが上がっているのに test が横ばいなら、それは過学習のよくある警告サインです。
  2. 失敗をプロンプトに貼らない:改善する側が失敗したトランスクリプトを読むことはあっても、その中身をプロンプトに貼り付けてはいけません。
  3. 答えを構造的にモデルの手の届かない場所に置く:モデルは eval の答えを直接見つけて「報酬ハック」することがあります。

3つ目について、スキルのガイドはかなり踏み込んで書いています。正解・ルーブリック・期待出力は採点器の中にだけ置き、システムプロンプトにも、モデルが読めるツールの結果にも、bash で開けるファイルにも、コンテナがマウントするフィクスチャにも置かない、としています。そして、こう続けます。

"don't look at the answers" in a prompt is not a defense, and an agent under optimization pressure will eventually find a cat evals.json that wins the game without playing it.

(プロンプトに「答えを見ないで」と書くのは防御になりません。最適化の圧力がかかったエージェントは、いずれゲームをプレイせずに勝てる cat evals.json を見つけます。)

公開ベンチマーク由来の eval で、エージェントに Web やネットワークのツールがある場合は、答えが インターネット経由でも 手に入ることにも注意が必要です。ガイドは、合格したトランスクリプトに解答ミラーの取得が含まれていないかを確認し、含まれていればその合格を無効にするよう指示しています。


第4部:/claude-api hillclimb で改善を回す 🔁

原則がわかったところで、hillclimb の中身を見ていきます。Claude Code で /claude-api hillclimb を実行すると、Claude は与えられた eval に対して改善を繰り返します。

何を変えさせるかを自分で決める

元記事によると、Claude に変更を許す対象は次の中から選べます。

  • システムプロンプト
  • スキルや指示ファイル
  • ツールの description
  • モデルの選択、effort、その他の API パラメータ
  • ハーネスのコード

スキルのガイドでは、これに加えて 「触ってはいけないもの」 も必ず聞くことになっています。コンプライアンス上の免責文、トーンの要件、契約上必須のツールなど、「スコアが上がるとしても変えてはいけない」ものはたいてい何かしらあるからです。

始める前に決めること:目標・分割・ノイズ

ループを始める前に、Claude はまず「何を最適化したいか」を聞きます。ガイドに載っている選択肢は4つです。

目標 意味
主要指標を上げる eval が新しく、スコアに明らかな余白があるとき(推奨)
コストを下げる 主要指標をベースラインの誤差の範囲内に保ったまま
レイテンシを下げる 同上
別のモデルに移り、そのモデルで主要指標を取り戻す モデル移行のとき

選んだ目標が、各ラウンドで狙う指標、止める条件、そして「下げてはいけない指標(ガードレール)」を決めます。コスト目標の場合、元記事によると Claude はプロンプトキャッシュ、選んだモデルとの相性に合わせたプロンプトの見直し、モデルと effort の選択といった、よくあるコスト要因を検討します。

次に、Claude は eval のセットを ランダムに train と test に分けます。ガイドではさらに細かく、「tags[0](主要なグループ)で層別化し、ベースラインのスコアで選んではいけない」と書かれています。失敗しやすいケースだけを train に集めると、分析役が極端なケースばかり見てしまい、しかもそうしたケースは再実行で平均に戻りやすいからです。

そして、最初のラウンドの前に、Claude は eval のノイズ(偶然だけでスコアがどれだけ動くか)が、採用したい最小の改善幅より小さいか を確認します。小さくなければ、その旨を伝えて、反復回数やケース数を増やすよう提案します。

ガイドでは、これを「Step 0.5:eval が登れることを証明する」と呼んでいます。ノイズの確認のほかに、スコアが依存している仕組みが本当に配線されているか(ツールが本当にエージェントのツール一覧に出ているか、など)、集計値を生の結果から計算し直して一致するか、ベースラインで失敗したケースの採点が公平か、といったチェックも並んでいます。

1ラウンドの中身

いよいよループです。以下の図は、元記事の Figure 6 とスキルのガイドをもとに、1ラウンドの流れを描いたものです。

各ラウンドで、Claude は前のラウンドの train のトランスクリプトを読み、1つの変更 をパッチとして提案します。元記事によると、このとき狙うのは「eval のノイズを超えて効果が見える変更」です。1行の言い回しを変えるのではなく、失敗の原因になっているセクションを書き直したり、足りないルールを加えたりして、根本から直します。

判定のルールは表にするとシンプルです。

train test 判断
上がった 上がった 変更を残す ✅
上がった 横ばい 過学習を疑って元に戻す ⚠️
下がった(悪化) ― 元に戻す ❌

ガイドにはもう少し細かい規則もあります。train が下がって test が上がった場合は、反復回数が少ないと単なるノイズのことがあるので、2回目の実行でも同じ傾向が出たときだけ残します。同点の場合は後のラウンドを優先します。

分析役は train しか見ない 🧱

スキルのガイドを読んでいて、うまい設計だなと感じたのが、分析役の分離 です。変更を提案するのは、毎ラウンド新しく起動される分析用のサブエージェントです。渡されるのは、train に属するケースのトランスクリプトのパス、train の行だけを抜き出したスコア(results.jsonl と scores.tsv)、改善対象の現在の版、変更してよい範囲と触らない範囲、そのラウンドで狙う指標で、test のトランスクリプトは渡されません。

メインのセッションは、変更を選ぶためにトランスクリプトを読みません。見るのはスコアだけです。ガイドはこれを「データ分離の保証」と呼んでいて、変更を提案する側が train 以外を一切見ないので、test セットの情報が変更案に漏れようがない、という理屈です。

分析役には、次の3つの心得も渡されます。

  • 暗記ではなく一般化する:失敗の「内容」(train のケースに出てきた固有名詞やフレーズ)ではなく、失敗の「振る舞い」を記述する
  • 削除の副作用を名指しする:何かを消す提案をするときは、どのケースが回復するかだけでなく、どのケースが悪化しそうかも挙げる
  • 別のレバーを試してよい:特に序盤は、同じ文の言い換えではなく、ツールの description や API パラメータなど別の対象を試すのも有効

eval の実行は数分から数時間かかることがあるので、Claude はそれをバックグラウンドで回し、その間もユーザーとの会話には応じられるようになっています。最初の無人ラウンドの前には runner のコマンドを見せて許可をもらい、パーミッションの確認で誰も見ていないラウンドが止まらないようにします。

スコアが停滞したら、直す前に分類する 🗂️

改善を何ラウンドか続けると、どこかでスコアが動かなくなります。元記事によると、スコアが2〜3ラウンド停滞したら、Claude は残っている train の失敗を1件ずつ読み、原因ごとに分類します。どの修正もノイズ以上の改善を見込めないときは、停滞を待たずに早めにこの分類を行い、反復回数やケースを増やすよう提案します。

スキルのガイドでは、この分類のバケツが次のように定義されています。

バケツ 見分け方 次の一手
成果物の不足 必要な事実をモデルが持っておらず、推測や検索をしている ここはループの得意分野。改善を続ける
採点との食い違い 出力は正しく見えるのに不合格。またはプロンプトとルーブリックが別のことを求めている 採点器を直し、全ラウンドを保存済みの出力で採点し直す
ハーネス・インフラ 認証エラー、タイムアウト、レート制限などで採点前に失敗している ハーネスを直す。直るまで分母から除く
構造の問題 内容はあるのにモデルがたどり着けていない。特定の言語やプロバイダだけ常に弱い 内容を足すより、表への集約やファイル分割などで構造を直す
ばらつき 同じコードでの合否の反転が、ラウンド間の差と同じくらい大きい このレバーではノイズ床に達している。最良の結果を報告し、反復を増やすか目標を変える

以下の図は、分類のあとにどう動くかをまとめたものです。

元記事は、この分類で拾えるものとして「曖昧な eval のケース」「ハーネスのエラー」「実行ごとのばらつき」を挙げ、正当な失敗だけが次のラウンドに進む と書いています。

ガイドには、もう1つ面白い使い方が書かれています。分類の結果、1〜2件ずつの小さな原因が十数個並んでいるような「ロングテール」の状態だった場合は、それぞれに最小限の内容をまとめて一度に足す「breadth pass」を行います。普段の「1ラウンド1変更」の原則をあえて破るやり方で、個々の原因は独立していて、どれも単独では誤差を超えるほど効かないからこそ、まとめて扱う、という考え方です。

最後に残るもの:test の結果と「マージしない」という選択肢

改善のループが終わると、Claude はコードを test セットで最も良かった版 に戻した状態で引き渡します。レポートでは、test の結果をベースラインと比べ、信頼区間つきで示します(元記事の Figure 7)。

元記事でいちばん印象に残ったのは、次の一文です。

If the gain is within noise, it says so and recommends against merging.

(改善がノイズの範囲内なら、Claude はそう伝えて、マージしないよう勧めます。)

スキルのガイドでも、「誤差の範囲で盛った改善より、『今回は効かなかった、予算があれば次はこれを試す』という正直な報告のほうがユーザーの役に立つ」と書かれています。自動化ツールが「やめておきましょう」と言ってくれる設計は、地味ですが信頼できるポイントです。

ガイドによると、最終レポートには次のような項目が含まれます。

  • 見出し:ベースラインの test スコア → 最良ラウンドの test スコア(それぞれ信頼区間つき)と差
  • ラウンドごとの表:変更内容、train と test のスコア、ガードレール指標。誤差を超えた差だけを目立たせる
  • 適用済みの変更一覧:それぞれに [REQUIRED](壊れているものの修正)か [TUNE](スコアは上がったが、採用はユーザーの判断)のタグ
  • 失敗の内訳:拒否、ハーネスやサーバーのエラー、タイムアウト、本当の能力不足の件数
  • 前後比較のトランスクリプト2〜3組:同じ入力に対するベースラインと最良版の出力
  • 次に試すこと:まだ手を付けていないレバーの具体的な候補

[REQUIRED] と [TUNE] を分けてくれるのは、レビューする側にとってありがたい工夫です。たとえば「対象モデルでエラーになるパラメータの削除」は REQUIRED、「プロンプトの言い回しの調整」は TUNE、という具合に、差分を選んで取り込めます。


第5部:2つの事例 📊

元記事は、Anthropic 社内で hillclimb を回した事例を2つ紹介しています。

事例1:コストを下げるために改善を重ねる 💸

1つ目は、社内のカスタマーサポートのベンチマークで、コストを下げつつ性能も上げる ことを目標にした事例です。

  • チケットは全部で44件。そのうち30件を探索(search)に使い、14件を held-out(探索では一度も見ない)にしました。
  • 出発点は Opus 4.8 のデフォルト(high)effort で、探索用チケットでの判定精度は 74.4%、1チケットあたりのトークンコストは 4.6 セントでした。

改善は次の順番で重ねられました。

段階 構成 探索用チケットの精度 1チケットあたりのコスト
① Opus 4.8、high effort(ベースライン) 74.4% 4.6¢
② Opus 5.5、low effort、監査済みプロンプト 87.8% 1.9¢
③ Sonnet 5、low effort、同じプロンプト 88.9% 1¢
④ Sonnet 5、low effort、改善したプロンプト 98.9% 約1¢

各段階で何をしたのかを順に見ていきます。

② プロンプトの監査とモデルの変更:Claude は最初にプロンプトを監査し、必須のツール呼び出しの儀式(mandatory tool-call rituals)、スクラッチパッドのステップ、矛盾したルールを取り除きました。そのうえで Opus 5.5 を low effort で試したところ、ベースラインの精度を上回る 87.8% になり、コストは開始時の半分以下の 1.9 セントになりました。

このコスト削減の一部は、Opus 5.5 の価格によるものです。元記事によると、Opus 5.5 は Opus 4.8 と比べて入力・出力トークンが20%安く、キャッシュの読み取りは60%安くなっています。claude-api スキルの価格表では、入力・出力が 100万トークンあたり $5 / $25 から $4 / $20、Opus 5.5 のキャッシュ読み取りが $0.20 です(Opus 4.8 のキャッシュ読み取りは、入力単価の0.1倍として計算すると $0.50 になり、60%減と一致します)。

③ 1段下のモデルで再確認:Opus 5.5 で基準を超えられたので、Claude はさらに安いモデルでも超えられるかを確認するために、1段階下のモデルを試しました。Sonnet 5 の low effort はほぼ同じ 88.9% で、コストはさらに約半分の 1 セントになりました。

④ プロンプトの改善:最後に、Claude はルーティングのルールと、返金上限(refund cap)の相互参照をプロンプトに加え、Sonnet 5 の精度を 98.9% まで引き上げました。コストはほぼ変わっていません。

そして、いちばん大事な数字はここからです。探索で一度も使わなかった 14件の held-out チケットでは、最終構成が 90.5%、元の構成が 78.6% でした。コストは約5分の1です。

探索用チケットでの 98.9% と、held-out での 90.5% の間に差があるところに、train と test を分ける意味がよく表れています。「探索に使ったケースの数字」だけを見ていたら、実力を高く見積もりすぎていたことになります(逆に言えば、held-out でもベースラインより約12ポイント高いので、改善自体は本物だと判断できます)。

📝 この事例で使われたプロンプト監査の考え方は、Anthropic の「Reducing cost and improving performance with Claude Platform」にもまとめられています。claude-api スキルには /claude-api prompt-audit や /claude-api cost-optimize というサブコマンドもあり、同じ方向の作業を eval なしで進めることもできます。

事例2:claude-api スキル自身の性能改善 🧩

2つ目の事例は、claude-api スキル自身です。このスキルは Anthropic の API の使い方や Claude を扱うコツをまとめたもので、この記事で紹介しているサブコマンドもその一部です。Anthropic は、スキルが API を使うコードを正しく書けるかを確かめるために、ドキュメントから作った eval セットを用意しました。

eval でのスタートは 66% でした。改善を重ねる Claude にはドキュメントと SDK へのアクセスを与え、Claude 自身が誤りを見つけて修正できるようにしました。

フェーズ 内容 合格率
ベースライン ― 66.1%
① 足りない内容を足す 8つの機能のカバーが欠けていたのでセクションを追加 → 74%。C# と Java の型の表の誤りを修正 → 77% 74% → 77%
② コードの書き方を直す 失敗をまとめて振り返った結果、旧い API の書き方を新しい書き方へ導く表をスキルの冒頭近くに追加 80%
③ 採点器を直す 欠陥のあるタスクと採点器を修正し、スキルもさらに編集 約88%(87.9%)

この事例で面白いのは、②と③が「停滞したら分類する」ステップから生まれていることです。スコアが2ラウンド停滞したあと、Claude は残っている失敗を根本原因ごとに分類しました。通常のラウンドは最も多い失敗に対して1つ編集しますが、このステップは編集をせず、残っている失敗を原因ごとに仕分けるだけです。元記事によると、この振り返りは次の2点で役立ちました。

1つ目:内容はあるのに、古い書き方をしていた。 失敗をまとめて見ると、スキルの中に正しい情報はあるのに、Claude が学習で覚えた古い API の形(trained priors)でコードを書いていることがわかりました。そこで、覚えている形から現在の形へ導く表を、スキルの冒頭近くに追加しました。

覚えている古い形 現在の形
固定のトークン予算つきの extended thinking(最近の Opus モデルでは API が拒否する) adaptive thinking
旧バージョンの web search / web fetch ツール 現在のバージョンのツール

あわせて、C# と Java で「固定予算の thinking を使わない」という注意書きを、adaptive thinking の例より上に移動しました。これで 80% まで上がりました。

(ちなみに、Claude Code に同梱されている claude-api スキルの SKILL.md を開くと、冒頭近くに「Warning: API Drift - Your Training Prior May Be Stale」という見出しの表が実際にあります。改善を重ねる中で見つかった対策が、配布されているスキルにも入っているようです。)

2つ目:いつまでも改善しないタスクは、タスクか採点器が怪しい。 明らかな内容の不足を埋めても一向に改善しないタスクは、例か採点器に欠陥があるサインです。元記事は2つの例を挙げています。

  • あるタスクは「1種類のエラーを捕捉するコード」を求めていたのに、採点器は「少なくとも3つのエラーの連鎖」を求めていました。Claude はタスクの文面を書き直しました。
  • 別の採点器の指示はドキュメントと矛盾していました。実際の API で試したところ、ドキュメントの方が正しいことがわかりました。

これらの修正と追加のスキル編集で、合格率は約88%になりました。

2つの事例から読み取れること

2つの事例を並べると、改善の重ね方には2種類あることがわかります。

1つ目は、プロンプトの監査とモデル・effort という「設定のレバー」でコストを大きく下げ、最後にモデルを固定したままプロンプトを改善して精度を上げた例です。2つ目は、内容を足すだけでは伸びなくなったところで、失敗の分類によって「書き方の癖」と「物差しの欠陥」を見つけた例です。共通しているのは、どちらも held-out の結果やノイズを確かめながら、1段ずつ改善を積み上げている点です。


始め方 🚀

元記事の「Getting started」によると、claude-api スキルは Claude Code に同梱されているので、まず Claude Code を更新します。

claude update

そのうえで、Claude Code の中で次のコマンドを実行します。

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

使い分けは次のとおりです。

こんなとき 使うコマンド
特定の問題について、評価セットをまだ持っていない /claude-api build-eval。トレースなどの例を渡すと、それを手がかりに入力と採点器を設計してくれる
eval はすでにあり、目標(性能を上げる、性能を保ってコストを下げる、など)に向けて改善したい /claude-api hillclimb。登る途中で過学習をチェックし、最初のラウンドの前と停滞したときには eval 自体のバグも点検してくれる

build-eval に引数を付けると、それが「何を測りたいか」という最初の質問への答えとして扱われます。たとえば /claude-api build-eval メールの振り分け精度 のように、評価したいフローを最初から伝えられます。

使う前に知っておきたいこと

最後に、スキルのガイドを読んでいて「これは事前に知っておくと安心だな」と感じた点をまとめます。

  • eval の実行にはお金がかかります。 build-eval は本番の実行の前に「N 件 × R 回を <モデル> で、およそ Z 分」と確認してきます。費用を聞けば、試運転の実測 usage から計算した見積もりを出してくれます。
  • 承認は形式ではありません。 入力と採点方法の承認は、ガイドが「承認こそが成果物」と書くほど重視している部分です。ここでしっかり目を通すほど、最後の数字を信頼できます。
  • runner には変更検知の仕組みがあります。 スキル同梱の runner の雛形は、runner 自体やロックファイルのハッシュを記録し、ハーネスのファイルが変わると --approve-harness で承認し直すまで止まります。このフラグはユーザーが渡すもので、Claude は渡さないことになっています。
  • 結果はリポジトリに残せます。 eval をコミットしておけば、次のモデルが出たときにも同じ物差しで再ベースラインを取れます。

まとめ

この記事では、claude.dev ブログの「Automating eval design and hillclimbing with Claude」と、claude-api スキル本体のガイドをもとに、/claude-api build-eval と /claude-api hillclimb の考え方と手順を整理しました。

要点を振り返ると、次のようになります。

  • よい eval は、本番に似ていて、強いモデルほど高得点で、満点との間に「届きうる余白」があり、ばらつきが小さいものです。今のモデルの失敗だけを集める「敵対的サンプリング」は避けます。
  • build-eval は、入力の承認と採点方法の承認という2つのゲートを通しながら、コードベースの中に eval を組み立て、ベースラインを信頼区間つきで出してくれます。
  • hillclimb は、1ラウンドに1つの変更を加え、train だけを読み、test で判定します。train だけが上がったら過学習を疑って戻し、停滞したら直す前に失敗を分類します。
  • 事例 では、held-out のチケットで 78.6% → 90.5%・コスト約5分の1、スキルの eval で 66% → 約88% という結果が出ています。

それでも、この記事でいちばん持ち帰ってほしいのは、「改善がノイズの範囲内なら、マージしない」と言えることも自動化の一部 だという点です。スコアを上げる仕組みはいくらでも作れますが、上がったように見えるだけの数字を見抜く仕組みは、意識して組み込まないと手に入りません。claude-api スキルの2つのコマンドは、その「自分をだまさない」ための手順を、最初から組み込んでくれています 🙌

次の一歩としては、まず手元のアプリの中から「1つのフロー」を選び、/claude-api build-eval で最初の eval を作ってみるのがおすすめです。モデルを乗り換える予定がある方は、移行の前にベースラインを取っておくと、移行後の比較がずっと楽になります。本記事では詳しく扱いませんでしたが、eval の健全性チェックリスト(スキル内の eval-audit.md)や、コスト目標専用の探索順序(cost-hillclimb.md)も、同じスキルの中に用意されています。

参考

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?