9月10日、Arin Simeが「How Voice AI Agents Handle Interruption: State Machines vs Streaming Approaches」と題した記事を公開した。この記事では、音声AIエージェントにおける割り込み処理を「ステートマシン」と「ストリーミング」の2つのアーキテクチャから比較し、WebRTC.venturesのエンジニア3名のインタビューを通じて実装レベルの知見を紹介している。
音声AIエージェントで最も難しい問題の一つが「割り込み処理」だ。ユーザーがエージェントの発話中に話し始めたとき、システムはどう振る舞うべきか——この問題には、設計レベルで根本的に異なる2つのアプローチが存在する。
ステートマシン vs ストリーミング:何が違うのか
ステートマシン型は、idle → listening → processing → speaking → handling interruption のように明示的な状態と遷移を定義する。1つのフェーズが完了してから次に進む逐次型であり、フローを監査しやすく、コンプライアンス要件のある用途(予約受付、インテークフォームなど)に向いている。欠点はレイテンシと自然さで、ターン間に無音の「間」が生じやすく、割り込みも状態遷移として明示的にモデリングする必要がある。
ストリーミング型は、ASR(音声認識)、LLM、TTS(音声合成)を並列で走らせる。ユーザーが話し終わる前にLLMがレスポンスを生成し始め、TTSはトークン単位でオーディオをストリームする。割り込みはオーディオレベルで自然に発生するため、体験としてはより人間らしい。ただし、VAD(音声活動検出)のチューニングや競合状態への対処が必要で、実装の複雑度は高い。
実際のところ、PipecatやLiveKit Agentsのような主要フレームワークは両方を組み合わせて使う。低レイテンシのためにストリーミングパイプラインを使いつつ、会話フェーズの管理やビジネスロジックの強制にはステートマシンをオーバーレイする設計だ。
現場エンジニア3人の証言
記事の本体は、WebRTC.venturesの音声AIエンジニア3名へのインタビューで構成されている。3名はそれぞれ異なるユースケースに対して異なるアーキテクチャを選択しており、「これが正解」という共通解があるわけではない点が興味深い。
Andrés Rincon(医療トレーニングシミュレーター)
最も興味深いのは、Andrésのチームがプッシュトーク(PTT)を意図的に採用した経緯だ。
ストリーミング型を試作したが、問題が出た。
「心理士は考えているとき、長い沈黙を取る。自動システムはその沈黙をターン終了と判断してしまい、AIクライアントが話し始めた。セッションが不自然に感じられた」
そこでチームはidle → user speaking → processing → agent speakingの4状態のステートマシンに切り替え、ターン開始はPTTボタンのイベントのみで制御するようにした。VADを使わないため、沈黙を誤検知しない。ターン終了もボタンリリースで決定される。
このアーキテクチャでは、割り込みシーケンスは以下のようになる:
- TTSがストリーミング中、アバターが発話中
- ユーザーがPTTボタンを押す → これが割り込みイベント
- LLM生成・TTS・アバターをすべて停止
- ブラウザがWebSocket経由でマイク音声を送信開始
- Chirp 3(GoogleのSTTモデル)がリアルタイムで文字起こし
- ボタンリリースでターン終了(沈黙ではなく)
- トランスクリプトをGoogle ADK(Agent Development Kit)に渡し、次の応答を生成
「ストリーミングはオーディオを動かす。だが誰が発言権を持つかを決めるのは、何らかのステートマシンでなければならない」というのがAndrésの結論だ。
Suman Paudel(業務トレーニングプラットフォーム)
LiveKitとPipecatの両方で実装した経験を持つSumanは、割り込み検出から沈黙までのパス全体を100〜300msで処理する必要があると指摘する。
彼のパイプラインは次のレイヤー構成だ:
- ノイズ抑制:セルフホスト環境ではDeepFilterNetを使用(Krispはクラウド専用)。誤割り込みの最大の原因が背景ノイズであるため、このステップの重要度は高い
- Silero VAD:音声活動を検出
- ゲーティングレイヤー:最小発話時間閾値とセマンティックターン検出器(Pipecat SmartTurnやNamoターン検出器)を組み合わせ、本当の割り込みかノイズかを判別
本当の割り込みと判断したら、以下をほぼ同時に実行する:
- LLM生成のキャンセル
- TTS合成の停止
- プレイアウトキュー・トランスポートバッファ・SIPブリッジのジッターバッファをすべてフラッシュ
最後の項目を見落とすと、TTSを止めてもダウンストリームに残ったオーディオが約1秒流れ続け、ユーザーには「聞いていない」と感じさせる。
さらに微妙な問題として、会話コンテキストのズレがある。LLMが1文まるごと生成していても、ユーザーが聞けたのは半分だけというケースでは、生成済みの全文を会話履歴に残すと、エージェントが「ユーザーが聞いていない内容」を参照してしまう。SumanはTTSの再生位置とコンテキストを同期させることでこれに対処している。
デバッグのしやすさについては「ステートマシンに軍配が上がる」と明言する。ストリーミング型はゴーストオーディオや部分的な割り込みといった奇妙な症状が出やすく、個々のフレームをトレースして競合状態を探す羽目になる。
Fahad Mahmood(AIセールスエージェント)
FahadはLiveKitベースの音声パイプラインを構築し、VADの後段に音響的ターン検出モデルを配置している。このモデルはピッチ、イントネーション、リズムといった音響特徴を解析し、ユーザーが本当に発話を終えたのか、単に考えるために間を置いているのかを判定する。沈黙の長さだけで判断する従来のアプローチとは異なる。
最も難しかったバグ:「セラピストは意図的に沈黙する」
Andrésが挙げた最悪のバグが象徴的だ。自動ターン検出がセラピスト訓練生の発話を繰り返し遮断するという問題で、原因はモデルや実装のバグではなかった。
「セラピストはノートを確認するために止まる。患者に問いかけた後、答えが返ってくるのを待つために止まる。自動システムはその沈黙をターン終了と判定し、AIクライアントが割り込んだ」
「誰が発言権を持つか」という問題は、技術的な最適化より先に、ドメイン特性の理解が必要だということだ。
実装の選択基準
3名の証言を整理すると、選択の基準はユースケースによって明確に異なる:
- 決定論的な制御が必要な用途(医療・コンプライアンス・トレーニング)→ ステートマシン中心
- 自然な低レイテンシ会話が必要な用途(サポートボット・セールス)→ ストリーミング中心
- ほとんどの本番環境 → ストリーミングのデータプレーン + ステートマシンによる「発言権」管理のハイブリッド
詳細はHow Voice AI Agents Handle Interruption: State Machines vs Streaming Approachesを参照していただきたい。