跳到主要内容

qq-voice

收藏0

让 QQ 机器人用 GPT-SoVITS 本地合成的嗓音发语音消息。当用户说「发个语音」「用语音说」「我想听你说话」「读给我听」「voice」时使用;在 QQ 私聊/群里想用语音回一句时也用。

让 AI 安装

lrt最新版本 0.1.0更新于 2026-11-01下载 0 次

SKILL.md

QQ 语音(GPT-SoVITS 本地 TTS)#

本地部署了 GPT-SoVITS:本地合成 wav → 走 QQ 官方机器人接口以「语音」消息发出(msg_type 7)。 有两条路,优先用 A。

方式 A:通道级(只在 QQ 会话里有效,最自然)#

在 QQ 私聊/群的回复里,把整条回复写成这样:

[[voice]]主人,我在这儿呢,今天累不累呀?
  • QQ 通道会把这行识别成「要说的内容」,合成语音后当成语音气泡发出去;
  • 合成失败会自动降级成普通文字,不会丢消息;
  • 标记只认开头;一条回复一个语音,后面的文字仍然走普通消息;
  • 不要在 Web/桌面会话里写 [[voice]],那边没有这个钩子,会原样显示。

适合:闲聊、撒娇、道晚安这类一两句话。写长段落、贴代码、讲正事时用文字。

方式 A+:自动语音(默认关闭)#

QQBot.send() 还有一层自动语音:打开后,QQ 里的短回复(≤120 字、不含代码块/表格/链接)会按概率自动转成语音气泡,不需要 agent 配合。

默认 auto_voice: false——只在别人明确要语音时才发(用方式 A 的 [[voice]] 或方式 B)。

开关都读同一份 qqvoice\config.json:

键默认说明
auto_voicefalse总开关;关着的时候只有显式 [[voice]] 才会发语音
auto_voice_ratio0.5打开后有多大概率把这条回成语音,1 = 每条都语音
auto_voice_max_chars120超过这个字数的回复仍然用文字

TTS 服务自愈:发语音时如果 9880 没在监听,SDK 会自己拉起 TTS 服务(CUDAGraph=0、cwd 指向项目目录),等端口就绪后重试一次;冷启动约 20 秒。可用环境变量 GPTSOVITS_PYTHON / GPTSOVITS_PROJ / GPTSOVITS_START_CMD 覆盖路径。

方式 B:命令行(任何会话都能发)#

当前会话发(自动认人在哪个 QQ 会话,按 DSH_SESSION_ID 反查):

qqvoice\say-here.cmd --text "要说的话"

指定对象发(绕开自动识别):

qqvoice\say.cmd --text "要说的话"                        # 默认主人私聊
qqvoice\say.cmd --scope group --target <群openid> --text "要说的话"

只合成不发送:加 --dry,音频落在 qqvoice\out\。

音色:本地微调模型#

  • 用自备音声素材微调出来的专属模型(素材如来自第三方,请自行确认版权):
    • s1(韵律)<GPT-SoVITS目录>\logs\<模型>\<模型>-e15.ckpt
    • s2(声码器)<GPT-SoVITS目录>\logs\<模型>\<模型>_e8_s712.pth
    • 写在 GPT_SoVITS\configs\tts_infer.yaml 的 custom 段(version v2)。
  • 参考音是素材内的真人音频(prompt_lang: ja,硬限制 3~10 秒):默认 refs\<参考音>\<参考音>.wav。
  • 音色参数存在 qqvoice\config.json:temperature 0.7 / sample_steps 32 / cfg_rate 0.35 / speed 1.05;合成后自动过一遍 ffmpeg loudnorm=I=-16:TP=-1.5:LRA=11 再上传(否则偏轻发闷)。
  • 换参考音只改 ref + prompt_text(两者必须严格对应);换音色模型改 tts_infer.yaml 的 custom 段后重启 TTS。

参数#

参数说明
--text必填,要合成的话(中文,10~100 字最自然)
--scopec2c / group,不填读 config.json 或按会话自动判断
--targetopenid,不填读 config.json / 会话映射
--ref / --prompt-text参考音色与对应文本,默认读 qqvoice\config.json
--out指定 wav 输出路径
--dry只合成不发送

依赖与排错#

  • TTS 服务 http://127.0.0.1:9880;没起来先跑 <GPT-SoVITS目录>\gptsovits\start-api.cmd(可设登录自启)。
  • 首次请求加载模型约 515 秒,之后单句 0.51.5 秒。
  • 100016 invalid appid or secret:qqvoice\.env 的 AppSecret 过期,从配置中心/凭据管理取当前值更新。
  • TTS 报 Resource 'averaged_perceptron_tagger_eng' not found:nltk 数据缺失,跑 python -c "import nltk; nltk.download('averaged_perceptron_tagger_eng')"。文本里出现英文单词会触发这个检查。
  • 通道级 [[voice]] 依赖 QQBot.js 的本机补丁(@tencent-connect/qqbot-nodejs/dist/QQBot.js),改完要重启 DSH 才生效;补丁文件注意备份。

说话风格#

  • 1~2 句,口语化,带语气词(呀、哦、嘛)更自然。
  • 别念 markdown、表情、网址。
  • 语音发出就无法编辑,发之前想清楚。

用途与依赖

作者没写,这些是平台读文件后整理的,以文件为准。

使用示例

请求:用语音跟我说句晚安吧

预期

在 QQ 会话的回复开头写 [[voice]]晚安呀,今天也辛苦啦,早点睡哦。通道识别到开头的标记后,会把这句话交给本地 GPT-SoVITS(127.0.0.1:9880)用微调音色合成 wav,经 ffmpeg loudnorm 处理后,通过 QQ 官方机器人接口以 msg_type 7 的语音气泡发出。若 TTS 没在监听,会先自动拉起服务(冷启动约 20 秒)再重试一次;仍失败则自动降级成普通文字发送,不会丢消息。

适用场景
  • 用户在 QQ 私聊或群里说「发个语音」「用语音说」「读给我听」
  • 闲聊、道晚安这类一两句话,想用语音回一句
  • 需要给指定 QQ 群或某个 openid 单独发一条语音
  • 只想先试听合成效果,不想真的发出去(--dry)
  • 想调整音色、语速、参考音后重新合成
输入
  • 要合成的话(--text,中文 10~100 字最自然)
  • 发送范围:c2c 或 group(--scope,可省)
  • 目标 openid(--target,可省)
  • 参考音色文件与对应 prompt 文本(--ref,--prompt-text,可省,默认读 config.json)
  • wav 输出路径(--out,可省)
  • 是否只合成不发送(--dry)
输出
  • QQ 会话中的语音气泡消息
  • 降级时的普通文字消息(TTS 失败时)
  • 合成好的 wav 文件(--dry 或 --out 时落在 qqvoice\out\)
  • 命令行执行日志与报错信息
运行环境
Windows 环境(.cmd 脚本),配合 Python 3 运行的 GPT-SoVITS 本地服务;通道级 [[voice]] 需要 Node.js 运行的 DSH 及打过补丁的 @tencent-connect/qqbot-nodejs
依赖
  • GPT-SoVITS 本地部署(含 gptsovits\start-api.cmd 与 9880 端口的 API 服务)
  • ffmpeg(合成后做 loudnorm 音量归一)
  • nltk 及 averaged_perceptron_tagger_eng 数据(文本含英文单词时会检查)
  • @tencent-connect/qqbot-nodejs(需打本机 QQBot.js 补丁)
  • DSH(QQ 通道宿主,打补丁后需重启)
  • GPT-SoVITS 微调模型:s1 .ckpt、s2 .pth