GEMINI LABEN
NANOLITE — Nano Banana 2 Liteが登場しました。Googleで最も速く、最もコスト効率の高いGemini Imageモデルで、軽量な画像生成を安く回したい用途に向いていますOMNIFLASH — Gemini Omni Flashがpublic previewになりました。ネイティブにマルチモーダルなモデルで、企業や開発者が独自の動的な動画ワークフローを構築できますAGENTS — Managed Agentsが拡張されました。background: trueでサーバー側の非同期実行とポーリング、リモートMCPサーバー連携、対話をまたぐ認証情報のリフレッシュに対応しますMEMORY — Memory BankのIngestEvents APIが一般提供になりました。イベントの取り込みとメモリ生成を分離し、コンテンツを継続的にストリームできますTHROUGHPUT — Provisioned Throughputで、同一モデル・同一リージョンに対して最大7件の保留オーダーを提出できるようになりましたDEPRECATE — 画像生成モデルは8月17日に、Gemini Enterprise Agent PlatformのGrok 4.1系は8月20日に停止される予定ですNANOLITE — Nano Banana 2 Liteが登場しました。Googleで最も速く、最もコスト効率の高いGemini Imageモデルで、軽量な画像生成を安く回したい用途に向いていますOMNIFLASH — Gemini Omni Flashがpublic previewになりました。ネイティブにマルチモーダルなモデルで、企業や開発者が独自の動的な動画ワークフローを構築できますAGENTS — Managed Agentsが拡張されました。background: trueでサーバー側の非同期実行とポーリング、リモートMCPサーバー連携、対話をまたぐ認証情報のリフレッシュに対応しますMEMORY — Memory BankのIngestEvents APIが一般提供になりました。イベントの取り込みとメモリ生成を分離し、コンテンツを継続的にストリームできますTHROUGHPUT — Provisioned Throughputで、同一モデル・同一リージョンに対して最大7件の保留オーダーを提出できるようになりましたDEPRECATE — 画像生成モデルは8月17日に、Gemini Enterprise Agent PlatformのGrok 4.1系は8月20日に停止される予定です
記事一覧/API / SDK
API / SDK/2026-06-02上級

Gemini APIの設定ドリフトを止める — モデルID・安全設定をコード化して環境差を検出する

同じコードなのにアプリごとに挙動が違う原因の多くは、モデルIDや安全設定の環境差です。設定をコード化し、本番の実効設定をスナップショットして差分を検出する設計を、実装レベルで解説します。

Gemini API191設定管理本番運用47個人開発者8CI5

プレミアム記事

「アプリAだけ、なぜか出力が短く切れる」。複数のアプリで同じ Gemini 統合を使い回していると、こうした"片方だけ"の不具合に何度かぶつかります。コードを何度見比べても差は見つからない。原因はコードではなく、**環境ごとに少しずつズレた設定(config drift)**でした。アプリAの本番だけ max_output_tokens が古い値のまま残っていた、というだけの話です。

(私・廣川政樹は2014年から個人開発で複数のアプリを運営しており、現在は壁紙・癒し系を中心に6本前後のアプリで Gemini API を併用しています。設定の食い違いで深夜に原因を追った経験が、この記事の出発点です。)

設定ドリフトは、コードレビューでは捕まりません。git diff に出てこないからです。モデルIDや安全設定は環境変数やダッシュボードの設定値として外部化されることが多く、コードと別の場所で静かにズレていきます。ここで扱うのは、Gemini 統合の設定を「コード化(config-as-code)」し、本番で実際に効いている設定をスナップショットして、環境間の差分を機械的に検出する設計です。祖父が宮大工で「手を動かすことが一つの信心だ」と言っていたのを思い出すのですが、設定もまた、目に見えないところを丁寧に揃えておくほど後で楽になる領域です。

設定ドリフトはなぜ静かに事故になるのか

ドリフトが厄介なのは、壊れた瞬間にエラーにならない点です。max_output_tokens が小さすぎても 200 が返ってきます。safety_settings が緩い環境では通っていたプロンプトが、別の環境の厳しめ設定で finish_reason: SAFETY になります。どちらも例外を投げないので、監視のエラー率には乗りません。ユーザーレビューで「途中で切れる」と指摘されて初めて気づく、という遅延が生まれます。

私が実際に検出した範囲では、ドリフトしやすい設定は次の7項目です。発生頻度と影響度から、検出の優先順位をつけています。

  1. モデルID — 最重要。gemini-2.5-flash のまま放置 vs gemini-3.2-flash へ更新済み、のように世代が割れる。出力品質とコストが両方ズレる
  2. max_output_tokens — 出力が途中で切れる典型原因。デフォルト値の変更時に更新漏れが起きやすい
  3. safety_settings — しきい値の不一致で片方だけブロックされる
  4. temperature / top_p — 再現性とトーンがズレる。A/Bテストの残骸が本番に残りがち
  5. system_instruction — プロンプト改善の反映漏れ。アプリごとにコピペ運用していると最も腐りやすい
  6. thinking_config(thinking budget) — レイテンシとコストに直結。検証用の大きな値が残ると課金が跳ねる
  7. APIバージョン / SDKバージョンv1betav1 の混在など。挙動の差は小さいが原因切り分けを難しくする

