受付AIアバター MVP — 技術詳細

Gemini Flash Live を使った受付AIアバターの勉強用プロトタイプです。最大のポイントは 「Web検索を挟んでも会話が無音にならない」設計で、以下ではその仕組みを含めて技術構成を説明します。

1. 全体アーキテクチャ

ブラウザ マイク / テキスト入力 FastAPIサーバー /reception/ws(音声プロキシ) /settings, /api/config Gemini Live 音声会話(低遅延) Gemini(非Live) + Google Search 保存データ config.yaml(設定) data/trending_topics.json logs/*.jsonl(セッションログ) WebSocket 音声中継 非同期・裏で発火

図の要点:ブラウザとFastAPIサーバーはWebSocketで常時接続。サーバーはGemini Liveとも別のWebSocketで常時接続し、音声をほぼそのまま中継する。企業リサーチや時事ネタの取得は、 この音声の接続とは別に、Gemini(非Live)+ Google Searchへ非同期で発火する(点線)。

2. 会話フロー(4フェーズ)

フェーズ名称やること終了条件
1受付確認訪問者名・アポ相手・予約時刻を確認必須スロットが全部埋まる
2属性収集企業名・業界・来訪都道府県などを確認。企業名が埋まった瞬間に裏でリサーチ発火必須スロットが全部埋まる
3案内中雑談会議室まで案内する想定のビジネス雑談。リサーチ結果・時事ネタ・想定QAを自然に活用設定したターン数に到達(既定10)
4到着・締め会話を締めくくり「こちらが会議室です」で終了締めの発話が1回完了

3. 無音対策:非同期バックグラウンドリサーチ

Gemini Liveの応答生成をブロックせずに検索するため、tool呼び出しへの応答は即座に返し、 実際の検索は裏で並行実行、完了したら「声に出さない内部メモ」として会話に差し込みます。

0秒 約12秒後 会話は途切れず継続(雑談・追加の質問など) 裏でGoogle検索を実行中(企業概要・業界動向など) 企業名スロット確定 → tool応答は即座に「記録しました」を返す(ブロックしない) 検索完了 → [内部メモ]として会話に裏から注入 → 次の発話で自然に活用

実測値:検索完了まで平均12秒前後かかるが、この間も音声のやり取りは止まらない。 さらに、最初の音声チャンクが届くまでの体感遅延は実測 約0.85秒(ターン全体の完了時間とは別物)。

案内中雑談での追加リサーチ(lookup_more)

想定外の話題を振られた場合も同じ非同期パターンを使い回す。モデルが lookup_more というfire-and-forgetなtoolを呼び、その場は相槌でつなぎながら裏で追加検索し、結果を次のターンで使う。

4. 外出しパラメータ(設定画面から編集できるもの)

区分内容設定画面のセクション
A. 話し方・人格名前・一人称・口調・呼称・NGトピック・誠実さの指示A
B. 音声設定Voice名B
C. フェーズ制御案内中雑談のターン数・聞き直し回数・タイムアウト秒数C
D. 収集スロット項目の追加・削除・キー/ラベル/フェーズ/必須の編集(完全動的)D
F. 自社情報・QA会社名・概要・会議室案内・想定QAの追加削除F
E. 検索・リサーチ有効/無効・モデル・検索観点・発火スロット・文字数上限E
G. ログログレベル・プリセットID(A/B比較用)G
時事ネタ手動更新ボタン/起動時24時間鮮度チェックの自動更新ページ下部

保存はconfig.yamlへの書き込みのみで、サーバー再起動は不要です (WebSocket接続のたびにconfig.yamlを読み直す設計のため、次の会話から反映されます)。

5. ファイル構成

ファイル役割
main.pyFastAPIエントリポイント。起動時の時事ネタ鮮度チェックも担当
config.yaml外出しパラメータの実体
reception/config.pyconfig.yamlの読み書き・バリデーション
reception/slots.py来訪者情報スロットの管理
reception/phases.pyフェーズ1〜4のステートマシン・ターン数管理
reception/prompts.pyシステムプロンプト・tool宣言の動的組み立て
reception/knowledge.py自社情報・QAのテキスト整形
reception/research.py非同期リサーチ本体・ResearchCoordinator
reception/trending.py時事ネタの取得・キャッシュ
reception/session_log.pyJSONLセッションログ(効果測定用)
reception/live_proxy.pyGemini Live WebSocketプロキシ本体
reception/settings_routes.py/settings, /api/config, /api/trending-topics
static/index.html受付デモ画面
static/settings.html設定編集画面
tests/pytest一式(下記参照)

6. テスト状況 47件 全通過

対象内容
config読み込み・保存・バリデーション(キー重複/不正文字/フェーズ範囲/trigger_slot_key整合性)
slots / phasesスロット充足判定、フェーズ遷移、ターンカウント
promptsスロット構成に応じた動的なtool宣言・進行案内文の生成
research / trending非ブロッキング性(検索中もキューが即座に返る)、エラー時のフォールバック
settings API保存 → 再読み込み → システムプロンプト反映までの一気通貫確認
app bootFastAPIアプリの起動・ルーティング確認

テストはtests/fixtures/config.yamlという固定フィクスチャを見る設計にしており、 運用者が本物のconfig.yamlを設定画面から自由に変更してもテストが壊れないようにしている。

7. 既知の制約