不写一句语音识别代码,用 litellm 跑通实时语音对话

📅 发布时间:2026/8/19 17:35:45
不写一句语音识别代码,用 litellm 跑通实时语音对话
不写一句语音识别代码用 litellm 跑通实时语音对话【免费下载链接】litellmThe fastest, litest AI Gateway. Rust core with Python SDK. Call 100 LLM APIs in OpenAI (or native) format with cost tracking, guardrails, load balancing, and logging [Bedrock, Azure, OpenAI, Anthropic, OpenAI, VertexAI, vLLM, Nvidia NIM]项目地址: https://gitcode.com/GitHub_Trending/li/litellm深夜两点改完第三版接口文档我实在不想再敲一个字对着麦克风嘟囔了一句把这部分改成被动语态两秒后草稿躺进了编辑器。这套说人话、电脑干活的语音交互底层只靠一个开源网关 litellm 串起来——全程没写一行语音识别代码。今天把这条链路怎么搭、怎么调、怎么踩坑原原本本讲给你听。先搞清楚三件事litellm 是什么语音链路分几步litellm 的一句话定义一个用 OpenAI 格式统一调用 100 多家 LLM 的网关。你写的代码永远只认 OpenAI 的请求体至于背后是 Bedrock、OpenAI 还是 xAI全由网关在配置里悄悄转译。语音交互链路拆开就三段听语音转写麦克风的 PCM 音频流 → 文本OpenAI 系叫 realtime transcriptionBedrock 系叫 Nova Sonic想LLM 处理文本进模型产出回复文本说语音合成回复文本 → 音频帧推回你的扬声器。大部分教程会让你分别接 ASR、LLM、TTS 三个服务再自己拼数据流。litellm 的玩法不同它把听想说的全过程收敛成一个 WebSocket 端点/v1/realtime你在一条连接里送音频、收音频中间发生了什么网关替你扛了。先别急着碰那一堆 session 参数我们把最小路径跑通再说。让第一帧音频流进 litellm最小可运行配置环境只需要三样Python 3.9、一个能出声的麦克风、三个依赖。pip install litellm pyaudio websockets从仓库拉代码示例都躺在 cookbook 目录里git clone https://gitcode.com/GitHub_Trending/li/litellm cd litellm接着写一个代理配置把 Bedrock 的 Nova Sonic 注册成网关里的虚拟模型# proxy_server_config.yaml model_list: - model_name: bedrock-sonic # 对外只认这个名字 litellm_params: model: bedrock/us.amazon.nova-sonic-v1:0 # 真实模型由网关转译 aws_region_name: us-east-1导出 AWS 凭据后启动网关export AWS_ACCESS_KEY_IDxxx AWS_SECRET_ACCESS_KEYxxx litellm --config proxy_server_config.yaml --port 4000另开一个终端直接跑仓库自带的实时客户端 cookbook/nova_sonic_realtime.pypython cookbook/nova_sonic_realtime.py对着麦克风说一句你好不出意外的话你会看到终端里冒出一行回复文本耳机里同步响起 AI 的声音。到这一步链路已经通了。图litellm 代理把一次语音交互的耗时、token、成本完整记录下来方便你逐环排查从能跑到好用初版方案 vs 改进方案 ⚡第一版能通但体验一言难尽声音断断续续、回复要等半天、偶尔还听岔。逐一对比改动前后你会发现差别全藏在细节里。改动一音频采样率对齐模型口味。初版直接用声卡默认采样率推流Nova Sonic 压根不买账。对照源码里的注释——输入要 16kHz、输出给 24kHz——立刻改成INPUT_SAMPLE_RATE 16000 # 模型只认这个输入采样率 OUTPUT_SAMPLE_RATE 24000 # 播放端按这个采样率开流改动二VAD 参数别用默认值。说话断句全靠服务端的语音活动检测默认阈值会把稍长的停顿误判成你说完了。于是把静音判定收紧turn_detection: { type: server_vad, threshold: 0.5, # 超过这个音量才算开口 prefix_padding_ms: 300, # 开口前保留一点缓冲 silence_duration_ms: 500 # 静音多久视为一句话结束 }改动三换模型不动代码。这是 litellm 最值钱的地方。想从 Bedrock 切到 xAI 的 Grok 语音模型只要在配置里多加一个虚拟模型model_list: - model_name: grok-voice-agent litellm_params: model: xai/grok-2-vision-1212 api_key: os.environ/XAI_API_KEY model_info: mode: realtime然后把连接 URL 里的modelbedrock-sonic改成modelgrok-voice-agent客户端一行不改网关负责把 OpenAI 风格的会话协议翻译成各家的方言。一次完整对话数据到底怎么流转 ️把上面的片段拼起来一次对话是这样的session.update先发过去告诉网关我这边是什么格式、你要怎么断句麦克风每 1024 帧一小块编码成 base64 塞进input_audio_buffer.append源源不断往 WebSocket 里推服务端 VAD 检测到静音够了自动触发处理等价于你手动发input_audio_buffer.commit模型开始回复文本走response.text.delta在终端实时打印音频走response.audio.delta解码后写进输出流播放。elif event_type response.audio.delta: audio_bytes base64.b64decode(data.get(delta, )) await self.audio_queue.put(audio_bytes) # 丢进队列播放线程取走三路任务各干各的接收消息、抓麦克风、放扬声器靠一个异步队列解耦。谁慢了都不至于互相卡死——这正是实时语音应用该有的姿势。三个真实踩过的坑问题、原因、解法坑一对方说话像含了口水音频质量稀碎。原因环境噪声没处理VAD 阈值 0.5 太低把键盘声当成了人声。 解法戴耳麦、离麦克风近一点把threshold调到 0.6~0.7再不行就加大CHUNK_SIZE到 2048让每帧携带的信息更完整。坑二一问一答要等两三秒实时感全无。原因链路里有两处隐性等待——模型首字延迟和音频缓冲过大。 解法看 litellm 后台日志里的 latency 指标定位瓶颈把silence_duration_ms从 500 降到 300让模型更早开始生成换首字更快的模型在音质和速度之间找平衡。坑三说着说着连接断了日志甩你一个 ConnectionClosed。原因WebSocket 长连接容易被网络波动打断且默认收包上限太小音频一多就爆。 解法建连时显式调大上限并给异常路径兜底self.ws await websockets.connect( self.url, additional_headersheaders, max_size10 * 1024 * 1024, # 默认 1MB 太小放大到 10MB )断线别慌脚本的异常分支会打印原因CtrlC干净退出重连即可。下一步从 demo 走向你自己的语音助手litellm 的价值不在于多了一个语音 SDK而在于它把语音交互里最脏的活——各家协议的转译、会话管理、成本核算——统一收敛了。你写的语音逻辑可以多年不换背后的模型想换就换。接下来按这个顺序动手把 cookbook/livekit_agent_sdk/main.py 跑一遍体验打字对话 → 语音回复的另一种链路形态改voice字段和instructions给你的助手立一个固定人设挂上观测面板盯着每次对话的 token 和成本再做延迟优化。把第一行音频送进 WebSocket 的那一刻你离只说不动手的编程体验就只差一个麦克风了。【免费下载链接】litellmThe fastest, litest AI Gateway. Rust core with Python SDK. Call 100 LLM APIs in OpenAI (or native) format with cost tracking, guardrails, load balancing, and logging [Bedrock, Azure, OpenAI, Anthropic, OpenAI, VertexAI, vLLM, Nvidia NIM]项目地址: https://gitcode.com/GitHub_Trending/li/litellm创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考