
LLMのチャットUIとAPIで挙動が違う?プロバイダー横断で原因と対策を整理してみた
はじめに
「ChatGPTで完璧に動いたプロンプトが、APIに持っていったら全然違う結果になる...」
こんな経験ありませんか?自分もプロンプトを検証する際にチャットUIで試してからAPIに移植する流れをよくやるのですが、同じプロンプトなのに挙動が変わることがあり、原因を調べてみました。
結論から言うと、これはOpenAIだけの問題ではなく、Claude(Anthropic)やGemini(Google)でも同じパターンが存在します。本記事では、なぜ挙動が違うのか、各プロバイダーでどう対処すべきかを整理します。

なぜチャットUIとAPIで結果が違うのか
挙動差の原因は大きく2つのレイヤーに分かれます。
1. モデルバージョンの不一致
チャットUI(ChatGPT、claude.ai、Gemini アプリ)とAPIでは、同じモデル名でも裏で走っているスナップショットが異なることがあります。
- チャットUIはプロバイダーが随時アップデートする(変更ログが出ないことも多い)
- APIは明示的にバージョンを指定しない限り、デフォルトのエイリアスが使われる
- エイリアス自体もプロバイダー側で切り替わることがある
2. 隠れたデフォルト設定
チャットUIには、ユーザーからは見えない設定が多数適用されています:
| 設定項目 | チャットUI | API |
|---|---|---|
| System Prompt | プロバイダーが設定済み(長文) | 未設定(空白)か自分で指定 |
| Temperature | 会話向けに最適化された値 | モデルのデフォルト値(異なることあり) |
| Top-p / Top-k | 調整済み | モデルデフォルト |
| 安全性フィルター | 厳しめに設定 | APIによって異なる(設定可能) |
| コンテキスト管理 | 自動要約・切り詰め | 開発者が制御 |
つまり、チャットUIで「うまくいった」のは、見えない設定群との組み合わせでうまくいっていた可能性が高いのです。
モデルバージョニング:各プロバイダーの仕組み
以下はモデルバージョン指定の代表的なパターンです(具体的なバージョン名は時期により変わります)。
OpenAI
gpt-4o ← エイリアス(変わりうる)
gpt-4o-2024-08-06 ← ピン留めスナップショット(固定)
- エイリアス(
gpt-4o)はOpenAIが新しいスナップショットに切り替えると挙動が変わる - ピン留めバージョン(日付入り)は変わらない
- ChatGPT側のモデルはAPI公開前のバージョンが使われることもある
Anthropic(Claude)
claude-sonnet-4-5-20250514 ← ピン留め(固定)
claude-sonnet-4-5-latest ← エイリアス(変わりうる)
- claude.ai は独自のシステムプロンプトとパラメータ設定を持つ
- APIではピン留めバージョンを指定すれば完全に固定される
latestエイリアスはAnthropicが新モデルリリース時に更新
Google(Gemini)
gemini-2.0-flash-001 ← ピン留め(固定)
gemini-2.0-flash ← エイリアス(変わりうる)
- GeminiアプリとAPI間で同じパターン
- Google AI Studio で試した結果とAPIで異なることもある(Studio独自のデフォルトがあるため)
クロスプロバイダー比較
| 観点 | OpenAI | Anthropic | |
|---|---|---|---|
| ピン留めバージョン形式 | model-YYYY-MM-DD |
model-YYYYMMDD |
model-NNN |
| エイリアス更新頻度 | 数ヶ月に1回 | モデルリリース時 | モデルリリース時 |
| チャットUI更新頻度 | 頻繁(週次レベル) | 月次程度 | 頻繁 |
| UI側system prompt公開 | 非公開(リークあり) | 非公開 | 非公開 |
| API deprecation通知 | あり(6ヶ月前目安) | あり | あり |
| チャットUI→API移植難度 | 中〜高(隠れたsystem promptが長い) | 中(パラメータの差が比較的少ない) | 中〜高(AI Studioとの差も加わる) |
プロンプト移植の実践チェックリスト
チャットUIで検証したプロンプトをAPIに移す際のチェックリスト:
1. モデルバージョンを固定する
# Bad: エイリアスは変わりうる
model = "gpt-4o"
# Good: ピン留めバージョンを使う
model = "gpt-4o-2024-08-06"
2. パラメータを明示的に指定する
# チャットUIのデフォルトに依存しない
response = client.chat.completions.create(
model="gpt-4o-2024-08-06",
temperature=0.7, # 明示的に指定
top_p=1.0, # 明示的に指定
max_tokens=4096, # 明示的に指定
messages=[...]
)
3. System Promptを再現する
チャットUIには見えないsystem promptが入っている。APIでは自分で設定する必要がある:
messages = [
{"role": "system", "content": "あなたは..."}, # 自分で定義
{"role": "user", "content": "実際のプロンプト"}
]
4. テスト環境を構築する
- 同一プロンプト × 同一パラメータで複数回実行し、ばらつきを確認
- Temperature=0 でも完全に決定的ではないことに注意(特にOpenAI)
- チャットUIの結果をベースラインとして保存し、APIの結果と比較
5. バージョン更新に備える
- ピン留めバージョンにもEOL(End of Life)がある
- deprecation通知を監視する仕組みを入れる(各社のchangelogやstatus page)
- 定期的に新バージョンへの移行テストを実施
まとめ
| 学び | 実務での判断基準 |
|---|---|
| チャットUIは「お試し環境」であり「本番」ではない | プロトタイプはUIで、本番実装は必ずAPIで再検証 |
| エイリアスは便利だが不安定 | 本番ではピン留めバージョンを使う |
| 見えない設定が結果を左右する | temperature, system prompt, top_p は必ず明示 |
| 全プロバイダーで同じ問題が起きる | プロバイダー乗り換え時も同じチェックリストが使える |
フレームとしては:API(ピン留めバージョン)= 安定・再現可能、チャットUI = 揮発性が高い(プロバイダーが随時調整) と覚えておくと、トラブル時の原因切り分けが速くなります。








