Claude Media
Claudeの回答が毎回違うのはなぜか — 非決定性の3つの発生源と対処

Claudeの回答が毎回違うのはなぜか — 非決定性の3つの発生源と対処

同じプロンプトでもClaudeの答えは揺れます。サンプリング・推論サービス側・エージェントの経路分岐という3層で原因を切り分け、structured outputsや複数回実行など再現性が要る場面の対処をまとめます。

同じプロンプトを2回送ると、Claudeは違う答えを返すことがあります。これは不具合ではありません。語の選択がそもそも確率的であること、推論サービス側の計算が完全には固定されないこと、そしてエージェントでは行動の経路自体が分岐すること。ばらつきはこの3層で仕組みとして発生します。どの層から来ている揺れかを見分けると、抑えられるものと抑えられないものの区別がつきます。

3つの発生源を先に整理する

発生源何が起きるか主に効く場面利用者が制御できるか
サンプリング何が起きるか次の語を確率分布から選ぶ主に効く場面すべての応答利用者が制御できるか旧モデルのAPIのみtemperatureで縮小できる(Opus 4.7以降・Sonnet 5.5は不可)
推論サービス側何が起きるかtemperature 0でも完全一致しない主に効く場面API連携・自動処理利用者が制御できるかできない
経路分岐何が起きるかツール実行の選択・順序が毎回変わる主に効く場面Claude Codeなどのエージェント利用者が制御できるか環境の固定と検証で部分的に

上から順に、応答の1文字ずつ・API呼び出し1回ごと・タスク1件ごと、と揺れのスケールが大きくなります。順に見ます。

発生源1: Claudeは次の語を確率で選んでいる

言語モデルは、次のトークン(語の断片。Claudeでは英語約3.5文字に相当)を1つに決めているわけではなく、候補の確率分布から選んでいます。文章は数百〜数千個のトークン選択の積み重ねなので、途中のどこか1箇所で2番手の候補が選ばれれば、そこから先は別の文章になります。このランダム性を制御するのがtemperatureです。高くすると多様で創造的な言い回しが増え、低くすると最も確からしい表現に寄った保守的な出力になります。

Messages APIにはtemperature引数があり、既定値は1.0、範囲は0.0〜1.0です。リファレンスの使い分けは、分析や選択式のタスクなら0.0寄り、創作系なら1.0寄りです。既定は「毎回同じ答えを返す」設定ではなく、表現の幅を持たせる側に振ってあります。同じ質問への回答が言い回しごと変わるのは、この既定の直接の帰結です。

ただし、この引数は非推奨になりました。Claude Opus 4.6より後に出たモデルはtemperatureを設定できず、1.0は後方互換のために受け付けられるものの、ほかの値は400エラーで拒否されます。該当するのはClaude Opus 4.7以降とClaude Sonnet 5.5などです。Opus 4.6自体と、Sonnet 4.6以前、Haiku 4.5は従来どおり指定できます。

サンプリング系の引数はtemperatureだけではありません。top_kはOpus 4.6より後のモデルではどの値も400エラーになります。top_pは0.99以上だけが受け付けられ、それ未満は400エラーです。いずれもMessages APIリファレンスで非推奨と表記されています。該当モデルでは、temperature・top_p・top_kのどれを使っても、実質的に揺れを下げられません。

ばらつき自体は欠陥ではありません。ブレインストーミングや文章の代替案出しは、この確率的な選択があって初めて機能します。問題になるのは、再現性を暗黙に期待した使い方と組み合わせたときだけです。

発生源2: temperatureを0にしても同一にはならない

指定できるモデルで0.0にすれば毎回同じになるかというと、なりません。Messages APIのリファレンスには「temperatureを0.0にしても、結果は完全には決定的にならない」と明記されています。用語集はさらに踏み込んで、同一の入力でもAPI呼び出しごとに異なる出力になりうること、これがAnthropic自身の推論サービスでも、サードパーティーのクラウドプロバイダー経由でも当てはまることを記しています。

リファレンスと用語集には内部要因の説明がありません。一般にGPUでの並列計算は浮動小数点演算の順序やバッチの組まれ方で結果がごくわずかに揺れることが知られており、その微小な差が確率上位の候補が拮抗する場面で別のトークンを選ばせます。一度分岐すれば、そこから先の文は別の文章です。Opus 5.5の移行ガイドも、決定性のためにtemperature 0を使っていた場合、以前のモデルでも同一の出力は保証されていなかったと注意しています。

