◉GEMINI LABEN
●ARGON — gemini-4-argon が 10/13 に GA。複雑なコーディング・エージェント・数学・科学向けです●DEEP RES — deep-research-pro-preview-12-2025 は 10/23 に停止、残り6日。移行先は deep-research-preview-04-2026●NANO — gemini-nano-banana-2.1 が GA(10/06)。gemini-3.1-flash-image は非推奨で停止日は未発表です●MCP — ツール結果が 8.5万トークンに膨らんだ事例を、ADK で 310 トークンに包んで抑えた報告が出ています●FLASH — gemini-3.7-flash と 3.5-flash は新しい Flash モデルに自動で回されます(10/08)●NEW — クラッシュ報告を毎回ゼロから読ませない — 既知バグ早見表を先に grep し…●ARGON — gemini-4-argon が 10/13 に GA。複雑なコーディング・エージェント・数学・科学向けです●DEEP RES — deep-research-pro-preview-12-2025 は 10/23 に停止、残り6日。移行先は deep-research-preview-04-2026●NANO — gemini-nano-banana-2.1 が GA(10/06)。gemini-3.1-flash-image は非推奨で停止日は未発表です●MCP — ツール結果が 8.5万トークンに膨らんだ事例を、ADK で 310 トークンに包んで抑えた報告が出ています●FLASH — gemini-3.7-flash と 3.5-flash は新しい Flash モデルに自動で回されます(10/08)●NEW — クラッシュ報告を毎回ゼロから読ませない — 既知バグ早見表を先に grep し…
記事一覧/API / SDK
◈ API / SDK/2026-07-01上級

AI Studio で通ったプロンプトが API では静かに崩れるとき — 差分を計測して切り分ける運用メモ

AI Studio では完璧に動いたプロンプトが、自分のコードから Gemini API を呼ぶと空応答や 404 になる。目視ではなく、設定差と finish_reason・使用トークン・解決モデル名を機械的に記録する小さなハーネスで、原因別に切り分ける運用手順をまとめました。

gemini-api287google-ai-studio3troubleshooting59instrumentationsafety-filtermodel-name

✦ プレミアム記事

Studio 上で何度叩いても綺麗に返ってきたプロンプトが、Get code でコピーして自分のコードに落とした途端に空文字を返す。私も個人開発でいくつも API を触ってきましたが、この「昨日は動いていた」の一言で片づけたくなる状況が、いちばん時間を溶かします。厄介なのは、多くの場合エラーすら出ないことです。例外が飛べばスタックトレースを追えますが、response.text が静かに空文字で返るときは、どこから疑えばいいのか手がかりが乏しいのです。

そこで私がたどり着いたのは、原因を目視で探すのをやめて、Studio と API の「差」そのものを毎回記録する小さなハーネスを挟むという進め方でした。差分を数字で残せるようになると、次に同じ症状が出たときの調査時間が体感で数分に縮みます。2026 年前半に Gemini API 側で起きた変更(Interactions API の GA 化、未制限 API キーの遮断、preview モデルの相次ぐ廃止)も、この「静かに壊れる」系統の事故を増やしているので、そこも織り込んで書きます。

なぜ目視の突き合わせは破綻するのか

「Studio の設定とコードを見比べればいい」という助言はよく見かけますし、正しくもあります。ただ実務では破綻しがちです。理由は三つあります。

一つ目は、Studio が裏で補っている初期値が UI に全部は出ていないこと。二つ目は、モデル名がエイリアス(gemini-flash-latest のような *-latest)だと、同じ文字列でも解決先が日によって変わり得ること。三つ目は、空応答の原因が複数レイヤー(安全フィルタ・権限・モデル解決・API バージョン)にまたがるのに、response.text はどのレイヤーで落ちても同じ「空文字」に見えることです。

目で追える差は「見えている設定」だけです。事故の多くは見えていない差で起きます。だから、突き合わせの対象を人間の注意力から、機械が吐くログへ移します。

最小の観測点 — 空応答のときに必ず残す4つの値

まず、既存の呼び出しに観測を足すところから始めます。response.text だけを見ている実装に、次の4つを必ずログへ落とします。これは新しい SDK(google-genai)の usage_metadata と candidates から取れます。

from google import genai
from google.genai import types
 
client = genai.Client(api_key="YOUR_API_KEY")
 
