Skip to main content
Glama

OpenCode 语音控制(离线 ASR)

ci license platform python

按住 F8 或鼠标侧键说话 → 松开 → SenseVoice 本地转写 → 文本自动作为用户消息投递到当前 OpenCode 会话。

  • ASR:sherpa-onnx + SenseVoice-small (int8),纯 CPU,中文/中英混说,本机实测 11s 音频转写 0.28s

  • 交互:全局热键 / 鼠标侧键按住说话(push-to-talk),无需唤醒词

  • 投递:OpenCode HTTP API(Basic auth,自动从 opencode service status 发现端口)

  • 打断:说“停止 / 取消”等词直接中断当前 agent 回合,不投递文本

  • 纠错:config.toml 里的 [terms] 把常见误识别替换成代码写法(如“use state”→useState)

  • MCP:voice 服务器提供 status / listen / interrupt,listen 让 agent 等待用户口头确认(该次语音不会自动提交)

目录

src/voice_asr/
  asr.py            SenseVoice 封装
  audio.py          麦克风采集、静音裁剪、重采样
  corrections.py    术语纠错
  opencode_client.py OpenCode 会话发现与 prompt 投递
  daemon.py         热键/鼠标守护进程 + 本地控制接口 (127.0.0.1:8756)
  mcp_server.py     MCP stdio 服务器(工具层)
  check.py          自检:设备列表 / 模型 / 转写
config.toml         配置
models/sensevoice/  SenseVoice int8 模型 (239MB) + tokens
logs/               运行日志
scripts/            MCP/投递自检、开机自启安装脚本

Related MCP server: genpark-conversational-barge-in-interruption-arbitrator-skill

快速开始(从零克隆)

git clone https://github.com/BioMediChen/opencode-voice.git E:\voice
cd E:\voice

# 1) Python 环境(uv 会自动装 3.12)
uv sync

# 2) 下载 SenseVoice int8 模型(约 239MB,国内可用 hf-mirror)
New-Item -ItemType Directory -Force models\sensevoice | Out-Null
curl.exe -L -o models\sensevoice\model.int8.onnx https://hf-mirror.com/csukuangfj/sherpa-onnx-sense-voice-zh-en-ja-ko-yue-2024-07-17/resolve/main/model.int8.onnx
curl.exe -L -o models\sensevoice\tokens.txt https://hf-mirror.com/csukuangfj/sherpa-onnx-sense-voice-zh-en-ja-ko-yue-2024-07-17/resolve/main/tokens.txt

# 3) 自检
uv run voice-check --record 4
uv run python scripts\selftest_e2e.py

# 4) 启动守护进程
uv run voice-daemon

平台:Windows 10/11(音频提示音、全局热键依赖 Windows)。Linux 下需自行处理 winsound 和音频设备。

实测效果

[recording:mouse:x2] ... release to transcribe
[asr] 1.38s  测试us stay和优 effect.
[terms] ... -> 测试useState和useEffect.
[sent -> ses_e6047cd3...] opencode MCP 语音转文字接入

SenseVoice-small int8 在 Ryzen 7 8840U(8C/16T)上的实测:5.7 秒语音转写 0.14 秒, RTF ≈ 0.03(约为实时的 30 倍),全程离线、无 GPU。

作为命令行工具安装(可选)

不想克隆整个仓库时:

uv tool install git+https://github.com/BioMediChen/opencode-voice

# 配置和模型放在固定目录(模型路径相对 config.toml 所在目录解析)
$env:VOICE_CONFIG="E:\voice\config.toml"
voice-daemon

安装后可用:voice-daemon、voice-mcp、voice-check。 MCP 注册时把 command 换成本机的 voice-mcp 可执行文件即可。

使用

# 自检:列出输入设备,用麦克风录 4 秒并转写
uv run voice-check --record 4

# 转写一个 wav 文件
uv run voice-check --wav whisper.cpp\samples\jfk.wav

# 端到端自检(不消耗模型额度)
uv run python scripts\selftest_e2e.py

# 前台启动守护进程(调试用,能看实时日志)
uv run voice-daemon

# 静默启动(日常使用)
start-voice-silent.cmd

启动后按住 F8 或鼠标侧键说话,松开即发送(开始/结束各有一声提示音)。

