news 2026/8/19 17:35:43

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

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
不写一句语音识别代码,用 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 transcription,Bedrock 系叫 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_ID=xxx AWS_SECRET_ACCESS_KEY=xxx litellm --config proxy_server_config.yaml --port 4000

另开一个终端,直接跑仓库自带的实时客户端 cookbook/nova_sonic_realtime.py:

python 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 里的model=bedrock-sonic改成model=grok-voice-agent,客户端一行不改,网关负责把 OpenAI 风格的会话协议翻译成各家的方言。

一次完整对话:数据到底怎么流转 🎙️

把上面的片段拼起来,一次对话是这样的:

  1. session.update先发过去,告诉网关"我这边是什么格式、你要怎么断句";
  2. 麦克风每 1024 帧一小块,编码成 base64 塞进input_audio_buffer.append,源源不断往 WebSocket 里推;
  3. 服务端 VAD 检测到静音够了,自动触发处理(等价于你手动发input_audio_buffer.commit);
  4. 模型开始回复:文本走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_headers=headers, max_size=10 * 1024 * 1024, # 默认 1MB 太小,放大到 10MB )

断线别慌,脚本的异常分支会打印原因,Ctrl+C干净退出,重连即可。

下一步:从 demo 走向你自己的语音助手

litellm 的价值不在于"多了一个语音 SDK",而在于它把语音交互里最脏的活——各家协议的转译、会话管理、成本核算——统一收敛了。你写的语音逻辑可以多年不换,背后的模型想换就换。

接下来按这个顺序动手:

  1. 把 cookbook/livekit_agent_sdk/main.py 跑一遍,体验"打字对话 → 语音回复"的另一种链路形态;
  2. voice字段和instructions,给你的助手立一个固定人设;
  3. 挂上观测面板,盯着每次对话的 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),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/19 17:28:20

一劳永逸的U盘启动盘:Ventoy插件配置从入门到实战

一劳永逸的U盘启动盘:Ventoy插件配置从入门到实战 【免费下载链接】Ventoy A new bootable USB solution. 项目地址: https://gitcode.com/GitHub_Trending/ve/Ventoy 还在为装系统反复折腾U盘?传统启动盘工具往往做一次格式化一次,换…

作者头像 李华
网站建设 2026/8/19 17:20:59

如何为 Noctis 贡献代码:开源 VSCode 主题项目的完整协作指南

如何为 Noctis 贡献代码:开源 VSCode 主题项目的完整协作指南 【免费下载链接】noctis Noctis is a collection of light & dark themes with a well balanced blend of warm and cold colors 项目地址: https://gitcode.com/gh_mirrors/no/noctis 为 No…

作者头像 李华