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-04-26中級

Gemini API のレスポンスで日本語が文字化けする時、最初に見るべき4つの場所

Gemini API で日本語レスポンスが文字化けする原因は、API側ではなくクライアント側の4つのレイヤーに潜んでいます。HTTPデコード、ストリーミングのチャンク境界、出力先の encoding、サロゲートペアの順にチェックする実践ガイドです。

gemini-api279troubleshooting57japaneseencodingutf-8streaming18

Gemini API を本番アプリに組み込んだ翌日、ユーザーから「画面が あい のような英数字記号に化けて読めません」という連絡が入る — そんな経験は、API を一度でも実装したことがある方なら覚えがあるのではないでしょうか。

私自身も Gemini API を使ったチャットアプリを最初にデプロイしたとき、ローカルでは綺麗に表示されていた日本語が、本番のログには \xe3\x81\x82\xe3\x81\x84 のような16進文字列で並んでいて、原因の特定に半日を費やしました。

実は Gemini API そのものは UTF-8 で正しい日本語を返しています。文字化けが起きる場所はほとんどの場合、API レスポンス側ではなく呼び出し側のクライアントコード・ストリーミング処理・出力先にあります。ここではGemini API で日本語レスポンスが文字化けしたときに、最初にチェックすべき4つのポイントを順番に解説します。

チェックポイント1: HTTP レイヤーの Content-Type と charset を確認する

最初に疑うべきは、HTTP レスポンスのデコードを担うクライアントライブラリの挙動です。

Gemini API は application/json; charset=UTF-8 を返しますが、フレームワークによっては charset を見落として ISO-8859-1 でデコードしてしまうケースがあります。Python の requests で発生しやすいパターンです。

import requests
 
# NG: 化けるパターン
response = requests.post(url, json=payload)
print(response.text)  # 'ã\x81\x82ã\x81\x84' のように化けることがある
 
# OK: 明示的に encoding を指定する
response = requests.post(url, json=payload)
response.encoding = "utf-8"
print(response.text)  # 正しく日本語表示される

response.text は内部的にエンコーディング判定を行いますが、ヘッダーの優先順位や apparent_encoding の挙動でブレることがあります。確実なのは response.json() を使うか、response.content.decode("utf-8") で明示的にバイト列をデコードする方法です。

JavaScript / Node.js の fetch でも同様の問題が起きます。

// OK: JSON で受け取れば fetch が UTF-8 デコードを担当する
const res = await fetch(url, {
  method: "POST",
  body: JSON.stringify(payload),
});
const data = await res.json();
console.log(data.candidates[0].content.parts[0].text);
 
// NG → OK: 自前でバッファ操作する場合は TextDecoder で明示
const buf = await res.arrayBuffer();
const decoded = new TextDecoder("utf-8").decode(buf);

ここまで確認しても化けるなら、原因は次のレイヤーにあります。

チェックポイント2: ストリーミングのチャンク境界でマルチバイト文字が切れている

Gemini API のストリーミングレスポンス(generateContentStream)でだけ文字化けが起きる場合、その犯人はほぼ間違いなくチャンク境界です。

UTF-8 では日本語1文字が3バイトで表現されます。SSE(Server-Sent Events)のチャンクは任意のバイト数で区切られるため、「あ」(E3 81 82)の3バイトが2つのチャンクに分かれることがあります。各チャンクを個別に decode("utf-8") すると、不完全なシーケンスでデコードエラーや化け文字 ? が混入します。

# NG: 各チャンクを個別にデコードする実装はバグります
async for chunk in stream:
    text = chunk.decode("utf-8")  # マルチバイト境界で壊れる
 
# OK: IncrementalDecoder で状態を保持する
import codecs
decoder = codecs.getincrementaldecoder("utf-8")()
 
async for chunk in stream:
    text = decoder.decode(chunk)  # 不完全なバイトはバッファされる
    if text:
        yield text
 
# ストリーム終了後に残りをフラッシュする
final = decoder.decode(b"", final=True)

公式 SDK(google-generativeai)を使っている場合は SDK 内部で IncrementalDecoder を使っているため、自前でストリームを読んでいる時だけこの問題が起きます。Edge Runtime や Cloudflare Workers で Response.body を直接 getReader() している場合は、特に注意が必要です。

ストリーミング全般のチャンク制御については Gemini API ストリーミングレスポンスのチャンクエラーとUX設計 で詳しく扱っています。

チェックポイント3: 出力先(コンソール・ファイル・DB)の encoding 設定

API から正しく日本語が取れていても、それを書き出す側で化けるパターンも非常に多いです。