# 查看状态
curl.exe http://127.0.0.1:8756/status

# 无麦克风时直接测试投递
curl.exe -X POST http://127.0.0.1:8756/submit -H "Content-Type: application/json" -d "{\"text\":\"你好\"}"

配置要点(config.toml)

项

说明

hotkey.key

键盘触发键,f1..f12 / caps_lock / scroll_lock / 单字符

hotkey.mouse

鼠标触发键,x1(后) / x2(前) / middle,[] 关闭

audio.device

留空用系统默认;填序号或名称片段(如 HECATE)

commands.stop

说完即打断的短语(整句匹配,忽略标点)

terms

误识别 → 目标写法;英文规则按单词边界匹配,不会破坏 useState

opencode.session_mode

auto(跟随活跃/最近会话,支持多项目)/ directory(限定目录)/ pinned(固定 session_id)

opencode.directory

directory 模式下的目标目录

opencode.session_id

pinned 模式下的固定会话

asr.language

auto / zh / en / ja / ko / yue

修改配置后重启守护进程。注意鼠标侧键同时也会被浏览器/资源管理器当作“前进/后退”, 如果觉得干扰,可以把 hotkey.mouse 改成 ["middle"] 或 []。

自检与术语维护

# 端到端自检:守护进程 / 会话创建 / 投递 / 纠错 / 停止分支(不消耗模型额度)
uv run python scripts\selftest_e2e.py

# MCP 服务器工具列表自检
uv run python scripts\selftest_mcp.py

# 扫描日志,找出还没被 [terms] 覆盖的英文词,给出待补建议
uv run python scripts\suggest_terms.py

[terms] 的格式是「正确写法 = [可能被听成的说法]」,以 use 开头的两词名称会自动展开 use/us/u/you/优/优思/优斯 与 state/stay/stat、effect/affect 等音近组合, 所以通常只需写标准说法,例如:

[terms]
"useState" = ["use state"]
"OpenCode" = ["open code", "opencode"]
"E:\\voice" = ["e 盘 voice", "e voice"]

多项目切换

opencode.session_mode = "auto" 时的选择顺序:

  1. 配置了 session_id → 固定投递到该会话

  2. 当前有且仅有一个会话在运行 → 投递到它(语音打断/追加指令就靠这条)

  3. 否则投递到最近更新的会话(跨项目生效,跟着你正在用的会话走)

如果想锁定某个项目,改成 "directory" 并设置 opencode.directory; 想锁定某个会话,改成 "pinned" 并填写 opencode.session_id。

MCP 注册

全局配置 ~/.config/opencode/opencode.json 已注册:

{
  "mcp": {
    "servers": {
      "voice": {
        "type": "local",
        "command": ["E:\\voice\\.venv\\Scripts\\python.exe", "-m", "voice_asr.mcp_server"],
        "cwd": "E:\\voice",
        "environment": { "PYTHONUTF8": "1", "PYTHONIOENCODING": "utf-8" }
      }
    }
  }
}

MCP 服务器在需要时会自动拉起守护进程(VOICE_NO_AUTOSTART=1 可关闭)。

开机自启

已通过 scripts/install-autostart.ps1 在启动文件夹创建 OpenCode Voice.lnk。 重新安装/更换路径时重跑:

powershell -ExecutionPolicy Bypass -File scripts\install-autostart.ps1

许可证

MIT

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    D
    maintenance
    Provides voice transcription control and polling for MCP-compatible agents, enabling start/stop/pause/resume and retrieval of new text via tools.
    8
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables coding agents to hold spoken conversations by exposing speech-to-text and text-to-speech tools over MCP, routing them to a local daemon that drives a Chrome window using on-device speech recognition and Piper synthesis. It supports listening, speaking, and reading files aloud within a Claude Code plugin or an MCP gateway.
    2 npm
    MIT
  • A
    license
    Not graded
    quality
    A
    maintenance
    Exposes a local, hands-free voice room to any MCP client, letting agents read speaker-labelled conversation turns, wait for the next turn, list who is present, and speak aloud through local text-to-speech. Speech recognition, speaker identification and voice output all run on the user's own machine, so agents receive text with speaker names rather than audio.
    Apache 2.0