# 语音克隆培训包 - 部署与验证指南 ## 概述 培训包现已包含完整语音克隆能力,支持: - ✅ 声音档案录制与管理 - ✅ 文本转语音合成(Fmode IndexTTS2) - ✅ 自动语气识别(自然/友好/致歉/关怀/提醒) - ✅ 企微 SILK 编码 - ✅ 直接发送到企微联系人 ## 构建信息 **当前版本**: - exe 大小:96.0 MB - 平台:Windows x64 - 语音依赖:已内置(ffmpeg/ffprobe/wx-voice) - 后端服务:Fmode Server `https://server.fmode.cn/api/voice/indextts2` **构建命令**: ```bash node scripts/build-training-package.mjs ``` ## 部署步骤 ### 1. 准备培训包 拷贝整个 `dist/qiwei-training/` 目录到培训机,确保包含: ``` dist/qiwei-training/ ├── qiwei-workbench.exe # 96MB 主程序(含语音依赖) ├── .env.local # 本机凭据配置 ├── README.md # 使用说明 ├── qiwei.runtime.config.mjs ├── web/ # 工作台前端 └── knowledge/ # 客服知识库 ``` ### 2. 配置凭据 编辑 `.env.local`: ```env QIWEI_AUTH_TOKEN=sk-xxx # 必填:Fmode Token(从 https://server.fmode.cn 获取) QIWEI_UID= # 可选:登录后自动填充 QIWEI_GUID= # 可选:登录后自动填充 ``` ### 3. 启动工作台 双击 `qiwei-workbench.exe`,浏览器会自动打开 `http://127.0.0.1:4320`。 ## 语音克隆使用流程 ### 步骤 1:录制参考音频 **要求**: - 时长:5-30 秒 - 格式:WAV/MP3/M4A(推荐 WAV) - 质量:清晰、无背景噪音、自然语速 - 内容:朗读一段完整的客服话术(不要读单字) **示例话术**: > "您好,我是您的专属顾问小王。很高兴为您服务。关于您咨询的房源信息,我这边已经为您整理好了详细资料,包括户型图、价格和周边配套。如果您方便的话,我可以现在发给您,也可以约个时间带您实地看房。请问您这边什么时间比较合适呢?" ### 步骤 2:初始化声音档案 通过工作台或 MCP 工具调用: ```javascript // 方式 1:工作台 UI(推荐) // 在工作台「语音克隆」面板上传参考音频 // 方式 2:MCP 工具调用 qiwei_enroll_voice({ filePath: "D:/recording/reference.wav", guid: "your-guid" // 可选,多账号时指定 }) ``` **结果**: - 档案保存到 `outputs/voice//profile.json` - 参考音频保存到 `outputs/voice//reference-*.wav` ### 步骤 3:合成并发送 ```javascript qiwei_send_cloned_voice({ toId: "wmAbCdEfGhIjKlMnOpQrSt", // 企微联系人 ID text: "您好,关于您咨询的房源,我已经整理好资料了。", tone: "auto", // 自动识别语气:natural/friendly/apology/empathetic/reminder confirmed: true // 必须明确确认(真实发送操作) }) ``` **流程**: 1. 调用 Fmode `indextts2` 合成 WAV 音频 2. ffmpeg 转换为 24kHz 单声道 3. wx-voice 编码为企微 SILK 格式 4. 上传到企微获取 fileId 5. 发送语音消息 ## 计费说明 **语音合成费用**(从 Fmode 飞马余额扣费): - 成本价:3元/万字符 - 客户价:9元/万字符 - 结算方式:实时扣费(通过 NewAPI quota) **示例**: - 50 字客服话术 ≈ 0.045 元 - 200 字产品介绍 ≈ 0.18 元 - 1000 字详细说明 ≈ 0.9 元 **余额查询**: ```bash curl -H "Authorization: Bearer sk-xxx" \ https://server.fmode.cn/api/product/balance ``` ## 故障排查 ### Q1: exe 启动后提示缺少依赖? **可能原因**:构建时使用了 `--external` 标志 **解决方案**: ```bash # 重新构建,确保不带 --external node scripts/build-training-package.mjs ``` ### Q2: 语音合成返回 403 Forbidden? **原因**:Token 无效或未配置 **解决**: 1. 检查 `.env.local` 中的 `QIWEI_AUTH_TOKEN` 2. 确认 Token 以 `sk-` 开头 3. 在 https://server.fmode.cn 检查 Token 状态 ### Q3: 语音发送后对方收不到? **排查步骤**: 1. 检查控制台日志,确认 SILK 编码成功 2. 查看 `outputs/voice//` 下是否有 `.silk` 文件 3. 确认企微账号在线且有发送权限 4. 检查 `toId` 是否正确(应为 `wmXxxx` 格式) ### Q4: ffmpeg 或 wx-voice 报错? **现象**:`Error: spawn ffmpeg ENOENT` 或 `WxVoice encode failed` **原因**:二进制依赖未正确打包 **解决**: ```bash # 验证打包是否完整 node scripts/verify-voice-in-training-package.js # 如果验证失败,清理后重新构建 rm -rf dist/qiwei-training node scripts/build-training-package.mjs ``` ## 验证清单 运行自动化验证: ```bash node scripts/verify-voice-in-training-package.js ``` **检查项**: - ✅ exe 文件存在且大小合理(~96MB) - ✅ 源码包含完整语音服务模块 - ✅ package.json 声明语音依赖 - ✅ Fmode 后端地址已配置 - ✅ README 包含语音使用说明 ## 手动功能测试 ### 测试 1:声音档案初始化 ```bash # 准备测试音频(5-30秒 WAV) # 启动工作台 cd dist/qiwei-training ./qiwei-workbench.exe # 在工作台上传参考音频 # 预期:outputs/voice//profile.json 生成 ``` ### 测试 2:语音合成(不发送) ```javascript // 在工作台控制台或通过 MCP 调用 const service = new VoiceCloneService(guid); const wavPath = await service.synthesize({ text: "这是一条测试语音", tone: "natural" }); // 预期:返回 WAV 文件路径,可播放验证 ``` ### 测试 3:完整发送流程 ```javascript // 发送到测试联系人(需提前加好友) qiwei_send_cloned_voice({ toId: "测试联系人的企微ID", text: "您好,这是一条测试语音消息。", confirmed: true }); // 预期:对方收到语音消息,音色与参考音频一致 ``` ## 技术架构 ### 依赖关系 ``` qiwei-workbench.exe (96MB) ├── bun runtime ├── 业务逻辑 │ ├── voice-clone-service.js │ ├── agent-workbench-service.js │ └── ... └── 二进制依赖(已打包) ├── @ffmpeg-installer/ffmpeg (~50MB) ├── @ffprobe-installer/ffprobe └── @binsee/wx-voice (~10MB) ``` ### 调用链路 ``` 用户输入文本 ↓ VoiceCloneService.synthesize() ↓ POST https://server.fmode.cn/api/voice/indextts2 ├── Headers: Authorization: Bearer sk-xxx ├── Body: multipart/form-data │ ├── payload: {text, tone, model} │ └── audio: reference.wav └── Response: audio/wav (24kHz) ↓ ffmpeg 转换 → 24kHz 单声道 WAV ↓ WxVoice.encode() → SILK 格式 ↓ 企微 /msg/uploadMediaFile → fileId ↓ 企微 /msg/sendVoice → 发送成功 ``` ### 配置项 [voice-clone-service.js:230](E:/workspace/QIWEI-skill/mcp/src/core/voice-clone-service.js#L230): ```javascript const endpoint = String(config.endpoint || 'https://server.fmode.cn/api/voice/indextts2').trim(); ``` **可通过环境变量覆盖**: ```env QIWEI_VOICE_ENDPOINT=http://127.0.0.1:7338/api/voice/indextts2 # 本地开发 ``` ## 后续优化(方案 B) 如果方案 A 验证通过,可考虑将 SILK 编码移到后端: **新接口**:`POST /api/voice/qiwei/send` **请求**: ```json { "text": "您好,关于您咨询的房源...", "tone": "friendly", "referenceAudio": "base64...", "toId": "wmAbCdEfGhIjKlMnOpQrSt" } ``` **响应**: ```json { "messageId": "xxx", "fileId": "xxx", "silkSize": 45678 } ``` **优势**: - 培训包体积减小 60MB(去除 ffmpeg/wx-voice) - 客户端无需处理音频编码 - 后端统一质量控制 - 更易于调试和监控 --- **文档版本**:v1.0 **更新时间**:2026-08-20 **维护者**:Fmode 团队