def call_with_probe(model: str, contents: str, config: types.GenerateContentConfig):
    res = client.models.generate_content(model=model, contents=contents, config=config)
    cand = res.candidates[0] if res.candidates else None
    probe = {
        # 1. なぜ止まったのか(STOP / SAFETY / MAX_TOKENS / RECITATION など)
        "finish_reason": str(cand.finish_reason) if cand else "NO_CANDIDATE",
        # 2. 入力側でブロックされたか(プロンプト自体が弾かれるケース)
        "prompt_feedback": str(res.prompt_feedback),
        # 3. 実際に消費したトークン(0 に近ければ生成前に落ちている)
        "usage": {
            "prompt": res.usage_metadata.prompt_token_count,
            "output": res.usage_metadata.candidates_token_count,
        } if res.usage_metadata else None,
        # 4. サーバが返したモデル名(エイリアスが何に解決されたか)
        "resolved_model": getattr(res, "model_version", None),
    }
    return res, probe
 
cfg = types.GenerateContentConfig(temperature=0.7)
res, probe = call_with_probe("gemini-flash-latest", "今日のニュースを3行で", cfg)
print(probe)
print("text:", res.text or "(empty)")

ここで効いてくるのが4番目の model_version です。*-latest を渡していると、サーバが実際に何へ解決したかは投げてみないと分かりません。Studio で試したその日と、本番で叩く日で解決先がずれていれば、「同じモデル名なのに挙動が違う」の正体はここです。finish_reason が SAFETY なら安全フィルタ、output トークンが 0 に近いのに finish_reason が STOP なら生成前の段階(権限・モデル解決)を疑う、という初動の分岐がこの4値だけで立ちます。

✦

ここまでお読みいただきありがとうございます。

この記事の続きを読む

この先には、実装コードやベンチマーク結果など、実務でお役に立てる内容をご用意しています。このサイトは広告を掲載しておらず、サーバーや開発にかかる費用はメンバーの皆様のご支援で成り立っています。もしお役に立てていましたら、ご支援いただけますと大変ありがたいです。

この記事で得られること
✦Studio の Get code と本番呼び出しの設定差を機械的に diff し、finish_reason・usage・実際に解決されたモデル名まで一度に記録する小さなハーネスの作り方
✦*-latest エイリアスのドリフトや preview モデル廃止で「昨日まで動いていた」が静かに壊れる箇所を、事前に計測して掴む観測ポイント
✦空応答・400・404 を症状ではなく原因(安全フィルタ / 権限・地域 / モデル解決 / API バージョン)で切り分ける、二分探索の再現手順
Stripe による安全な決済 · いつでもキャンセル可能
✦

この記事を購入する

この先の内容をすべてお読みいただけます。一度のご購入で、いつでも何度でもアクセスできます。このサイトは広告を掲載しておらず、皆さまのご支援がサーバー費用などの運営を支えています。

または
メンバーシップなら全記事が読み放題 →
シェア

お読みいただきありがとうございます

Gemini Lab は広告なしで運営しており、サーバー費用などの運営コストはメンバーシップのご支援で賄っています。実装コード・ベンチマーク・本番設計パターンなど、実務でお役立ていただける記事を毎日更新しています。もし読んでよかったと感じていただけましたら、ぜひご覧ください。

  • ✦コピー&ペーストで使える実装コード付き
  • ✦毎日新しい上級ガイドを追加
  • ✦¥580/月 または ¥1,480 の永久アクセス
メンバーシップを見る →

関連記事

◈ API / SDK2026-10-16
models は 200 なのに generateContent だけ 403 になる日 — 切り分けの順番を先に決めておく
モデル一覧の取得は 200 で通るのに、生成リクエストだけが 403 permission_denied で止まるときの切り分け手順です。キー・プロジェクト・請求の順に確かめる小さな診断スクリプトと、リトライしてはいけない理由、サポートへ渡す材料の揃え方をまとめました。
◈ API / SDK2026-05-20
Gemini API のストリーミングが本番だけまとめて返ってくる — Cloud Run・Vercel・Cloudflare のバッファリング対処
ローカル開発では一文字ずつ流れるのに本番デプロイ後だけ応答が一括で返ってくる — Cloud Run / Vercel / Cloudflare Workers / Nginx で発生するストリーミングバッファリング問題を、原因と対処パターン別に整理しました。
◈ API / SDK2026-05-17
Gemini API で画像バッチ分析の INVALID_ARGUMENT エラーを診断する
Gemini API で複数画像を一括分析するとき INVALID_ARGUMENT エラーが出て詰まった経験はありませんか。MIMEタイプ・サイズ制限・リクエスト構造という3つの原因を診断し、File API と inline data を使い分けて根本解決する実践ガイドです。