你對語音 Agent 問完一句話,空白了一拍才聽見它開口。工程儀表板顯示 LLM 第一個 token 要等約 1.5 秒,於是團隊準備換模型。但語音 Agent 延遲究竟卡在模型、判斷你說完了、語音合成,還是用戶端播放器開始播放?只憑一個 TTFT 數字,還答不出來。
這篇是給第一次替語音系統量延遲的讀者:不用先懂分散式追蹤,我們會把「說完話到第一聲」拆成可記錄的事件,再用同一批繁中語句做 A/B。你最後會拿到一份能填入自己 Trace 的工作簿,知道下一個該調的旋鈕是什麼。約 1.5 秒 TTFT來自一位開發者在 2026 年 9 月的自述,並非語音 Agent 的通用基準。
先說結論:語音 Agent 延遲是一段路,不是一個模型數字
一句話記住:第一聲等待=使用者說完到播放器出聲;Trace 要標出路上每一個交接點。STT 是把語音轉文字的「耳朵」,LLM 是組織回答的「腦」,TTS 是把文字變成聲音的「嘴」;端點判斷則像話筒旁的主持人,決定何時輪到 Agent 說話。想先看整套系統如何運作,可讀Agent Harness 的白話解釋。
本文只診斷一個讀者問題:同一回合,從最後一個使用者語音樣本到裝置實際開始播放,時間花在哪裡?任務是否做對、數字有沒有聽錯,另用Voice Agent Eval 的回歸測試驗收;兩張成績單要一起看。

