前言¶
在 DeepSeek Harness(DSH)里给智能体回复加语音,常见做法是等整段 assistant 消息「落盘」后再合成。上游 @goodandready/dsh-tts 的 speakAsItGoes 也是消息粒度:多步回合里每一步都是一条消息,本地模型往往要等第一步整段输出(含 reasoning)结束,浏览器才听到第一段声音,主观上会觉得「语音总是慢半拍」。
YevheniiMiachyn/dsh-tts-live 是在上游 0.4.16 基础上的 fork,保留原有 TTS 能力与 provider 链,额外提供可选的句级 live 路径,并附带面向本地 OpenAI 兼容 TTS 的几项修复。下面介绍它是什么、能做什么,以及如何安装与配置。
这是什么¶
- 名称:社区目录中的
dsh-tts-live,仓库 YevheniiMiachyn/dsh-tts-live,npm 包名仍为@goodandready/dsh-tts(与上游同名,但本 fork 不发布到 npm)。 - 维护者:YevheniiMiachyn;SkillHub 分类为「模型推理」。
- 定位:在 DSH Web UI 中为 agent 回复做语音合成;本 fork 的核心增量是 按句实时播报、有序流式队列、宿主侧 barge-in 取消,以及对
customprovider 的 WAV 等本地部署修复。 - 与上游关系:基础插件的 provider 链、设置 UI、云后端、本地化等问题应走 GooDAnDReaDY/dsh-tts;与 live 句级流式 相关的问题在本 fork 仓库提 Issue。许可证 MIT,保留上游版权声明。
为什么需要句级 live 路径¶
上游在 assistant 消息 settle 之后才朗读;本地 GPU 栈上,「等整段消息」往往是语音延迟的主要来源。本 fork 通过进程内的 agent/assistant-stream 事件驱动 真正的句级 TTS:模型每写完一句即可进入合成队列,首句甚至可以在 assistant/message settle 之前开始合成,模型仍在输出时用户就能听到前面几句。
设计上是保守的:live 路径 默认关闭、需显式开启;落盘消息路径仍是权威来源;streamingEnabled(上游 SSE / AudioWorklet 路径)与 live 模式 相互独立,互不要求。
本 fork 的核心能力¶
句级流式与队列¶
- 监听
agent/assistant-stream,按句切分并排队合成。 - 有序句子队列:一句一段、按序发布,带稳定 id,避免客户端重复播放或乱序。
- 每条队列与 settle 片段都带 session / turn / step 归属。
- 落盘对账:settle 消息到达后,已读过的文本与消息对齐,只发布未读尾部。
- 多步与 tool call:reasoning 与 tool-call JSON 不朗读;已在 live 阶段播过的 step 不会重复朗读。
- 可配置首句/后续句最小字符数、单段上限、轮询间隔,以及在 tool call 前是否 flush 未读 remainder。
Barge-in 与 late-settle¶
- 宿主提供
POST /dsh-tts/bargein:丢弃待播音频并中止进行中的合成(按 session)。 - Late-settle suppression:barge-in 已丢弃的音频不会因重试或重新 settle 被「复活」。
本地部署相关修复(相对上游)¶
customprovider 请求response_format: 'wav',并按格式返回audio/wav。- 修复 abort 未正确挂接导致无法取消进行中的合成。
- 阻止浏览器
SpeechSynthesis在 provider 失败时用 OS 语音「掩盖」错误。 - Provider 超时提高到 120 s,适应本地 TTS 冷启动。
- 修复 live 尾部重复发布(基于
claimedEnd精确认领文本范围)。
更细的补丁列表见仓库 PATCHES.md;设计说明见 LIVE-SENTENCE.md。
继承自上游的能力(简要)¶
本 fork 仍是一套完整的 DSH TTS 插件:在 Web UI 开启 Speak agent replies 后,由宿主后端合成并推送到浏览器,API 密钥不进入客户端。支持多 provider 回退链(OpenAI、ElevenLabs、Edge、Piper、eSpeak、custom OpenAI 兼容端点等),以及文本清洗、IT 词典、子 agent 音色、缓存与若干 HTTP 路由(如 GET /dsh-tts/stream、POST /dsh-tts/speak)。这些能力与上游一致;需要句级 live 时使用本仓库,需要官方 npm 包时使用 @goodandready/dsh-tts(不含本 fork 的 live 功能)。
安装与启用¶
README 要求 从本仓库 checkout 安装,用 file: 依赖固定已测产物;生产环境避免 link:。SkillHub 页面标注当前版本为 v0.4.16-local.14(与 package.json 一致)。
- 在本仓库按发布说明准备
dsh-tts-<version>.tgz包(路径替换为你的实际目录与版本号)。 - 执行官方安装命令:
dsh plugin --profile web add file:/path/to/dsh-tts-<version>.tgz
若只需上游 npm 版(无 live 句级流式),可使用:
dsh plugin --profile web add @goodandready/dsh-tts
- 安装后重启 DSH Web UI(README 示例:
systemctl --user restart dsh-web),并刷新浏览器标签页。
运行环境:README 标明 Node 20+。插件以当前 DSH 进程权限在宿主侧执行合成与网络访问,安装前请阅读源码与 MIT 许可证,并自行评估 provider 与本地引擎配置。
典型配置:开启 live 句级流式¶
在 settings.yaml 的 dsh-tts: 段落下增加或修改下列键(均来自 README 文档):
| 键 | 默认值 | 含义 |
|---|---|---|
liveSentenceStreaming |
false |
live 句级路径总开关 |
liveMinCharsFirst |
12 |
首句允许 flush 前的最少字符 |
liveMinChars |
48 |
后续句 flush 的最少字符 |
liveMaxChars |
0 |
单段硬上限;0 时回退到 sentenceChars |
livePollMs |
150 |
live 期间待播队列轮询间隔(毫秒) |
liveFlushOnToolCall |
true |
tool call 前是否 flush 未读 remainder |
示例(README 中的 validated 生产取向:streamingEnabled 保持独立且可为 false):
dsh-tts:
speakReplies: true
liveSentenceStreaming: true
liveMinCharsFirst: 12
liveMinChars: 48
liveMaxChars: 0
livePollMs: 150
liveFlushOnToolCall: true
streamingEnabled: false
Web UI 中可在 Settings → Plugins → Plugin settings 调整多数面向用户的项;provider API 密钥通过链编辑器写入 DSH 凭证存储(PUT /dsh-tts/credential),不保存在插件 settings 明文里。
需要打断当前会话播报时,由集成方调用 POST /dsh-tts/bargein(具体请求体以仓库当前实现为准)。
适用场景与限制¶
更适合
- 本地或自托管 DSH + 本地/兼容 TTS,希望 边生成边读,缩短「第一句可听」的等待。
- 多步 agent(含 tool call),需要 不读 reasoning/JSON、且避免同一步重复朗读。
- 使用
customOpenAI 兼容 TTS 且需要 WAV 与更长合成超时。
需要注意
- GPU 争用:LLM 与本地 TTS 共用 GPU 时,live 只改善调度(更早开读),不会加快模型或 TTS 本身。
- 不解决 TTFT:首 token 时间仍取决于模型与硬件;live 消除的是「首句已存在之后」仍等整段 settle 的等待。
skipCode: true时 inline code 被剔除,由代码片段组成的句子可能读得断断续续;live 模式下句子更多,更容易听到。- 性能因模型、TTS 引擎与 GPU 配置而异;release 说明中的数字来自特定本地环境,不宜外推为通用基准。
DSH 生态强调「一切皆插件」;SkillHub 为社区目录,与 DeepSeek / 幻方无官方从属关系。
结尾¶
dsh-tts-live 在成熟 TTS 插件之上,用可选、默认关闭的句级 live 路径,把「等整段消息再读」改成「按句排队、可对账、可 barge-in」,并针对本地 custom WAV 与取消/超时做了生产向修补。若你正在 DSH 里做语音 agent,且瓶颈是 message-level 播报,可从 SkillHub 页进入仓库,按 README 用 file: 包安装并打开 liveSentenceStreaming 做验证。
- 目录页:https://www.skillhub.cn/plugins/YevheniiMiachyn/dsh-tts-live
- GitHub:https://github.com/YevheniiMiachyn/dsh-tts-live