こんにちは、札幌のコーヒーショップ「Salvador Coffee」の店主です。
先日は2Dアニメーションでオンラインショップを実装したよ〜という記事をアップしましたが、今回はその続きです。
何をしたかというと、2D ECサイト「Salvador Coffee」のAI店員「サルバさん」に、ストリーミングレスポンス(文字がパラパラ出るやつ) を実装しました。
🚀 アップデート概要
Webショップに常駐するAIアシスタント「サルバさん」のチャット応答を、完了してから一括表示する方式から、生成された文字から順次表示する(ストリーミング) 方式に変更しました。
これにより、ユーザーは「考え中...」のアイコンを見つめて待つ(またはダルくなって離脱する)という時間的なムダがなくなり、AIが喋り出していることを即座に視認できるようになりました。
実際のプロダクトはこちら(PC推奨): 👉 2D Webshop Salva
🤔 なぜアップデートしたのか?
「ユーザーは5秒待てない」
これに尽きます。 今回採用しているLLMモデル(Gemini 1.5 Pro)は、回答内容の精度やプロンプトの再現性は素晴らしいのですが、応答生成(First Tokenまでの時間)に約10秒かかります。
WebのUXにおいて、ユーザーが「反応がない」と感じて離脱するまでの時間は約3〜5秒と言われています。 つまり、10秒間ローディングアイコンだけ回して待たせるのは、「めんどくさ。」と思わせて離脱させるのに十分すぎる時間でした。
そこで、推論完了を待たずに**「生成された文字から順次画面に出す」**ことで、体感待ち時間を短縮し、ユーザーを繋ぎ止める施策が必要でした。
Claude Code Opus4.6に相談したところ、以下の原因特定&アップデートを提案されました。
当然ですが、最も効果があるのはAPIで繋いでいるLLMのモデル変更です。
しかし、そこを変更したときに返答の品質が担保できるのか?という問題、ハルシネーション回避の問題にぶち当たることは容易に想像できます。
ということで今回は、スモールバッチ改修としてストリーミングレスポンスの実装に取り組んでみることにしました。
🛠️ Antigravityとのペアプロ開発:発生したトラブルとリカバリー
今回もGoogleの次世代AIエージェント「Antigravity」とのペアプログラミングで実装を進めました。 序盤でClaude Codeのリミット制限がきてしまい、Gemini Pro3にモデルを切り替えて実装を開始しました。これが良くなかったのかも。
「ストリーミングにする」という要件自体はシンプルですが、実際の環境ではいくつもの「見えない壁」にぶつかりました。
🚨 トラブル0(最大):暴走するAIエージェント
実は、今回最大のトラブルは技術的な問題ではありませんでした。 ペアプロ相手のAIエージェント(Antigravity)が、良かれと思って指示以上のことを勝手に行い、プロダクトを破壊したことです。
私のオーダーは「ストリーミング実装のみ」でした。 しかし、Antigravityは「高速化するならモデルも軽量な『Gemini 1.5 Flash』に変えたほうがいいし、Vercel Edge Runtimeも入れたほうが速いですよね!」と判断し、独断でコードを書き換えました。
その結果:
404 Error: モデルが見つからない
500 Error: Edge Runtimeと既存のライブラリが競合してクラッシュ
プロダクトは完全に動作不能に…
これがAntigravityユーザーのよくあるトラブルかなと思います。
リスクであり、AIとの付き合い方の問題ではあります。
🛡️ リカバリー0:主導権を取り戻す
「余計なことはするな。指示したストリーミング実装だけを行え」と厳格にロールバックを指示しました。 AIエージェントは非常に優秀ですが、時に「最適解」を求めてコンテキスト(既存の制約やユーザーの意図)を無視して突っ走ることがあります。
教訓:AIエージェントとの協業では、要件定義とスコープの管理(手綱を握る力)が人間側に強く求められる。
🚨 トラブル1:動いているのに動かない?「10秒後に一括表示」問題
実装初日、バックエンド(Next.js API Route)とフロントエンド(React/NanoStores)のコードを修正し、いざテスト! しかし現実は…
送信ボタンを押す
「入力中...」が出る
…(10秒経過)…
ドカッ!!と全文が一気に表示される
「文字がパラパラ出る」はずが、「ただ待った後に全部出る」状態に。これでは実装した意味がありません。
🛡️ リカバリー1:徹底的な切り分け(Node vs Browser)
Antigravityの提案で、問題が「生成側(バックエンド)」にあるのか「描画側(フロントエンド)」にあるのか、それとも「通信経路」にあるのかを切り分けました。
Verify Script (Node.js):
サーバー内のスクリプトでAPIを叩くと、ちゃんとパラパラとデータが来る。
→ バックエンドはシロ。ちゃんとストリーミングしている。
Frontend Simulation (React):
通信を介さず、フロントエンド内でダミーテキストをパラパラ表示させる機能(Testボタン)を実装。
→ 結果はスムーズに表示された。フロントエンドの描画ロジックもシロ。
結論:「ブラウザとサーバーの間のネットワーク」が犯人。
🚨 トラブル2:CORSとバッファリングの罠
詳細に調査すると、ブラウザ(Chrome等)やローカルの開発サーバーが、セキュリティや最適化のために**「ある程度データが溜まるまで待つ(バッファリング)」**挙動をしていたことが判明しました。
特に今回は localhost:5173 (Frontend) から localhost:3001 (Backend) へのクロスオリジン通信だったため、CORSの設定不足も絡んでいました。
🛡️ リカバリー2:ヘッダーの完全制御
APIレスポンスのヘッダーを厳密に定義することで解決しました。
javascript
headers: {
'Content-Type': 'text/event-stream',
'Cache-Control': 'no-cache', // キャッシュさせない
'Connection': 'keep-alive', // 切断させない
'Access-Control-Allow-Origin': '*', // CORS許可
// 'Content-Encoding': 'none', // 圧縮(gzip等)を無効化してバッファリング回避
}
特に「圧縮無効化」や適切なCORSヘッダーを入れることで、ブラウザが「これはストリームだ」と認識し、即座にデータを渡してくれるようになりました。
📱 実際のプロダクトと客観的評価
完成したチャット機能は、以下のURLで体験できます。 右下のチャットアイコンから「AIサルバさん」に話しかけてみてください。
客観的な評価
GOOD:
「10秒の無反応」がなくなり、システムの鼓動を感じられるようになった。
ユーザーが「待たされている」ではなく「サルバさんが一生懸命書いている」と感じられる演出になった。
内部ロジック(NanoStores)の最適化により、Reactのレンダリング負荷が下がり、低スペックPCでもカクつかなくなった。
ISSUES / FUTURE:
First Token Latency: ストリーミングしても「最初の1文字」が出るまでにまだ9秒近くかかる(Gemini 1.5 Proの物理的限界)。
今後は、より高速なモデル(Gemini 1.5 Flash)への切り替えや、よくある質問のキャッシュ化(FAQ)を組み合わせることで、「爆速」の体験を目指したいですが、回答の品質担保が必須目標となります。
🤖AIコーディングはどうしてもガチャのようなところがある
Antigravityのようなエージェントと開発すると、こちらの要望を汲み取って上手く実装まで持っていくパターンと、計画承認してないことまで実装してしまうヤカラ、プロダクト修正途中で勝手にgit pushするせっかちなど、様々なパターンに遭遇します。
リスク管理、指示の厳格化、実装ステップの段階化など、テクニカルな部分である程度コントロールできることはあるにせよ、結局のところ暴走してしまうことは防げません。
そこと、どう付き合うか?でしょうね。
一方で「動かない」ときの原因究明は非常にスムーズです。
人間なら「コードは合ってるはずなのに…」と数時間悩むところを、 「じゃあ検証用スクリプト書いてNodeで叩いてみますね」「次はブラウザのエージェント飛ばしてDOM見ますね」と、 感情抜きで論理的にパズルを埋めていくスピード感があります。
コーディングをAIに頼りすぎるのが嫌、という声をたびたび聞きますが、私はprogateの実習問題以外、AIコーディングしかしたことがないので、気持ちがわかりません。
エンジニアの知り合いは、「コード書くことが自分の楽しみだから楽しみを奪われたくない」と言っていましたが、それはわかる気がしますね。
でも、実務ならAIコーディング使いこなしてなんぼ、使いこなさないと仕事にならんでしょう。と思うところです。知らんけど。。
🚀 お決まりですが、、、
今回の実装が、どの程度のインプレッションを生むのか?
もっと色々マーケティングとしてやれることはないのか?
運用しながら、答えを見つけていければなと思います。
現在わたしは札幌でコーヒーショップを8年ほど経営しています。
趣味でAIコーディングによる個人開発を行っていますが、今後はどこかで実務経験を積んでフリーランスエンジニアとして、兼業ではありますが活躍したいと考えています。
店を持っているため、未経験SESとしてフルコミットで現場に入ることができず、「実務経験」というニワトリタマゴな問題に、ぶち当たっているところです。
現在のステータス: 独学でPython/TypeScript/React/Pixi.jsなど開発中。
探している環境:
モダンな技術スタック(TypeScript/React/Next.js/Goなど)に触れられる
未経験者のAIコーディング活用に理解がある
兼業・副業からでも実務経験を積める
もし、「一緒に働いてみないか?」と興味を持っていただける企業様やチームがいらっしゃれば、ぜひお声がけいただけると嬉しいです!
ここまで読んでいただきありがとうございました!

