Claude Media
プロンプトチェーンでClaudeに自己修正させる3段構成

プロンプトチェーンでClaudeに自己修正させる3段構成

生成→レビュー→改善を3回のAPI呼び出しに分ける自己修正パターンの実装方法と、Opus 5が持つネイティブな自己修正との違いを示します。

Claudeに下書きを作らせ、その下書きをレビューさせ、レビュー結果を反映して直させる。この3段の流れは、1つのタスクを3回のAPI呼び出しに分けるだけで実装できます。各ステップを独立した呼び出しにすることで、途中の出力をログに残したり、レビューの合否で処理を分岐させたりできるようになります。Claude Opus 5が単体で持つ「自己修正」の挙動とは別物なので、両者を混同すると無駄な指示を重ねてコストを増やすだけになります。

3回の呼び出しで何が手元に残るか

プロンプトチェーンの自己修正パターンは、1つの出力を生成・レビュー・改善の3回のAPI呼び出しに分けて作る設計です。公式のプロンプトガイドが、連鎖させるパターンのうち最も一般的なものとして挙げています。

手順

3回の呼び出しの流れ

  1. 1

    生成

    タスクをそのまま実行させ、下書き(draft)を受け取ります。

  2. 2

    レビュー

    下書きと評価基準を渡し、基準ごとの合否と理由を返させます。

  3. 3

    改善

    下書きとレビュー結果を渡し、不合格の項目だけを直させます。

各ステップの出力は独立したレスポンスとして手元に残ります。レビュー結果だけを人が確認して承認するフローも、失敗したステップだけの再実行も、この分割があってはじめて作れます。

前提 — なぜ推論をモデルに任せず呼び出しを分けるのか

Claudeの最新モデルは、adaptive thinkingとサブエージェントのオーケストレーションによって、複数ステップの推論の大部分を内部で処理します。Extended thinkingとAdaptive thinkingの違いで扱ったとおり、思考の深さそのものはモデルが自律的に判断する設計に移っています。それでも、明示的なプロンプトチェーンには別の役割があります。中間の出力を検査したい場合や、特定のパイプライン構造を強制したい場合には、依然として有効です。

「モデルに任せれば済む推論」と「呼び出しを分けて強制したい構造」は別の問題です。前者はモデルの内部処理に委ねてよく、後者は呼び出しの数そのものを設計者が決める必要があります。3段の自己修正パターンが向くのは後者で、レビューを独立したAPI呼び出しとして取り出し、結果を外部から見える形にしたい場合です。

呼び出しを3回に分けることの代償も無視できません。draftの本文をreviewとrefineの呼び出しにそれぞれ埋め込むため、同じテキストを複数回の入力トークンとして送ることになります。1回の呼び出しで完結させる場合に比べ、入力トークンの合計は増えます。検査・分岐・再実行のどれも必要ないタスクにまで3段構成を適用すると、コストだけが増えて得られるものがない設計になります。

「自己修正」が指す2つの別物

ここで注意が必要なのは、「自己修正」という言葉が公式ドキュメント内で2つの別の現象を指していることです。

くらべる

「自己修正」が指す2つの別物

設計者が作る

プロンプトチェーン

生成・レビュー・改善を別々のAPI呼び出しに分けます。レビュー結果が1つのレスポンスとして返るので、保存・承認画面への表示・次のステップへの受け渡しができます。

モデルが行う

モデル単体の挙動

Claude Opus 5が応答の中で自分の間違いを見つけて直します。過程は既定では外から見えません。

公式のOpus 5向けプロンプトガイドは、Claude Opus 5が指示されなくても自分の間違いをよく見つけて直すと説明しています。「ダブルチェックして」「回答前に再検証して」といった指示は、モデルが既に行っている再確認と重なってコストを増やすだけなので避けるよう勧めています。

1回の呼び出しの中で「よく確認してから答えて」と念押しするのは、この重複にあたります。本当に必要なのは、レビューを別の呼び出しとして取り出し、結果を外から検査できる形にすることです。念を押すことと、呼び出しを分けて検査可能にすることは、目的が違います。

モデルとeffortで変わる「勝手な自己確認」の量

モデル単体の自己確認は、モデルとeffortによって量が変わります。Sonnet 5.5のプロンプトガイドによると、コーディングのタスクでは変更を完了と報告する前に確認するのが通常です。ただしeffortがlowのときは、テストやビルドを走らせずに完了と報告することがあります。これを防ぐsystem promptの文例もガイドに載っています。実行できるコードを変えたら、報告の前にテストや型チェック、ビルドを実際に走らせる、という内容です。

