跳转至

SOP-001:小樱桃语音交互体系

语音设备日常运维 · VAD 参数 · 音量增益 · PowerMem · 角色设定 · 故障排查

服务器拓扑

┌─────────────┐     WebSocket      ┌──────────────────┐
│   ESP32     │ ─────────────────→ │  xiaozhi-esp32-  │
│   (音箱)    │    ws://:18000     │  server (docker)  │
└─────────────┘                    └────────┬─────────┘
                                     ┌──────┴──────┐
                                     │  open-xiaoai │
                                     │  -xiaozhi    │
                                     │  桥接器      │
                                     └──────┬──────┘
                                     ┌──────┴──────┐
                                     │  智谱 API    │
                                     │  glm-4.5-air │
                                     └─────────────┘

关键地址: - 服务器 IP:192.168.31.27 - WebSocket 端口:18000 - HTTP 端口:18003 - 容器名:xiaozhi-esp32-server

参数表

VAD(语音活动检测)

参数 server bridge 说明
threshold 0.30 0.10 进入说话的门槛
threshold_low 0.20 0.01 退出说话的门槛(保持 hysteresis 差距)
min_speech_duration 250ms 最短语音触发时长
min_silence 1200ms 1200ms 静默多久算完(两端统一)
boost 10(代码未读取,无效参数 配置中 +10,但 bridge 代码无任何引用
frame_window_threshold 3 连续几帧达到 threshold 才算开始说话(防误触)

VAD 双阈值(hysteresis):threshold > threshold_low,防止在边界处反复触发/关闭。 桥接器 VAD 默认值见 /app/.venv/.../silero_vad/__init__.py,配置覆盖见 /app/config.py。 服务器 VAD 默认值见 silero.py:27(threshold=0.5, threshold_low=0.2, min_silence=1000),.config.yaml 覆盖为当前运行值。 ⚠️ server 修改方式:改 .config.yamldocker restart xiaozhi-esp32-server ⚠️ bridge 修改方式:改 config.pydocker restart open-xiaoai-xiaozhi

唤醒与超时

参数 bridge server 说明
唤醒前动作 "嗯!" + 0.5s 缓冲 bridge before_wakeup,KWS 唤醒时播放缓冲
小爱拦截 abort_xiaoai + sleep 2.0s 小爱正在说话时拦截并等待
唤醒后动作 "小小苏,拜拜" bridge after_wakeup,退出时播报
唤醒词 你好小樱桃/小樱桃你好/呼叫小樱桃/召唤小樱桃 支持 4 个变体
唤醒超时 20s 超过此时间未说话自动退出
WS 超时 120s(close_connection_no_voice_time 无语音多久断连
TTS 超时 15s(tts_timeout TTS 生成超时上限

音量

# 位置 增益 实现方式
1 桥接器 codec.py:100 audioop.mul(pcm_data, 2, 1.5) 约 +3.5dB PCM 采样值相乘
2 桥接器 config.py boost: 10 无效参数(代码未读取此字段)
3 服务器 util.py(init_and_run 补丁) audio + 6 = +6dB PCM 采样值相加
4 服务器 .config.yaml gain: 3 CosyVoice2 API 增益参数

#1、#3、#4 是同一组,一起调小樱桃和小爱的音量一致性。

2(boost)是无效参数,代码未读取,修改无任何效果。

模型配置

参数
LLM (主) glm-4.5-air via 智谱 open.bigmodel.cn
LLM (备用) deepseek-chat via api.deepseek.com(max_tokens=500, temperature=0.7)
Embedding embedding-3 via 智谱 open.bigmodel.cn(2048 维)
TTS CosyVoice2-0.5B:anna via 硅基流动 siliconflow(gain=3, response=wav)
ASR FunASR SenseVoiceSmall(容器内本地,模型 data/models/SenseVoiceSmall
PowerMem selected_module=powermem(启用量化记忆,向量库=sqlite)

角色设定(小樱桃)

  • 身份: 苏子桐的 AI 小伙伴(不是助手、不是老师)
  • 年龄定位: 永远比苏子桐大 2 岁(她 6 岁我 8 岁,她 10 岁我 12 岁)
  • 关系: 朋友/玩伴,不是管教者
  • 语气: 童真、好奇、偶尔调皮
  • 原则: 引导表达 > 直接给答案。不主动说教
  • 知识边界: 通过 PowerMem 知道苏子桐的经历,但不假装全知

prompt 四段结构:模板规则 + few-shot + 动态上下文(时间/记忆) + 聊天历史

用户画像 — 双层注入

总体结构

每次对话时,系统向 LLM 注入两层用户画像:

<memory>
  <stable_profile>         ← 你维护的权威事实
    [按话题匹配注入]
  </stable_profile>

  <dynamic_profile>        ← PowerMem 自动学习
    [AI 从对话中提取的印象]
  </dynamic_profile>

  优先级:stable 高于 dynamic,冲突时以 stable 为准
</memory>

稳定层(你维护)

  • 来源: stable_profile.txt(位于服务器数据目录)
  • 格式: 6 个 <topic> 话题块 + _default 兜底块
  • 基本信息(年龄、身高、体重)
  • 学习(RAZ、英语、游泳)
  • 生活作息(睡眠时间)
  • 兴趣爱好(动画角色)
  • 社交(家人、手表、微信)
  • _default(简短概要,话题不命中时兜底)
  • 匹配方式: 用户消息关键词 → 命中对应话题块
  • 聊 RAZ → 只注入"学习"块,省 token
  • 聊叶罗丽 → 只注入"兴趣爱好"块
  • 都不命中 → 仅注入 _default
  • 更新方式: 直接覆盖文件,下一句话立即生效(无需重启容器)
  • 备份: 同目录 stable_profile.txt.bak
  • 路径: /opt/xiaozhi-esp32-server/data/stable_profile.txt
  • 权限: 同目录其他配置文件一致

动态层(AI 自动)

  • 机制: 对话完成后 save_memory() 分成三步:
  • [PATCH7] 去重(MD5)→ 过滤无意义词(拜拜/再见等)→ 写入 memories 表(payload 存原始对话,vector 列存 1536 维嵌入向量)
  • [中修] 从最近 5 条记忆拼成 profile → 更新 user_profiles 表 → 清除 last_profile_content 缓存,下次对话重新读取
  • [深修] 嵌入前清洗文本(去"苏子桐说:"/"小樱桃回答:"前缀 + 去表情符号),只对事实核心调用智谱 embedding-3 API 生成向量
  • 数据源: 智谱 embedding-3 + https://open.bigmodel.cn/api/paas/v4/
  • 配置路径: 容器内 /opt/xiaozhi-esp32-server/data/.config.yamlMemory.powermem.embedder.config
  • 冲突时: stable_profile 优先

持久化说明

修改桥接器参数 → 直接改 /app/config.py + 重启容器

/app/config.py           ← 桥接器参数(VAD/唤醒词),bind mount 挂载
/app/xiaozhi/services/audio/codec.py   ← 音量增益 audioop.mul,直接改

服务器端:

/opt/xiaozhi-esp32-server/data/.config.yaml       ← 服务器参数
/opt/xiaozhi-esp32-server/data/init_and_run.py    ← 启动补丁(音量增益 + 模糊匹配 + 记忆保存)
/opt/xiaozhi-esp32-server/core/utils/util.py       ← 音量增益(init_and_run 启动时打补丁)
/opt/xiaozhi-esp32-server/core/connection.py       ← 模糊匹配 + 记忆保存(init_and_run 启动时打补丁)

故障排查

症状 可能原因 检查
没声音 VAD 门槛太高 / 音量太低 检查 threshold 和 gain
破音 总增益过高 总增益 ≥ +18dB 时有削顶风险
回答太长被截断 VAD min_silence 太长 检查 server 和 bridge 的 min_silence
反复触发/频繁打断 threshold == threshold_low hysteresis 双阈值需保持差距
沉默不答 TTS 超时 / ASR 超时 检查日志中的 timeout
答非所问/说胡话 PowerMem 污染 / model 不可用 检查 LLM 响应 + API key
名字念错/叫不对 ASR 听歪 + 模糊匹配没兜住 缺的角色名加到 hotwords.txt(122条)

ASR 热词与模糊匹配

Hotwords + 拼音模糊匹配,两层兜底。

第一层:后处理模糊匹配(connection.py _fuzzy_correct_names)

ASR 完成后、LLM 处理前,接管文本做角色名修正:

策略 匹配条件 示例
精确匹配 seg == hw 海绵宝宝 → ✅
编辑距离 ≤ 1 2字名首字必须相同(防误匹配) 赛咯赛罗 ✅ / 和迪巴迪
拼音完全相同 编辑距离 ≥ 2 但拼音去声调后一致 赛箩赛罗 ✅(同音) / 紫曰紫悦

拼音匹配的额外收益: 多音字、口齿不清、同音别字全部覆盖。 防误匹配:2字名编辑距离=1时首字不同不匹配(防 和迪→巴迪)。

数据源:hotwords.txt

  • 路径:/opt/xiaozhi-esp32-server/data/hotwords.txt
  • 当前:122 个名字(奥特曼/小马宝莉/叶罗丽/迪士尼等角色)
  • 特点:文件式动态加载,无需重启容器,改完即生效
  • 更新方式:直接编辑文件或告诉我加角色名

文件位置

文件 用途 持久化方式
connection.py 实时代码(_fuzzy_correct_names init_and_run.py 启动补丁
init_and_run.py 容器重启后补丁代码 挂载在容器内
hotwords.txt 角色名列表(122条) bind mount 挂载

变更日志

铁律:改参数必更新

任何涉及小樱桃代码、配置、参数的变更,必须同步更新本 SOP 对应章节。 不改 SOP-001 视为变更未完成。

检查清单: - [ ] VAD 参数变了? → 更新参数表 - [ ] 音量增益变了? → 更新参数表 - [ ] 模型/API变了? → 更新模型配置 - [ ] 角色设定变了? → 更新角色设定 - [ ] 排查流程新增了? → 更新故障排查 - [ ] 版本日志追加了一笔

日期 版本 变更
2026-07-06 v1 初版,基线参数固化
2026-07-08 v2 新增 ASR 热词拼音模糊匹配章节
2026-07-08 v3 修正音量参数(1~4# 分组)、VAD 值对齐实际运行值、更新 TTS/CosyVoice2 模型配置、更新持久化文件路径
2026-07-08 v4 桥接器 VAD 初调:threshold 0.10→0.20,threshold_low 新增0.15,min_speech 250→300ms
2026-07-08 v5 稳定状态:VAD 全部还原(0.10/0.01/250ms),仅留 min_silence=1000ms;唤醒改用"嗯!"+0.5s缓冲;TTS key 修正(硅基流动);prompt 讲故事不中断;SOP 记录 VAD 参数和唤醒流程
2026-07-09 v6 用户画像重构:双层注入(stable_profile.txt + PowerMem),年龄定位修正为"永远比苏子桐大2岁",反哺机制从向量切片改为文件直接注入
2026-07-10 v8 PowerMem 三层加固:①PATCH7(去重+过滤无意义词+直写 SQLite)②中修(对话后刷新 user_profiles 表)③深修(修正 embedder 配置字段名 + 清洗嵌入文本去前缀表情 + 真实 1536 维向量写入)。语义搜索从空向量升级为智谱 embedding-3 全链路。

相关文档

方向 链接
🔗 输入 SOP-004 融合画像更新(反哺来源) · SOP-003 雷达扫描与推送(日志归档)
🔗 输出 最新画像(反哺目标)
📝 变更 版本日志