前言¶
DSH 的理念是「一切皆插件」,消息、工具、输出都可以由插件接管。但想让智能体直接开口说话,仍然有不少工程问题要处理:不同厂商的 TTS 接口不统一,密钥放哪、音色怎么选、每个片段用什么语气、其他插件要复用同一套语音服务,都要自己拼。dsh-tts-service 就是来解决这些问题的插件,由 loveandbeepbrother 维护,用一个包提供多家 TTS 供应商和一个统一的语音服务。下面介绍它的结构、安装方式和典型用法。
定位¶
dsh-tts-service 是一个面向 DeepSeek Harness(DSH)的多供应商文本转语音服务。它注册 Doubao TTS 2.0、阿里云百炼(Model Studio,含 CosyVoice、Qwen-Audio-TTS、Qwen3-TTS)以及任何兼容 POST /audio/speech 的 OpenAI 兼容端点,让用户自己选音色,并让智能体可以按片段(per-segment)指定语气。
它同时是一个可被其他插件复用的服务:其他插件可以调用同一个 ctx.ttsService,不用各自再接一遍 TTS。
一个包分成多个插件入口,在 DSH 插件页面分别开关:
| 入口 id | 作用 | 默认开启 |
|---|---|---|
tts-service |
提供服务 ctx.ttsService:供应商注册、选择(供应商、音色、语言)、合成、音色列表。 |
是 |
tts-doubao |
供应商:Doubao(火山引擎)TTS 2.0。 | 否 |
tts-bailian |
供应商:阿里云百炼 / Model Studio。 | 否 |
tts-openai-compatible |
供应商:任意兼容 POST /audio/speech 的端点。 |
否 |
tts-say |
智能体工具 tts_service_say、tts_service_voices、tts_service_select,以及输出注册表 ctx.ttsSay。 |
是 |
tts-speaker-windows |
输出方式:在电脑前时通过 PC 扬声器播放(仅 Windows)。 | 是 |
需要先说明一点:插件没有默认供应商,也没有默认音色。在你选定之前,tts_service_say 会以 VOICE_NOT_SELECTED 失败,并告诉智能体应该去哪选。另外,当前版本合成的是完整片段,不做流式输出。
安装与启用¶
安装命令来自项目 README:
dsh plugin add @loveandbeepbrother/dsh-tts-service
也可以从 GitHub 安装:
dsh plugin add github:loveandbeepbrother/dsh-tts-service
运行环境要求:
- DSH
>=0.2.1-rc.3 <0.3.0-0(含预发布版本;项目测试针对 0.2.1-rc.5)。 - Node.js 22 及以上,DSH 自带的版本即可。
- 至少一家供应商的账号和 API Key,合成费用由供应商计费。
- 使用扬声器输出时,需要 Windows 和 Windows PowerShell(
powershell.exe,系统默认自带)。
启用步骤:
- 在插件页面打开一个供应商入口(
tts-doubao、tts-bailian或tts-openai-compatible),填写其表单。 - 把 API Key 存进 DSH 的凭据存储。
- 选定音色:让智能体「列出可用音色」再「使用某个音色」,或直接在 Text-to-Speech Service(
tts-service)的设置里填写provider和voices。 - 让智能体说一段话。
密钥管理¶
配置文件里不存放密钥值,只存放密钥名。密钥值来自 DSH 的凭据服务(ctx.credentials,即设置页的 key store);没有加载凭据服务时,则来自启动 DSH 时的进程环境变量。密钥在每次请求时读取,因此轮换后立即生效。设置页只显示该密钥是否已经配置。
| 入口 | 配置字段 | 默认密钥名 | 用途 |
|---|---|---|---|
tts-doubao |
apiKeyEnv |
VOLCENGINE_TTS_API_KEY |
合成(火山引擎控制台「API Key 管理」中的 API Key)。 |
tts-doubao |
accessKeyEnv、secretKeyEnv |
VOLCENGINE_ACCESS_KEY、VOLCENGINE_SECRET_KEY |
可选:火山引擎账号 AK/SK,仅用于列出完整音色目录。 |
tts-bailian |
apiKeyEnv |
DASHSCOPE_API_KEY |
合成和列出克隆音色(与官方 DashScope SDK 同名)。 |
tts-openai-compatible |
apiKeyEnv |
OPENAI_COMPATIBLE_TTS_API_KEY |
以 Authorization: Bearer 发送。本地无需密钥的端点可留空。 |
这些字段名都可以重命名,例如需要同时接入两个同类型端点时,用不同的密钥名区分。
选择音色¶
音色选择保存在 tts-service 的设置里,写入用户 profile,不需要重启。设置项有:
| 字段 | 含义 |
|---|---|
provider |
默认供应商 id,留空表示无。 |
voices |
每个供应商的默认音色:供应商 id → 音色 id。音色 id 只在所属供应商内有意义,因此从 Doubao 换到 Bailian 再换回来,两边的选择都会保留。 |
language |
默认语言代码,默认 auto,必须是供应商声明支持的值。 |
有三种设置方式,都写入同一份设置且立即生效:
- 设置页:在 Text-to-Speech Service 设置里修改
provider和voices。 - 让智能体操作:先问「有哪些音色」(
tts_service_voices),再「切换到……」(tts_service_select)。智能体回复会说明旧音色、新音色以及如何改回去。 - 从插件代码调用:
await ctx.ttsService.configure({ provider: 'doubao', voices: { doubao: 'voice-id' } })
tts_service_voices(插件中对应 ctx.ttsService.voices(id))会列出音色及其支持的语言、是否跟随语气描述。无法完整的列表会明确标注不完整,也可以手动输入音色 id。
错误处理是明确的:供应商未注册、语言不被支持、文本超过 maxChars、无法生成该格式,都会直接失败。服务不会静默切换到另一个供应商。
供应商细节¶
Doubao TTS 2.0(tts-doubao,供应商 id doubao)¶
| 字段 | 默认值 | 说明 |
|---|---|---|
providerId |
doubao |
需要跑两份时可改。 |
resourceId |
seed-tts-2.0 |
作为 X-Api-Resource-Id 发送。 |
apiKeyEnv、accessKeyEnv、secretKeyEnv |
见上文 | |
sampleRate |
24000 |
16-bit 单声道 PCM。 |
maxChars |
300 |
每次请求的字符上限。 |
timeoutMs |
60000 |
有几个细节需要注意。语气描述和「上下文」(用户上一句话)会合并成一条音色指令,通过 additions.context_texts 发送。只有 Doubao 2.0 系统音色(id 含 uranus)会跟随这条指令,克隆音色不跟随。音色列表方面,没有 AK/SK 时返回从官方音色表转录的 2.0 系统音色静态表,且标注为不完整;有 AK/SK 时插件调用官方 ListSpeakers API(HMAC-SHA256 签名,service 为 speech_saas_prod,region 为 cn-beijing)。语言支持 auto、zh、en、ja,以 explicit_language 发送。
Alibaba Bailian(tts-bailian,供应商 id bailian)¶
| 字段 | 默认值 | 说明 |
|---|---|---|
model |
cosyvoice-v3-flash |
也可填 cosyvoice-v3-plus、cosyvoice-v2、cosyvoice-v3.5-flash、qwen-audio-3.1-tts-flash、qwen3-tts-flash 等。音色只与同模型搭配。 |
region |
cn-beijing |
可选 ap-southeast-1、cn-hongkong、us-east-1、eu-central-1、ap-northeast-1。密钥、workspace 和模型按 region 隔离。 |
workspaceId |
— | API 主机的第一段标签(如 llm-xxx)。设置后使用 workspace 域名 {workspaceId}.{region}.maas.aliyuncs.com,否则使用旧的 DashScope 域名。eu-central-1 和 ap-northeast-1 必须设置。阿里云表示 DashScope 域名自 2026-09-30 起不再新增功能,因此建议设置。 |
apiKeyEnv |
DASHSCOPE_API_KEY |
|
sampleRate |
24000 |
CosyVoice / Qwen-Audio-TTS;Qwen3-TTS 固定 24000。 |
maxChars |
Qwen3-TTS 为 600,其他为 2000 | |
timeoutMs |
60000 |
覆盖合成调用和音频下载。 |
接口层面,CosyVoice 和 Qwen-Audio-TTS 走 /api/v1/services/audio/tts/SpeechSynthesizer,Qwen3-TTS 走 /api/v1/services/aigc/multimodal-generation/generation;两者都返回有效期 24 小时的音频 URL,插件负责下载。是否跟随自由形式的语气描述(instruction)要看模型:
| 模型 | 是否跟随自由语气描述 |
|---|---|
qwen-audio-* |
是,系统音色、克隆音色和设计音色均可(少数英语音色除外)。 |
cosyvoice-v3.5-* |
是(该模型只有克隆和设计音色)。 |
cosyvoice-v3-flash |
仅克隆和设计音色可以;系统音色只接受固定的指令模板。 |
OpenAI 兼容端点(tts-openai-compatible)¶
任何兼容 POST /audio/speech 的端点都可以直接接入,密钥以 Authorization: Bearer 发送,本地无需密钥的端点可将密钥字段留空。
从插件复用服务¶
这个包是一个 ES Module,package.json 中 main 指向 ./src/service.js,types 指向 ./index.d.ts。除了默认导出,exports 字段还按子路径导出了各个入口:./doubao、./bailian、./openai-compatible、./say、./speaker-windows,配套的 locale 文件也有对应子路径。想在自己的插件里直接调用语音服务,可以通过 ctx.ttsService.configure(...)(见上文)或 ctx.ttsService.voices(id) 完成。
其他插件即使不启用 tts-say,也能复用同一个 ctx.ttsService。这降低了多个插件各自接 TTS、音色和密钥策略不一致的风险。
适用场景与注意¶
适合以下几类人:
- 想在 DSH 里让智能体直接说话、并按片段控制语气的组合开发者。
- 已经在用多家 TTS 供应商、希望统一音色选择与密钥管理的人。
- 想做一个需要播报或语音提醒的插件、并复用同一套语音服务的人。
使用时需要注意:
- 先在插件页面打开供应商入口并配置密钥,再选音色;否则合成会失败。
- 合成按供应商计费,密钥在每次请求时读取,轮换后立即生效。
- 只使用需要一个完整片段、不要求流式播放的场景;当前版本不支持流式合成。
- 语气描述能否生效取决于供应商和音色型号,列音色时要看是否标注「跟随语气描述」。
- 插件以当前 DSH 进程的权限运行,安装前应自行检查源码与许可证(
package.json声明为 MIT License)。当前版本号为0.1.0。 - 社区目录站是独立站点,与 DeepSeek / 幻方无官方从属关系。
小结¶
dsh-tts-service 的价值在于,把「接哪家 TTS、选哪个音色、按片段给语气、其他插件复用」这几件事收敛到一个插件里:一个包、多个入口,供应商按需开关,音色保存在 profile 里,密钥只存名字。对需要让 DSH 智能体开口说话的人来说,这是目前比较省事的路径。
- 目录页:https://www.skillhub.cn/plugins/loveandbeepbrother/dsh-tts-service
- GitHub:https://github.com/loveandbeepbrother/dsh-tts-service