メインコンテンツへスキップ
ブログ一覧に戻る
AI活用・LLM

temperatureを0にしても出力は一致しない|「再現性」の定義を置き換える

2026年10月15日
14分で読めます

この記事でわかること

temperatureを0にしたのに出力が揺れる原因を、Azure OpenAIとOpenAIの公式記述から整理します。公式は既定の挙動を非決定的と明記し、seedとsystem_fingerprintが一致してもばらつきは珍しくないと書いています。「再現性がある」を出力の一致から、条件の記録とばらつきの幅へ定義し直す判断軸を示します。

「同じプロンプトを同じモデルに投げているのに、出力が毎回違う」。この報告を受けて最初に出てくる対処は、ほぼ決まっています。temperature を 0 にする。

それでも揺れます。そして多くの場合、調査はここで止まらずに迷走します。設定を変えたのに現象が消えないので、「まだ見落としている設定があるのではないか」という方向に探索が進んでしまうからです。

探すべきものは設定ではありません。「再現性がある」という言葉を、何を指すものとして使っているかです。この記事では、公式ドキュメントが実際に何を保証し、何を保証していないかを確認したうえで、検証と回帰テストが設計できる定義に置き換えます。

確認するのは Azure OpenAI の公式ドキュメントと、OpenAI Cookbook のレシピの2つです。他ベンダーのAPI(プログラムから呼び出す窓口)が同じ挙動をするかは確認していないため、一般化はしません。また、非決定性がなぜ生じるのか——計算の内部で何が起きているのか——は、参照した2つの文書のどちらにも説明がないため扱いません。

30秒で要点

  • Azure OpenAI の公式ドキュメントは、既定の挙動を「同じ質問を複数回投げれば異なる応答が返る可能性が高く、応答は非決定的と見なされる」と明記している
  • seed と system_fingerprint が一致していても「ばらつきが観察されることは現時点では珍しくない」と公式が書いている。決定性は保証されていない
  • max_tokens が大きいほど、seed を設定していても決定性は下がる。長く書かせるほど再現しにくい
  • したがって「再現性がある」を「出力が一致すること」と定義すると、どの設定でも達成できない。定義を何を固定したかが記録に残っており、ばらつきの幅が分かっていることに置き換える
  • 回帰テストは文字列の完全一致ではなく、満たすべき性質(パースできる/必須キーがある/数値が範囲内)で判定し、品質は割合で観測する

公式が保証しているのは「決定的に近づけること」までである

Azure OpenAI の reproducible output のドキュメントは、冒頭で既定の挙動をこう説明しています。既定では、同じ質問を複数回投げれば異なる応答が返る可能性が高く、したがって応答は非決定的と見なされる——。そのうえで reproducible output を、「この既定の挙動を選択的に変更して、より決定的な出力を得やすくするプレビュー機能」と位置づけています。

ここで2つのことが同時に書かれています。

  • 応答が非決定的であることは、不具合ではなく既定の仕様である
  • reproducible output が与えるのは一致ではなく、決定性への近づきやすさである

さらに同じページの Important ボックスには、次のように書かれています。reproducible output でも決定性は保証されない。seed パラメータと system_fingerprint がAPI呼び出しのあいだで同じであっても、応答にある程度のばらつきが観察されることは現時点では珍しくない。そして、同一の呼び出しであっても max_tokens の値が大きいほど、seed を設定していても応答は一般に決定的でなくなる——。

この記述が置かれている順番が重要です。「seed を指定すれば再現できる」が先にあって、そこに例外が添えられているのではありません。保証しないことを先に宣言し、そのうえで近づける手段を提供しているという構造です。なお、この機能は同ページで Preview と明記されています。

OpenAI 側の記述も、当初から同じ形でした。seed パラメータを紹介した Cookbook のレシピは、Chat Completions と Completions のAPIが既定で非決定的であると書き、seed を指定したときにシステムが行うのは「決定的にサンプリングしようとする best effort(最善の努力)」であり、得られるのは "mostly deterministic"(おおむね決定的)な出力だとしています。リクエストのパラメータと system_fingerprint が一致していても応答が異なる可能性がわずかに残る、とも書かれています。

このページの扱いには注意が必要です。冒頭に「このレシピはアーカイブされており、古いモデルやAPIを参照している可能性がある」と表示されています(ページ上の日付表示は2023年11月6日、当時はベータで一部モデルのみの対応と書かれています)。したがって、ここから読み取れるのは設計方針が当初からそう宣言されていたという事実だけです。現行の仕様値や対応モデルの根拠には使えません。

「温度」という比喩が、何を下げているのかを隠している

