前言¶
在 DeepSeek Harness(DSH)里盯着流式文字看,眼睛还是要跟字走;如果等整条回复写完再丢给普通 TTS,往往还要多等 2 秒左右才听到第一个音节。常见做法是整段合成 mp3 再用 <audio> 播放,首声被压在「全文生成 + 编码完成」之后。
下面介绍社区插件 dsh-breeze-speak(维护者 rirtue):挂在宿主 llm/stream 钩子上,第一句一凑齐就向 BreezeBlue(Breeze TTS 2)发起合成,走 /stream 拿 PCM 裸流,用 Web Audio 边收边播。资料里实测首包大约 0.55–1.3 秒,相对「等整段 mp3」的 2.1–2.8 秒,首声能落在模型还在吐后面文字的时间段里,体感上约 0.6 秒出声。默认只念回复开头第一句,也是为了控制 Breeze 积分消耗。
这是什么¶
dsh-breeze-speak 是一个 DSH 插件(npm 包名 dsh-breeze-speak,当前资料中的版本 v1.0.1,MIT 许可证)。分类上落在 SkillHub 的「模型推理」条目;GitHub 星标为 1。它解决的问题很具体:把每轮模型回复用指定音色念出来,且尽量不让「等 TTS」拖慢你听到第一句话的节奏。
插件按 DSH 惯例拆成宿主半边(index.js)和网页半边(client.js),并通过 cordis.patch.yml 以 id: breeze-speak 写入 profile 配置树。
核心功能¶
流式触发,不等整段回复¶
- 挂住宿主
llm/stream洋葱中间件,随模型增量累积文本。 - 每当有新的 text delta,就检查是否已经凑齐第一句(句号、叹号、问号、分号、省略号或换行等)。
- 第一句一完整就立刻发起合成,而不是等
finally里整条回复结束。
默认只念第一句¶
配置项 firstSentenceOnly 默认为 true,只朗读回复开头第一句;可在 ~/.dsh/breeze-speak.json 里关掉,以念更多内容(会多耗 Breeze 积分)。
文本清理与其它插件隔离¶
送给 Breeze 前会剥掉代码块以及 {}、[]、【】 等标记,避免被逐字念成「左花括号」。同时会跳过由其它插件发起的模型调用(例如返回 JSON 的心情判定),避免把别家插件的 JSON 串进朗读。
PCM 流式播放¶
走 Breeze 的 /stream 端点,以 SSE 推送 PCM 帧;网页半边 drain 到 Web Audio 时间轴上连续播放,而不是等整段 mp3 编完。
设置页:Key 与在线音色¶
设置入口为「设置 → Breeze 朗读」:
- 填写 Breeze API Key(形如
brz_...),保存后立即生效,无需重启。 - 浏览在线音色:按名字 / 语言 / 性别 / 来源筛选、分页;「▶ 官方试听」播 Breeze 自带预览(免费);「念一句」用该音色试合成(耗少量积分,不改变已保存音色);「选为我的音色」保存默认
voiceId。
设置页只暴露 key 和音色选择器;enabled、firstSentenceOnly、maxChars、instructions 需在配置文件里改,并真正退出桌面应用再开才生效(插件主代码不热重载)。
组成与依赖¶
| 文件 | 作用 |
|---|---|
package.json |
声明 dsh.bundle.patch、dsh.client、入口 |
cordis.patch.yml |
插入 profile(id: breeze-speak) |
index.js |
宿主:apply(ctx)、注册路由、钩住 llm/stream |
client.js |
网页:window.__ModuleLoader__.load、设置槽位、播放 |
前置条件(来自 README):
- Node >= 22(DSH 自带运行时满足即可)。
- DSH 引擎
>= 0.2.1-rc.2(见package.json的engines.dsh)。 - 有效的 BreezeBlue API Key。
API Key 与音色¶
Key 三种来源,优先级:设置页 > 环境变量 BREEZE_API_KEY > ~/.dsh/.credentials.yaml 里的 refs.BREEZE_API_KEY。设置页点「清空」会回退到后两者。Key 在每次合成 / 拉音色时动态解析,保存后不用重启。
默认示例音色为 voc_u3nxkd5578wc;建议在设置页「在线音色」里从你账号可用的音色里选一个(例如输入名字 →「拉取」→ 试听 →「选为我的音色」)。
拉音色与合成都会访问 api.breeze.blue(发送文本与 key)。明文 key 不下发到浏览器;网页半边只收 PCM 帧和打码后的 key 尾号。
配置¶
配置文件路径:~/.dsh/breeze-speak.json(不存在则用默认;设置页保存 key 或音色时也会写入此文件)。
{
"enabled": true,
"firstSentenceOnly": true,
"maxChars": 120,
"voiceId": "voc_u3nxkd5578wc",
"instructions": "用傲娇又有点心虚、软软的语气念,句尾轻轻上扬再收回去。",
"apiKey": ""
}
- 改 key 或 voiceId:设置页保存即可,立即生效。
- 改
maxChars、instructions、firstSentenceOnly、enabled:编辑上述文件后完整重启 DSH 桌面应用。
安装与启用¶
SkillHub 目录页与 GitHub 仓库均将该插件标识为 rirtue/dsh-breeze-speak,包已发布到 npm(publishConfig.registry 为 https://registry.npmjs.org)。已抓取资料中未给出固定的 dsh plugin add … 单行命令,安装时请按你当前 DSH 版本的插件安装流程,从 SkillHub 插件页 或 GitHub README 的说明操作;在安装前建议阅读源码与 MIT 许可证,并确认插件以 当前 dsh 进程权限运行。
启用后:
- 打开「设置 → Breeze 朗读」,粘贴
brz_...并保存。 - 拉取并选定默认音色,必要时用「念一句」试听。
- 正常对话;默认会在第一句出现后自动发起朗读。
宿主 HTTP 路由(前缀 /dsh-breeze-speak/)¶
仅供理解插件边界,日常通过 UI 即可:
| 方法 | 路径 | 说明 |
|---|---|---|
GET |
/stream |
SSE:推送 pcm 帧,随后 pcm-end 或 error |
GET |
/state |
返回 enabled、voiceId、keyed、keyMasked 等 |
POST |
/config |
保存/清空 API Key |
GET |
/voices |
代理 Breeze 音色库(page 从 1 起,page_size 等) |
GET |
/preview-url?url=... |
代理官方预览 mp3(仅允许 https://r.breeze.blue/) |
POST |
/voice |
保存 voiceId |
POST |
/preview |
即时合成一句试听 |
每个 handler 先做 准入围栏(ctx.connection.requestRejection):要求已认证的存活 Peer,否则 401/403。因此 shell 里裸 curl 通常无法访问;请用设置页或带 API token 的方式。写操作还会校验 Origin / sec-fetch-site 防跨站。
适用场景与注意¶
适合谁
- 长时间用 DSH 对话、希望少盯屏或边做别的事边听首句结论的开发者。
- 已有 BreezeBlue 账号、能接受按句/按字消耗积分,且愿意自己挑音色、写
instructions语气的人。
注意
- 默认只念第一句:长回答的后续内容不会自动全念,除非你改配置并接受更高积分消耗。
- 插件会调用外网 TTS;除 Breeze API 外,资料未描述其它出站流量,但 key 与文本会发往
api.breeze.blue。 - 社区目录 SkillHub 与 DeepSeek / 幻方无官方从属关系;插件同理为社区维护,使用前请自行审计代码。
结尾¶
dsh-breeze-speak 把「第一句写完」和「Breeze PCM 流式合成」绑在 llm/stream 上,用 Web Audio 压低首声延迟,并在设置页完成 Key 与上万在线音色的管理。若要查看元数据或提 issue,见 SkillHub 目录页 与 GitHub:rirtue/dsh-breeze-speak。