voice-for-dsh
September 6, 2026 · View on GitHub
给 DeepSeek Harness Web(dsh web)加"输出朗读"能力的语音插件: 每轮 DeepSeek 输出结束后,先把输出做口语化转写(代码/表格/Markdown 等不适合朗读的内容改写为口语), 再通过 TTS 播报出来。
一句话:让 dsh 开口说话。 开开关 = 每轮结束自动播报;关 = 不自动,但每条助手消息上有"朗读"按钮手动播。
项目定位:这是一个个人项目,围绕作者自己的使用习惯设计,不一定适合所有人。两种"进阶"引擎的定位不同:
- 豆包云 TTS(付费):情感化朗读——方言、多音色、情绪演绎,提供有趣的声音体验;
- 本地英文 TTS(免费):把中文回复先转写成英文口语再朗读——用"听英文"替代"读中文", 换一种信息通道接收同样的内容,长文工作后节省认知资源、缓解困倦(这是本项目的核心动机)。
只想给 dsh 加个"普通朗读"的话,默认的浏览器 TTS 开箱即用、零配置;不认同上述思路也可随时切回。
功能
- 自动播报开关:开 = 每轮结束自动"转写 + 播报";关 = 不自动,保留手动按钮。
- 每消息"朗读"按钮:手动转写并播报该条输出;已完整朗读过的消息旁有 ↻ 重新生成按钮 (跳过转写缓存,用当前配置重新转写 + 合成)。
- 转写(LLM):代码块/表格/URL/Markdown 标记改写为口语文稿,不逐字朗读原文。
- TTS 三引擎:
browser:浏览器speechSynthesis(零配置、免费、离线兜底);volcengine:豆包语音合成 2.0(双向流 WebSocket 默认 + HTTP 单向兜底), 8 种方言、中英文音色、情感演绎指令;网关可配(plan智能体套餐 /standard标准付费 /custom自定义端点,仅端点路径不同,鉴权一致);local:本地 Kokoro-82M v1.0(免费、离线、数据不出本机;英文播报—— 中文回复先转写为英文口语再朗读,部署见docs/local-tts.md)。
- 省钱设计(详见下方"成本与隐私"):
- 同一消息重复朗读 → 转写缓存命中,零新增 LLM 调用;
- 重播同一消息 1h 内 → 豆包服务端缓存命中,免重合成、不重复计费;
- 转写失败自动降级为"原文直读",不中断使用。
截图
对话:每条消息的朗读按钮、已朗读徽标与自动朗读开关
设置页:转写/引擎/语种方言/音色与试听
平台支持
- Windows:✅ 已实测(开发与发布均基于 Windows)。
- macOS / Linux:⚠️ 未实测。Host 半逻辑已在 CI(
ubuntu-latest)上跑通零成本测试; 未验证的是浏览器语音引擎行为(speechSynthesis)与界面交互。欢迎在 Mac/Linux 上试用并反馈 (见docs/ROADMAP.md)。
安装
插件是 dsh 的 bundle(
packages/dsh-plugin-voice),通过dsh plugin --profile web add装进webprofile。以下命令假设你已经装好 dsh(未全局安装时用npx @deepseek-ai/dsh前缀)。
前置要求
- Node.js 22+(双向流播报依赖 Node 22 的全局
WebSocket;仅用浏览器 TTS 时可低至 18+) - dsh(
@deepseek-ai/dsh@0.1.2-rc.1或更高兼容版本) - (可选)火山引擎语音合成 API Key(新版控制台「API 管理」页获取,见 快速入门),用于豆包 TTS;不配则用浏览器语音兜底
从 clone 安装
git clone https://github.com/junarch/voice_for_dsh.git
cd voice_for_dsh
# 1) 安装插件自身依赖
cd packages/dsh-plugin-voice && npm install && cd ../..
# (若提示 peer 依赖 ERESOLVE,改用 npm install --legacy-peer-deps)
# 2) 把插件装进 web profile(<path> 换成仓库绝对路径或相对路径)
npx @deepseek-ai/dsh plugin --profile web add link:packages/dsh-plugin-voice
# 3) 启动 dsh web
npx @deepseek-ai/dsh web
浏览器打开 http://127.0.0.1:3080,在设置页找到"语音播报"即可配置。
提示:
dsh plugin add的相对路径锚定到执行命令时的当前目录;若解析失败,直接给绝对路径 (如link:C:\path\to\voice_for_dsh\packages\dsh-plugin-voice)。
本地英文 TTS(可选,免费)
默认引擎是浏览器 TTS,装完插件就能用。想启用"英文播报"(本地 Kokoro-82M),需额外下载模型 (约 350MB,只存本机、不入 git):
# 在仓库根目录执行(Windows):自动创建虚拟环境 + 下载模型,首次约 350MB、视网络数分钟
pwsh scripts/setup-local-tts.ps1
# 启动本地合成服务(保持窗口开着;首次加载模型需数秒)
local\venv\Scripts\python.exe scripts\local-tts-server.py
然后重启 dsh 并刷新浏览器,设置页 → 语音播报 → 播报引擎选 本地 Kokoro(英文·免费)。
自检:浏览器打开 http://127.0.0.1:8880/health 返回 {"ok":true} 即就绪。
注意:本地引擎固定英文播报(中文回复先转写成英文再朗读),需保持"需要转写模型"开启。
Mac/Linux 不跑此脚本,可用同协议的现成服务替换(见 docs/local-tts.md §4);
换音色、模型文件说明与常见问题也都在该文档。
配置
所有配置在 settings.yaml 的 voice: 命名空间,设置页可可视化编辑。字段说明见
docs/pipeline.md §6。
成本与隐私(请先读)
- 转写:每次"首次朗读"会调用一次你配置的 LLM(settings.yaml 里的 provider),花 token。
- 同一消息重复朗读不花(转写缓存命中);重新生成(↻)会重新转写(花)。
- TTS:浏览器语音免费;本地 Kokoro 免费且内容不出本机(仅转写仍走 LLM); 豆包 TTS 按字符/时长计费,同一消息 1h 内重播 → 服务端缓存命中,不重复计费。
- 隐私:你的对话内容会发送给你配置的第三方服务(转写 LLM、豆包 TTS);
选本地 TTS(
local)时合成完全在本机进行。在涉及敏感内容的会话里请谨慎。 - 默认不开启自动播报;引擎默认免费系统 TTS,全流程不花钱;需要豆包时在设置页切换 (= 显式启用付费的豆包 API,自动播报成本门控随之生效);本地 Kokoro 免费不受门控限制。
开发与测试
# 零成本 mock 集成测试(覆盖转写/缓存/TTS/防重复计费等)
node scripts/test-host.mjs
# 真实外呼探针(花几分钱,验证火山接口行为)
node scripts/tts-cache-probe.mjs
- 测试方法论:
docs/testing.md - 开发手册:
docs/development.md - 发布清单:
docs/release.md
文档
| 文档 | 内容 |
|---|---|
docs/pipeline.md | 转写/TTS 管线行为 + voice: 配置 schema + 不变式 |
docs/local-tts.md | 本地英文 TTS 部署/对接/换音色/故障排查 |
docs/architecture.md | DSH 插件机制与关键决策 |
docs/development.md | 开发循环 / 安装卸载 / 常见坑 |
docs/testing.md | 测试方法(含账单防御) |
docs/release.md | 发布前清单 + 发版流程 |
docs/providers.md | TTS/转写供应商接入规范(含本地 TTS) |
docs/ROADMAP.md | 开发规划:多平台/新供应商/测试/安全收尾 |
贡献与安全
- 贡献指南:
CONTRIBUTING.md - 行为准则:
CODE_OF_CONDUCT.md - 报告安全漏洞:
SECURITY.md(走 GitHub 私有漏洞报告,勿发公开 issue)