では、なぜ「temperature を 0 にすれば止まる」と感じるのでしょうか。

温度という言葉がよくできているからです。温度を下げれば分子の動きは鈍り、やがて止まる。この直観は馴染みがよく、しかも実際に temperature を下げると出力の揺れは目に見えて減ります。効果が観察できてしまうぶん、効果の範囲を確かめる動機が生まれません。 期待どおりの方向に数字が動いたとき、人はその操作がどこまでを担っているかを問わなくなります。

しかし、公式が「他のパラメータも一致させる必要がある」と書いていること自体が、temperature が揺れの一部しか担っていないことを示しています。同ページの Additional considerations 節は、reproducible output を使いたいなら seed を呼び出し間で同じ整数に設定し、temperature や max_tokens など他のパラメータも一致させるべきだと指示しています。もし temperature が揺れの全部を担っているなら、この指示は要りません。

比喩が強すぎると、「下げる」という操作の対象が何であるかを問わなくなります。ここで必要なのは、比喩を手放して何を固定したのかを列挙することです。

system_fingerprint は、固定するための入力ではない

seed と並んで出てくる system_fingerprint は、公式の説明ではモデルが動作するバックエンド構成を表す文字列で、chat completion オブジェクトの一部として返ります。そして seed と組み合わせて、決定性に影響しうるバックエンドの変更が行われた時点を把握するために使えるとされています。OpenAI Cookbook の側も、この値が変わる契機としてリクエストのパラメータを変えたときを挙げています。

この説明は、使い方の向きを示しています。system_fingerprint は出力を固定するための入力ではありません。出力が変わったときに、条件が変わったのかどうかを後から言えるようにするための記録です。

したがって、system_fingerprint を保存していない実行結果については、「同じ条件で再実行した」と主張できません。保存していないのは値ではなく、主張の根拠です。

公式ページ自身が、一致しない例を載せている

ドキュメントの実行例を見ると、この機能の性質がさらにはっきりします。

Azure OpenAI のページは、短い物語を生成させる例を3回ずつ、seed なしと seed=42 で示しています。seed なしの3つはそれぞれ別の文面になります。seed=42 の3つは、1つめと2つめが逐語で一致し、3つめは第1文のあとで別の文面に分岐します。この例の max_tokens は 50 です。ページはまた、seed なしの出力について「似た要素や逐語の重複はあっても、応答が長くなるほど乖離していく傾向がある」と述べています。

OpenAI Cookbook のレシピには、反復実行の結果が数値で載っています。既定設定での平均距離が 0.1136714512418833、seed を 123 に固定し temperature を 0 にした場合が 0.0449054397632461。下がってはいますが、0 ではありません。

この数値の読み方には留保が2つあります。1つは、距離の定義(埋め込み間の距離なのか文字列としての距離なのか)と試行回数を本記事では確認していないこと。もう1つは、これがアーカイブ済みページ掲載時点のモデルでの結果であり、現行モデルの再現性の水準を示すものではないことです。読み取れるのは「0 にはならなかった」という方向だけです。

「再現性がある」を、記録できる条件として定義し直す

ここまでの記述を前提にすると、「出力が一致すること」を再現性の定義に置くのは、達成できない基準を自分で設定していることになります。置き換える先はこうです。

再現性がある = そのとき何を固定していたかが記録として残っており、同じ条件で再実行したときのばらつきの幅が分かっている

この定義には、達成できたかどうかを確かめる手段があります。記録する列を決めればよいからです。

表が収まらない場合は、横にスクロールできます

記録する列なぜ必要か
プロンプト(テンプレートと埋め込んだ値を分けて)「同じプロンプト」が実際に同じだったかを後から確認できる
モデル名呼び出し先が変わっていないことの最低条件
temperature / top_p公式が「他のパラメータも一致させる」と指示している対象
max_tokens値が大きいほど決定性が下がると公式が明記している
seed固定していたか、していなかったかを区別する
system_fingerprintバックエンド構成が変わった時点を後から言える
実行日時上のすべてが同じでも結果が違ったとき、時間を軸に並べられる

ばらつきの幅を数で言うなら、分母と分子も決めておきます。分母は同一条件での実行回数、分子はそのうち基準を満たした回数です。単位は率(%)になります。「出力が安定している」という言い方を「同一条件20回中18回が基準を満たした(90%)」に置き換えられれば、次に設定を変えたときに比較ができます。「安定している」は比較できませんが、率は比較できます。

一致を要求してよい場面と、割合で見るしかない場面を分ける

回帰テストが書けなくなるのは、この2つを同じ方法で検査しようとするときです。

