◉GEMINI LABEN
●CLI 0.62.0 — Gemini CLI v0.62.0(9月29日)に Gemini 3.8 Flash と 3.5 Flash-Lite の対応が入りました。OAuth の更新トークンを保持する修正も入っています●10/02 — 本日、gemini-2.5-flash-image が提供終了日を迎えました。移行先は gemini-3.1-flash-image で、差し替え漏れの洗い出しが今週の作業です●TOOLS — Gemini CLI で MCP のツールが128個を超えると 400 エラーになる、という Issue が上がっています。ツール数の絞り方が論点です●NEW — 3月に増えた Docs・Sheets・Slides・Drive の Gemini 機能、半年後に残したものと外したもの●CLAUDE — Claude Code から Gemini 3.8 へ日本語処理を振る併用が Zenn で読まれています。振る仕事と振らない仕事の線引きが論点です●12/31 — 3.8 / 3.7 / 3.6 Flash と robotics-er-2 の導入価格終了まで残り90日。3.5 Flash は据え置きです●CLI 0.62.0 — Gemini CLI v0.62.0(9月29日)に Gemini 3.8 Flash と 3.5 Flash-Lite の対応が入りました。OAuth の更新トークンを保持する修正も入っています●10/02 — 本日、gemini-2.5-flash-image が提供終了日を迎えました。移行先は gemini-3.1-flash-image で、差し替え漏れの洗い出しが今週の作業です●TOOLS — Gemini CLI で MCP のツールが128個を超えると 400 エラーになる、という Issue が上がっています。ツール数の絞り方が論点です●NEW — 3月に増えた Docs・Sheets・Slides・Drive の Gemini 機能、半年後に残したものと外したもの●CLAUDE — Claude Code から Gemini 3.8 へ日本語処理を振る併用が Zenn で読まれています。振る仕事と振らない仕事の線引きが論点です●12/31 — 3.8 / 3.7 / 3.6 Flash と robotics-er-2 の導入価格終了まで残り90日。3.5 Flash は据え置きです
記事一覧/API / SDK
◈ API / SDK/2026-07-04上級

Gemini API の英語出力に日本語が『たまに』混ざるとき — 混入率を計測して段階的に締める運用メモ

英語出力を指示したGemini APIが、100回に数回だけ日本語を混ぜてくる——この『たまに』を止められない本当の理由と、混入率をSLOとして計測し、段階的リカバリで本番品質まで締める運用パターンを実装コード付きで整理します。

gemini-api286python105multilingual4observability11production105

✦ プレミアム記事

英語サマリーを返すだけの単純な処理を書いたつもりが、100 本流すと 3 本ほど、末尾の一文だけ日本語が顔を出します。ローカルで 20 回試したときは一度も再現せず、本番で数日回してから読者の指摘で気づく——個人開発で多言語のコンテンツ生成を Gemini API に任せていて、私自身が一番手を焼いたのはこの「たまに混ざる」でした。

厄介なのは、これがバグらしいバグに見えないことです。例外は飛ばず、JSON も壊れず、大半の出力は完璧な英語。だからこそ、テストでは捕まらず、監視にも引っかからないまま本番をすり抜けます。ここでは「英語で出力させても日本語が混ざる」現象を、止める前にまず計測するという順番で扱います。混入を連続量として観測できるようにしてから、System Instructions・Few-shot・スキーマ検証・段階的リカバリを、それぞれの効き目を測りながら重ねていきます。

なぜ「たまに」なのか — 二値ではなく確率で起きている

英語を指示しても日本語が混ざる直接の原因は、Gemini が大量の多言語コーパスで学習されており、長い日本語入力に注意(attention)が強く引かれることにあります。プロンプト末尾に短く Answer in English と添えても、入力本文が長いほど指示の相対的な強度は下がります。加えて、固有名詞や引用のように「そのまま保持したほうが正確だ」とモデルが判断した箇所は、指示を強めない限り原語で残ります。

ここで見落としやすいのが、この現象が決定論的ではないという点です。同じ入力でも、温度やサンプリングの揺らぎによって、混ざる回もあれば混ざらない回もあります。つまり本質は「混入するか否か」という二値ではなく、「1,000 出力あたり何回混ざるか」という確率です。私の翻訳パイプラインの実測では、入力が 2,000 トークンを超えるあたりから Gemini 2.0 Flash で混入が目立ち始め、2.5 Pro でも 3.1 Pro でも完全にゼロにはなりませんでした。「モデルを上げれば直る」という発想を捨てるべき理由がここにあります。相手が確率なら、対策も「計測して閾値まで下げる」という形にせざるを得ません。