語音 Agent 延遲先記哪 8 個時間戳?
把一通電話想成餐廳出餐:客人點完菜、服務員確認、廚房出第一道、跑菜員拿到、餐盤真的上桌,是不同時刻。你的 Trace 也要為同一個 turn_id保留下面八個事件。每個事件記「事件發生時間」和「由哪個元件觀察」,不要把後來收到的日誌時間冒充事件時間。
- speech_end:測試音檔最後一個有聲樣本的時間;線上流量可另記 VAD 判定的最後說話時間,兩者來源分開標。
- partial_stt_at:先收到可變動的暫時逐字稿;它可用於預備工作,不能當成完整回合已結束。
- final_stt_at:拿到該段最終轉寫。像 Deepgram 的
is_final表示一段文字定稿,speech_final才是偵測到停頓後的回合端點;長句可能有多段定稿。 - turn_complete_at:端點判斷正式宣布使用者說完,容許 Agent 回應。
- llm_request_at:LLM 請求正式送出。另記服務端可用的排隊與提示處理欄位。
- first_usable_text_at:第一段能安全交給 TTS 的文字到達。另記供應商 TTFT,因第一個 token 未必足以發聲。
- tts_first_audio_at:TTS 第一個可解碼音訊區塊抵達你的播放器;這仍是「包裹送達」,不是「餐上桌」。
- playback_start_at:用戶端播放器確實開始輸出第一段音訊。這是本文一致使用的可觀測終點;若要確認實際聲學出聲,須另用迴錄或外部收音量測。
對照LiveKit 的量測定義時,特別注意 end_of_utterance_delay 已含部分 transcription_delay,不能把兩個現成欄位再相加。LiveKit 也分開列 llm_node_ttft、tts_node_ttfb、playback_latency 和端到端延遲;各欄位是否可取得還取決於所用管線與回合判斷方式。最穩的總數是同一時鐘下的 playback_start_at − speech_end。
照著填一輪語音 Agent 延遲 Trace
先用一段人工設計的算式練習,學會讀時間戳。假設 speech_end=0 ms、final_stt=220 ms、turn_complete=380 ms、llm_request=410 ms、first_usable_text=1090 ms、tts_first_audio=1320 ms、playback_start=1510 ms。那麼這輪第一聲等待是 1510−0=1510 ms;從送出 LLM 到可用文字是 1090−410=680 ms;音訊已抵達、但播放器尚未開聲的距離是 1510−1320=190 ms。這些數字只用來示範計算,沒有對任何產品宣稱性能。
別把上面的差值當成六個互不重疊的積木:STT 可能在你仍說話時已開始,LLM 可能根據 partial STT 預先啟動,TTS 也可能邊收文字邊生成。總延遲看首尾;原因看事件之間的等待與重疊。若多台機器的時鐘未對齊,先在同一程序用單調時鐘量各段時長,再用同一個 turn_id 串起跨服務事件;切勿直接減兩台主機的牆上時間。
可把以下欄位放進 CSV 或觀測系統:turn_id,case_id,variant,region,model_id,context_tokens,speech_end,partial_stt_at,final_stt_at,turn_complete_at,llm_request_at,first_usable_text_at,tts_first_audio_at,playback_start_at,false_endpoint,barge_in_fail。音訊與逐字稿可能含個資;比較延遲時只保留必要的事件與受控測例,避免把真實通話原文放進公開 Trace。
A/B 工作簿:一次只改一個旋鈕
第一步,鎖住測試條件。把同一批音檔、同一模型版本、TTS 聲線、系統提示、上下文長度、部署區域與網路條件記在表頭;工具呼叫回合另分一組。每段音檔在 A、B 都跑,交錯順序,避免把晚間流量或模型暖機差異錯認成改動效果。
第二步,先選一個待驗假說。如果 turn_complete_at−speech_end 最大,試一個端點判斷設定;如果 first_usable_text_at−llm_request_at 最大,才試縮短上下文或另一模型;如果 playback_start_at−tts_first_audio_at 偏大,先查播放器緩衝。每輪只動一項,其餘條件照抄 A。
第三步,兩組都報 P50、P95 和失誤率。P50 是一半回合比它快的中位數,P95 讓你看最慢那一小群;先對每個回合計算首尾時間差,再分別求 A、B 分位數。不要把各段 P95 加成總 P95:最慢的端點判斷與最慢的 LLM 不一定出現在同一通。另列「太早搶話」率、「使用者插話後 Agent 沒停」率,以及回答是否仍符合任務,避免只換到一個會搶話的快系統。
第四步,把改善歸因到事件。若 B 的總 P95 下降,而 turn_complete 提前、LLM 與播放器段保持接近,端點設定才是合理候選原因。若 TTFT 下降但第一聲原地踏步,查看 TTS 等字數門檻、網路和播放器。ElevenLabs 對串流的說明也把模型生成、第一包音訊與實際播放分成不同階段。
四個常見旋鈕,怎麼知道調對了?
① 端點等待:快一點,會不會搶話?
痛點是「主持人」等太久才交棒。做法是固定音檔,將端點閾值 A/B,各記 turn_complete_at−speech_end 與自然長停頓的誤切率。Deepgram 文件示範 endpointing=300 這類毫秒參數,也說明 interim、is_final、speech_final 是不同訊號。這是某一家 API 的參數範例,改用其他供應商時應對照其回合判斷語義。
② Partial STT 預備:文字改了怎麼辦?
痛點是等待完整逐字稿後才開始所有工作。可用 partial STT 預先建立候選回答,但只有文字穩定、回合確認後才交給會發聲或有副作用的步驟;若 partial 被修正,取消候選。A/B 看 llm_request_at 是否提前,以及被取消的生成、誤答、錯誤工具動作是否增加。Deepgram 的原始範例展示 interim 字詞後來被改寫,這正是預生成要設取消閘門的原因。進一步的回歸案例見Voice Agent Eval。
③ LLM 輸入:1.5 秒究竟等在哪?
痛點是 TTFT 已經很長,卻還不知道是請求排隊、提示過長、工具定義太多或模型生成。先記 llm_request_at、服務端可取得的排隊/處理時間、first_usable_text_at 和 context_tokens;再單獨試縮短歷史訊息,或比較快取命中與未命中的相同前綴。A/B 要同時查回答品質,並依各供應商實際回傳的欄位解讀快取,不能用「快取已開」推定這輪已命中。如何整理上下文,可延伸讀省 token 的上下文方法。
④ TTS 與播放器:首包到了,耳朵聽到了嗎?
痛點是後端記了第一包音訊,但手機仍安靜。分別記 tts_first_audio_at、首包送往用戶端、playback_start_at;只改串流切塊或播放器緩衝其中一項,觀察第一聲、卡頓與聲音自然度。TTS 串流能讓首包提早抵達,卻仍需足夠文字與播放緩衝;官方 WebSocket 指南也提醒較小的文字塊會牽動語音品質。想比較語音模型的功能與體驗,可搭配Nari Qwen3-TTS/ASR 教學。
繁中測例與可接受的延遲預算
至少準備四類你自己有權使用的固定錄音:短問句「今天幾點關門?」;句中長停頓「幫我查……下週三的車票」;修正句「訂星期四,等一下,改星期五」;插話「先等等,我還沒說完」。同時保留一段含數字與中英混用的語句,檢查提早啟動是否把尚未穩定的字交給 LLM。每一類在不同噪音、裝置與網路條件下分層看,別把乾淨錄音的 P50 當成所有人的體驗。
延遲預算不是業界固定的「必須低於一秒」。先用自己服務的 A 組得出 P50、P95 與失誤率,再定義:一般短問句的第一聲目標、長停頓容許的誤切上限、插話後的停止時間,以及答案正確率底線。一份公開的原始 Trace 報告以五場對話、36 個回合展示 P50 與 P95 可相差很多;那是作者的系統、語料與設定,不是你產品的目標值。
常見問題:語音 Agent 延遲怎麼判讀?
TTFT 降了,第一聲一定會提早嗎?
不一定。第一個 token 到來後,TTS 可能還要等足夠的字;音訊抵達後,播放器仍可能緩衝。看 playback_start_at−speech_end 才知道用戶端可觀測的變化。
可把 STT、端點、LLM、TTS 各自 P95 相加嗎?
不該。欄位可能互相包含,工作也可能重疊;各段最慢回合通常不是同一輪。先在每個回合計總時間,再計總時間的 P95。
收到 is_final 就代表使用者說完了嗎?
對 Deepgram 而言,不是。is_final 可只表示一段轉寫定稿;speech_final 才對應偵測到停頓的端點。其他系統要讀自己的事件定義。
端點閾值越短越好嗎?
不一定。短閾值可能改善短問句,也可能把繁中自然停頓切成兩輪;同時看長停頓誤切率和總延遲。
Partial STT 可以直接拿去執行工具嗎?
先建立候選,待確認再執行。暫時轉寫會修正,尤其否定詞、日期與數字;有副作用的動作應等待可核對的最終意圖。
第一個音訊封包等於第一聲嗎?
不等於。封包還可能在傳輸、解碼與緩衝;把播放器實際開始輸出的時間另記,才能回答使用者體感。
A/B 應先試換模型嗎?
先看 Trace 最大等待在哪一段。若延遲集中在端點或播放器,換模型很難碰到該段;若 LLM 段最大,再把模型列為受控變數。
語音轉語音模型也要這套方法嗎?
要保留首尾與交接事件,內部拆段則依架構改寫。端到端模型未必提供獨立 STT/TTS 欄位;先記使用者說完、模型回應開始、用戶端播放,再補廠商實際可觀察的事件。Gemini Live 的回合生命週期可作另一種架構對照。
給新手的三個重點
- 先量
playback_start_at−speech_end,它回答「人等了多久」。 - 在同一回合標出端點、轉寫、可用文字、首包音訊與播放;同名指標先核對定義。
- 每次只改一個旋鈕,用固定繁中測例比較總延遲 P50/P95、搶話與插話失誤。
接著閱讀
左右滑動查看更多推薦
下一步:先拿一段音檔,畫出第一聲的路線
今天先挑一段短問句和一段長停頓錄音,照八個時間戳填完 A 組,再只調一個你懷疑的瓶頸做 B 組。若你要把這套量測與更完整的 Agent 建置方法串起來,也可從AlphaLab 課程接著學。記住那句話:第一聲等待是一段路;Trace 才知道慢在哪一站。






