
1. Realtime 客户端照搬时speech-to-speech 的 LLM 地址才是唯一要动的地方如果你手上有一份为 OpenAI Realtime 写的语音客户端现在又想把后端换成开源 speech-to-speech第一件事不是重写 WebSocket 和 WebRTC而是到 TaoToken 官网 拿一个 API Key再把 LLM 插槽的 base_url 改成https://taotoken.net/api。很多开发者迁移时容易把两条链路混在一起一条是 Realtime 客户端到 speech-to-speech 本地服务另一条是 speech-to-speech 内部 LLM 到模型供应商。前者决定你的客户端怎么发音频、怎么收事件、怎么处理 barge-in后者决定“会想”这一层到底调用谁家的模型。TaoToken 在这里只承担第二件事所以客户端代码不需要推翻重写真正需要改的是流水线里的 LLM handler。这也是 speech-to-speech 这个开源项目比较讨巧的地方它对外实现 OpenAI Realtime 协议客户端原来怎么连现在就怎么连对内把 VAD、STT、LLM、TTS 拆成可替换模块LLM 插槽接受 OpenAI 兼容接口。于是迁移路径可以非常短下载项目、装依赖、拿到 TaoToken Key、设置 base_url、启动本地 Realtime 服务、把原有客户端指过去。本文按“迁移 Realtime 客户端”的视角把改地址片段、运行日志、常见报错和同机编码工具配置串起来。你不需要先成为语音流水线专家只要先把 LLM 地址换对剩下的音频链路可以沿用 speech-to-speech 默认配置逐步验证。2. 先定位TaoToken 在 speech-to-speech 四层流水线的哪一层speech-to-speech 的核心可以理解为四层VAD判断你有没有开始说话、有没有停下来。STT把音频转成文本常见选择有本地 Parakeet、Whisper、Paraformer 等。LLM根据对话历史生成回复文本这是 TaoToken 要接的位置。TTS把回复文本合成语音常见选择有 Qwen3-TTS、ChatTTS 等。这四层各自独立运行通过队列连接因此任何一层出问题都可以单独排查。迁移 Realtime 客户端时最怕的是一上来就怀疑 WebSocket 协议不兼容。其实更常见的情况是Realtime 连接已经建立STT 也正常出字但 LLM 请求 401、404 或模型名不存在导致 TTS 一直没有输入最后表现为“客户端连上了但 AI 不说话”。所以正确顺序是先确认 speech-to-speech 本地服务能启动再确认 Realtime 客户端能连上本地服务然后单独验证 LLM 插槽能通过 TaoToken 返回文本最后再听 TTS 是否正常出声、barge-in 是否生效。TaoToken 的 Key 和控制台入口都在官网注册、创建 Key、查看模型这些步骤不要散落在各种旧教程里统一从 TaoToken 官网 进入即可。创建好 Key 后把它放进环境变量不要在代码里硬编码。3. 可复制的改地址片段环境变量、SDK 与启动参数speech-to-speech 的不同版本可能通过环境变量、CLI 参数或自定义 handler 读取 LLM 配置。最稳的做法是先把 OpenAI 兼容所需的三件事准备好API Key、Base URL、模型名。先设置环境变量export TAOTOKEN_API_KEYYOUR_API_KEY export OPENAI_API_KEY$TAOTOKEN_API_KEY export OPENAI_BASE_URLhttps://taotoken.net/api export LLM_MODELgpt-4o-mini注意Base URL 就写https://taotoken.net/api不要再手动拼/v1。很多 OpenAI SDK 会自动追加路径手动多写一层反而容易 404。如果你的 speech-to-speech 版本支持通过 CLI 指定 LLM 地址可以按类似方式启动python -m speech_to_speech \ --language auto \ --llm_model_name $LLM_MODEL \ --llm_base_url https://taotoken.net/api \ --llm_api_key YOUR_API_KEY不同版本的参数名可能不同先用--help确认。只要看到base_url或api_base这类字段就把它指向 TaoToken 的 API 地址。如果项目默认使用 OpenAI SDK也可以直接写一个最小验证脚本先确认 LLM 插槽能通import os from openai import OpenAI client OpenAI( api_keyos.environ[TAOTOKEN_API_KEY], base_urlhttps://taotoken.net/api, ) stream client.chat.completions.create( modelos.getenv(LLM_MODEL, gpt-4o-mini), messages[ {role: system, content: 你是一个语音助手回复尽量短。}, {role: user, content: 用一句话确认 TaoToken LLM 已连通。}, ], streamTrue, ) for chunk in stream: delta chunk.choices[0].delta.content or print(delta, end, flushTrue)这个脚本的意义是在接入 Realtime 客户端之前先把“思考层”单独跑通。只要这里能流式输出说明 Key、Base URL、模型名三件事至少没有硬伤。然后再回到 speech-to-speech 主流程。Realtime 客户端那边通常不用改ws://127.0.0.1:speech-to-speech-realtime-port/v1/realtime端口以你本地实际启动日志为准。客户端发送的音频事件、会话更新事件、打断事件都保持原样。也就是说你原来为 OpenAI Realtime 写的客户端逻辑继续用只是它连到本地 speech-to-speech 服务而本地服务再去调 TaoToken 的 LLM。4. 运行日志一次成功的 Realtime 语音回合长什么样配置改完后不要只看“进程没退出”。最好按一次完整对话来读日志。下面是一类正常的迁移后日志形态字段名以你实际版本为准[config] vadsilero sttparakeet llmopenai-compatible ttsqwen3 [llm] base_urlhttps://taotoken.net/api modelgpt-4o-mini [server] realtime listening on ws://127.0.0.1:8765/v1/realtime [stt] partial: 今天适合出门吗 [stt] final: 今天适合出门吗 [llm] POST https://taotoken.net/api/chat/completions [llm] request_idchatcmpl_xxx first_token386ms [tts] first_audio_chunk142ms [server] assistant_audio_start [vad] barge_in detected [server] assistant_audio_stop你需要重点看四个位置第一base_url是否显示为https://taotoken.net/api。如果日志里仍然是默认的 OpenAI 地址说明环境变量或启动参数没有生效。第二first_token是否出现。如果 STT 已经出 final 文本但 LLM 一直没有 first token优先查 Key、模型名、网络出口和 401/404 错误。第三first_audio_chunk是否出现。如果 LLM 有文本输出但 TTS 没有音频块问题就不在 TaoToken而在 TTS 后端或音频设备。第四barge_in是否被识别。如果你说话时 AI 没有停下检查 VAD 阈值、输入设备采样率以及客户端是否还在持续推送麦克风音频。如果只想快速验收可以对着麦克风说一句短问题例如“用一句话介绍你自己”。正常日志应该按 STT final、LLM first token、TTS first audio chunk 的顺序推进。任何一步断掉都先修那一段不要同时改四层。5. 迁移 Realtime 客户端时最容易踩的 6 个排障点排障点一401 或 invalid api key。先确认YOUR_API_KEY已经替换而不是原样保留。再确认没有把 Key 多套一层BearerOpenAI SDK 通常会自动加。如果仍然 401去 TaoToken 官网 的 API Keys 页面重新创建一个 Key并确认复制时没有夹带空格。排障点二404 或 path not found。最常见原因是 Base URL 写成了https://taotoken.net/api/v1或者代码里又拼了一次/v1/chat/completions。按照本文配置base_url 只写https://taotoken.net/api。排障点三模型名不存在。LLM 插槽即使能请求也不代表模型名一定可用。模型名要以控制台或模型列表为准。先用最小脚本验证再把同一个模型名填进 speech-to-speech。排障点四Realtime 客户端连不上。这时不要先怀疑 TaoToken。Realtime 连接发生在客户端和本地 speech-to-speech 服务之间。检查本地服务是否启动、端口是否被占用、WebSocket 路径是否正确。TaoToken 只影响 LLM 请求不影响 Realtime 握手。排障点五有文字没声音。如果日志里 LLM 已经返回文本但没有音频块问题通常在 TTS 设备或 TTS 后端。检查扬声器、采样率、是否选择了本地 TTS 模型。不要因为没声音就去改 Base URL。排障点六不能打断。barge-in 依赖 VAD 和客户端持续上传音频。如果客户端在 AI 说话时暂停了麦克风采集VAD 就收不到你的插话。检查客户端是否保持音频流以及服务端是否开启打断逻辑。把这六个点按链路顺序排查能省掉大量“看起来像协议不兼容”的误判。6. 同机顺手配Claude Code、Codex、CC Switch 的 TaoToken 接入语音链路跑通后很多开发者会在同一台机器上继续用编码工具。这里也可以统一到 TaoToken但要注意不同工具的配置格式不同不要把环境变量套错。Claude Code 使用settings.json和ANTHROPIC_*变量。可以在用户级或项目级配置{ env: { ANTHROPIC_BASE_URL: https://taotoken.net/api, ANTHROPIC_API_KEY: YOUR_API_KEY, ANTHROPIC_MODEL: claude-sonnet-4-5 } }Codex 使用config.toml不要混用ANTHROPIC_*model gpt-5 model_provider taotoken [model_providers.taotoken] name TaoToken base_url https://taotoken.net/api env_key TAOTOKEN_API_KEY wire_api chat然后设置export TAOTOKEN_API_KEYYOUR_API_KEYCC Switch 如果用于切换 Claude Code 供应商可以按“三件套”理解名称、Base URL、API Key。一个最小配置形态类似{ name: TaoToken, baseUrl: https://taotoken.net/api, apiKey: YOUR_API_KEY }字段名以你使用的 CC Switch 版本为准但核心信息就是这三项。不要给 Codex 配ANTHROPIC_BASE_URL也不要把 Claude Code 的ANTHROPIC_*直接复制到 Codex 的config.toml里。统一配置的好处是语音项目、终端编码、Claude Code 都走同一套 Key 管理后续排查 401 或额度问题时不会到处翻配置文件。注意 Key 只放本地环境变量或本地配置文件不要提交到公开仓库。7. 从本地跑通到团队可用延迟、Key 管理与模型选择当本地日志能完整跑出 STT、LLM、TTS 三段后下一步才是优化和团队化。延迟方面先测 LLM 首 token。语音对话的体感很大程度取决于“STT final 到 LLM first token”这段。如果这段很长可以换更轻的模型或者减少 system prompt 长度。TTS 首包延迟也要看但它和 TaoToken 无关更多取决于本地 TTS 模型和硬件。Key 管理方面不要多人共用一把 Key。开发机、测试机、生产演示机分开创建方便定位问题也方便轮换。YOUR_API_KEY永远只是占位符真实 Key 不写进博客、不写进截图、不写进 Git。模型选择方面语音助手不需要每次都用最重的模型。短回复、低延迟、稳定流式输出比“写得长”更重要。先用小模型跑通链路再根据场景替换。speech-to-speech 的模块化设计允许你只换 LLM 这一层其他 VAD、STT、TTS 不动。如果团队要做生产验证建议加三项检查每次启动打印 LLM base_url每次请求记录 request_id每次失败区分 401、404、超时和模型不可用。这样出问题时一眼能看出是 TaoToken 配置问题还是本地音频链路问题。8. 下一步行动模型对话 → Coding Plan → 创建 Key → Claude Code 文档如果你已经有一份 OpenAI Realtime 客户端迁移动作可以压缩成一句话客户端照搬speech-to-speech 本地服务照常启动只把 LLM 插槽的 base_url 改成https://taotoken.net/apiKey 用YOUR_API_KEY替换。建议按下面顺序完成落地先到模型对话页体验接口效果https://taotoken.net/models/detail/chat?utm_sourcetaotoken_aicg_blog_endutm_contentcsdn_ugc_voice_chat如果你同时需要编码场景查看 Coding Planhttps://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcsdn_ugc_voice_plan创建自己的 API Key并替换配置里的YOUR_API_KEYhttps://taotoken.net/console/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentcsdn_ugc_voice_keys需要把 Claude Code 一起接上时参考 Claude Code 文档https://taotoken.net/doc/ClaudeCodeAnthropic?utm_sourcetaotoken_aicg_blog_endutm_contentcsdn_ugc_voice_claudecode改完地址后用最小脚本确认 LLM 能流式返回再启动 speech-to-speech最后用原 Realtime 客户端发一次“你好”。当日志里依次出现 STT final、LLM first token、TTS first audio chunk并且你插话时能看到 barge-in说明这次迁移已经完成。