高级 📋 6 个步骤 第 468 / 470 篇

用 LiveKit Agents 搭可打断的语音智能体(STT→LLM→TTS 流水线)

LiveKit Agents 开源实时语音智能体框架实操:装依赖、配密钥,用 AgentSession 串起 STT→LLM→TTS 流水线,打开 allow_interruptions 实现自然打断,并用 function_tool 让语音 Agent 中途调用工具。

2026.09.24· 18 分钟阅读· 约 1516 字· 🎙️ LiveKit / 🔊 语音智能体

语音智能体(Voice Agent)和普通聊天机器人最大的区别是:用户开口说完,到听见回复,整段延迟得压在 1 秒以内,否则对话就断开、像卡顿的电话。LiveKit Agents 是开源的实时语音智能体框架(基于 WebRTC),它把语音识别(STT)→ 大模型(LLM)→ 语音合成(TTS)用语音活动检测(VAD)和打断处理串成一条可生产的流水线。本教程带你从装依赖、配密钥,到跑通一个能自然插话、会调用工具的语音助手,全程可复现。

🎙️ 本教程适合:想做语音客服、语音陪练、电话机器人的开发者。你需要 Python 3.10+ 和若干 API Key(下文会列出)。类似思路也适用于 OpenAI Realtime,但 LiveKit 的好处是 STT/LLM/TTS 各自可换厂商。

先搞懂:语音智能体为什么难

语音对话是一条接力:用户说话 → VAD 判断"说完了"→ STT 转成文字 → LLM 生成回答 → TTS 合成语音 → 播放。每一段都吃延迟,加起来要控制住:

阶段典型耗时说明
VAD 端点检测200–500ms判断用户何时说完,太激进会打断半句话
STT 语音识别60–300msDeepgram Nova-3 较快
LLM 生成300–800ms流式输出,首字越快越好
TTS 首包音频75–200msCartesia / ElevenLabs 较快

打断(barge-in)是必做项:用户说话时,Agent 正在念的半句 TTS 必须立刻停掉,否则两边同时响。LiveKit 的 VAD 会接管这件事——你只要打开允许打断即可,不要自己写停播逻辑。

Step 1:装好 LiveKit Agents 与插件

1 建虚拟环境并装 SDK

用一个干净的虚拟环境,避免和别的项目依赖打架。下面按"可换厂商"的经典流水线装:OpenAI 做 LLM、Deepgram 做 STT、Cartesia 做 TTS、Silero 做 VAD、并带上降噪插件。

python -m venv .venv
source .venv/bin/activate        # Windows: .venv\Scripts\activate
pip install "livekit-agents[openai,deepgram,cartesia,silero,noise-cancellation]"
💡 想用原生实时模型(如 OpenAI Realtime、Gemini Live)把 STT/LLM/TTS 合成一个端点、延迟更低?把安装改成 livekit-agents[openai,realtime,silero,turn-detector,noise-cancellation],并把下面的 AgentSession 里的 llm= 换成 openai.realtime.RealtimeModel(...) 即可,其余结构不变。

Step 2:准备三把密钥

2 把密钥放进 .env

LiveKit Agents 需要一个实时房间(LiveKit Cloud 或自托管 Server),再各选一家 STT / LLM / TTS 供应商。把密钥写进项目根目录的 .env

LIVEKIT_URL=wss://your-project.livekit.cloud
LIVEKIT_API_KEY=your_livekit_api_key
LIVEKIT_API_SECRET=your_livekit_api_secret
DEEPGRAM_API_KEY=your_deepgram_key
OPENAI_API_KEY=your_openai_key
CARTESIA_API_KEY=your_cartesia_key

密钥安全.env 绝不能提交进 git。在项目里加一个 .gitignore.env;任何 API Key 泄露都能被别人拿去扣费。本机调试用 python-dotenv 读取即可。

Step 3:写出最小可运行语音 Agent

3 经典流水线:三件组件拼一个 Agent

新建 agent.py。核心是 AgentSession:把 STT、LLM、TTS 分别挂上去,框架自动处理 VAD、轮次和打断。VoicePipelineAgent 是经典流水线封装,allow_interruptions=True 打开打断。