特に Windows 環境のコンソール出力は要注意です。Python のデフォルト標準出力は cp932(Shift_JIS)が選ばれることがあり、print(response_text)UnicodeEncodeError が発生するか、化け文字に置き換えられます。

import sys
import io
 
# Windows でコンソールに日本語を出すための定石
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding="utf-8")
print(gemini_response)  # 正しく出力される
 
# ファイル書き出しも同じく encoding を明示する
with open("output.txt", "w", encoding="utf-8") as f:
    f.write(gemini_response)

データベースに保存する場合は、テーブルの文字コードが utf8mb4 になっているかも必ず確認してください。MySQL の古いデフォルト utf8(実体は3バイトUTF-8)では、絵文字や一部の漢字(𠮷野家の「𠮷」など)を含むレスポンスが切り捨てられて文字化けします。

チェックポイント4: 絵文字とサロゲートペアの取り扱い

Gemini はカジュアルな会話文を生成する際に、絵文字(🎉 や 😊)を自然に挿入することがあります。これらは UTF-16 サロゲートペアで2要素として表現されるため、文字数カウントや切り詰め処理で破綻しやすい部分です。

const text = "おめでとう🎉";
console.log(text.length);  // 7 — 絵文字が2文字としてカウントされる
 
// NG: 後ろから切ると絵文字が割れて化ける
text.slice(0, 6);  // "おめでとう\uD83C" のような不正な孤立サロゲート
 
// OK: Array.from でコードポイント単位に分解してから処理する
const points = Array.from(text);
points.slice(0, 5).join("");  // "おめでとう"

私の経験では、Gemini のレスポンスを Web Push 通知のタイトルに使う場面で、200文字制限のために slice(0, 200) をしていたら、ちょうど絵文字の途中で切れて配信エラーになったことがあります。ユーザー向けに表示する文字列を切り詰める時は、必ずコードポイント単位で扱うのが鉄則です。

日本語と英語が混在するレスポンスのコントロールについては、Gemini API の言語制御 — 出力が混在する問題の修正 で別途まとめています。出力品質そのものを底上げしたい方は、Gemini API 日本語タスク実践ガイド も合わせてご覧ください。

まずはこの順番でログに息を吹き込んでみてください

文字化けは原因の切り分けが命です。まずはログ出力を print(repr(response_text)) のように repr で囲んで、実際にどの段階のバイト列・文字列が壊れているかを可視化しましょう。'\xe3\x81\x82' のように生バイトが見えていればデコード前、'あ' のように Unicode コードポイントなら正しくデコードできています。

Gemini API はサーバー側ではきちんと UTF-8 を返してくれます。原因はかならずクライアント側の4つのレイヤー(HTTP デコード・ストリームチャンク・出力 encoding・サロゲートペア)のどこかにあるはずです。今日のうちに repr で1行ログを足しておくと、次に同じ事故が起きた時に5分で犯人を捕まえられるようになります。

シェア

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

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

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

もしこの記事がお役に立ちましたら、チップ(¥150)で応援いただけると大変励みになります。広告なしでの運営を続けるため、皆さまのご支援が大きな力になっています。

関連記事

API / SDK2026-05-23
Gemini API のストリーミングが本番で「途中で切れる」とき、私が試している原因切り分けの順序
Gemini API のストリーミング応答が本番で途中で切れる症状を、ネットワーク・SDK・サーバー側のどこから疑うかの順序を、個人開発で実際に踏んだ事例ごとに整理しました。
API / SDK2026-05-20
Gemini API のストリーミングが本番だけまとめて返ってくる — Cloud Run・Vercel・Cloudflare のバッファリング対処
ローカル開発では一文字ずつ流れるのに本番デプロイ後だけ応答が一括で返ってくる — Cloud Run / Vercel / Cloudflare Workers / Nginx で発生するストリーミングバッファリング問題を、原因と対処パターン別に整理しました。
API / SDK2026-03-29
Geminiストリーミング応答が途切れる時の対処法 — 原因特定から再接続まで
Gemini API のストリーミング応答が途中で切れてしまう問題を解決。ネットワークタイムアウト、チャンク処理エラー、トークン上限超過、安全フィルター中断など、原因別の対処方法と再接続ロジックを実装例付きで解説。
📚RECOMMENDED BOOKS
大規模言語モデル入門
山田育矢
LLM開発
生成AIプロンプトエンジニアリング入門
我妻幸長
プロンプト
Claude CodeによるAI駆動開発入門
平川知秀
AI駆動開発
※ アフィリエイトリンクを含みます
もっと見る →