👌

チャット形式の画像生成 UX を改善した話

に公開

背景

自作のチャット UI で、LLM にプロンプトを投げて回答を得る仕組みを作っていました。
ChatGPT のように、テキストで質問したり、モードを切り替えて画像を生成したりできるイメージです。

画像生成には以下を利用していました:

  • nanobanana
  • GPT-Image-1

このときの仕様はざっくりいうとこんな感じです。

  • 画像生成モード = OFF
    → テキストプロンプトに対して、普通のテキスト回答が返ってくる
  • 画像生成モード = ON
    → プロンプトに対して「画像」が生成される

この時点では 「画像生成のみ対応」 で、
一度出力した画像を編集することはできない仕様 でした。


問題になった UX

UI はチャット形式なので、ユーザーから見るとこう見えます:

  1. プロンプトを投げる
  2. 画像が返ってくる
  3. さらにプロンプトを投げると、「さっきの画像を編集してくれそう」に見える

人間の感覚だと、

「前に生成してくれた画像を、もう少しこうして」と続けてプロンプトを投げれば、
その画像をベースに編集してくれるはず

と期待してしまいます。

しかし実際には、

  • 画像は 毎回「新規生成」 されるだけ
  • 過去の画像に紐づく編集という概念がそもそもない

という状態でした。

その結果、UI/UX 的にこんな誤解を生みやすくなっていました。

  • チャットは「文脈を覚えている」
    → だから 前の画像も覚えていて、それを編集してくれるだろう とユーザーが思う

最初に考えていた案:直前の画像だけ編集可能にする

最初の構想では、

直前に出力した画像だけ を編集できるようにする」

というイメージを持っていました。

しかしここで大きな問題にぶつかります。

✋ そもそも、「今のプロンプトは生成なのか?編集なのか?」をどう判定するの?

最初に思いつくのは、

  • プロンプトの内容から「編集っぽいかどうか」を判定する

    • 例: 「もう少し明るく」「背景を青にして」「同じ構図で〜」など

ですが、これは実装的にかなりハードルが高いです。

  • 言語表現のパターンが多すぎる
  • モデルや言語によっても変わる
  • 誤判定したときの UX がかなりストレス

nanobanana ではプロンプトからモード判定しているように見えましたが、同じことを自作でやるのはコストが高い と判断しました。


解決策:生成と編集を「ボタン」で明確に分ける

そこで方針を変えて、以下のような設計にしました。

1. スレッドの役割を分ける

まず、チャットスレッド自体を役割で分離します。

  • 通常スレッド:テキスト回答に専念
  • 画像生成用スレッド:画像生成・画像編集に特化

画像生成用スレッドでは、

  • LLM へのプロンプト送信
  • 画像生成 API の呼び出し
  • 出力画像の一覧表示

など、画像関連の操作に集中できるようにしました。

2. 「編集する」ボタンを用意する

次に、ユーザーが自分の意思で「編集モード」を宣言できるように しました。

  • 各出力画像のところに 「編集する」ボタン を配置

  • そのボタンを押下すると:

    • 「どの画像を編集対象にするか」が明確になる
    • 以降のプロンプトは「その画像を編集するためのもの」として扱える

これによって、

  • 画像の新規生成
  • 既存画像の編集

を、ユーザー側からも開発側からも はっきり区別できる ようになりました。


ボタン方式のメリット

この「編集する」ボタン方式にしたことで、いくつか良い点が生まれました。

① 生成か編集かが明確になる

  • ボタンを押さない → 「新規画像生成」
  • ボタンを押す → 「選んだ画像を編集」

と、仕様がシンプルで直感的になりました。

プロンプトの内容に頼らず、
UI の操作そのものを「意図の宣言」として扱える のが大きいです。

② 過去の画像も編集できる

最初構想していたのは「直前の画像だけ編集」でしたが、
ボタン方式にしたことで、過去の画像も自由に編集対象にできるようになりました。

  • 3つ前に生成した画像でも、「編集する」を押せば編集対象にできる
  • ユーザー自身が「この画像をベースにしたい」と選べる

という形で、UX と柔軟性の両方を実現できました。

③ 実装もシンプルになる

実装の観点でも、

  • 「どの画像を編集するか」 = 「ユーザーがボタンを押した画像」
  • その画像に紐づく ID / URL / gcsFileId などを state として持つ
  • 編集フローではその ID を使って、nanobanana / GPT-Image-1 の編集 API に渡す

というシンプルな設計に落とし込めます。

「プロンプトのニュアンスから編集かどうかを推測する」
というフワっとしたロジックを組まずに済むのはかなり大きいです。


まとめ

今回の学びをざっくりまとめると:

  • チャット形式の UI は、
    「前のコンテキスト(画像)を覚えていてくれるはず」 という期待値をユーザーに与える

  • しかし実装が「単なる画像生成モードの ON/OFF」だと、その期待を裏切ってしまう

  • プロンプトの内容だけで「生成 or 編集」を判定するのは、実装が複雑で誤判定リスクも高い

  • そこで、

    • 画像専用スレッド で画像生成・編集に特化
    • 各画像に 「編集する」ボタン を付けて、ユーザーの意図を明示的に受け取る
  • その結果:

    • 生成と編集の区別が UX 的にもコード的にも明確に
    • 過去の画像も編集対象として扱えるように
    • nanobanana / GPT-Image-1 といった画像モデルも扱いやすくなった

という形で、
「チャット × 画像生成」の UX と実装の両方をいい感じに整理できた という話でした。

Discussion