import asyncio
from dotenv import load_dotenv
from livekit import agents
from livekit.agents import AgentSession, Agent
from livekit.plugins import openai, deepgram, cartesia, silero

load_dotenv()

class Assistant(Agent):
    def __init__(self):
        super().__init__(instructions="你是简洁友好的语音客服,每次回答不超过两句话。")

async def entrypoint(ctx: agents.JobContext):
    await ctx.connect()
    session = AgentSession(
        vad=silero.VAD.load(),
        stt=deepgram.STT(model="nova-3", language="multi"),
        llm=openai.LLM(model="gpt-4.1-mini"),
        tts=cartesia.TTS(),
    )
    await session.start(agent=Assistant(), room=ctx.room)
    await session.generate_reply(instructions="向用户问好,并说明你能帮什么忙。")

if __name__ == "__main__":
    agents.cli.run_app(agents.WorkerOptions(entrypoint_fnc=entrypoint))
💡 模型名随版本会变动,以官方文档为准:Deepgram 用 nova-3、OpenAI 用 gpt-4.1-mini 这类小模型即可压低延迟与成本;TTS 换声音用 cartesia.TTS(voice="...")

Step 4:让 Agent 能插话(打断)

4 打开 allow_interruptions

打断在 LiveKit 里是"开箱即用"的:VAD 一旦检测到用户又开始说话,会取消正在播放的 TTS、截断 Agent 上句未念完的部分,把新的用户语音路由给 STT。你只需要显式允许,并控制 VAD 灵敏度。

session = AgentSession(
    vad=silero.VAD.load(min_speech_duration=0.2),   # 多短算"开口"
    stt=deepgram.STT(model="nova-3"),
    llm=openai.LLM(model="gpt-4.1-mini"),
    tts=cartesia.TTS(),
    turn_detection="stt",        # 用 STT 做端点检测
)
await session.start(agent=Assistant(), room=ctx.room, allow_interruptions=True)

别在 HTTP-only 环境里硬扛:LiveKit 建立在 WebRTC 房间模型上,需要实时传输。纯 HTTP 环境请走 Twilio Media Streams 或托管平台(Vapi / Retell)。电话场景用 LiveKit 的 SIP 中继接入 PSTN。

Step 5:给语音 Agent 加工具调用

5 function_tool 让模型中途查数据

语音 Agent 也能在对话中途调工具,例如查订单。用 @function_tool 装饰一个异步函数,框架会把函数注册进会话,模型按名字调用,schema 写清楚能显著降低幻觉。

from livekit.agents import function_tool

class Assistant(Agent):
    @function_tool
    async def lookup_order(self, order_id: str) -> str:
        """按订单号查询客户订单状态。"""
        # 这里换成你真实的 CRM 查询
        return f"订单 {order_id}:已发货,预计明天送达。"
🔑 工具函数要短、要纯:语音场景里每次工具调用都加一轮推理延迟,尽量把需要的判断在一次 sampling 里问完,不要在循环里反复请求模型。

Step 6:本地试跑与上线

6 先用 console / dev 模式验证

不接 LiveKit 房间也能先验证逻辑:console 模式用麦克风本地对话;dev 模式连 LiveKit Cloud 的开发房间,打开 agents-playground 网页即可对话。

python agent.py console     # 本地麦克风,无需 LiveKit 连接
python agent.py dev         # 连 LiveKit Cloud 开发房间
python agent.py start       # 生产 worker 模式
🚀 验证清单:① 开口能打断 Agent 播报;② 工具调用能返回真实数据;③ 长静默 15 秒后 Agent 主动提示,避免"以为掉线"。生产用 livekit server cli deploy 或 Docker Compose 自托管。

常见问题

现象原因与处理
运行报缺 API Key检查 .env 是否能被 load_dotenv 读到,变量名是否与插件一致
用户一开口就被打断VAD 太灵敏,调大 min_speech_duration 或 silence 阈值
延迟明显偏高换小模型 + 流式 TTS,并优先选同区域供应商
← 返回教程中心