dsh-tts-service:给 DSH 智能体接上多供应商语音合成

前言

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,系统默认自带)。

启用步骤:

  1. 在插件页面打开一个供应商入口(tts-doubao、tts-bailian 或 tts-openai-compatible),填写其表单。
  2. 把 API Key 存进 DSH 的凭据存储。
  3. 选定音色:让智能体「列出可用音色」再「使用某个音色」,或直接在 Text-to-Speech Service(tts-service)的设置里填写 provider 和 voices。
  4. 让智能体说一段话。

密钥管理

配置文件里不存放密钥值,只存放密钥名。密钥值来自 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,必须是供应商声明支持的值。

有三种设置方式,都写入同一份设置且立即生效:

  1. 设置页:在 Text-to-Speech Service 设置里修改 provider 和 voices。
  2. 让智能体操作:先问「有哪些音色」(tts_service_voices),再「切换到……」(tts_service_select)。智能体回复会说明旧音色、新音色以及如何改回去。
  3. 从插件代码调用:
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
羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

小夜