反対側もあります。xhighとmaxでは、作業を終えたあとに自分でレビューと検証のラウンドを始めることがあり、サブエージェントを使うこともあります。同じガイドは、通常の作業はhigh以下で回すよう案内しています。自己レビューを始めないようsystem promptで指示する文例も載っています。maxでのコーディングの検証では、レビュー用サブエージェントの起動が止まり、品質を変えずにセッションのコストが約3分の1下がったと報告されています。

この挙動を踏まえると、チェーンを組むときの前提が見えてきます。レビューを独立した呼び出しにしているのに、各呼び出しのeffortをxhigh以上にすると、呼び出しの内側でも自己レビューが始まって重複することがあります。ガイドが説明しているのは、コーディング作業での挙動です。逆にeffortをlowに落としたステップは、確認が浅くなる可能性があります。ステップごとのeffortは、レビューの深さを誰が受け持つかという設計の一部です。

ステップ1: draftを生成する

最初の呼び出しは、通常のタスク実行と同じです。役割(role)を明示すると、レビュー基準との対応が取りやすくなります。

curl https://api.anthropic.com/v1/messages \
  -H "x-api-key: $ANTHROPIC_API_KEY" \
  -H "anthropic-version: 2023-06-01" \
  -H "content-type: application/json" \
  -d '{
    "model": "claude-sonnet-5",
    "max_tokens": 4096,
    "system": "You are a technical writer producing an internal migration guide for developers.",
    "messages": [
      {"role": "user", "content": "Write a short guide section explaining how to move a request from budget_tokens to adaptive thinking with the effort parameter."}
    ]
  }'

レスポンスのcontentをそのままdraft_textとして保持し、次のステップの入力にします。この時点では検証も修正も行いません。

Sonnet 5はthinkingを省略すると思考が有効になります。max_tokensは思考と本文を合わせた出力の上限なので、思考に使われた分だけ本文に回せる量が減ります。下書きが途中で切れるときは、まずmax_tokensの値と、思考にどれだけ使われたかを見てください。

ステップ2: reviewでdraftを評価基準に照らす

2回目の呼び出しでは、draftと評価基準を両方渡してレビューさせます。プロンプトが指示・コンテキスト・可変の入力を混在させるときは、それぞれをXMLタグで囲むと解釈のズレを減らせます。

review_prompt = f"""
<draft>
{draft_text}
</draft>
 
<criteria>
- 技術的に正確か(budget_tokensの仕様と矛盾しないか)
- 開発者がそのまま実行できる手順になっているか
- 結論が先に来ていて、冗長な前置きがないか
</criteria>
 
Review the draft against each criterion above. For each criterion, state pass or
fail and give a one-sentence reason.
"""

レビューの呼び出しには、生成の呼び出しとは別のsystemを与えておくと、役割の切り替えがはっきりします。たとえば「You are a strict technical editor.」に「基準に照らして評価し、本文は書き換えない」という趣旨を足します。同じモデルでも、「文章を作る」役割から「評価するだけ」の役割へ明確に切り替わります。3ステップぶんの役割を1つのsystem文字列に詰め込む必要はありません。呼び出しごとにsystemを持てるのは、分割したことで得られる利点の1つです。

レビューの指示に「重大な問題だけ報告して」「控えめに指摘して」と書くのは避けます。Opus 5のガイドによると、モデルがその指示を文字どおりに受け取って報告を減らすことがあります。ガイドの勧めは、すべて報告させて絞り込みは別の工程で行う形です。チェーンなら、レビューには全項目の合否を出させ、どの不合格を直すかは次の改善ステップか呼び出し側のコードで決められます。

レビューの合否をその後の処理で分岐条件に使いたい場合は、この呼び出しに構造化出力を組み合わせ、pass / failをJSONの決まった位置に固定します。実装のSDKごとの型定義の書き方はStructured outputsの型定義パターンで比較しています。生成(ステップ1)や改善(ステップ3)と違い、レビューは自由文を作る作業ではなく評価基準への当てはめなので、構造化出力と相性がよいステップです。

ステップ3: refineでレビュー結果を反映する

3回目の呼び出しでは、元のdraftとレビュー結果の両方を渡し、fail判定が付いた項目だけを直すよう指示します。

refine_prompt = f"""
<original_draft>
{draft_text}
</original_draft>
 
<review_feedback>
{review_result}
</review_feedback>
 
Revise the draft to address every criterion marked fail in the review feedback.
Leave sections that passed unchanged. Do not introduce new claims that were not
in the original draft or the feedback.
"""

「passした項目には触れない」という指示を入れておくと、改善のたびに無関係な部分まで書き直される事態を避けられます。3回の呼び出しのmessages配列は互いに独立しているため、前のステップの会話履歴をそのまま引き継ぐ必要はありません。必要なテキスト(draftとレビュー結果)だけを次のプロンプトに埋め込めば十分です。

改善ステップの出力は、そのまま次の処理に渡す本文になります。Opus 5は以前のモデルより、自分の以前の発言への訂正を言葉にして述べる傾向があるとガイドは説明しています。「ここを修正しました」という注記が本文に混ざると、保存や表示のときに邪魔になります。改善の呼び出しには、修正後の本文だけを返すよう指示しておくと混入を防げます。ガイドには、利用者の判断に影響する訂正だけを簡潔に述べ、影響しない修正は黙って直す指示文の例も載っています。

使い分け早見表 — 3段チェーンとネイティブな自己修正のどちらを使うか

状況向いている設計
1回の応答の質を上げたいだけで、途中経過は見なくてよい向いている設計何もしないか、軽い指示に留める(モデルのネイティブな自己修正に任せる)
レビュー結果を人がログで確認したい、承認フローに乗せたい向いている設計本記事の3段プロンプトチェーン
レビューの合否を次の処理の分岐条件に使いたい向いている設計3段チェーン + レビューステップの構造化出力
生成・レビュー・改善のどこかだけを失敗時に再実行したい向いている設計3段チェーン(各ステップが独立した呼び出しなので再実行範囲を絞れる)
「もう一度確認して」と念押ししたいだけ向いている設計何もしない(Opus 5では既にモデルが行っている再確認と重複する)

よくあるつまずき

  • レビュー基準を書かずにレビューさせる: 何を評価するかが伝わらず、改善ステップの入力として使えない曖昧なフィードバックが返ってきます。基準は<criteria>のように箇条書きで明示します
  • レビューと改善を1回の呼び出しに戻してしまう: 3ステップに分けたのは検査・分岐したいからです。単に品質を上げたいだけなら、そもそも呼び出しを分ける必要はありません
  • ループの終了条件を決めない: レビューが「まだ直すべき」と言い続ける限り改善を繰り返すと、ラウンド数が無制限に増えコストが膨らみます。最大ラウンド数を先に決めておきます
  • 各ステップのeffortを揃えてしまう: draftとrefineは新しい文章を作るタスクで、reviewは評価基準への当てはめだけです。effortの使い分けに沿って、reviewだけoutput_configのeffortを下げる選択肢があります。品質が保たれるかは、自分の評価データで測ってから決めます
ループ回数を制限する実装の骨格
MAX_ROUNDS = 2
 
def self_correct(task: str) -> str:
    draft = generate(task)
    for round_index in range(MAX_ROUNDS):
        review = review_draft(draft)
        if review["overall_verdict"] == "pass":
            break
        draft = refine(draft, review)
    return draft

reviewの判定に構造化出力を使っておくと、review["overall_verdict"]のような固定の位置をif文で見るだけでループを止められます。自由文のレビュー結果から「もう直す必要があるか」を毎回パースする実装より事故が起きにくくなります。

まとめ

途中の出力を見たい、合否で分岐したい、失敗したステップだけ再実行したい。この3つのどれかが必要なときに、3段チェーンは費用に見合います。品質を上げたいだけなら、Opus 5のように自己確認が強いモデルでは念押しの指示もチェーンも足さず、まず1回の呼び出しで結果を見るほうが、コストが読みやすくなります。

参照した一次ソース

この記事の記述は、次の一次ソースと照合しています。更新時に参照先が変わった場合は一覧も更新します。

  1. platform.claude.com/docs/en/build-with-claude/prompt-engineering/claude-prompt…
  2. platform.claude.com/docs/en/build-with-claude/prompt-engineering/prompting-cla…
  3. platform.claude.com/docs/en/build-with-claude/prompt-engineering/prompting-cla…
  4. platform.claude.com/docs/en/build-with-claude/effort
  5. platform.claude.com/docs/en/build-with-claude/thinking
この記事を共有:XはてブLinkedIn