まず混入を計測する — 二値の検出器と混入率

対策を積む前に、出力を数えられる状態にします。ひらがな・カタカナ・漢字の Unicode 範囲を検出する軽量な関数を用意し、混入した「文字数の割合」まで返すようにしておくと、後で閾値を引けます。

import re
from dataclasses import dataclass
 
JP_RANGE = re.compile(r"[぀-ヿ一-鿿]")
 
@dataclass
class LangCheck:
    contaminated: bool      # 日本語が1文字でも混入したか
    jp_chars: int           # 日本語文字数
    total_chars: int        # 全文字数
    ratio: float            # 混入率(0.0-1.0)
    sample: str             # 最初に見つかった混入箇所の周辺
 
def check_english_output(text: str) -> LangCheck:
    matches = list(JP_RANGE.finditer(text))
    total = len(text) or 1
    sample = ""
    if matches:
        i = matches[0].start()
        sample = text[max(0, i - 20): i + 20]
    return LangCheck(
        contaminated=bool(matches),
        jp_chars=len(matches),
        total_chars=total,
        ratio=len(matches) / total,
        sample=sample,
    )

ratio を持たせるのが要点です。末尾に一文だけ日本語が残る軽症と、丸ごと日本語で返ってくる重症を、同じ「混入」で括ってしまうと後段の判断を誤ります。sample に混入箇所の周辺を残しておくと、ログを見ただけで「固有名詞が残っただけか、指示自体が無視されたのか」を切り分けられます。

そのうえで、本番の各呼び出しにこの検査を通し、混入率を時系列で残します。私は 1 リクエストごとに 1 行のログを出し、日次で「混入したリクエストの割合(contamination rate)」を集計しています。これを一種の SLO として扱い、たとえば「0.5% 未満」を維持目標に置くと、対策の効果を体感ではなく数字で語れるようになります。

import json, time
 
def log_lang_metric(request_id: str, model: str, in_tokens: int, chk: LangCheck):
    print(json.dumps({
        "ts": time.time(),
        "request_id": request_id,
        "model": model,
        "in_tokens": in_tokens,
        "contaminated": chk.contaminated,
        "jp_ratio": round(chk.ratio, 4),
        "sample": chk.sample,
    }, ensure_ascii=False))

in_tokens を必ず一緒に残すのがコツです。後で集計すると、混入は入力長と強く相関しているのが見えてきます。相関が見えれば、「長い入力だけ対策を厚くする」という費用対効果の高い打ち手に進めます。

✦

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

この記事の続きを読む

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

この記事で得られること
✦出力言語の混入を『0か1か』ではなく混入率という連続量として計測する検出器とログ設計
✦System Instructions・Few-shot・response_schema それぞれが『どの条件で効いてどこで破れるか』の実測比較
✦盲目的な再試行ではなく、違反箇所を引用して締める段階的リカバリの実装と人手エスカレーションの線引き
Stripe による安全な決済 · いつでもキャンセル可能
✦

この記事を購入する

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

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

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

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

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

関連記事

◈ API / SDK2026-04-23
Gemini API × Langfuse — LLM オブザーバビリティの本番実装ガイド
Gemini API を本番運用するチーム向けに、Langfuse を使った LLM オブザーバビリティの実装を体系的に解説します。トレース設計、コスト可視化、プロダクショントレースでの LLM-as-Judge 評価、PII マスキング、サンプリングまで動作コード付きで網羅します。
◈ API / SDK2026-05-15
Gemini API を asyncio で並列化したら、壁紙アプリの多言語説明文生成が12倍速になった
12言語の App Store 説明文生成を Gemini API の asyncio 並列化で13分から65秒に短縮した実装記録です。Semaphore によるレート制限対策と、google-generativeai から google-genai への移行で変わった点まで含めてまとめました。
◈ API / SDK2026-04-22
Gemini API 本番の耐障害性設計 — Circuit Breaker・Bulkhead・フォールバックモデルで AI サービスを落とさない実装パターン
Gemini API の本番運用で発生する 429・503・タイムアウト障害を乗り切るための耐障害性設計を実装レベルで解説します。Circuit Breaker、Bulkhead、フォールバックモデル切替、Graceful Degradation までコード付きで網羅します。
📚RECOMMENDED BOOKS
大規模言語モデル入門
山田育矢
LLM開発
生成AIプロンプトエンジニアリング入門
我妻幸長
プロンプト
Claude CodeによるAI駆動開発入門
平川知秀
AI駆動開発
※ アフィリエイトリンクを含みます