Google GenAI SDK のストリーミングでマルチターン画像編集🍌が不安定になる問題と対処法

Google GenAI SDK のストリーミングでマルチターン画像編集🍌が不安定になる問題と対処法

こんにちは!

Gemini 3 Pro Image (Nano banana Pro)を使ったマルチターン画像編集機能を実装していたところ、動いたり動かなかったりするという厄介な問題に遭遇しました。

本記事では、この問題の現象、原因調査の過程、そして解決策を共有します。


問題の現象

実行環境

Google GenAI SDKライブラリ(pip): google-genai 1.56.0

期待する動作

  1. ユーザー: 「かわいい子猫の画像を生成して」
  2. Gemini: 子猫の画像を生成
  3. ユーザー: 「この子にメガネをかけて」
  4. Gemini: 同じ子猫にメガネをかけた画像を生成

実際に起きた現象

  1. ユーザー: 「かわいい子猫の画像を生成して」
  2. Gemini: 茶色の子猫の画像を生成
  3. ユーザー: 「この子にメガネをかけて」
  4. Gemini: メガネをかけた女の子の画像を生成
あれれ、メガネをかけた子猫になるはずが、メガネをかけた女の子の画像が生成されてしまった

つまり、前回生成した画像を「覚えていない」状態になっていました。

厄介だったのは「再現性のなさ」

この問題が特に厄介だったのは、動いたり動かなかったりするという点でした。

  • 同じコードなのに、タイミングによって成功したり失敗したり、と挙動が変わる
  • サーバー再起動したら、タイミングからは長時間動作しなくなる
  • 開発環境では動いたが、ステージングでは動かない

同一コードで急に動かなくなると、「いったん再起動しよう」などとりあえずやってしまうと、環境の固定が崩れてしまい、問題の切り分け難しくなり「さっきまで動いてたのに...」という状況が発生し、原因特定に時間がかかりました。


原因調査

thought_signature の仕組み

Gemini 3 Pro Image のマルチターン画像編集は、thought_signature という仕組みに依存しています。

  • 画像生成時に、モデルは thought_signature を返す
  • これは生成した画像の情報(構図、色、内容など)を保持する約2MBのデータ
  • 次のターンでこれを渡すことで、前回の画像を「覚えている」状態になる

Google の公式ドキュメントによると

If you use the official Google Gen AI SDKs and use the chat feature, thought signatures are handled automatically.

ということで、つまり、SDK のチャット機能を使えば自動管理されるはず...でした。
この thought_signature という仕組みをつかえば、テキストチャットで行う毎回それまでのすべての履歴を送信する、ということを避けることができます。

SDK のチャットセッション

私たちのアプローチでは Google GenAI SDK の client.aio.chats.create() でチャットセッションを作成し、chat.send_message_stream() でメッセージを送信していました。

# チャットセッション作成
chat = client.aio.chats.create(model="gemini-3-pro-preview", config=config)

# メッセージ送信(ストリーミング)
response_stream = await chat.send_message_stream(content_parts)
async for response in response_stream:
    # レスポンス処理
    ...

ドキュメント通りなら、これで thought_signature は自動管理されるはず。しかし実際には動作しませんでした。

GitHub Issue #1791 の発見

調査を進める中で、GitHub で関連する issue を発見しました。

[Bug] ChatSession history fragmentation when using send_message_stream with Thinking (Gemini 3 Pro)
https://github.com/googleapis/python-genai/issues/1791

当該issue

この issue によると

When using Gemini 3 Pro Preview with thinking_config enabled, the ChatSession history becomes fragmented when using send_message_stream. Instead of appending a single model turn with the complete response, the SDK appends multiple model turns corresponding to the streaming chunks.

つまり、send_message_stream() を使うと、チャット履歴が断片化されてしまうというバグが報告されていました。

期待値

[User, Model]  # 2エントリ

実際

[User, Model, Model, Model, Model, ...]  # 複数のModelエントリ

ストリーミングのチャンクごとに履歴エントリが追加されてしまい、会話構造が壊れるとのこと。

「動いたり動かなかったり」の理由

この issue を読んで、「動いたり動かなかったり」の理由が推測できました。

  1. 同じサーバーインスタンス内で連続してリクエストすると、セッションがメモリ上に残っているため動くことがある
  2. サーバー再起動新しいセッションでは、壊れた履歴から再開しようとして動かない
  3. タイミングやネットワーク状況によって、履歴の断片化の程度が変わる

これが再現性のない挙動の原因でした。


解決策

非ストリーミング版を使う

issue #1791 を参考に、send_message_stream() の代わりに send_message() を使うことにしました。

# 修正前(ストリーミング)
response_stream = await chat.send_message_stream(content_parts)
async for response in response_stream:
    # 処理
    ...

# 修正後(非ストリーミング)
response = await chat.send_message(content_parts)
# 処理
...

結果

非ストリーミング版に変更したところ、マルチターン画像編集が安定して動作するようになりました。

  • 子猫を生成 → 同じ子猫にメガネを追加
今度は、ちゃんと、元の子猫にメガネが装着されました
  • 何度試しても同じように​
  • サーバー再起動後も動作

まとめ

問題

Google GenAI SDK の send_message_stream() を使うと、チャット履歴が断片化され、thought_signature が正しく管理されない。

影響

Gemini 3 Pro Image のマルチターン画像編集が不安定になる(動いたり動かなかったりする)。

解決策

send_message_stream() の代わりに send_message() を使う。

副作用

  • リアルタイムのストリーミング表示ができなくなる(文章+SVG出力などでの逐次表示に影響)
  • 画像生成完了まで結果が返ってこない
  • ただし、進捗表示(「処理中です...」など)のサブメッセージを別途実装すれば UX への影響は最小限で済む