ポイントは、これらがコードのリポジトリ外に散らばっていることです。環境変数、シークレットマネージャ、Remote Config、ダッシュボードの手動設定。散らばっているほどドリフトします。最初の一手は、これらを一箇所のコードに集約することです。

設定を「単一の真実の源」にコード化する

まず、Gemini に渡す設定を型付きのスキーマとして定義します。Pydantic を使うと、値の検証とシリアライズが同時に手に入ります。次のコードは、ドリフト検出の対象になる設定を1つのモデルにまとめたものです。

# gemini_config.py
from pydantic import BaseModel, Field
from typing import Literal
import hashlib
import json
 
class SafetyThreshold(BaseModel):
    category: str
    threshold: Literal[
        "BLOCK_NONE", "BLOCK_ONLY_HIGH",
        "BLOCK_MEDIUM_AND_ABOVE", "BLOCK_LOW_AND_ABOVE",
    ]
 
class GeminiConfig(BaseModel):
    """1アプリ1環境ぶんの Gemini 実効設定。これを単一の真実の源とする。"""
    app_id: str
    environment: Literal["dev", "staging", "production"]
    model_id: str = Field(pattern=r"^gemini-[\d.]+-(flash|pro)(-lite)?$")
    api_version: Literal["v1", "v1beta"] = "v1"
    max_output_tokens: int = Field(ge=1, le=65536)
    temperature: float = Field(ge=0.0, le=2.0)
    top_p: float = Field(ge=0.0, le=1.0)
    thinking_budget: int = Field(ge=0, le=24576)
    safety_settings: list[SafetyThreshold]
    system_instruction_sha: str  # 本文ではなくハッシュで管理する
 
    def fingerprint(self) -> str:
        """app_id/environment を除いた"効き目"だけのハッシュ。環境間比較に使う。"""
        payload = self.model_dump(exclude={"app_id", "environment"})
        canonical = json.dumps(payload, sort_keys=True, ensure_ascii=False)
        return hashlib.sha256(canonical.encode("utf-8")).hexdigest()[:16]

ここで効いてくるのが fingerprint() です。app_idenvironment を除いた設定本体をハッシュ化することで、「dev と production で効き目が同じか」を1つの文字列の一致で判定できます。system_instruction は本文ではなくハッシュ(system_instruction_sha)で持つのがコツです。本文をそのまま比較すると差分が読みにくく、シークレットが混ざるリスクもあるためです。

各アプリの設定は、コードと同じリポジトリに置いた JSON で宣言します。これが「あるべき姿(desired state)」です。

# configs/wallpaper_app.production.json
{
  "app_id": "wallpaper-app",
  "environment": "production",
  "model_id": "gemini-3.2-flash",
  "api_version": "v1",
  "max_output_tokens": 2048,
  "temperature": 0.4,
  "top_p": 0.95,
  "thinking_budget": 0,
  "safety_settings": [
    {"category": "HARM_CATEGORY_HARASSMENT", "threshold": "BLOCK_MEDIUM_AND_ABOVE"}
  ],
  "system_instruction_sha": "a1b2c3d4e5f60718"
}

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

この記事の続きを読む

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

この記事で得られること
設定ドリフトが静かに事故になる仕組みと、検出すべき7項目の優先順位
モデルID・安全設定・生成パラメータをコード化する単一の真実の源の実装
本番の実効設定をスナップショットし、環境間の差分をCIで止めるゲートの作り方
Stripe による安全な決済 · いつでもキャンセル可能

この記事を購入する

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

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

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

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

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

関連記事

API / SDK2026-06-17
生成文の『文体の癖』を数値で見張る — 既定モデルの差し替えを文体ドリフトで検知する設計
既定モデルが頭越しに変わると、出力の正しさはそのままでも文体の癖が静かにズレます。生成文の敬体率や文長分布をフィンガープリント化し、統計的に文体ドリフトを検知してパイプラインを止める設計を、依存ライブラリなしの実装で解説します。
API / SDK2026-06-14
Gemini APIの『デフォルトモデルが上がる』を事故にしない — モデルIDの固定と既定変更の検知設計
既定モデルが静かに上がると、同じコードのまま出力長・推論挙動・コストが変わります。モデルIDを単一の真実の源で固定し、レスポンスの実効モデルを検証して既定変更を検知する設計を、実装レベルで解説します。
API / SDK2026-06-03
Gemini 生成物の来歴を残す — 再現と監査のためのプロベナンス設計
数ヶ月後に「この出力はどのモデルとプロンプトで作ったのか」が追えなくなる前に。Gemini の生成物へ来歴メタデータを刻み、品質調査とモデル移行を再現可能にする設計をまとめます。
📚RECOMMENDED BOOKS
大規模言語モデル入門
山田育矢
LLM開発
生成AIプロンプトエンジニアリング入門
我妻幸長
プロンプト
Claude CodeによるAI駆動開発入門
平川知秀
AI駆動開発
※ アフィリエイトリンクを含みます
もっと見る →