ハクソク

世界を動かす技術を、日本語で。

HNに表示: 500ms未満のレイテンシーを持つ音声エージェントをゼロから構築しました

概要

  • 世界最大級の消費財企業向けに、音声エージェントの自作パイプラインを構築した体験談
  • 市販プラットフォーム(Vapi等)より2倍速い400ms台の応答速度を実現
  • 音声エージェントの本質的な難しさと、ターンテイク制御の重要性を解説
  • 地理的配置やモデル選定がレイテンシー削減の鍵であることを実証
  • 実装例・設計図・GitHubリポジトリも公開

音声エージェント自作記:超低遅延パイプラインの構築と学び

  • 半年間、大手消費財企業のために音声エージェントのプロトタイプを開発
  • VapiやElevenLabsなどの市販音声エージェントSDKは便利だが、内部の複雑さを隠蔽
  • GPT-5.3やClaude 4.6の登場、ElevenLabsの大型資金調達を受け、自作オーケストレーション層に挑戦
  • 1日・約100ドルのAPI利用料でVapi相当の機能を2倍速で実現(約400msエンドツーエンド)
  • 本稿では、音声エージェントの難易度・ターンテイク制御・STT/LLM/TTSのストリーミング連携・地理/モデル選定による最適化を解説

音声エージェントが難しい理由

  • テキストチャット型エージェントはユーザー操作が明確なターン境界を作るため制御が容易
  • 音声ではリアルタイムかつ連続的なオーケストレーションが必要
  • システムは常に「話しているか、聞いているか」を判定し続ける必要
  • 発話終了の検出が困難(間やノイズ、非言語音も多い)
  • タイミングの僅かなズレが会話体験を大きく損なう
  • 良質な音声エージェントは個々のモデル性能より、全体の協調制御が肝心

ターンテイク制御の基本設計

  • 最初にChatGPTでアーキテクチャを反復設計し、頭の中で全体像を構築
  • 音声エージェントは本質的に「話しているか/聞いているか」の2状態+2遷移のみ
    • ユーザーが話し始めたら即時にエージェントの発話や生成を中断・バッファ削除
    • ユーザーが話し終えたら即時応答生成・ストリーミング開始
  • このターン検出ループが音声体験の核

VADと事前録音応答による初期実装

  • FastAPIサーバー+Twilio WebSocketで8kHz音声ストリーム受信
  • Silero VAD(軽量・2MB)で音声区間を検出
  • シンプルな状態管理で話し終わり検出時に録音WAV再生、話し始めで即中断
  • VADのみでも会話っぽさ・低遅延のベースラインを実現

VAD単独の限界

  • 単なる音声検出では「発話完了」の判定が困難
  • 間やゆっくり話すユーザーで早すぎる切り替え・割り込みが発生
  • 実用的なターンテイクには**音声信号+意味的な判定(STT)**が不可欠
  • VAD実装は制御フローの明確化と遅延ベースライン取得には有効

本格パイプラインへの進化:Fluxとリアル音声エージェント

  • Deepgram FluxでストリーミングSTT+ターン検出を統合
  • Fluxの「ターン開始/終了イベント」をトリガーにパイプラインを制御
  • ユーザー発話終了時:
    • トランスクリプト+履歴をLLMへ送信
    • 最初のトークン到着と同時にTTSへストリーム転送
    • TTS音声をTwilioへ即時送信
  • **WebSocketの事前確立(TTS用)**で300ms近い遅延削減
  • バージイン(割り込み)時も即時キャンセル・音声バッファ削除
  • 以上で自然な会話体験・低遅延ストリーミングを実現

地理的配置とレイテンシーの実際

  • ローカル(南トルコ)で検証:平均1.7秒の遅延(Vapi比2倍)
  • Railway EUリージョンへデプロイ+全サービスEU配置
    • 平均遅延690ms(Twilio加味で約790ms)
    • 同条件のVapiより50ms高速
  • 主観的にも応答性・割り込みの自然さが大幅向上

モデル選定と最適化

  • OpenAI gpt-4o-mini利用から、Groq llama-3.3-70bへの切り替えで推論遅延3倍短縮
  • **TTFT(First Tokenまでの時間)**が体験の鍵
  • ストリーミング必須、逐次パイプラインは会話用途では破綻

成果とまとめ

  • 400ms台のエンドツーエンド遅延(電話停止→最初の音節)を実現
  • STT→LLM→TTSのストリーミング連携・即時割り込み対応
  • VAD単独では不十分、意味的ターン検出が必須
  • 地理的配置が最大の遅延要因、全サービスの近接配置が重要
  • GitHubリポジトリ: https://github.com/NickTikhonov/shuo
  • 著者のXアカウント: https://x.com/nick_tikhonov

