Skip to main content

VOICE_MODE — 语音输入

Feature Flag: FEATURE_VOICE_MODE=1 实现状态:完整可用(双后端:Anthropic OAuth / 豆包 ASR) 引用数:46

一、功能概述

VOICE_MODE 实现”按键说话”(Push-to-Talk)语音输入。用户按住空格键录音,音频流式传输到 STT 后端,实时转录显示在终端中。支持两个后端:
  • Anthropic STT(默认):通过 WebSocket 流式传输到 Nova 3 端点,需要 Anthropic OAuth
  • 豆包 ASR(Doubao):通过 doubaoime-asr 包的 AsyncGenerator 协议流式识别,使用独立凭证文件,无需 Anthropic OAuth

核心特性

  • Push-to-Talk:长按空格键录音,释放后自动发送
  • 流式转录:录音过程中实时显示中间转录结果
  • 无缝集成:转录文本直接作为用户消息提交到对话
  • 双后端切换:通过 /voice 命令参数选择 STT 后端,持久化到 settings.json

二、用户交互

UI 反馈

  • 录音指示器:录音时显示红色/脉冲动画
  • 中间转录:录音过程中显示 STT 实时识别文本
  • 最终转录:完成后替换中间结果

三、实现架构

3.1 门控逻辑

文件:src/voice/voiceModeEnabled.ts 两层检查函数:
  1. Feature Flagfeature('VOICE_MODE') — 编译时/运行时开关
  2. GrowthBook Kill-Switch!getFeatureValue_CACHED_MAY_BE_STALE('tengu_amber_quartz_disabled', false) — 紧急关闭开关(默认 false = 未禁用)
  3. Auth 检查(仅 Anthropic)hasVoiceAuth() — 需要 Anthropic OAuth token(非 API key)
  4. Provider 检查voiceProvider 设置决定使用哪个后端,豆包后端跳过 OAuth 检查

3.2 核心模块

3.3 数据流

Anthropic 后端

豆包 ASR 后端

3.4 音频录制

支持两种音频后端(两个 STT 后端共享):
  • macOS 原生音频:优先使用,低延迟
  • SoX(Sound eXchange):回退方案,跨平台

3.5 豆包 ASR 适配器设计

文件:src/services/doubaoSTT.ts 豆包后端使用适配器模式,将 doubaoime-asr 的 AsyncGenerator 协议桥接到 VoiceStreamConnection 接口: AudioChunkQueue — push 式异步队列:
  • 实现 AsyncIterable<Uint8Array> 接口
  • push(chunk) 将音频数据入队,push(null) 发送结束信号
  • 内部维护等待者(waiting)和缓冲队列(chunks)两个状态
connectDoubaoStream() — 连接入口:
  • 动态导入 doubaoime-asr(optionalDependencies)
  • ~/.claude/tts/doubao/credentials.json 加载凭证
  • 创建 AudioChunkQueue 和 VoiceStreamConnection
  • 立即触发 onReady(避免与 useVoice 的音频缓冲死锁)
  • finalize() 立即返回(豆包在录音过程中已返回结果)
  • 后台 async IIFE 消费 transcribeRealtime generator,映射响应类型到回调
响应类型映射

3.6 后端选择逻辑

文件:src/hooks/useVoice.ts
豆包后端的特殊处理:
  • 跳过 getVoiceKeyterms() 调用(豆包无需关键词提示)
  • 跳过 Focus Mode(if (!enabled || !focusMode || isDoubaoProvider())

四、关键设计决策

  1. 双后端共存:豆包后端作为独立适配器与 Anthropic 后端并存,不替换原有流程,通过 voiceProvider 设置切换
  2. 设置持久化voiceProvider 存储在 settings.json,通过 /voice 命令修改,跨会话生效
  3. OAuth 独占(Anthropic):Anthropic 后端使用 voice_stream 端点(claude.ai),仅 OAuth 用户可用
  4. 豆包无需 OAuth:豆包后端使用独立凭证文件,不依赖 Anthropic 认证,通过 isVoiceAvailable() 放宽门控
  5. GrowthBook 负向门控tengu_amber_quartz_disabled 默认 false,新安装自动可用
  6. onReady 立即触发:豆包后端在连接建立后立即触发 onReady,避免与 useVoice 音频缓冲的时序死锁(Anthropic 需要等待 WebSocket 握手)
  7. finalize() 立即返回:豆包在录音过程中已返回所有结果,用户抬手时无需等待处理
  8. 乐观可用性检查isDoubaoAvailableSync() 在首次调用时返回 true,实际导入错误在 connectDoubaoStream 中处理
  9. optionalDependenciesdoubaoime-asr 作为可选依赖,安装失败不影响 Anthropic 后端

五、使用方式

豆包凭证配置

凭证文件路径:~/.claude/tts/doubao/credentials.json

六、外部依赖

七、文件索引