今後

  • SDK のバグ修正を待つ
  • issue #1791 の進捗を監視
  • 修正されたらストリーミング版に戻すことを検討

参考リンク


最後に

同一コードで「動いたり動かなかったりする」バグは、原因特定が非常に難しいですね。今回のケースでは、SDK の内部動作を疑うまでに時間がかかりました。

同じ問題で困っている方の参考になれば幸いです。

それでは、次回またお会いしましょう!

Read more

AIエージェントを"事業に載せる"ために【第1回】

AIエージェントを"事業に載せる"ために【第1回】

AI導入事故は何を示しているのか — AI導入を"事業に載せる"ために、いま設計すべきこと(全3回) こんにちは!Qualitegコンサルティングチームです! AIエージェントを導入する企業が増える一方で、 「試してみる」段階から「事業に載せる」段階へ進める難しさ が、はっきり見え始めています。 本シリーズでは、AIエージェント導入を技術論だけでなく、責任分解・監査可能性・契約・運用統制を含む業務設計の問題として整理します。 全3回を通じて、「AIが賢いかどうか」ではなく、「AIを業務に載せるために何を設計するか」を考えていきます。 第1回となる本記事では、2025年に起きた2つの事例を出発点に、なぜいま「責任設計」が問題になっているのかを見ていきます。 上図は、本シリーズ全体で扱う論点の全体像です。 AIエージェントの導入は、技術的なモデル選定だけでは完結せず、権限設計、契約、監査、品質監視、保険、異常時対応まで含めた設計が必要になります。 第1回ではまず、なぜこうした設計が求められるようになったのかを、実際の事例から見ていきたいとおもいます なお、本シリー

By Qualiteg コンサルティング
PII検出の混同行列では見えないもの ― 認識器間衝突と統合テスト

PII検出の混同行列では見えないもの ― 認識器間衝突と統合テスト

こんにちは!Qualiteg研究部です! 個人情報(PII: Personally Identifiable Information)の自動検出は、テキスト中から特定の表現を抽出し、それがどの種類のPIIに当たるかを判定する問題として捉えることができます。 電話番号、人名、口座番号、金額表現など、検出対象のPIIタイプが増えるにつれて、単一の手法ではカバーしきれなくなり、性質の異なる複数の認識器(Recognizer)を組み合わせるマルチレイヤー構成が採用されるのが一般的です。 本稿で想定しているのは、ユーザーが海外製LLMにチャットを送信する直前に、その内容に個人情報や機密情報が含まれていないかをリアルタイムに検査するユースケースです。 この場面では、検出精度だけでなく、送信体験を損ねない速度が不可欠です。 高精度なLLMやBERT系モデル、NERベースの手法は有力ですが、送信前チェックの第一層として常時適用するには、レイテンシやコストの面で不利になることがあります。 そのため、本システムでは、正規表現、辞書、軽量なルールベース認識器を組み合わせた超高速な第一層を設け、そ

By Qualiteg 研究部, Qualiteg AIセキュリティチーム
日本語対応 LLMランキング2026 ~ベンチマーク分析レポート~(3月6日版)

日本語対応 LLMランキング2026 ~ベンチマーク分析レポート~(3月6日版)

はじめに 本レポートは、Nejumi Leaderboard 4のベンチマークデータ(2026/3/6版)に基づいて、日本語対応LLMの性能を総合的に分析したものです。 前回は 2025/12/18 版の分析レポート を公開しましたが、約3か月でまたもや大きな変動がありました! (定期的に最新LLMランキングを更新してまいります。当社のX(旧Twitter)をフォローいただくことで更新情報を受け取り可能です) Nejumi Leaderboard 4は、日本語タスクにおけるLLMの性能を多角的に評価する信頼性の高いベンチマークとして知られています。 本分析では、商用APIモデルとオープンモデルの両方を対象に、それぞれの特徴や傾向を詳しく見ていきます。 オープンソースモデルについて Weightがオープンなモデルは場合によっては「オープンソースモデル」、「OSSモデル」と呼ばれますが、モデルによっては「オープンソース」と呼ぶには不十分な場合があるため本稿では、「オープンソースモデル」ではなく「オープンモデル」と表現しています。 ベンチマーク分析について 本レポートは

By Qualiteg コンサルティング, Qualiteg プロダクト開発部
日経トレンディ 2026年4月号に Bestllam の広告を掲載しました

日経トレンディ 2026年4月号に Bestllam の広告を掲載しました

こんにちは! このたび、日経トレンディ 2026年4月号(2026年3月4日発売、雑誌)に、当社のエンタープライズ向け統合型AIプラットフォーム「Bestllam」を掲載しました。 日経トレンディ(雑誌)は全国の書店・コンビニエンスストアにてお買い求めいただけますので、お手に取った際はぜひご覧くださいませ。 Bestllam とは? Bestllam は、「チャットで指示するだけ。仕事が終わっている。」をコンセプトに開発した、エンタープライズ向けの統合型AIプラットフォームです。 主な特長 20種類以上のLLMを、契約一本で OpenAI GPT、Anthropic Claude、Google Gemini をはじめ、DeepSeek、Qwen、Llama など商用・オープンソース合わせて20種類以上のLLMを1つの契約で利用できます。各プロバイダと個別に契約を結ぶ手間が不要になります。 6つのLLMに同時質問して、最適な答えを選択 同じ質問を複数のLLMに一括投げかけ、回答を比較・検討できます。各モデルの得意・不得意を活かすことで、重要な意思決定や精度が求められる業

By Qualiteg ビジネス開発本部 | マーケティング部