0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Antigravityによくあるトラブル報告 / ユーザー離脱率からPMF / AIチャットの「10秒の壁」を突破したい。/ ストリーミング実装 with Antigravity(ポンコツver),個人開発。

0
Posted at

こんにちは、札幌のコーヒーショップ「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に相談したところ、以下の原因特定&アップデートを提案されました。

image.png

image.png

当然ですが、最も効果があるのは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サルバさん」に話しかけてみてください。

👉 2D Webshop Salva

客観的な評価
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コーディング活用に理解がある
兼業・副業からでも実務経験を積める

もし、「一緒に働いてみないか?」と興味を持っていただける企業様やチームがいらっしゃれば、ぜひお声がけいただけると嬉しいです!

ここまで読んでいただきありがとうございました!

記事にいいねをいただけると励みになります!☕️

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?