付記:技術的ポイントまとめ

  • 音声エージェントはターンテイク問題、単なる音声認識問題ではない
  • VADのみでは限界、意味的なターン終了判定が不可欠
  • 本質は「話す」vs「聞く」の1ループ+2遷移
  • バージイン時の即時キャンセル・ターン終了時の即時応答が体験を決定
  • STT→LLM→TTSは全てストリーミングで連携、逐次処理は非現実的
  • TTFT(First Tokenまでの時間)が最重要
  • 地理的配置が最大のレイテンシー要因、全サービスを同一リージョンに配置
  • Groqの~80ms TTFTが大きなブレイクスルー

参考リポジトリ・SNS

  • GitHub: https://github.com/NickTikhonov/shuo
  • X (Twitter): https://x.com/nick_tikhonov

Hackerたちの意見

すごくワクワクする突破口だね。これは実際、ゲームエンジンのネットコード進化の初期を思い出させる。レイテンシはオーケストレーションの問題だから(モデルの問題じゃない)、一般的なフレームワークを超えるためには、共に配置してパイプラインを積極的に使うことが重要なんだ。カーマックの2013年の「レイテンシ軽減戦略」論文も、VRに関して同じことを言ってたよね。「ミリ秒ごとにパイプラインの異なるステージに隠れていて、自分でフルパスをトレースしないと見つからない」って。温かいTTSのWebSocketプールで約300msを節約できるのは、まさにこの良い例だね。
それなら、Soniox Real-time(60言語に対応)を使う手もあるよ。エンドポイント検出をネイティブにサポートしてて、モデルはユーザーのターンが終わったタイミングを把握するように訓練されてる。これ、VADよりも常に良い結果が出るんだ。Sonioxは、Pipecatの背後にいる会社Dailyが行った独立したベンチマークでも勝ってるし、デモもホームページで試せるよ。https://soniox.com/ Disclaimer: 以前Sonioxで働いてた。追記: ちょっと早くコメントしちゃった。VADしか見てなくて、すぐにSonioxを思い出したんだ。昨年、リアルタイムエンドポイント検出を実装した最初のサービスだったから。
投稿を読めば、DeepgramのFluxを使ったってわかるよ。これもエンドポイント検出ができて、VADよりも高レベルの抽象化になってる。
使ってるんだね!そこでの仕事はどうだった?消費者向けの製品もあるみたいだね。競合に比べて、どうやってこんなに安くて最先端の技術を手に入れてるんだろう?
個人的には、STT -> LLM -> TTSは行き止まりだと思う。未来はエンドツーエンドだね。2年前にこれを試して、ゲーム用GPUにローカルでインストールできるデモも作ったんだけど、実際のタスクに使えるものを作るにはエンドツーエンドモデルの訓練が必要だと結論づけた。すごく興味深い問題で挑戦したいけど、サイドプロジェクトには予算が足りないな。
もしそう思うなら、nvidiaから出てくる新しいものを楽しめるよ。https://research.nvidia.com/labs/adlr/personaplex/
その利点は、パイプラインの各部分に新しいモデルを組み込めることだね。めっちゃセクシーかって言うと、そうでもないけど。それぞれのモデルの種類は異なるペースで進化してる(TTSはすごく早く進むし、低遅延のSTT/ASRは遅め、LLMは結構いいペースで進んでる)。
でも、スピーチ・トゥ・スピーチモデルのKVキャッシュは、ターンごとにサイズが爆発的に増えるってどこかで読んだことがあるから、デバイス上でのフルデュプレックスS2Sは、短いチャット以外では使えなくなるかもしれない。
基本的に、「自分のターンがいつかを推測する」っていうのはモデルに組み込む必要があると思う。モシが開発したフルデュプレックスモードが、最終的に行き着くところだと思うよ。https://arxiv.org/abs/2410.00037
これは素晴らしいまとめだね、ありがとう!LLMのレイテンシに関しては、OpenAIが最近ResponsesクライアントにWebSocketを導入したから、少し速くなるはずだよ。代替案としては、デバイス上で超小型のLLMをローカルで動かすこともできる。自分で完全にローカルなパイプラインを構築したら、ストリーミングや最適化なしでサブ秒のRTTが出たよ。https://github.com/acatovic/ova
すごくクールだね!スターを付けて、読みたいリストに入れたよ。もしよかったら、話したりノートを共有したりしたいな。
> 声はターンテイキングの問題だね。声に関しては、誰も活用していない低いところにある果実がある気がする。フィラー言葉やペーシングだね。LLMが沈黙に気づくと、実際の応答が生成される間に文脈に応じたフィラー言葉で埋めるんだ。「うんうん」とか「そうそう」みたいな感じで。これがあれば、やり取りがもっと会話っぽく感じられるし、話し手がまだ話しているときには、ユーザーの邪魔をしないで済む。フィラー言葉を言ってから、また聞き続けるって感じで。
100% - これについては、これを書いた後すぐに考えたよ。これを実現する一つの方法は、小さくて遅延の少ないモデルが最初の返答を選択肢の中から生成して、その後、TTSの応答を積極的にキャッシュして遅延を超低くすることだね。「うーん、ちょっと考えさせて…」みたいな返答は、ミリ秒単位で出せるようになる。
最近: https://blog.livekit.io/prompting-voice-agents-to-sound-more...
話し終わる前に応答を予測できるといいね。それは話し手が言うことによって変わるかもしれないけど、すぐに始められるかもしれない。
あー、これめっちゃ興味深い!これ、俺がAmazon Alexaでやってたことなんだ(特許も持ってる)。その時に学んだ面白い事実: 会話中の人間同士の平均遅延は0ms(ゼロ)なんだよ。つまり、多くの場合、聞き手は話し手が話し終わる前に話し始めるってこと。たぶん、君も経験したことあるよね。「お互いの文を終わらせる」って話すのはそのため。脳が相手の言うことを予測しながら、同時に返答を処理してるからなんだ。だから、相手が予想外のことを言うと、「え?」って言って、脳が修正した後に半秒遅れて答えるんだよ。事実2: 人間は音声アシスタントに遅延を期待してる理由が2つある。一つは、コンピュータが考える必要があるって知ってるから。もう一つは、携帯電話のせい。携帯電話には人間同士の会話を壊す遅延があって、脳は音声アシスタントを携帯電話のように考えるんだ。事実3: Alexaからの応答はほとんど500ms未満にならない。ローカルで出される「今何時?」みたいなものでもね。ここでの鍵は意味的なターンの終わり。これは数年前に取り組んでいたことだけど、その時は計算能力が足りなかった。だから当時は、ターンの終わりはただ300msの沈黙だったんだ。これ、すごく面白い。Alexaで働いてから数年経つけど(俺が書いたことは公開されて話題になってる)、彼らがターンの終わりの意味的検出に進展を見せたのか気になる。編集: あ、地理についても君が言う通りだね。それはAlexaにとって大きな進展だった。処理をユーザーに近づけることができたから。
これ、面白いね!シェアしてくれてありがとう!なんでAmazonやGoogle、Appleがここ数年で音声アシスタント/エージェントの波に乗らなかったのか気になる。3社とも既存の製品とユーザーがいて、オーバー・ザ・エアのアップデート一つでカテゴリーを定義してキャッチできるのに。
> 平均遅延 それって、半分の応答が負の遅延ってこと?つまり、人間はお互いの文をちょうど半分の時間で遮るってこと?
すごいね!先週、全く違う技術スタックで同じ目的のアシスタントを3つ作ったよ。(Raspberry Pi Voice Assistant)ジャービスは、内蔵の「ジャービス」というキーワードでウェイクワード検出にポーキュパインを使ってる。音声入力はElevenLabs Scribe v2を通して文字起こしされるんだ。LLMレイヤーは、主にGroq llama-3.3-70b-versatileを使って、バックアップにGroq llama-3.1-8b-instantを使ってる。テキスト読み上げはSmallest.ai LightningとChetanの声を使ってるよ。音声の入出力はALSA(arecord/aplay)で処理されてる。エンドツーエンドのレイテンシは3.8〜7.3秒だよ。(Twilio + VPS)このセットアップは、Twilio Media Streamsを使ってμ-law 8kHz形式で音声を取り込むんだ。Silero VADがスピーチを検出してターンの境界を決める。Groq Whisperがバッチ文字起こしを担当してる。LLMスタックは、Groq llama-4-scout-17b(主)、Groq llama-3.3-70b-versatile(バックアップ1)、Groq llama-3.1-8b-instant(バックアップ2)を自動フェイルオーバーでチェーンしてる。テキスト読み上げはSmallest.ai LightningとPoojaの声を使ってる。音声はPCMからμ-law 8kHzにエンコードされて、Twilio経由でストリーミングされるよ。エンドツーエンドのレイテンシは0.5〜1.1秒だね。───(Alexa Skill)ティナは、Alexaの内蔵ASRを通して音声入力を受け取り、その後AlexaのNLUで意図を検出するんだ。LLMはClaude Haikuで、OpenClawゲートウェイを通してルーティングされてる。音声出力はAlexaのネイティブなテキスト読み上げを使ってるよ。エンドツーエンドのレイテンシは1.5〜2.5秒だね。
使用するTTSモデルによっては、LRUキャッシュを使うことでレイテンシをさらに減らせるかもしれないね。よく使うフレーズをキャッシュから取得して、新しくTTSで生成する代わりにね。ただ、音の自然さはTTSモデルの動作に依存するし、同じテキストの2つのチャンクが毎回同じように聞こえるかどうかにもよるよ。
それ、半秒の遅延だね。0.4から0.5秒。これはGEO軌道の衛星を介した電話の会話と同じくらいの遅延だよ。もしかしたら、俺が年齢層が上なのかもしれないけど、この遅延を覚えてるし、このクラスの遅延で会話を続けるのがどうだったかも思い出すよ。(それでも素晴らしい進歩だけど、UXには気をつけてね)
IRLで人間レベルのレイテンシを達成しようとする際の課題の一つは、対面でのターンテイキングに非言語的な手がかりに頼っていることだね。例えば、https://www.sciencedirect.com/science/article/pii/S001002772...