HAPI 语音助手实战指南:用 ElevenLabs / Gemini Live / Qwen Realtime 语音驱动你的 AI 编程 Agent 【免费下载链接】hapiApp for Codex / Claude Code / Pi / OpenCode / Kimi Code / Grok Build, vibe coding anytime, anywhere项目地址https://gitcode.com/gh_mirrors/hapi6/hapi点击查看免费下载HAPI 为 AI 编程 AgentCodex / Claude Code / Pi / OpenCode / Kimi Code / Grok Build 等内置了一套完整的语音交互能力你可以在 Web 端通过麦克风直接向当前会话中的编码 Agent 下达指令、用是/否语音审批权限请求、并收听任务完成或出错的语音播报。本文以 docs/guide/voice-assistant.md 为骨架结合仓库中 hub服务端、shared共享协议与 web前端的源码实现完整讲解三个语音后端ElevenLabs ConvAI、Gemini Live、Qwen Realtime与两类语音转写Dictation的配置、使用、安全模型与故障排查帮助你在一小时内搭建起可用的语音编程工作流。核心能力一览语音助手Voice Assistant本质上是在你的语音与当前活跃的编码会话之间架起一座双向桥梁无论会话运行的是哪种 Agent它都负责把你的请求转发给 Agent并把结果用自然语言播报出来。它主要解决三类场景开口即编程直接说话提出需求、追问进展、请求改代码例如让 Claude 重构 auth 模块语音审批权限Agent 请求执行命令或访问文件时说允许或拒绝即可完成审批无需触碰键盘进度主动播报任务完成、出错、权限请求到达时助手会主动用语音总结无需你反复追问。从 shared/src/voice.ts 的VOICE_TOOLS定义可以看到助手在任何后端上都固定持有两个客户端工具messageCodingAgent把请求转发给活跃 Agent超时 120 秒与processPermissionRequest处理权限批准/拒绝决策值只能是allow或deny超时 30 秒。这两个工具是语音 → 编码 Agent链路的全部核心。架构总览两条截然不同的音频通路HAPI 的语音连接按后端分为两种架构详见 shared/src/voice.ts 中VoiceBackendType与 hub 路由实现Browser → WebRTC → ElevenLabs ConvAI → Voice Assistant → HAPI Hub → Coding AgentElevenLabs 走 WebRTC音频直接点对点流式传输到 ElevenLabs 的 ConvAI 服务HAPI Hub 只负责向 ElevenLabs 申请短时效的会话令牌本身不转发音频。Browser → WebSocket → HAPI Hub proxy → Gemini Live / Qwen Realtime → Coding AgentGemini Live 与 Qwen Realtime 走 WebSocket浏览器先连接到 Hub 侧的代理/api/voice/gemini-ws、/api/voice/qwen-ws见 hub/src/web/server.ts代理在服务端注入 API Key 与会话配置后再与上游建立连接。这两条通路的共同安全设计是提供商 API Key 永远不进入浏览器。ElevenLabs 场景中浏览器只拿到短时效 conversation tokenGemini/Qwen 场景中 Key 全程留在 Hub 的 WS 代理里hub/src/web/routes/voice.ts 的/voice/gemini-token、/voice/qwen-token返回的是代理地址而非真实 Key。实时转写会话OpenAI / ElevenLabs / Deepgram同样由 Hub 铸造一次性凭据下发给浏览器。前置条件准备提供商凭据使用语音助手至少需要一个助手后端Assistant Backend的 API 凭据ElevenLabs注册 ElevenLabs 账号并创建 API KeyGemini Live从 Google AI Studio 获取 Gemini API KeyQwen Realtime从阿里云百炼Model Studio获取 DashScope API Key。使用 Dictation仅语音转文字则至少需要一个转写提供商见下文转写提供商一节或一个 OpenAI 兼容的本地转写服务。凭据体系环境变量优先Settings 立即可用凭据有两种来源优先级是进程环境变量运维引导首选 Settings 中保存的值。环境变量在进程启动时生效Settings 中保存的凭据则通过 hub/src/config/providerCredentials.ts 的内存覆盖层getProviderEnvironment()立即生效无需重启 Hub——只有修改进程环境变量才需要重启。完整的凭据环境变量清单原文档给出了完整的环境变量集合逐项整理如下# 语音助手后端配置任意一个即可启用语音助手 export ELEVENLABS_API_KEY... # ElevenLabs ConvAI export GEMINI_API_KEY... # Gemini LiveGOOGLE_API_KEY 同样可用 export DASHSCOPE_API_KEY... # Qwen RealtimeQWEN_API_KEY 同样可用 # 可选固定 Hub 的默认助手后端 export VOICE_BACKENDelevenlabs # elevenlabs | gemini-live | qwen-realtime # Dictation 转写提供商按需配置任意组合 export OPENAI_API_KEY... # gpt-transcribe / gpt-live-transcribe export ELEVENLABS_API_KEY... # scribe_v2 / scribe_v2_realtime export DEEPGRAM_API_KEY... # nova-3 标准 / 实时转写 export GROQ_API_KEY... # whisper-large-v3 # 或使用 OpenAI 兼容的本地服务例如 Speaches export TRANSCRIPTION_BASE_URLhttp://127.0.0.1:8000/v1 export TRANSCRIPTION_MODELSystran/faster-whisper-large-v3 export TRANSCRIPTION_API_KEY... # 可选注意两点ELEVENLABS_API_KEY同时承担助手后端与转写提供商两个角色GOOGLE_API_KEY与GEMINI_API_KEY、QWEN_API_KEY与DASHSCOPE_API_KEY是两组别名对源码中按逻辑锁处理——只要其中一个被环境变量设置另一个也无法从 Settings 覆盖或清除。这些模型名并非文档臆造均可在 shared/src/voice.ts 的常量中查到OPENAI_TRANSCRIPTION_MODEL gpt-transcribe、OPENAI_REALTIME_TRANSCRIPTION_MODEL gpt-live-transcribe、ELEVENLABS_TRANSCRIPTION_MODEL scribe_v2、ELEVENLABS_REALTIME_TRANSCRIPTION_MODEL scribe_v2_realtime、DEEPGRAM_TRANSCRIPTION_MODEL nova-3、GROQ_TRANSCRIPTION_MODEL whisper-large-v3。Settings 界面的凭据管理在Web Settings → Voice中可以增删这些凭据保存到 Hub 的 settings 文件界面上一律掩码显示只展示后四位见providerCredentials.ts的maskSecret()。凭据状态接口区分env / settings / none三种来源由环境变量锁定的 Key 在 UI 中不可编辑Settings 保存的 Key 则始终允许修改。API Key永远不会以完整形式返回给浏览器。Web Settings → Voice → Dictation中内置的凭据预设是ElevenLabs、OpenAI、Groq三组已配置的 Deepgram 与 OpenAI 兼容凭据同样可以在该页面继续管理。保存 Key 后提供商列表无需重启 Hub 即时刷新。转写提供商一览OpenAI支持标准gpt-transcribe与实时gpt-live-transcribe两种模式ElevenLabs支持标准scribe_v2与实时scribe_v2_realtimeDeepgram支持标准与实时模型nova-3Groq仅标准模式whisper-large-v3OpenAI 兼容服务仅标准模式需要同时配置TRANSCRIPTION_BASE_URL与TRANSCRIPTION_MODELBrowser on-device仅实时模式。依赖桌面浏览器自带的SpeechRecognition端侧 APIHAPI 会在开始转写时检查所选语言包且不会从该选项回退到浏览器托管识别移动端与未知浏览器环境会直接失败关闭fail closed因为该 API 仍属实验性部分 Android WebView 存在不安全的残缺实现。后端配置实战ElevenLabs在 ElevenLabs 注册/登录在账号设置中进入 API Keys 页面创建新 Key启动 Hub 前设置环境变量export ELEVENLABS_API_KEYyour-api-key hapi hub --relayHub 在首次使用时会在你的 ElevenLabs 账号中自动创建一个名为Hapi Voice Assistant的 Agent对应 shared/src/voice.ts 的VOICE_AGENT_NAME常量与buildVoiceAgentConfig()配置模板当你选择了非默认音色时Hub 会为该音色创建专属 Agent命名规则为Hapi Voice Assistant [voice:id]见 hub/src/web/routes/voice.ts 的getVoiceAgentName()从而保证音色选择始终生效。如果希望使用自己已有的 ElevenLabs Agent 而非自动创建的export ELEVENLABS_AGENT_IDyour-agent-id如果希望把特定音色映射到自己的 Agent覆盖按音色自动创建的默认行为export ELEVENLABS_VOICE_AGENT_MAP{voice-id: agent-id}Agent 的解析优先级从源码/voice/token路由看是请求中的customAgentId→ELEVENLABS_VOICE_AGENT_MAP映射 → 按音色自动创建/查找 →ELEVENLABS_AGENT_ID→ 兜底自动创建默认 Agent。Hub 还会对既有 Agent 执行幂等的platform_settings.overrides对齐ensureAgentOverrides否则客户端 SDK 在发送agent.prompt/tts.*覆盖字段时会因服务端拒绝而崩溃。Gemini Liveexport GEMINI_API_KEYyour-api-key # 或 GOOGLE_API_KEY hapi hub --relayGemini Live 模型在源码中为gemini-2.5-flash-native-audio-latestshared/src/voice.ts 的GEMINI_LIVE_MODEL。由于 Gemini Live API 不支持临时令牌Hub 采用服务端 WS 代理转发音频Key 注入发生在服务端hub/src/web/routes/voice.ts 的/voice/gemini-token返回apiKey: proxied占位值。代理地址基于请求来源推导HAPI_PUBLIC_URL可在反向代理场景下覆盖。Qwen Realtimeexport DASHSCOPE_API_KEYyour-api-key # 或 QWEN_API_KEY hapi hub --relayQwen Realtime 模型为qwen3.5-omni-flash-realtimeQWEN_REALTIME_MODEL默认音色Tina同样走 Hub 侧 WS 代理hub/src/web/qwenProxyHandler.ts。该代理实现了严格的ack-gate机制Hub 先向上游发送自己持有的session.update注入工具、音色、指令与 VAD 参数只有收到 DashScope 的session.updated确认后才放行客户端帧在此之前客户端帧会被排队预算 1 MiB超限以 1009 关闭防止客户端在工具/音色/指令锁定前抢先发送response.create等帧。客户端session.update只被允许修改instructions字段isQwenSafeClientFrame。多后端并存时的默认选择当配置了多个后端时Hub 默认使用ElevenLabs除非设置了VOICE_BACKEND。从源码resolveHubVoiceBackend看若VOICE_BACKEND指定的后端未配置凭据会回退到第一个已配置的后端浏览器用户可在Settings → Voice中按浏览器覆盖后端选择resolveEffectiveVoiceBackend用户偏好 Hub 默认 第一个已配置项。Dictation 模式只用语音转文字如果只需要语音转文字而不需要语音助手在 Web 端打开Settings → Voice选择Dictation再选择一个已配置的转写提供商即可。Dictation 有两种模式标准模式默认点击麦克风开始录音再次点击停止停止后整段音频上传转写转写文本插入 composer永不自动发送实时模式说话过程中实时显示转写草稿停止说话后插入最终结果。标准模式的实现细节可以从 web/src/hooks/useDictation.ts 看到浏览器用MediaRecorder以audio/webm;codecsopus或按支持情况回退 mp4/ogg录制停止后以speech.webm之类的文件 POST 到 Hub 的/voice/transcription标准转写端点Hub 再转发给对应提供商上传上限 25 MiB超时 120 秒。实时模式则通过 web/src/hooks/useRealtimeDictation.ts 实现OpenAI 走 WebRTC、Deepgram 走 WebSocket、ElevenLabs 走官方useScribeSDK均先向 Hub 申请一次性实时转写令牌。原生 iOS 与 Android 应用详见 原生应用指南目前只支持标准 Dictation它们选择 Hub 上第一个支持标准转写的提供商发现成功后显示麦克风录音停止时上传转写文本插入草稿供审查。凭据配置在 Hub 或 Web Settings → Voice 完成。实时转写、语音助手与提供商选择等控制项均为 Web 端功能。使用从点击麦克风到语音命令启动语音会话在 Web 应用中打开一个会话点击 composer 中的麦克风按钮composer 为空时发送按钮会显示麦克风图标按提示授予麦克风权限开始说话。助手连接期间状态栏会出现一个语音状态胶囊voice pill显示 Connecting连接中、Active活跃、Muted静音、Error出错等状态你可以在不结束会话的情况下静音麦克风。语音命令速查表你说的话发生什么Ask Claude to... / Have it...把你的请求发送给编码 AgentRefactor the auth module编码类请求自动转发给 AgentYes / Allow / Go ahead批准待处理的权限请求No / Deny / Cancel拒绝待处理的权限请求直接提问语音助手能答则自己回答这些路由规则在 shared/src/voicePromptLayers.ts 的VOICE_PLATFORM_FIXTURES中写得非常明确与编码、文件、开发、调试相关的请求必须先调用messageCodingAgent工具直接称呼助手Assistant, explain...才由助手自己回答权限请求到来时助手应立刻播报Claude 想运行一条 bash 命令允许吗并等待你的决定。该文件还规定了一系列 TTS 输出规则不逐字符朗读哈希/ID/路径session ending in ZAJ 而非逐个字母拼读、用省略号表示停顿、URL 中的句号读作 dot、缩写逐字母拼读API 读作 A P I。Settings → Voice 设置面板全解用户可配置项都集中在Settings → VoiceVoice mode语音助手双向对话或 Dictation仅语音转文字Voice backendElevenLabs、Gemini Live 或 Qwen Realtime仅当 Hub 配置了多个后端时显示Voice Language自动检测或指定语言助手与 Dictation 共用。源码层面未指定语言时助手会镜像用户的语音语言并全程保持一致buildVoiceLanguageBlock()见 shared/src/voice.ts指定zh时会追加专门的中文口语块shared/src/voicePromptLayers.ts 的VOICE_CHINESE_LANGUAGE_BLOCKVoice选择助手音色。ElevenLabs 列出你账号下的全部音色含克隆音色并提供音频预览Gemini Live 与 Qwen Realtime 提供各自的内置音色目录可通过/voice/voices接口与 shared/src/voicePickerCatalog.ts 查看Opening助手连接时 Greet me 简单问候或 Brief me 播报最近 Agent 活动的语音摘要Response length助手Brief简洁、Balanced均衡、Detailed详细三档回答长度对应 shared/src/voicePersonality.ts 中RESPONSE_LENGTH_OPTIONS与追加到系统提示词中的长度指令。Settings → Voice → Advanced额外提供Persona instructions给助手改名/换品牌形象塑造性格与说话风格预设或自定义文本。源码层面提示词是分层的shared/src/voicePromptLayers.ts 的composeVoiceAgentPrompt()平台固定条款工具契约、上下文管道、路由规则不可编辑 提供商护栏禁止自称 Gemini/Claude/OpenAI 等底层模型名 身份层可重命名 性格层预设文案或自定义身份文本上限 8,000 字符、性格文本上限 16,000 字符How it soundsElevenLabs 的调音滑杆stability、style、speed、similarity boost、speaker boost与 Gemini 的 affective dialog情感化对话选项——对应 shared/src/voicePersonality.ts 的ElevenLabsVoiceSettings与GeminiVoiceOptionsVoice diagnostics检查合成的系统提示词大小与各后端线上限制的差异查看截断警告与上次语音会话的上下文提示并可预览只读的平台规则。提示词总长上限为 48,000 字符VOICE_SYSTEM_PROMPT_MAX_LENGTHGemini 代理通过 base64url 编码的?systemPrompt参数传递解码逻辑见 hub/src/voiceSystemPromptParam.ts。工作原理深挖上下文同步语音助手在以下时机自动收到上下文更新无需你请求你聚焦某个会话时加载完整历史Agent 发送消息或使用工具时权限请求到达时任务完成时。实现上Hub/Web 会通过streamDeferredVoiceContext()与deliverVoiceSessionContextAfterConnect()web/src/lib/voiceContextStream.ts在语音传输通道建立后按固定顺序先流式推送较旧历史、再投递引导上下文bootstrap context。ElevenLabs 侧的动态变量{{initialConversationContext}}也在连接时被填充shared/src/voice.ts 的VOICE_ELEVENLABS_SESSION_CONTEXT_BLOCK按每条消息 65,535 字节的 WebRTC 数据通道限制与 4,000 字节的引导预算分块发送。助手还会在 Agent 工作期间保持安静完成后再主动总结结果。两个核心工具所有后端都使用同一套工具定义shared/src/voice.ts 的VOICE_TOOLSmessageCodingAgent—— 把你的请求转发给活跃 Agent。参数只有一个必填的message字符串要求包含完整请求或指令processPermissionRequest—— 处理权限批准/拒绝。参数decision只能是allow或deny。工具定义会分别转换成各后端的格式ElevenLabs 用client类型工具、Gemini Live 用functionDeclarationsbuildGeminiLiveSetupMessage()、Qwen Realtime 用扁平 Realtime 结构的type: function工具buildQwenSessionUpdateMessage()注意其使用server_vad断句阈值 0.5、静音 800ms、前缀填充 300ms。音频链路与安全ElevenLabs浏览器 → WebRTC → ElevenLabs ConvAI → 助手 → Hub → 编码 AgentHub 仅铸造短时对话令牌Gemini Live / Qwen Realtime浏览器 → WebSocket → Hub 代理 → 上游 → 编码 AgentKey 服务端注入。Hub 是令牌铸造与代理的中心负责全部鉴权提供商 API Key 自始至终不进入浏览器。实用技巧指令要具体清晰完整的请求才能获得好结果等待完成Agent 工作期间助手保持安静结束后再总结用自然语言无需任何特殊命令语法保持会话聚焦同时只开一个活跃会话上下文最清晰。故障排查ElevenLabs API key not configured在环境中设置ELEVENLABS_API_KEY并重启 Hub。Gemini API key not configured在环境中设置GEMINI_API_KEY或GOOGLE_API_KEY并重启 Hub。DashScope API key not configured在环境中设置DASHSCOPE_API_KEY或QWEN_API_KEY并重启 Hub。麦克风权限被拒绝检查浏览器对麦克风的权限设置确保没有其他应用占用麦克风尝试刷新页面。小米/MIUI 设备上麦克风权限失败如果语音在小米/MIUI 设备上无法启动或浏览器无法请求麦克风权限请检查小米钱包等应用的**显示在其他应用上层权限**。悬浮窗、支付/钱包浮层、聊天气泡、录屏工具、翻译工具、护眼工具、游戏助手等都可能干扰浏览器的麦克风权限弹窗。请关闭活动的浮层、重新打开 HAPI 并再次授予麦克风权限。语音无响应确认会话已连接状态栏绿点检查语音状态胶囊显示的是 Connecting... 或活跃状态确保网络连接稳定。Failed to create ElevenLabs agent automatically确认 API Key 有效检查 ElevenLabs 账号配额是否充足尝试设置自定义ELEVENLABS_AGENT_ID。音频质量差使用耳机避免回声减少背景噪声检查网络连接稳定性。深入阅读服务端凭据管理与掩码逻辑hub/src/config/providerCredentials.ts含别名对逻辑锁与 Settings 覆盖层实现语音相关全部 REST/WS 路由hub/src/web/routes/voice.ts、hub/src/web/server.tsQwen 代理与 ack-gate 机制hub/src/web/qwenProxyHandler.ts共享协议与默认配置Agent 模板、工具定义、模型常量shared/src/voice.ts提示词分层与人格系统shared/src/voicePromptLayers.ts、shared/src/voicePersonality.tsWeb 端转写实现web/src/hooks/useDictation.ts、web/src/hooks/useRealtimeDictation.ts、web/src/api/voice.ts赞分享【免费下载链接】hapiApp for Codex / Claude Code / Pi / OpenCode / Kimi Code / Grok Build, vibe coding anytime, anywhere项目地址https://gitcode.com/gh_mirrors/hapi6/hapi点击查看免费下载相关推荐LlamaIndex Gemini Live 语音 Agent 集成实战基于 Google Gemini Live 构建实时语音对话 AgentLlamaIndex Gemini Live 语音 Agent 集成实战基于 Google Gemini Live 构建实时语音对话 Agent 导读 本文围人工智能RAG大模型从零开始打造专属AI语音助手VITS语音合成完整实战指南从零开始打造专属AI语音助手VITS语音合成完整实战指南 VITSConditional Variational Autoencoder with AdveNLP音频深度学习ElevenLabs JS SDK 文本转语音实战指南基于 elevenlabs/elevenlabs-js 的 TTS 编程规范JavaScript/TypeScriptElevenLabs JS SDK 文本转语音实战指南基于 elevenlabs/elevenlabs js 的 TTS 编程规范JavaScript/T上一篇curl 从源码编译与安装全指南autotools/CMake 双路线、TLS 后端选型与跨平台实战下一篇oh-my-pi 后台任务结果交付async-result 注入协议与结构化输出机制详解创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考