一致を要求してよい場面は、出力の形式を検証するときです。JSONとして成立しているか、必須キーが揃っているか、数値が想定範囲に入っているか。これらはスキーマで縛れるので、モデルの非決定性に賭ける必要がありません。形式が崩れたら失敗させてよい領域です。

割合で見るしかない場面は、文章の内容や品質を評価するときです。ここで文字列の完全一致をアサートすると、テストは「モデルが今日たまたま同じ文字列を返したか」を検査することになります。落ちたときに、プロンプトが劣化したのか、サンプリングが揺れただけなのかが区別できません。区別できない失敗は、やがて無視されます。

したがって、検査は3つに分けます。

  1. 形式の判定:1回の実行で、スキーマを満たすかを見る。満たさなければ失敗させる
  2. 性質の判定:1回の実行で、満たすべき性質(必須の項目が含まれる/禁止語が含まれない/数値が範囲内)を見る。満たさなければ失敗させる
  3. 品質の観測:複数回実行し、基準を満たした割合を記録する。単発の合否にしない

3つめを「テスト」ではなく「観測」と呼ぶのは、閾値を決めるために先にばらつきの幅を知る必要があるからです。幅を知らないまま閾値を置くと、閾値をまたぐたびに原因の分からない失敗が出ます。

確かなことと、まだ確かではないこと

確かなこと:Azure OpenAI の公式ドキュメントが、既定の挙動を非決定的と説明していること。seed と system_fingerprint が一致してもばらつきが観察されるのは珍しくないと明記していること。max_tokens が大きいほど決定性が下がると書いていること。seed 以外のパラメータも一致させるよう指示していること。OpenAI Cookbook が、seed で得られるのは best effort であり "mostly deterministic" だと書いていたこと。

まだ確かではないこと:他ベンダーのAPIが同じ挙動をするか(本記事では確認していません)。非決定性が生じる仕組み(参照した2文書に説明がありません)。現行モデルで実際にどの程度のばらつきが出るか(Cookbook の数値はアーカイブ済みページ掲載時点のものです)。なお Azure OpenAI のドキュメントは Microsoft Foundry(classic)向けと明示されており、新ポータル側の記述は確認していません。

10回走らせるだけの最小の検証

設定をどう変えるかの議論に入る前に、現状のばらつきの幅を測ります。

  1. 条件を1つ決める。プロンプト・モデル名・temperature・max_tokens・seed を固定する
  2. 同じ条件で10回実行し、出力と system_fingerprint を全部保存する
  3. 逐語で一致した本数を数える。何本が一致し、一致しなかったものはどこから分岐しているかを見る
  4. 評価したいのが正しさなら、合否の割合として記録する。人が1回見て「だいたい合っている」と判断するのをやめ、10回中何回が基準を満たしたかを書く

この4ステップで分かるのは「揺れているかどうか」ではなく揺れの幅です。幅が分かれば、temperature を下げる価値も max_tokens を絞る価値も、同じ尺度で比較できます。10回で足りなければ増やしますが、まずは10回で分布の形を見るところから始められます。

ここで決めた記録の列は、そのままAI機能の運用ログの設計にもなります。どこまでをAIに任せ、どこで人が確認するかという設計そのものについては、AIエージェント開発ガイド:ツール・承認・状態・停止を設計するで扱っています。

判断の土台として押さえておくこと

  • 公式が保証しているのは出力の一致ではなく、決定性への近づきやすさである
  • temperature は揺れの一部しか担っていない。公式自身が他のパラメータの一致を指示している
  • system_fingerprint は出力を固定する入力ではなく、条件が変わった時点を後から言うための記録である
  • 「再現性がある」を出力の一致で定義すると達成できない。何を固定したかの記録と、ばらつきの幅で定義する
  • 一致を要求してよいのは形式と性質の判定まで。内容の品質は割合で観測する
  • 長く書かせる機能ほど再現しにくい。max_tokens は再現性の設定でもある

参考資料・引用元

  • Microsoft Learn, Azure OpenAI の reproducible output に関するドキュメント(Microsoft Foundry(classic)向け). https://learn.microsoft.com/en-us/azure/foundry-classic/openai/how-to/reproducible-output (2026年10月13日確認・HTTP 200)
  • OpenAI Cookbook, seed パラメータで出力を一貫させる方法に関するレシピ(ページ上の日付表示 2023年11月6日、冒頭にアーカイブ表示あり). https://developers.openai.com/cookbook/examples/reproducible_outputs_with_the_seed_parameter (2026年10月13日確認・HTTP 200)

よくある質問(FAQ)