LiveKit Turn Detector Plugin

参照元: LiveKit Agents Documentation ロードマップ: 学習ロードマップ

What(何についてか)

LiveKit Turn Detector Pluginは、VAD(音声活動検知)に会話コンテキストを追加シグナルとして重ねるLLMベースのターン検出モデルだ。MultilingualModel という名前のオープンウェイトモデルとして提供されており、AgentSessionTurnHandlingOptions に渡すことで有効化される。

Why(なぜ必要か)

VAD単体の問題は、音響的な沈黙しか検知できない点にある。ユーザーが「ちょっと考えます…」と言って長い沈黙を取った場合、VADはそれを発話終了と判断してエージェントが割り込んでしまう。Turn Detectorはテキスト(STT結果)を会話コンテキストとして読み込み、「このユーザーは発言を終えたか」を言語的に推論することでこの問題を解決する。

How(どう動くか)

処理フロー

graph TD
    A["音声入力"] --> B["Silero VAD\n(沈黙を検知)"]
    A --> C["STT\n(トランスクリプト生成)"]
    B -->|"沈黙シグナル"| D["Turn Detector\n(MultilingualModel)"]
    C -->|"テキスト + 言語コード"| D
    D -->|"yes: ターン終了"| E["min_delay 後に終了宣言"]
    D -->|"no: まだ続く"| F["max_delay まで待機\n(超えたら強制終了)"]

Turn Detectorは「yes/no」の二値判定のみを行い、タイミング制御は min_delay / max_delay が担う。

要件

  • AgentSession 内での使用が必須
  • STTモデルが必須(テキストがなければコンテキスト判断不可)
  • VADとの組み合わせが推奨(最大性能)。STTプロバイダーのendpointingのみでも動作するが、精度・レイテンシがプロバイダー依存になる

インストール

uv add "livekit-agents[turn-detector]~=1.4"
uv run agent.py download-files  # モデルウェイトの事前ダウンロードが必要

モデルウェイトはpipパッケージに含まれていないため、初回実行前に明示的にダウンロードする。LiveKit Cloud環境ではCloud側で推論が動くためこのダウンロードは不要。

基本的な使い方

from livekit.plugins.turn_detector.multilingual import MultilingualModel
from livekit.agents import AgentSession, inference, TurnHandlingOptions
 
session = AgentSession(
    turn_handling=TurnHandlingOptions(
        turn_detection=MultilingualModel(),
    ),
    stt=inference.STT(language="multi"),
    # ... vad, tts, llm, etc.
)

inference.STT はLiveKit Inferenceを使うSTTクライアントで、LiveKit Cloud環境でのみ使用可能。ローカル・セルフホスト環境ではOpenAI STTやDeegramなど他のSTTプラグインを使う。

Endpointingパラメータ

MultilingualModel 自体に設定項目はない。タイミング制御は TurnHandlingOptions の以下3パラメータで行う。

mode Literal['dynamic', 'fixed'] デフォルト: fixed

  • "fixed": min_delaymax_delay をそのまま使う
  • "dynamic" (Python only): セッション中のポーズ統計(EMA)を基に min_delaymax_delay の範囲内で自動調整する。会話のテンポが速ければ遅延を縮め、ゆっくりなら伸ばす。セッション序盤は統計が蓄積されていないため fixed と大差なく、会話が長くなるほど真価が出る

min_delay float デフォルト: 0.5秒

Turn Detectorが「yes」と判定した後も、自然な会話の間(ま)を作るために最低限待機する時間。VADモードでは max(VAD silence, min_delay) として効く。STTモードではSTTのendpointing後に追加で適用される。

max_delay float デフォルト: 3.0秒

Turn Detectorが「no」と判定し続けても、この時間を超えたら強制的にターン終了とみなす。無限待ちを防ぐ上限として機能する。

Node.jsでは min_delay / max_delay の単位がミリ秒(500, 3000)。Pythonは秒(0.5, 3.0)。

言語対応

14言語対応(英語・スペイン語・フランス語・ドイツ語・イタリア語・ポルトガル語・オランダ語・中国語・日本語・韓国語・インドネシア語・トルコ語・ロシア語・ヒンディー語)。

言語の指定はSTT側で行い、Turn DetectorはSTTから言語コードを受け取って動作する。

stt=inference.STT(language="ja")   # 日本語固定
stt=inference.STT(language="multi") # 自動検出(多言語)

単一言語プロダクトでは固定指定の方が精度が高い。"multi" は言語検出のオーバーヘッドと汎化のトレードオフがある。なおSTTプロバイダー側が対象言語に対応しているかは別途確認が必要。

Realtime Modelとの併用

OpenAI Realtime APIのようなリアルタイムモデルはターン終了後にまとめてトランスクリプトを返すため、Turn Detectorが必要とするリアルタイムSTTストリームが存在しない。この場合、AgentSession に別途STTプラグインを追加する必要がある。

session = AgentSession(
    llm=openai.realtime.RealtimeModel(),
    stt=openai.STT(),                      # Turn Detector用に別途追加
    turn_handling=TurnHandlingOptions(
        turn_detection=MultilingualModel(),
    ),
)

STTを二重に動かすことになるためコストが増加する。Realtime ModelにTurn Detectorを乗せるかどうかはコストと精度のトレードオフで判断する。

ベンチマーク

Runtime performance:

モデルベースモデルサイズ推論レイテンシ
MultilingualQwen2.5-0.5B-Instruct396 MB~50-160 ms

自前デプロイ時はCPU上でローカル実行。RAM < 500MB。バースト型インスタンス(AWS t3/t4g)はCPUクレジット枯渇による推論タイムアウトのリスクがあるため、コンピュート最適化型(c6i/c7i)を推奨。

Detection accuracy(主要言語):

言語True Positive率True Negative率
英語99.3%87.0%
日本語99.3%88.8%
中国語99.3%86.6%
ヒンディー語99.4%96.3%

TPが全言語99%超と高い一方、TNは言語によって85〜96%のばらつきがある。「まだ続くのに終了と誤判定する」方向のエラーが相対的に残りやすく、割り込みが発生しやすい方向のリスクとなる。

デプロイ環境ごとの構成まとめ

環境STTTurn Detector推論モデルDL
LiveKit Cloudinference.STT 推奨Cloud側で実行不要
ローカル / セルフホストOpenAI / Deepgram等CPU上でローカル実行必要