実務上の含意ははっきりしています。「temperature 0なら出力は再現される」という前提で回帰テストや差分検知を組むと、いつか壊れる前提で設計する必要があります。完全一致の比較はLLMの生の出力に直接張れません。

発生源3: エージェントは経路そのものが分岐する

Claude Codeのようなエージェントでは、揺れのスケールがさらに上がります。エージェントはプロンプトと途中で得た情報にもとづいて、どのツールをどの順で使うかを自分で決めながら、数十手のアクションを連鎖させます。最初に読むファイルの選択が1つ変わるだけで、以降の探索・編集・検証の全経路が変わります。1文字の揺れではなく、仕事の進め方ごと分岐するわけです。

Anthropicのエージェント評価ガイドも、エージェントの挙動は実行ごとに変わり、同じタスクがある回は成功して次の回は失敗することを前提として扱っています。加えてエージェントには「環境」という入力があります。作業ディレクトリの中身、gitの状態、残っているキャッシュ。同じプロンプトでも環境が違えば、モデルから見れば別のタスクです。

環境の影響は思わぬ形で出ます。同ガイドには、社内evalで前回の試行が残したgit履歴をClaudeが読んで課題を有利に解いてしまった、という実例が載っています。前の実行の痕跡が次の実行の入力になっていたわけです。だからエージェント評価では、試行ごとにクリーンな環境から始めることが信頼できる計測の条件とされています。

Claude Codeで環境差を削る手段が--bareです。claude --help(v2.1.287で確認)の説明は次のとおりです。

--bare   Minimal mode: skip hooks (those defined in settings and by
         installed plugins; features built into Claude Code are
         unaffected), LSP, plugin sync, attribution, auto-memory,
         background prefetches, keychain reads, and CLAUDE.md
         auto-discovery. Sets CLAUDE_CODE_SIMPLE=1. Anthropic auth is
         strictly ANTHROPIC_API_KEY or apiKeyHelper via --settings
         (OAuth and keychain are never read).

チームメイトの~/.claudeにあるhookも、プロジェクトの.mcp.jsonのMCPサーバーも走らないので、マシンごとの差が入りにくくなります。ヘッドレス実行のガイドでは、サブエージェントやスキルの自動探索も省かれる、claude -pと組み合わせるCI向けの設定として説明されています。--bareを付けないclaude -pは、対話セッションと同じ文脈を読み込みます。作業ディレクトリや~/.claudeの設定がそのまま入力になるので、同じコマンドでもマシンによって条件が変わります。--bareでも、--add-dirで指定したディレクトリは部分的な例外で、.claude/skills/は読み込まれ、.claude/commands/と.claude/agents/は読まれません。サブスクリプションのログインは使われないため、ANTHROPIC_API_KEYが必要です。文脈が要るときは--append-system-promptや--mcp-configなどで明示的に渡します。

再現性が要る場面の対処 — 固定できるものから固定する

揺れの層ごとに、使える手段と保証の強さが違います。

固定したいもの手段保証の強さ
出力の形式手段structured outputs保証の強さスキーマ準拠を保証(例外あり)
内容のばらつき手段形式指定・例示(旧モデルならtemperatureも下げる)保証の強さ縮小(保証なし)
回答の根拠手段検索・文書を渡して出典を固定保証の強さ縮小
エージェントの環境差手段クリーンな環境・設定の固定保証の強さ環境要因のみ除去
完全な再現手段生成物を保存して再利用する保証の強さ完全

形式の固定に効くのがstructured outputsです。生成そのものをJSONスキーマで拘束する(constrained decoding)ため、パースに失敗する出力や必須フィールドの欠落がなくなります。応答本体だけでなく、strict: trueを付ければツール呼び出しの引数にも同じスキーマ保証をかけられるため、エージェントのツール入力が壊れて落ちる系のばらつきも塞げます。ただし保証されるのは形式であって内容ではなく、同じスキーマの中で違う値が返ることは普通にあります。また、安全上の拒否・max_tokensでの途中終了・enum値の大文字小文字という例外ではスキーマに一致しないことがあります。実装手順はstructured outputsでJSON出力を固定する方法にまとまっています。

