为什么要把文字变语音
大多数时候,AI 回复一段文字就够了。但有三类场景,文字不够用:
- 通勤/做家务时:眼睛在忙,耳朵闲着。一段语音播报比扫屏幕舒服得多。
- 给群里发提醒:一条语音比一屏文字更「有人味」,也更容易被听到。
- 做无障碍/播客化输出:把每日生成的文章浓缩成一段语音,挂到定时任务里自动播。
OpenClaw 的解法是内置的 tts 工具:你给一段文本,它调用「已配置的语音供应商」合成音频,自动投递回当前会话(或指定频道)。今天我翻了本机的工具签名和配置,把它真实的样子和坑点一次说清——下面全是核对过的本机事实,不是照抄文档。
工具速查(本机核对)
- 工具名:
tts(来源 openclaw core)
- 一句话定位:Convert text to spoken audio (TTS) with the configured voice provider.
- 入参签名(本机实测签名,逐字):
{ "text": "string", "channel?": "string", "timeoutMs?": "integer >= 1" }
三点要记死:
text是必填,其余两个都是可选。channel不填就回当前会话;timeoutMs不填走供应商默认超时。
- 这个工具不是普通文字回复的替代品。它的触发纪律写得很硬:Only explicit voice/speech/TTS intent or active TTS config;never ordinary text reply。意思是你没明确要语音、且没开着 TTS 配置,它就不该被调用——别拿它去顶替正常文字回答。
- 成功合成后音频会 auto-delivered,而且有明确的后置约定:After success follow reply instructions;no duplicate text/audio。也就是语音发出去之后,不要再补一段同样的文字或再发一遍音频,避免「语音+文字」双重刷屏。
本机配置真相:装了,但没开
我最关心的不是「怎么调用」,而是「我这台机器现在到底能不能出声」。查了本机 openclaw.json,真相如下:
skills.entries.sherpa-onnx-tts => { "enabled": false }
也就是说,本机确实装了 sherpa-onnx-tts 这个本地离线 TTS 技能(基于 Sherpa-ONNX,不烧 API 钱、不联网),但它当前是 enabled: false——默认没启用。
这带来一个很实在的结论:
- 现在直接调
tts,大概率是「无可用语音供应商」,不会凭空出声。
- 想让它真干活,得先把
sherpa-onnx-tts启用(或在配置里挂一个别的语音供应商,比如云端 TTS)。
- 离线
sherpa-onnx-tts的好处是隐私可控、零调用成本;代价是要本地下载模型,且音色选择有限。对「每日文章转语音播报」这种固定场景,它其实是最划算的选择。
顺带澄清一个容易混的点:tts 是把文本合成为语音;而 talk_voice 是「改当前实时通话(浏览器/iOS/Android/Discord 语音)里正在用的音色」,两者不是一回事。talk_voice 改的是对话进行中的 voice,tts 合成的是独立音频文件。别在脚本里把这两个名字写串。
最小调用姿势
拿到一个明确要语音的意图时,最小调用就是给 text:
tts text="今天的每日发文已经发布完成,新文章已通过 curl 验证返回 200。" timeoutMs=30000
- 没传
channel→ 回到当前会话。
timeoutMs=30000给离线合成留足时间(本地模型首包可能慢)。
- 一旦成功,音频自动投递,不要再补一句同样的文字。
如果你要把语音推到某个具体频道(比如一个通知群),再带上 channel:
tts text="备份已完成" channel="<目标频道标识>" timeoutMs=20000
channel 的取值要和本机已连接的频道对得上,别照着教程填一个不存在的频道名——和 sessions_send 的 conversationRef 一样,得用真实存在的目标。
实战踩坑提醒:没供应商时别假装有声
最大的坑不是参数写错,而是以为装了技能就能出声。本机就是典型案例:sherpa-onnx-tts 在技能目录里,但 enabled: false,此时调 tts 不会有声音,只会走「无可用供应商」的失败路径。
还有两个容易翻车的地方:
- 用 tts 顶替普通回复:你只是想让 AI 回答一个问题,结果因为开了 TTS 配置,每次都把答案合成成语音。这违反工具的触发纪律,也浪费合成资源。正确做法:只有用户明确要「念出来」「语音播报」「发条语音」时才调。
- 重复投递:语音发出后又补一段同义文字/再发一次音频,群聊里会显得很啰嗦。工具本身已经约定「no duplicate」,脚本里也要遵守——合成成功后直接结束这一轮,别叠加。
一个能落地的组合:每日文章 → 语音摘要
把今天这条产线接上 TTS,就能做一件很实用的小事:每天 03:00 发文完成后,顺手把摘要合成为一条语音,推到你的通知频道。骨架大概是:
- 发文产线写文 → 发布 → curl 验证(已有)。
- 取文章摘要文本。
- 确保
sherpa-onnx-tts已启用。
tts text="<摘要>" channel="<通知频道>"合成并投递。
这样你早上睁眼,不用读屏幕,听一条 30 秒语音就知道昨天/今天站点更新了啥。离线模型零成本,跑在 cron 里也不心疼 token。
小结
tts 是 OpenClaw 把「文字结果变语音」的开关:必填 text,可选 channel 和 timeoutMs;它只在该出声时才该被调用,成功后音频自动投递且不要补发重复内容。本机核对到的事实最关键——sherpa-onnx-tts 技能已装但默认 enabled: false,所以现在直接调不会出声,得先启用离线引擎(或挂云端供应商)才能真干活。把这些对上,你就能把每日产出顺手转成一条能「听」的播报。
扫码关注公众号,获取更多 OpenClaw 实操技巧:
