资讯动态

基于LiveKit与LangGraph构建实时语音AI通话代理的完整指南

发布时间:2026/8/22 2:58:08 来源:尧图企业网站定制
1. 项目概述构建一个实时语音AI通话代理如果你正在寻找一个能将任何LangGraph智能体Agent瞬间变成一个能和你“打电话”的AI伙伴的方案那么langgraph-voice-call-agent这个项目就是你一直在等的那个“轮子”。它本质上是一个后端服务通过整合LiveKit的实时音视频通信能力和LangGraph的智能体编排框架实现了类似ChatGPT Voice或Gemini Live那样的全双工、低延迟语音对话体验。简单来说你提供一个能处理文本对话的LangGraph智能体这个项目就能给它装上“耳朵”和“嘴巴”让它能听会说接入一个电话或语音聊天室。这个项目的核心价值在于“桥接”与“解耦”。它没有重新发明一个AI模型或一个复杂的语音处理引擎而是巧妙地用LiveKit处理所有实时音频流的传输、编解码和网络传输难题用成熟的第三方服务如Deepgram处理语音识别和合成自己则专注于最核心的“胶水”逻辑如何将实时的音频流事件无缝地转换成LangGraph能理解的文本请求再把LangGraph返回的文本流实时地转换成音频流播放出去。这种架构让你能专注于智能体本身的业务逻辑比如处理待办事项、查询信息、扮演角色而无需深陷WebRTC、音频缓冲区、回声消除等底层细节。2. 核心架构与设计思路拆解2.1 为什么选择LiveKit LangGraph的组合在构建实时语音AI时技术选型直接决定了开发复杂度和最终体验的上限。这里的选择背后有清晰的逻辑LiveKit负责“实时管道”它是一个开源的WebRTC基础设施项目。自己从零实现一个稳定、低延迟、支持多人、能穿透各种网络环境NAT的实时音视频服务是一个巨大的工程挑战。LiveKit封装了信令服务器SFU、TURN/STUN服务器、房间管理等复杂组件提供了简洁的SDK。对于这个项目而言LiveKit Agent SDKPython版是关键它允许我们以“参与者”的身份加入一个房间并直接接收和发送原始的音频轨道数据。这意味着我们不需要关心麦克风权限、音频采集、网络传输等问题只需要处理已经送到我们手里的音频包。LangGraph负责“智能大脑”LangGraph是LangChain团队推出的用于构建复杂、有状态AI应用的工作流编排框架。它的核心优势是能用图Graph的方式清晰地定义智能体的决策流程和状态流转支持循环、分支、多工具调用等复杂逻辑。与直接调用OpenAI的ChatCompletion接口相比使用LangGraph意味着你的智能体可以拥有记忆、可以执行一系列工具调用如查询数据库、调用API、可以根据中间结果决定下一步行动。这个项目要做的就是把实时语音流“喂”给这个强大的、可定制的“大脑”。项目的角色是“适配器”因此langgraph-voice-call-agent的定位非常明确它就是一个高质量的适配器Adapter。它监听LiveKit的音频流事件调用VAD语音活动检测判断用户是否在说话用STT语音转文本将说话内容转成文字将文字发送给LangGraph智能体接收智能体返回的文本流再用TTS文本转语音合成语音最后通过LiveKit播放出去。整个流程的稳定性和性能依赖于LiveKit管道和外部AI服务的质量。2.2 整体数据流与组件交互理解数据如何流动是调试和定制这个系统的关键。一次完整的语音交互其数据流大致如下用户端用户在前端如一个Web页面点击“加入房间”。前端使用LiveKit Client SDK连接到LiveKit服务器本地或云端发布自己的麦克风音频轨道。LiveKit服务器服务器将用户的音频流转发给所有房间内的订阅者包括我们的langgraph-voice-call-agent后台服务。Agent服务VAD 端点检测服务收到音频包后首先送入VAD模型如Silero VAD和说话人转换检测模型。这一步至关重要它决定了何时开始“听”和何时停止“听”。VAD检测到有语音活动且转换检测模型判断当前是用户在说话而非AI在回应则开始收集音频数据。Agent服务STT当检测到用户说话结束静音超时或显式端点将收集到的一段音频数据发送给STT服务如Deepgram获得转录文本。这里的一个优化点是可以使用流式STT在用户说话的同时就开始转录进一步降低延迟。Agent服务LangGraph适配器将转录文本连同当前对话的thread_id从参与者元数据中获取用于维持多轮对话上下文封装成一个请求发送给正在运行的LangGraph开发服务器。这里的连接是通过LangGraph的RemoteGraph客户端实现的它允许跨进程或跨网络调用定义好的图。LangGraph服务器接收到请求后LangGraph智能体开始工作。它根据定义的工作流可能调用工具、访问记忆状态最终生成一段回复文本。这个回复可以是流式的token by token也可以是完整的句子。Agent服务TTS收到LangGraph返回的文本流后立即或缓冲一小段后调用TTS服务如Deepgram TTS将文本合成为音频流。同样这里也可以使用流式TTS来减少首句延迟。Agent服务音频回传将TTS生成的音频数据包通过LiveKit Agent SDK发布到一个新的音频轨道上发送回LiveKit服务器。LiveKit服务器 用户端服务器将AI的音频流转发给用户端用户从耳机或扬声器中听到AI的回复。整个循环的关键在于“全双工”和“低延迟”。理想情况下用户说话结束到听到AI回复开始的延迟端到端延迟应控制在几百毫秒内才能有自然对话的感觉。这要求VAD/STT/TTS每个环节以及网络传输都必须高效。注意关于“Thread连续性”项目通过participant.metadata来传递thread_id。这是维持多轮对话上下文的核心。当用户从前端加入房间时前端需要生成或获取一个唯一的thread_id并将其设置在参与者的元数据中。这样无论用户说什么后端智能体都能根据这个thread_id找到正确的对话历史记录通常存储在LangGraph的检查点中实现连贯的聊天体验。如果thread_id丢失或错误每次对话都会变成独立的、无上下文的新会话。3. 核心模块深度解析与实操要点3.1 LiveKit Agent 主入口 (src/livekit/agent.py)这个文件是整个服务的启动器和总控制器。它不包含具体的语音处理逻辑而是负责搭建舞台、协调演员。核心类VoiceAgent通常继承自livekit.agents.Agent或类似基类。在__init__中它会初始化一系列处理器ProcessorVAD语音活动检测例如使用livekit.agents.vad.SileroVAD。你需要配置一个阈值如0.5和静音持续时间如500毫秒来决定何时判定语音开始和结束。STT语音转文本例如使用livekit.agents.stt.DeepgramSTT。需要传入你的Deepgram API密钥。这里要特别注意选择支持流式识别的模型并配置好语言和识别选项如是否加标点、是否识别数字格式。TTS文本转语音例如使用livekit.agents.tts.DeepgramTTS。需要选择声音模型如aura-asteria-en、设置语速、音高等。Turn Detection说话人转换检测这是一个关键但易忽略的组件。它用于区分用户语音和AI播放的语音防止AI“听”到自己说的话而产生循环。项目中使用了一个简单的基于语言英语的模型来判断当前音频是用户输入还是AI输出。LangGraph Adapter这是自定义的适配器负责与LangGraph服务器通信。工作流程on_room_connected当Agent成功连接到LiveKit房间后触发。在这里它会订阅房间内所有参与者的音频轨道。on_track_subscribed当成功订阅到一个音频轨道通常是用户的麦克风后触发。这里会将这个音频轨道“喂”给一个音频流水线。音频流水线这是LiveKit Agents框架的核心概念。它像一条流水线音频数据包从源头用户麦克风流入依次经过VAD、Turn Detection、STT等处理器的处理。每个处理器可以消费、修改或产生新的数据。VAD处理器监听流当检测到语音时开始收集音频片段。当VAD检测到静音用户停止说话它将收集到的音频片段推送给STT处理器。STT处理器将音频异步转录为文本然后触发一个事件例如on_speech_recognized。on_speech_recognized这是你编写的回调函数。当STT完成识别你会在这里拿到转录文本。此时你需要从当前参与者的元数据中提取thread_id。调用LangGraph Adapter将(thread_id, 用户文本)发送给LangGraph智能体。LangGraph Adapter会返回一个文本流异步生成器。处理LangGraph响应流一旦开始从LangGraph接收文本token就立即或缓冲后送入TTS处理器。TTS处理器会异步生成音频数据包。发布AI音频你需要创建一个音频源livekit.agents.audio.AudioSource将TTS生成的音频数据包写入这个源然后将这个源发布为一个新的音频轨道到房间中。这样其他参与者用户就能听到AI的声音。实操心得管理音频轨道生命周期一个常见的坑是音频轨道的创建和发布时机。不要在每次回复时都创建新轨道并发布这会产生大量冗余轨道。最佳实践是在Agent连接房间后预先创建一个音频源和轨道并发布。在后续的对话中始终向这个同一个音频源写入数据。当对话完全结束如参与者离开时再停止并清理该轨道。这能保证音频流的连续性和资源高效利用。3.2 LangGraph适配器 (src/livekit/adapter/langgraph.py)这个文件是连接LiveKit世界和LangGraph世界的桥梁。它的核心任务是调用远程的LangGraph图并处理其流式输出。核心原理RemoteGraphLangGraph提供了RemoteGraph类它允许你通过HTTP连接到另一个进程中运行的LangGraph开发服务器。你只需要知道图的名称和服务器地址就可以像调用本地函数一样调用它并支持流式响应。适配器的工作初始化读取环境变量LANGGRAPH_URL默认为http://localhost:2024创建RemoteGraph客户端。调用图提供一个run或astream方法。它接收thread_id和user_input作为参数。内部会构造一个符合LangGraph图输入格式的字典通常至少包含messages键其值是一个包含用户消息的列表。thread_id直接用作LangGraph的线程标识符用于持久化对话状态。处理流式响应LangGraph图可以配置为流式输出。适配器需要遍历这个流。流中的每个元素可能包含messages: 新的消息对象如AIMessage。custom: 自定义的事件或数据。其他图状态信息。 适配器需要从中提取出AI回复的纯文本内容。对于简单的聊天可能就是最后一条AIMessage的content对于复杂的流可能需要拼接多个片段的content。格式转换将提取出的文本封装成LiveKit Agents框架期望的格式例如ChatChunk对象或者直接返回字符串。这取决于主Agent中如何处理LLM的响应。关键配置在LangGraph服务器端你需要确保图graph)的stream_mode包含messages或custom以便客户端能接收到流式更新。同时图的检查点存储checkpointer必须正确配置这样才能根据thread_id恢复历史状态。# 示例适配器中的核心调用逻辑 async def astream_response(self, thread_id: str, user_input: str): # 构造输入 inputs { messages: [(human, user_input)], # 假设图接收这种格式 thread_id: thread_id } # 流式调用远程图 async for event in self.remote_graph.astream(inputs, config{configurable: {thread_id: thread_id}}): # 处理不同类型的事件 if messages in event: for msg in event[messages]: if msg.type ai: yield msg.content # 返回AI回复的文本流 # ... 处理其他事件类型3.3 示例LangGraph智能体 (src/langgraph/agent.py)这个文件展示了如何构建一个能与语音适配器配合的LangGraph智能体。它本身是一个标准的LangGraph图定义。图的结构通常是一个ReActReasoning Acting模式的智能体。图包含以下节点代理Agent节点调用大语言模型如GPT-4根据对话历史和当前查询决定下一步是“思考”还是“使用某个工具”。工具Tools节点定义智能体可以执行的具体操作。在这个待办事项示例中工具包括add_todo,list_todos,complete_todo,delete_todo。这些工具通常会操作某个状态如内存中的列表或数据库。路由逻辑根据模型的决定将执行流导向下一个节点继续思考或执行工具。执行工具后结果会再次送回给代理节点形成循环直到模型认为可以给出最终答案。状态管理LangGraph使用“状态”State对象在节点间传递信息。状态中通常包含messages对话历史和next指示下一步做什么等键。检查点Checkpoint机制会自动保存每次状态变更通过thread_id来索引这就是实现多轮对话记忆的原理。如何与语音适配器集成这个图本身对语音一无所知。它只接收文本输入通过messages状态进行逻辑处理输出文本。langgraph-voice-call-agent项目所做的就是将语音转成的文本输入到这个图再把图输出的文本转成语音。因此你可以用任何LangGraph图来替换这个示例图只要它遵循类似的输入输出接口接收消息列表返回消息或流。注意事项工具执行的确认在语音交互中对于“删除”这类危险操作示例中加入了用户确认环节。这在图形界面中可能是一个弹出框但在纯语音交互中实现起来更复杂。一种做法是让智能体在工具节点中生成一个需要确认的回复如“你确定要删除X吗”然后等待用户的下一条语音输入“是的”或“取消”。这要求你的图能处理这种“中断-继续”的流程可能需要更精细的状态设计。4. 从零开始的完整部署与实操流程4.1 本地开发环境搭建逐步详解假设你从一个全新的Ubuntu 22.04系统或macOS开发机开始。第一步安装基础依赖# 1. 确保系统有Python 3.12或更高版本 python3 --version # 检查版本如果不是3.12需升级 # Ubuntu 安装 Python 3.12 sudo apt update sudo apt install software-properties-common -y sudo add-apt-repository ppa:deadsnakes/ppa -y sudo apt update sudo apt install python3.12 python3.12-venv python3.12-dev -y # 2. 安装 uv一个更快的Python包管理器和安装器 # 使用官方安装脚本 curl -LsSf https://astral.sh/uv/install.sh | sh # 安装完成后重启终端或运行 source ~/.bashrc (或 ~/.zshrc) uv --version # 验证安装 # 3. 安装Docker和Docker Compose # 参考Docker官方文档https://docs.docker.com/engine/install/ # 对于Ubuntu通常如下 sudo apt install docker.io docker-compose-plugin -y sudo systemctl start docker sudo systemctl enable docker # 将当前用户加入docker组避免每次sudo sudo usermod -aG docker $USER # 注销并重新登录使组生效第二步获取项目并初始化git clone https://github.com/ahmad2b/langgraph-voice-call-agent.git cd langgraph-voice-call-agent # 使用uv创建虚拟环境并安装所有依赖 # uv sync 会读取 pyproject.toml 和 uv.lock创建虚拟环境并安装包 uv syncuv sync命令相当于pip install -e .的加强版它会确保你的环境与锁文件完全一致避免依赖冲突。第三步下载必需的模型文件VAD和Turn Detection模型不会自动下载需要手动运行命令获取。# 使用项目提供的Makefile命令 make download-files # 或者直接运行模块 uv run -m src.livekit.agent download-files这个命令会从预定义的位置下载Silero VAD模型和英语Turn Detection模型到本地缓存目录。如果遇到网络问题你可能需要手动寻找模型文件并放置到正确路径具体路径可以在src/livekit/agent.py的下载函数中找到。第四步配置环境变量项目根目录下创建.env文件填入必要的密钥。cp .env.example .env # 如果项目提供了示例文件 # 否则手动创建 .env 文件 nano .env.env文件内容示例# 本地LiveKit服务器配置使用docker-compose启动的 LIVEKIT_URLws://localhost:7880 LIVEKIT_API_KEYdevkey LIVEKIT_API_SECRETsecret # OpenAI API Key (用于LangGraph中的LLM例如GPT-4) OPENAI_API_KEYsk-your-openai-api-key-here # Deepgram API Key (用于STT和TTS注册地址https://deepgram.com/) DEEPGRAM_API_KEYyour-deepgram-api-key-here # LangGraph开发服务器地址默认即可除非你改了端口 LANGGRAPH_URLhttp://localhost:2024第五步启动本地LiveKit服务器项目自带的compose.yml定义了一个用于开发的LiveKit服务。# 在项目根目录下运行 docker compose up -d运行后使用docker compose ps检查状态应看到livekit容器正在运行。你可以访问http://localhost:7880虽然主要是WebSocket端口但HTTP端口也会打开来确认服务是否启动。第六步启动LangGraph开发服务器这是运行你的智能体逻辑的服务器。需要在一个新的终端标签页或窗口中运行。# 确保在当前项目的虚拟环境中 # uv sync 已经激活了环境或者你可以用 uv run uv run langgraph dev默认情况下它会在http://localhost:2024启动一个服务器。这个服务器加载的就是src/langgraph/agent.py中定义的图。控制台会输出类似LangGraph serving fastapi app at http://localhost:2024的信息。第七步启动LiveKit语音Agent最后启动连接LiveKit和LangGraph的核心服务。# 再次打开一个新的终端窗口进入项目目录 # 使用Makefile命令 make dev # 或直接运行 uv run -m src.livekit.agent dev如果一切顺利你会看到日志输出表明Agent正在尝试连接LiveKit服务器加载模型并等待参与者加入。至此后端服务全部就绪。你需要一个前端来测试。4.2 前端连接与测试作者提供了配套的前端项目langgraph-voice-call-agent-web。我们将其克隆并运行。# 在另一个目录克隆前端项目 cd ~/projects # 或其他目录 git clone https://github.com/ahmad2b/langgraph-voice-call-agent-web.git cd langgraph-voice-call-agent-web # 安装依赖并运行 npm install npm run dev前端默认运行在http://localhost:3000。打开浏览器访问该地址。前端配置在连接页面你需要填写LiveKit服务器的连接信息。对于本地开发URL:ws://localhost:7880API Key:devkeyAPI Secret:secret(注意前端通常不直接使用Secret而是由后端生成临时Token。这个前端示例可能简化了直接使用了Secret。生产环境绝对不要这样操作)点击连接加入一个房间可以随机生成房间名。授予浏览器麦克风权限。现在你应该可以对着麦克风说话并听到AI的语音回复了尝试说“Add a todo item: buy milk”然后说“List my todos”。4.3 部署到生产环境LiveKit Cloud本地开发没问题后下一步是部署到更稳定、可扩展的生产环境。这里以LiveKit Cloud为例。第一步获取LiveKit Cloud凭证访问 LiveKit Cloud 注册并登录。创建一个新项目例如my-voice-agent。进入项目设置找到API Keys部分。生成一个新的API Key或者使用默认的。你会得到API Key: 一串字母数字组合API Secret: 一串长字符串务必保密Server URL: 类似wss://your-project.livekit.cloud第二步更新后端环境变量修改你的.env文件或生产环境的环境变量配置# 注释掉或删除本地配置替换为Cloud配置 # LIVEKIT_URLws://localhost:7880 # LIVEKIT_API_KEYdevkey # LIVEKIT_API_SECRETsecret LIVEKIT_URLwss://your-project.livekit.cloud LIVEKIT_API_KEYyour-actual-api-key-from-cloud LIVEKIT_API_SECRETyour-actual-api-secret-from-cloud # OpenAI和Deepgram的Key保持不变 OPENAI_API_KEYsk-... DEEPGRAM_API_KEY...同时你需要注释掉或删除src/livekit/agent.py中关于启动本地LiveKit服务器的代码如果存在因为现在要连接的是云端服务。第三步部署后端服务你需要将你的Python Agent服务部署到一个云服务器或容器平台如AWS EC2, Google Cloud Run, Railway, Fly.io等。部署时需要注意将整个项目代码或构建的Docker镜像部署上去。设置好生产环境的环境变量.env文件或平台提供的Secret管理。确保服务器有公网IP并且能访问wss://your-project.livekit.cloud和https://api.openai.com、https://api.deepgram.com。确保LangGraph开发服务器也在运行可以和后端服务部署在同一台机器但监听不同的内部端口如http://localhost:2024。第四步更新前端连接信息在生产环境中前端不能使用API Secret直接连接。标准做法是你的后端需要提供一个生成临时Token的接口例如/api/token。前端在连接前先调用这个接口获取一个针对特定房间和用户的临时JWT Token。前端使用这个Token而不是API Secret连接到LiveKit Cloud。你需要修改前端代码将连接信息改为URL:wss://your-project.livekit.cloudToken: 从你的后端服务获取的动态Token。第五步测试生产环境部署完成后访问你的生产环境前端进行语音测试。由于LiveKit Cloud拥有全球边缘节点通常延迟会比本地开发更低、更稳定。5. 深度定制与高级配置指南5.1 替换或定制LangGraph智能体这是本项目最强大的地方。你不需要修改langgraph-voice-call-agent的核心代码只需要替换LangGraph服务器上的图定义。步骤创建你的新图在src/langgraph/目录下或任何新位置创建一个新的Python文件例如my_customer_agent.py。使用LangGraph定义你的智能体工作流。它可以集成向量数据库进行RAG检索、调用外部API、拥有复杂的多步骤推理逻辑。# my_customer_agent.py from langgraph.graph import StateGraph, END from langgraph.checkpoint import MemorySaver from langchain_openai import ChatOpenAI # ... 导入其他需要的模块 # 1. 定义状态 from typing import TypedDict, Annotated import operator class State(TypedDict): messages: Annotated[list, operator.add] # 对话历史 knowledge: str # 自定义状态例如从数据库查询的结果 # 2. 定义工具和函数节点 # 3. 定义LLM调用节点 # 4. 构建图 workflow StateGraph(State) # ... 添加节点和边 workflow.add_edge(...) # 5. 编译图并设置检查点存储 memory MemorySaver() # 或使用数据库存储 app workflow.compile(checkpointermemory)修改LangGraph服务器启动默认的uv run langgraph dev会加载src/langgraph/agent.py。你需要修改启动命令或创建一个新的启动脚本。一种简单的方法是创建一个新的入口文件例如serve_my_agent.py# serve_my_agent.py from langgraph.cli import dev import sys sys.path.insert(0, .) from src.langgraph.my_customer_agent import app # 导入你编译好的app if __name__ __main__: dev(app) # 启动开发服务器服务你的app然后使用uv run serve_my_agent.py来启动服务器。更新后端配置确保后端Agent中LANGGRAPH_URL指向你新的LangGraph服务器如果端口不同。例如如果你的新服务运行在8080端口则设置LANGGRAPH_URLhttp://localhost:8080。重启服务重启LangGraph开发服务器和LiveKit Agent服务。现在你的语音Agent就拥有了全新的“大脑”。前端用户与之对话时体验的就是你自定义的智能体逻辑。5.2 更换语音服务提供商项目默认使用Deepgram进行STT和TTS。如果你想换成其他服务商如OpenAI Whisper OpenAI TTS或Azure Speech Services需要修改src/livekit/agent.py中的初始化部分。LiveKit Agents框架提供了多种第一方和第三方的STT/TTS插件。以切换到OpenAI为例安装OpenAI插件uv add livekit-agents-openai修改Agent初始化代码# 原Deepgram配置 # stt DeepgramSTT(api_keydeepgram_key, languageen-US) # tts DeepgramTTS(api_keydeepgram_key, modelaura-asteria-en) # 替换为OpenAI配置 from livekit.agents import stt, tts from livekit.plugins import openai # 确保环境变量 OPENAI_API_KEY 已设置 stt_engine openai.STT() # 使用Whisper模型 tts_engine openai.TTS(modeltts-1, voicealloy) # 选择声音调整参数不同服务商的参数不同。例如OpenAI TTS可能需要设置speed而Deepgram可能需要设置model和voice。你需要查阅相应插件的文档。考虑成本与延迟Deepgram在语音识别方面可能具有成本和延迟优势而OpenAI的TTS声音质量可能更受青睐。根据你的需求进行选择和测试。5.3 优化性能与延迟实时语音对话对延迟极其敏感。以下是一些优化方向1. 使用流式STT和TTS确保你配置的STT和TTS引擎支持流式模式。流式STT可以在用户说话的同时就开始返回中间结果虽然最终准确率可能稍低但能极大减少“等待说话结束”的时间。流式TTS可以合成第一个词就开始播放减少首句延迟。在LiveKit Agents中这通常意味着使用astream而不是aio方法。2. 调整VAD参数VAD的threshold阈值和silence_duration静音时长直接影响响应速度。阈值越低越容易触发语音开始但也更容易误触发背景噪音。静音时长越短越早判定用户说完但可能导致一句话被截断。你需要在实际环境中反复测试找到平衡点。3. 并行处理与流水线理想情况下STT识别、LLM推理、TTS合成这三个耗时环节应该尽可能并行。例如当STT识别出第一个词时就可以开始发送给LLM虽然不完整LLM生成第一个token时就可以开始TTS合成。这需要精心设计数据流和缓存机制。LiveKit Agents的流水线模型为这种并行化提供了基础。4. 选择低延迟的LLM和区域如果使用OpenAI的API选择物理位置离你服务器近的区域如api.openai.comvsapi.openai.azure.com并考虑使用推理速度更快的模型如gpt-4o-mini比gpt-4快。5. 监控与度量在代码中添加关键节点的耗时日志例如“用户停止说话到STT完成”、“LLM首个token到达时间”、“TTS首个音频块生成时间”。这能帮你精准定位延迟瓶颈。6. 常见问题排查与实战经验6.1 连接与启动问题问题运行uv run -m src.livekit.agent dev时报ModuleNotFoundError原因最常见的原因是未正确安装依赖或者不在项目根目录下运行亦或是Python路径问题。解决确保在项目根目录包含pyproject.toml的目录下执行命令。确认已运行uv sync成功安装所有依赖。检查uv.lock文件是否存在。尝试使用绝对路径运行uv run python -m src.livekit.agent dev。如果使用了IDE确保IDE的Python解释器设置为了uv创建的虚拟环境通常位于./.venv。问题Docker Compose启动LiveKit失败端口被占用原因7880, 7881, 7882端口可能被其他程序如之前未正确退出的LiveKit容器占用。解决# 查看占用端口的进程 sudo lsof -i :7880 # 停止相关进程或先停止并移除所有Docker容器 docker compose down # 强制移除可能残留的容器 docker rm -f $(docker ps -aq) # 重新启动 docker compose up -d问题前端连接LiveKit服务器失败提示“无法连接”或“认证失败”原因URL、API Key或Secret错误服务器未运行网络策略阻止如浏览器安全限制、CORS。解决检查服务器状态docker compose ps确认livekit容器是Up状态。访问http://localhost:7880看是否有响应。检查连接信息前端填写的URL必须是ws://非SSL对应本地http://服务。Key和Secret必须是compose.yml中定义的devkey和secret。检查浏览器控制台查看Network标签下WebSocket连接的详细错误信息。CORS问题本地开发时如果前端是http://localhost:3000后端是ws://localhost:7880通常不会有CORS问题。如果遇到可能需要配置LiveKit服务器的CORS策略在生产环境中更常见。6.2 音频处理与对话逻辑问题问题能连接但说话后AI没反应也没有错误日志原因这是最棘手的一类问题可能发生在流水线的任何环节。排查步骤像侦探一样逐层排查检查麦克风前端页面是否显示麦克风图标在跳动浏览器的麦克风权限是否已授予可以尝试在浏览器其他网站如Google Meet测试页测试麦克风。检查VAD在src/livekit/agent.py中增加VAD事件的日志。看看当用户说话时是否触发了on_voice_activity_start和on_voice_activity_end事件。如果没有可能是VAD阈值设置太高或者音频数据没有正确送到VAD处理器。检查STT在STT的回调函数如on_speech_recognized中打印识别出的文本。如果这里没有日志说明VAD到STT的环节断了。检查STT引擎初始化是否正确API Key是否有效。检查LangGraph连接在LangGraph适配器中打印发送给LangGraph服务器的请求和接收到的响应。确认thread_id是否正确传递。检查LangGraph服务器是否在运行端口是否正确。检查TTS和音频发布在TTS合成后和发布音频前添加日志。确认TTS引擎是否被调用是否生成了音频数据。检查发布音频轨道的代码是否执行。问题AI能回复但回复延迟非常高超过3秒原因延迟可能来自STT、LLM或TTS。排查与优化分段计时在代码关键位置VAD结束、STT开始、STT结束、LLM请求开始、LLM首个token到达、TTS开始、TTS结束添加时间戳并计算差值。STT延迟尝试使用更快的模型如Deepgram的nova-2模型或启用流式识别。LLM延迟这是最常见的瓶颈。考虑使用更小、更快的模型如gpt-3.5-turbo或gpt-4o-mini。检查网络到OpenAI服务器的延迟。如果使用Azure OpenAI确保区域选择正确。TTS延迟同样尝试更快的TTS模型或启用流式合成。问题对话没有上下文AI每次都忘记之前说过的话原因thread_id没有正确传递或持久化。解决检查前端确保前端在加入房间时在participant.metadata中设置了一个唯一且稳定的thread_id。例如可以使用用户ID或会话ID。检查后端在on_speech_recognized回调中打印提取出的thread_id确认其值与前端设置的一致。检查LangGraph检查点确认LangGraph图的编译是否设置了checkpointer如MemorySaver或SqliteSaver。MemorySaver在内存中重启服务会丢失生产环境应使用数据库后端。确保configurable参数中包含了thread_id。6.3 生产环境部署问题问题部署到云服务器后Agent无法连接到LiveKit Cloud原因云服务器的出站网络策略可能阻止了WebSocket连接环境变量未正确设置服务器时间不同步导致JWT Token失效。解决测试网络连通性在云服务器上运行curl -I https://your-project.livekit.cloud看是否能收到响应。尝试使用wscat等工具测试WebSocket连接。检查防火墙/安全组确保云服务器的安全组规则允许出站连接到LiveKit Cloud的端口通常是443。验证环境变量通过print(os.environ.get(LIVEKIT_URL))等方式确认生产环境的环境变量已正确加载。检查时间同步运行date命令确保服务器时间与网络时间基本同步。时间偏差过大会导致JWT Token验证失败。问题服务运行一段时间后内存持续增长最终崩溃原因可能存在内存泄漏。常见于音频数据缓冲区未及时清理、LangGraph检查点内存无限增长、或异步任务未正确结束。排查监控内存使用htop或ps aux观察进程内存使用情况。检查音频轨道管理确保在参与者离开房间时正确清理了为其创建的所有处理器、音频源和轨道。检查LangGraph内存检查点如果使用MemorySaver每个thread_id的对话历史都会保存在内存中。对话越多内存占用越大。生产环境必须使用持久化检查点如SqliteSaver或RedisSaver并考虑设置过期策略。分析代码检查所有asyncio.create_task创建的任务确保它们有适当的结束条件或者使用asyncio.TaskGroup进行管理。问题如何实现多房间/多用户并发架构当前的Agent服务是一个单进程服务通过LiveKit服务器与多个前端用户连接。LiveKit服务器会处理多用户的媒体流分发。扩展性单个Agent进程的能力有上限CPU、内存、LLM API速率限制。为了支持更高并发你可以水平扩展运行多个相同的Agent服务实例它们都连接到同一个LiveKit Cloud项目。LiveKit Cloud会自动将用户负载分配到不同的Agent实例上。你需要一个负载均衡器来分配Agent实例的启动和管理Kubernetes或容器编排平台可以做到。优化单个实例使用异步I/O充分利用CPU优化LLM调用如批处理请求如果支持使用更高效的模型。关键点由于对话状态thread_id存储在检查点中你需要确保同一个用户的多次请求都能路由到同一个Agent实例或者使用共享的外部存储如Redis来保存检查点状态使所有Agent实例都能访问。LangGraph的RedisSaver正是为此场景设计的。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价