内容側のばらつきには、プロンプトエンジニアリングの定石が効きます。Opus 4.7以降やSonnet 5.5のようにtemperatureを下げられないモデルでは、これが主な手段です。公式ガイドは、出力形式を厳密に指定する、応答の書き出しをこちらで与える(prefill。ただしClaude 4.6以降はこの用法自体が400エラーで拒否されます)、良い例を見せる、根拠となる文書を渡して回答をそこに接地させる、といった手段を挙げています。prefillはJSON出力形式のstructured outputsと併用できない点だけ注意が要ります。指示の組み立て方の基礎はClaudeプロンプトの書き方が扱っています。

そして完全な再現が必要な部分は、生成の外に出すのが確実です。一度生成した出力を保存して使い回し、LLMは「生成時」だけに関与させる。コードなら生成結果をコミットした瞬間に再現性の問題は消えます。再現性を生成のたびに求めるのではなく、生成を1回に閉じ込める発想です。

ばらつきは消すものではなく測るもの — pass@kとpass^k

エージェントの揺れは設定では消えないので、Anthropicの評価設計では計測の対象として扱われます。評価ガイドの前提は、タスクごとに成功率が違うことです。あるタスクは90%、別のタスクは50%といった具合で、前回通ったタスクが今回落ちることもあります。1回の合否ではなく「何割の試行で成功するか」を測る、というのが出発点です。

コーディングでは、最初の1回で解にたどり着けるかを示すpass@1がよく使われます。1回目の成功率が50%なら、評価に含まれるタスクの半分で最初の試行が成功した、という読み方になります。使われる指標は2つあります。

くらべる

pass@kとpass^k

1回でも当たればよい

pass@k

k回試して少なくとも1回成功する確率です。試行を増やすほど上がります。1回あたりの成功率が0でなければ、kを増やすほど100%に近づきます。探索的な仕事に向きます。

毎回当たってほしい

pass^k

k回すべて成功する確率です。試行を増やすほど下がります。成功率が75%なら、k=10では0.75の10乗で約5.6%です。顧客向けエージェントのように毎回の信頼性が要る場面に向きます。

k=1ではどちらも1回あたりの成功率に等しくなります。1回あたりの成功率が75%のエージェントなら、連続して成功する確率は次のように落ちます。

数字

成功率75%のエージェントのpass^k

  • k=1

    75%

    1回あたりの成功率そのまま

  • k=2

    約56%

    0.75の2乗

  • k=3

    約42%

    0.75の3乗

75%のk乗。評価ガイドの例は3回で約42%

エージェントの信頼性は1回のデモでは測れません。複数回走らせて比率で語るほうが実態に合います。指標の背景とeval設計の全体像はAIエージェントのEval設計の解説で詳しく読めます。

よくある質問

同じチャットで聞き直しても答えが変わるのはなぜですか

聞き直した時点で会話履歴が伸びており、モデルに渡る入力そのものが前回と違うからです。コンテキストウィンドウには過去のやり取りが入るため、「同じ質問」でも条件は同じではありません。そこにサンプリングの揺れが重なります。

回答が毎回違うのは精度が低いということですか

別の性質です。ばらつきは確率的な生成の帰結で、誤りの多さとは独立しています。事実関係の答えが実行のたびに割れる場合は、根拠となる資料を渡して接地させるか、複数回実行して一致を確認する使い方が向いています。

複数回実行して答えを比べるのは有効ですか

用途によります。探索的な仕事なら、複数回生成して最も良い案を選ぶ使い方はpass@kの考え方そのもので、揺れを味方につける方法です。事実確認の用途なら、複数回の回答が一致するかを見ることで、揺れやすい箇所(=確信度の低い箇所)をあぶり出せます。ただし一致は正しさの証明ではないため、最終的な裏取りは出典側で行う必要があります。

Claude Codeで同じ指示なのに結果が違うのを減らせますか

環境要因は固定できます。残る経路の揺れには、テストのような検証手段をタスクと一緒に渡す方法が効きます。経路が違っても、検証を通った状態という着地点は揃えられます。

まとめ — 揺れの層で対処を選ぶ

揺れは故障ではなく仕様です。まず、揺れが1文字単位のサンプリングから来るのか、API呼び出し単位の推論サービス側か、タスク単位の経路分岐かを見分けます。形式の揺れならstructured outputs、完全一致が要る部分なら生成物の保存、経路の揺れなら成功率での評価と、層に合う手段を選ぶと無駄な調整が減ります。

この記事を共有:XはてブLinkedIn