語音 Agent:讓 Agent 開口說話的即時語音實作課

語音 Agent:讓 Agent 開口說話的即時語音實作課

前言:文字 Agent 之後,下一個介面是聲音

Agent 已經會寫程式、會操作電腦,但人類最重要的溝通通道既不是鍵盤也不是螢幕,而是聲音。客服電話、車載助理、醫療問診、語言學習——大量真實工作發生在「講電話」的情境裡。2024 年 OpenAI 發佈 Realtime API、Google 推出 Gemini Live、LiveKit 把 WebRTC 基礎設施加上 Agent 框架,語音 Agent 從研究 demo 走向量產。但真正的門檻不是「讓模型說話」,而是讓對話「像在講電話」:延遲要壓在 1 秒內、使用者可以隨時插話、模型要聽得出語氣。

兩種架構:串接管線 vs 端到端語音模型

如圖一,2026 年的語音 Agent 只有兩種形狀。

串接管線(Cascaded):麥克風 → VAD(語音活動偵測)→ 串流 STT → 端點偵測 → LLM → 串流 TTS → 喇叭。音訊在每個階段邊界都被轉成文字,每一段都是可替換的零件,常常來自不同廠商(STT 用 Deepgram 或 AssemblyAI,TTS 用 Cartesia 或 ElevenLabs,LLM 任意選)。

端到端語音模型(Speech-to-Speech):單一多模態模型直接吃音訊、直接吐音訊,文字只是轉錄副產物。代表作是 OpenAI Realtime API、Google Gemini Live、AWS Nova Sonic,以及開源的 Kyutai Moshi。

權衡很實在:串接的可控性高——每段邊界都有文字,可以換廠商、做 A/B 測試、插入政策檢查、留審計軌跡;代價是韻律和情緒在 STT 轉文字時被弄丟,而且你要自己處理輪次。端到端保留語氣、笑聲和猶豫,延遲結構上更低,但換供應商等於重寫架構,除錯時只能對著黑箱。

2026 年的產業共識值得注意:Vapi、Smallest AI、Decagon、Retell 的工程師在 Latent Space 播客上一致表示,真正上線扛流量的系統幾乎都是串接架構——護欄、可靠度、可解釋性壓過了端到端的優雅。端到端是未來,但生產的現在是串接。

延遲預算:800ms 怎麼花

語音對話的體感延遲有一條硬線:使用者講完到聽到回應,超過約 1 秒就會覺得「卡」。如圖二上半,一個典型串接管線的預算長這樣:STT 約 150ms、LLM 首字約 300ms、TTS 約 200ms、網路與緩衝約 150ms,總計 800ms。

關鍵洞察是:全串流架構下,總延遲趨近於各段的最大值,而不是加總。STT 邊聽邊轉、LLM 邊生成邊把 token 餵給 TTS、TTS 邊合成邊播放——管線重疊起來,瓶頸只剩最慢的那一段(通常是 LLM 的首字時間)。實務上還有三招壓延遲:preemptive generation(使用者還沒講完就先用中間轉錄開始生成,猜錯就丟掉)、串流 STT/TTS 全開、以及把回覆寫短——第一句話越短,首音出現得越快。

實作核心:輪次偵測與打斷

語音工程裡最不性感、也最難的問題是輪次(turn-taking):VAD 只回答「現在有沒有人在說話」,真正的問題是「他講完了,還是只是停頓?」切太快會打斷使用者,切太慢對話像在對講機。LiveKit 的做法是訓練一個語義輪次偵測模型:同時讀聲學訊號和即時轉錄的文字(填充詞、句法完整度),把等待窗口動態調在 0.3 到 2.5 秒之間——比固定靜音閾值自然得多。

另一半是打斷(barge-in),如圖二下半。使用者插話時,正確的反應鏈是:VAD 觸發 → 150ms 內停止 TTS → 清空播放緩衝 → 取消還在生成的 LLM → 把新話語送回 STT。LiveKit Agents、Pipecat 都把這條鏈做成了內建行為。兩個常見坑:第一,誤打斷——偵測到聲音但轉錄回來是空的(咳嗽、背景音),這時要恢復播放而不是丟掉對話;第二,Agent 打斷自己——喇叭的聲音被麥克風收回去,要用回音消除或客戶端降噪解決。

實作要點:LiveKit Agents 最小 session

下面是一個 LiveKit Agents 風格的最小語音 session 骨架(Python 概念碼):


from livekit.agents import Agent, AgentSession

class VoiceAssistant(Agent):
    def __init__(self):
        super().__init__(
            instructions="你是客服助理,回答簡短,一次只講一件事。",
        )

async def entrypoint(ctx):
    session = AgentSession(
        stt="deepgram/nova-3",        # 串流語音轉文字
        llm="openai/gpt-4o-mini",     # 推理+工具呼叫
        tts="cartesia/sonic-3",       # 串流語音合成
        vad="silero",                 # 語音活動偵測
        turn_detection="multilingual",  # 語義輪次偵測,而非固定靜音閾值
    )
    await session.start(room=ctx.room, agent=VoiceAssistant())

# 打斷處理是框架內建的:VAD 觸發 → 停止 TTS → 取消 LLM 生成 → 新話語送回 STT
# 誤打斷(轉錄為空)時自動恢復播放,對話不丟失

落地時的三個實務提醒:第一,傳輸用 WebRTC——LiveKit 的 SFU 就是為低延遲音訊設計的,不要自己拿 WebSocket 從頭刻;第二,電話線路(PSTN)只有 8kHz,端到端的音質優勢在電話上幾乎歸零,這也是串接至今仍是電話場景標準答案的原因;第三,先寫文字版 Agent 再加聲音——工具、政策邏輯、知識庫全部複用,語音只需要自己的輪次處理和評測。

評測與生產考量:成本和安全

語音的評測維度跟文字 Agent 不完全一樣:除了任務成功率,還要量首音延遲(time-to-first-audio)、打斷成功率、誤打斷率、噪音下的 STT 錯誤率。成本結構也不同:串接是可預測的每分鐘計費,端到端多半按 token 計費——而且為了保持上下文,每一輪都要重送累積的音訊歷史,通話越長越貴;兩種路線的每分鐘成本價差可達上百倍,選型時要先算帳。

安全上,聲音帶來新的攻擊面:語音版 prompt injection(用音訊藏指令)、語音偽造冒充身分。實務底線是:重要動作(轉帳、刪資料、對外承諾)永遠不要只靠語音確認,要嘛轉文字二次確認,要嘛留人工審核。

選型決策:何時用哪種

決策規則很直白:需要工具呼叫、結構化擷取、可審計軌跡、或走電話線路——選串接;追求自然度、最低延遲、情感語調、且對話是閒聊型而非交易型——選端到端。框架選型則看團隊:LiveKit Agents 是自己組裝的基礎設施(最大控制權、開源),Pipecat 同類;想快速上線就買 Vapi 這類託管服務。

結論:先讓管線轉起來,再追求自然

語音 Agent 的工程現實是:架構選串接還是端到端只是第一題,真正的功夫在延遲預算、輪次偵測和打斷處理這些「不性感」的細節。2026 年的務實路線是串接管線起手——可觀測、可除錯、可上線;等對話自然度變成瓶頸時,再把特定場景切到端到端。會說話不難,難的是讓人願意一直講下去。

來源

Uploaded Image Uploaded Image

沒有留言:

張貼留言