Files
note_sync/有趣的项目/AI桌面陪伴助手/AI桌面陪伴助手方案.md
T
ylhan bdd6bfb63d AI桌面陪伴助手:方案更新至 v2.4,代码剥离到独立仓库
代码剥离
- 助手本体、TTS 服务、P0 基准脚本、ESP32 固件移到 ~/workspace/ai-companion
  (独立 git 仓库),本目录只留方案、P0 报告与硬件记录
- 因此删除 esp32_smile_test.ino / esp32_touch_eyes.ino
- 同时移除已失效的 .gitignore(原本只为挡住模型体积,代码已搬走)

方案 v2.4 重大变更:架构从"单机"改为"服务器即助手、本地为客户端"
- 起因:实测 N5095 无 AVX2,跑不动可用的语音模型
- N5095 降为客户端/外设桥,只做 USB 接入、DoA、WebRTC 客户端
- 实施阶段表加进度列(P0/P1/P3/P4a 部分完成),新增三条验收要求
- 采购清单按实际到货更新,标出屏幕形态待确认(2.8寸 vs 原定1.28寸圆屏)

技术栈(实测更新)
- LLM:DeepSeek deepseek-flash(云端,必须关思考);本机 27B 已停用
- TTS:Qwen3-TTS 1.7B(服务器 3090);vits-zh-ll 因音色不满意被替换
- STT:Zipformer int8 未变,中文识别率仍是未闭合项

新增两份 P0 报告
- P0-Qwen3TTS报告.md:TTS 换型过程与实测
- P0-DeepSeek验证报告.md:四条路径验证

两份旧报告加了状态说明(结论仍有效但选型已变),
并修正了随代码移走而失效的引用与复现命令。
2026-09-15 11:08:56 +08:00

312 lines
30 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# AI 桌面陪伴助手 · 实施规划 v2.4
> 📁 **代码已与本文档分离**(2026-09-15)。本目录(Obsidian 笔记库)只保留
> 方案、P0 报告和硬件记录;所有代码在 **`~/workspace/ai-companion/`**
> (独立 git 仓库),包括:助手本体、TTS 服务、P0 基准脚本、ESP32 固件、
> `README.md`(代码说明)、`部署说明.md`(运维)——这两份也在代码仓库。
>
> 更新:2026-09-15。状态:**助手本体已在服务器上实现并跑通**(端到端测试 16/16);设备侧(N5095 外设桥、ESP32)尚未开始。
> 已确认:Ubuntu 24.04;N5095 / 16G 作为**客户端**;助手本体部署在 cadadmin-server(i9-14900K / 3090);麦克风、音箱、摄像头均未购;屏幕已于 09-14 到货并点亮(2.8 寸 ILI9341 触摸屏,非原定的 1.28 寸圆屏)。
> 核心目标:听得清、回应及时、可打断、表情明确、转头自然。
> 最新外形要求:屏幕不用太大;摄像头水平可用旋转总行程至少180°,按正前方左右各90°理解,不是镜头视场角180°。
> 原方案备份:AI桌面陪伴助手方案.v1备份.md。本版指标为拟定目标,不是已测性能。
>
> **本版重大变更:架构从"单机"改为"服务器即助手、本地为客户端"。**
> 起因是实测发现 N5095(无 AVX2)跑不动可用的语音模型——详见
> `P0-语音基准报告.md`。变更后 N5095 只做 USB 外设接入与网络桥接。
> 详细部署现状见代码仓库里的 `部署说明.md`,实测数据见本目录的四份 P0 报告。
## 1. 范围与待讨论事项
第一版做好中文语音、屏幕表情、按用户隔离的记忆;同一轮开发加入多人脸跟踪、轮流交互和显式身份切换。录入式人脸识别作为可关闭的试验功能,实测达标后用于身份建议;重叠说话分离、可靠声纹认人不作为首版要求。视觉问答和米家后续加入。
| 项目 | 状态/建议 | 影响 |
|---|---|---|
| **主机分工** | **服务器(cadadmin-server)跑助手本体;N5095 降为客户端/外设桥** | **v2.4 重大变更,见 §2** |
| 服务器 | i9-14900K / 32线程 / 188G / RTX 3090 24G,局域网延迟 1–2ms | 与 N5095 同局域网,1ms 级 |
| N5095 角色 | USB 麦克风阵列、USB 摄像头、DoA 读取、WebRTC 客户端、串口给 ESP32 | 不跑任何推理 |
| 使用人数 | 本人使用为主,同时考虑多人扩展 | 首版基础多人,身份与会话从一开始分离 |
| 新增预算 | 服务器为复用已有机器,不算追加采购 | 音频优先,其次屏幕,再机械 |
| 操作系统、现有外设 | Ubuntu 24.04 已确认;麦克风、音箱、摄像头都没有;屏幕已到货 | 需采购音频与摄像头 |
| 使用距离 | 待确认;暂以桌面约0.5~2米作为测试设计假设 | 不能当作已确认需求或性能保证 |
| 屏幕 | **已到货:2.8 寸 ILI9341 触摸屏**(与原定 1.28 寸圆屏不符,待确认最终形态) | 见 `ESP32-S3与2.8寸SPI触摸屏接线记录.md` |
| 摄像头旋转 | 水平可用总行程至少180°,正前方左右各90° | 优先屏幕与摄像头共用一轴头部,麦克风固定底座 |
| **LLM** | **DeepSeek `deepseek-flash`(云端,关思考)**;本机 Qwen3.8-27B 已停用 | 首 token 0.8–1.2s;月费来自 LLM 与按需视觉 |
| **TTS** | **Qwen3-TTS 1.7B(服务器 3090)**,Serena 音色 + 轻快活泼指令 | RTF 0.55–0.94;首音延迟的主要来源 |
| **STT** | Zipformer 中英双语 int8(CPU)——**仍是 2023 年模型,中文识别率未测** | v2.4 未替换,遗留项 |
| 米家设备 | 到扩展阶段收集型号、地区、网关/HA情况 | 集成与采购选择 |
| 结构 | 屏幕/摄像头到货后称重,确认加工条件 | 电机、支架、电源 |
## 2. 总体架构
```text
┌─ cadadmin-server(192.168.0.20)—— 助手本体 ────────────────┐
│ 会话引擎(身份 → 记忆 → LLM → TTS) │
│ ├─ LLM:DeepSeek deepseek-flash(云端,关思考) │
│ ├─ TTS:Qwen3-TTS 1.7B(RTX 3090,独立 HTTP 服务 :18040) │
│ ├─ STT:Zipformer 中英宽带 int8(CPU 4 线程) │
│ ├─ 记忆:SQLite(按 owner_user_id 强制隔离) │
│ └─ 身份:手动切换 + 访客兜底 │
└────────────────────────────────────────────────────────────┘
▲ WebRTC(计划) ▲ 手机/浏览器客户端
│ 局域网 1–2ms │
┌─ N5095 / 16G —— 客户端 / 外设桥 ───────────────────────────┐
│ USB 麦克风阵列(固定底座)──处理后音频、DoA──┐ │
│ USB 摄像头(随头部转动)──本地图像───────────┤ │
│ ├─ DoA 读取(本地,**不过网**——转头回路延迟敏感) │
│ ├─ 本地人脸检测 / 目标锁定 → 角度控制(不依赖LLM响应) │
│ ├─ 插话检测、音频编解码、WebRTC 客户端 │
│ └─ USB 串口 115200 → ESP32 │
└────────────────────────────────────────────────────────────┘
│
▼
ESP32-S3:本地表情、运动轨迹、限位、心跳超时处理
├─ SPI → 2.8寸 ILI9341 触摸屏(已到货)
└─ 控制信号 → 一轴执行器(独立合适供电支路)
```
- **分工原则:延迟敏感且硬件绑定的留在本地**(音频进出、唤醒、VAD、
插话检测、DoA、表情/动作),**算力密集的放服务器**(STT、TTS、LLM 调用、记忆)。
- Pipecat作为唯一会话管线框架。服务器侧用 WebRTC 传输(SmallWebRTC),
**WebRTC 自带 AEC、抖动缓冲、丢包恢复**——这解决了方案 P2 要求的 AEC 难题,
原本需要自行实现。[传输选型](https://docs.pipecat.ai/client/concepts/choosing-a-transport)
- 不叠加Vision Agents:它是Stream的独立框架,不是Pipecat官方扩展。人脸检测另选轻量本地模型。[项目官方仓库](https://github.com/GetStream/vision-agents)
- STT/TTS采用可替换适配器(本地/远端两种后端已实现)。LLM 为 DeepSeek
`deepseek-flash`;这是可更新别名,实施时记录实际版本并做流式/工具调用验证。
**实测必须显式关闭思考模式**,否则多轮与工具回灌一律 400。
[官方公告](https://deepseek.com/news/deepseek-v4-1-flash/) · 详见 `P0-DeepSeek验证报告.md`
- **视觉跟随在客户端做**(N5095 本地),先试640×480、5~10fps,
按CPU、温度和延迟调整,未承诺该帧率已可达到。视觉问答按请求抓拍和缩放上传,
不持续发送视频。
- CPU标称TDP不能当整机常开功耗;实际插座功率、风扇噪声、温度在原型阶段测量。
- **降级策略**:服务器或网络失效时,本地按键、静音和屏幕继续工作;
建议保留一个极小的本地 TTS 兜底(piper-x_low 仅 20MB、RTF 0.17),
用于播报"网络断了"——这是设备失联时唯一能出声的东西。
### 视频采集与框架边界
- Ubuntu由单一CameraService通过OpenCV/V4L2打开摄像头,维护带单调时间戳的最新帧;检测、身份候选和视觉问答共享采集源,不分别抢占设备。
- 本地检测以低分辨率/限帧消费最新画面,积压时丢旧帧;按需问答读取足够清晰的新帧并缩放编码。必要时从较高分辨率采集再降采样,实际USB带宽和解码负载需测试。
- Pipecat通过自定义适配器接入图像帧/取图工具。模型支持图像不等于当前Pipecat适配器已支持该模型的图像格式;P0补测纯文本流式、图片输入、工具调用、取消/超时四条路径。图像不通过时先修适配,不因此更换整套框架。[Pipecat DeepSeek服务](https://docs.pipecat.ai/api-reference/server/services/llm/deepseek)
- 图像请求带request_id、拍摄时间和会话轮次,过期帧拒绝使用,图片不无限留在对话历史中。摄像头拔出后禁用视觉,语音保持可用。
- 音频回调只做轻量读写;识别、合成和视觉推理在受控工作线程/进程执行,不能阻塞会话事件循环。各队列有限长,TTS限制预生成量。
## 3. 实施阶段与验收
阶段通过后再扩大范围,不预先给出未经验证的固定工期。
**进度列说明**:✅ 完成 · 🔶 部分完成 · ⬜ 未开始
| 阶段 | 实施内容 | 拟定完成标准 | 进度 |
|---|---|---|---|
| P0 环境与服务 | 盘点Ubuntu版本/USB;固定依赖;本地STT/TTS基准及DeepSeek请求 | 样例音频/文本先测试;设备到货后10次录放测试;记录RTF、首音延迟、CPU和内存 | 🔶 **环境盘点、STT/TTS/LLM 基准、DeepSeek 四条路径均已实测**;缺 10 次录放(无音频硬件)。**STT 中文识别率仍是未闭合项** |
| P1 基础语音 | 按键启动;流式回复;停止按钮;超时提示 | 20轮固定中文用例至少18轮完成;短问答结束到首段有声回复,目标P50≤2秒、P95≤4秒 | 🔶 **链路已跑通**(文本/音频 → STT → 记忆 → LLM → TTS → 音频,16/16 通过);缺实时音频进出、按键、20 轮用例。首音实测约 1.5s,加 VAD 后 **2.0–2.2s,卡在目标线** |
| P2 外放与表情 | AEC、打断、唤醒;听/想/说/离线/静音表情 | 指定距离音量下20次打断至少18次成功;检测到有效用户语音至停播目标≤300ms;30分钟外放无自我触发;运行2小时稳定 | ⬜ 未开始。**AEC 计划由 WebRTC 提供**(不自行实现) |
| P3 多用户记忆 | 用户档案、显式切换、偏好/摘要/修改/遗忘 | 两个用户同一问题得到各自偏好;未知用户无私人记忆;重启保留、更正/删除有效 | 🔶 数据层已实现并测试(身份隔离、越权删除、级联清理、候选不参与检索共 28 项);缺"修改/遗忘"的用户入口 |
| P4 一轴转头 | 静态DoA/人脸验证,再接电机;锁定和限位 | 左/中/右各10次唤醒至少27次转向正确区域;轻微移动不频繁摆动;断联/重启不撞限位;运动时重复P2测试 | ⬜ 未开始,待摄像头与电机 |
| P4a 基础多人/身份试验 | 2~3张脸跟踪;轮流发言;可选录入式人脸识别 | 20次轮流唤醒至少18次选中正确目标;同方向/交叉/遮挡时允许拒判;未知人、身份切换不得串记忆 | 🔶 `IdentityProvider` 接口与手动切换已实现(人脸候选**不自动切换**已测试);缺人脸检测 |
| P5 扩展 | 按需视觉问答;HA接一盏灯 | 检查10次视觉请求;开关灯、离线、超时均反馈真实结果 | 🔶 工具调用链路已验证(DeepSeek 与本机 vLLM 均通过);缺米家与视觉 |
验收记录距离、背景声音、播放音量、网络、模型版本、样本数。目标用于定位瓶颈,不保证所有环境都达到。耳麦通过不能代替远场外放验收。
**v2.4 新增的验收项**:
- **首音延迟必须按部署机(服务器)测**,不能沿用开发机的数字。
同一份代码在 N5095 上首音 1980ms,在服务器上 179ms(vits 时代)。
- **TTS 与 STT 的线程配置分别测**。实测两者线程扩展方向相反:
STT 超过 2 线程急剧退化(N5095 无 AVX2,4 线程慢 3.9 倍),
TTS 是线程越多越快。不能沿用一套配置。
- **换语音模型时必须重测首音延迟**。Qwen3-TTS 比 vits-zh-ll 音质好一个档次,
但首音从 179ms 涨到 1545ms(8.6 倍)。音质与延迟在这个硬件上是此消彼长的。
P2的30分钟/2小时测试仅是初步门槛,不能证明长期稳定。阶段通过后做一次正常音量下至少8小时运行:记录误唤醒次数、内存增长、音频欠载、重连及温度。P4a把“转对人”和“认对身份”分开统计,额外报告误认、拒判、切换次数,不用总成功率掩盖串身份。测试人数不足时,多用户记忆可用模拟身份测试,人脸/发言者匹配则明确标记未实测。
## 4. 分批采购清单
> **v2.4 更新(2026-09-15)**:ESP32-S3 开发板与屏幕**已于 09-14 到货并点亮**,
> 但屏幕是 **2.8 寸 ILI9341 触摸屏(240×320)**,与原定的 1.28 寸 GC9A01 圆屏不符。
> 接线与测试程序见 `ESP32-S3与2.8寸SPI触摸屏接线记录.md`。
> **最终屏幕形态待确认**——这会影响外壳与转台结构设计,越早定越省返工。
> 下列清单已按现状调整。
本表未报价:用户预算尚未确定,具体SKU和商家现价需核价。**当前实际还缺的只有音频(麦克风阵列+音箱)和摄像头。**
### 第一批:已基本到位
| 物品 | 数量 | 状态 |
|---|---:|---|
| ESP32-S3开发板 | 1 | ✅ 已有 N16R8(带 PSRAM) |
| 屏幕 | 1 | ✅ 已有 2.8 寸 ILI9341 触摸屏(**非原定 1.28 寸圆屏**) |
| USB数据线 | 按缺口 | 按缺口补 |
| 杜邦线/面包板/绝缘固定件 | 1套 | 按缺口补;只用于逻辑低电流,不走电机大电流 |
| 瞬时按键 | 2 | 待购;会话停止、软件静音,不宣称物理断麦 |
若最终决定用 1.28 寸圆屏形态,仍需单独采购 GC9A01 模块;若接受 2.8 寸方屏,则本批已完成。
两种形态的表情素材、外壳和结构设计都不同,**先定形态再动结构**。
### 同期优先核价:音频套件
| 物品 | 数量 | 优先候选/要求 | 下单条件 |
|---|---:|---|---|
| USB麦克风阵列 | 1 | Seeed reSpeaker XVF3800 USB 4-Mic Array成品板 | 核对具体SKU、USB固件、目标系统、DoA例程、录放音通道、输出与附件;报价合适再买 |
| 有源小音箱 | 1套 | 需新购;3.5mm模拟输入,体积小,合适独立供电 | 与阵列输出匹配;初期不选只能走USB音频/蓝牙的音箱 |
| 音频线 | 按缺口 | 匹配两端的3.5mm音频线 | 查套装是否自带 |
阵列官方资料列出USB音频、DoA主机控制、可接耳机/有源音箱的AUX输出。采购成品板,不能仅凭XMOS芯片名替代。[Seeed官方文档](https://wiki.seeedstudio.com/respeaker_xvf3800_introduction/)
拟定路径:N5095的TTS → 阵列USB播放端点 → AUX → 有源音箱。AEC需要实际播放参考;同一板卡也要验证固件/通道配置,不能假定接上即成功。[XMOS官方指南](https://www.xmos.com/documentation/XM-014888-PC/pdf/xvf3800_user_guide_v3.2.1.pdf)
不为了阵列额外购买XIAO ESP32S3,主机直接接USB即可。最终内置喇叭/功放留到结构阶段,按接口、电压、阻抗和功率匹配。
### 第二批:摄像头
- 需新购普通USB UVC单目摄像头1个,支持1080p及低分辨率模式。为早测多人/身份,可与第一批一起买;无需增加第二台摄像头。
- 优先小巧轻便、可固定、柔软线缆、有视场角资料的型号;近距离物品问答需核对最近对焦距离。
- 摄像头随头部水平旋转,可用总行程至少180°(左右各90°)。这是机械旋转范围,不要求购买180°鱼眼镜头。单摄像头只覆盖当前朝向的视野,转动可依次查看不同方向,不能同时看全180°范围。
- 首版多人按当前视野内、轮流发言验证。镜头选型兼顾多人覆盖与脸部像素,过广视角会让远处脸变小。
- 不需要双目/深度相机和ESP32-CAM。摄像头不影响P0~P3先行。
### 第三批:机械结构确定后购买
| 物品 | 为什么暂缓 | 解锁条件 |
|---|---|---|
| 舵机/步进 | 已要求可用行程≥180°,重量/重心/噪声未知,暂不锁MG996R/DS3218 | 称重后选型;额定/机械行程要有软限位余量,实测可用行程≥180° |
| 电机电源/降压 | 电压及启动/堵转电流依赖电机 | 数据表确认,峰值留余量 |
| 转台/轴承/支架/外壳 | 安装孔、重心、线缆弯曲需配合 | 原型尺寸确定 |
| 步进驱动、回零开关、编码器 | 取决于执行器及是否需要实测位置 | 电机方案确定 |
| USB Hub | 主机可能已有足够接口 | P0盘点确认不足 |
| 米家网关/新设备 | 兼容性依型号地区而异 | 现有设备验证后再定 |
当前不采购:新主机、GPU、双目相机、HC-05蓝牙、第二块视觉MCU、电池系统。
## 5. 音频与陪伴行为
### 语音方案(v2.4 已实测定稿)
STT是语音转文字,TTS是文字转语音。**v2.4 起语音推理全部在服务器**,
N5095 只做音频进出——实测证明 N5095 跑不动可用的语音模型,见 `P0-语音基准报告.md`。
| 模块 | 采用方案 | 实测 | 备选与限制 |
|---|---|---|---|
| VAD | 本地轻量VAD | — | 单独处理唤醒和说完判断 |
| 唤醒 | sherpa-onnx中文关键词检测作为候选 | — | 单独模型/词表,用户确定称呼后调阈值;普通STT不会自动等于唤醒引擎 |
| STT | **Zipformer 中英双语 int8**(服务器 CPU 4线程) | RTF 0.03 | **仍是 2023 年模型,中文识别率从未测过**(无参考文本)。候选:SenseVoice / faster-whisper large-v3,已下载未测 |
| TTS | **Qwen3-TTS 1.7B-CustomVoice**(服务器 3090,独立 HTTP 服务) | RTF 0.55–0.94 | 音色 Serena + 指令"用轻快活泼的语气说"(用户试听选定)。备选:vits-zh-ll(RTF 0.09 但音色不满意)、CosyVoice 2/3(未测) |
| LLM | **DeepSeek `deepseek-flash`**(云端,关思考) | 首 token 0.8–1.2s | 本机 Qwen3.8-27B 的 vLLM 已停用——GPU 让给 TTS。可改 `AI_LLM_PRIMARY=local` 切回,但切回后 GPU 不够跑 Qwen3-TTS |
[sherpa-onnx官方功能](https://k2-fsa.github.io/sherpa/intro.html)、[SenseVoice模型说明](https://k2-fsa.github.io/sherpa/onnx/sense-voice/pretrained.html)、[中文VITS模型](https://k2-fsa.github.io/sherpa/onnx/tts/pretrained_models/vits.html)。以上说明模型/运行时支持,不构成性能保证。
**音质与延迟的取舍(v2.4 的核心权衡)**:同一台服务器上
| 配置 | 首音延迟 | 音质 |
|---|---|---|
| 本地 Qwen3.8-27B + vits-zh-ll | **179 ms** | 用户不满意 |
| DeepSeek + Qwen3-TTS | **1545 ms** | 用户试听选定 |
用约 1.4 秒的首音延迟换音质。这个取舍是可逆的(改配置即可),
但**在 24GB 显存下两者不可兼得**。后续若装成 flash-attn 或实现真流式,
延迟可望收回一部分——详见 `P0-Qwen3TTS报告.md`。
P0测试10~20条不同长度中文,覆盖数字、日期、中英混读。记录STT识别错误、语音结束后等待时间、TTS首段耗时和RTF(生成/处理耗时除以音频时长,低于1表示平均快于实时)。音频与视觉并发时重测,限制推理线程和视觉帧率,避免CPU争抢。
**v2.4 补充:STT 与 TTS 的线程配置必须分别调**——实测两者线程扩展方向相反。
P0测试10~20条不同长度中文,覆盖数字、日期、中英混读。记录STT识别错误、语音结束后等待时间、TTS首段耗时和RTF(生成/处理耗时除以音频时长,低于1表示平均快于实时)。音频与视觉并发时重测,限制推理线程和视觉帧率,避免CPU争抢。
TTS按语义短句合成并播放,不把整段一次合成称为原生流式;分句仍要测首音等待、接句停顿及取消响应。本地效果不达标时先调整模型/线程/分句,再讨论是否开启云端后备,不自动发送音频到第三方。
- 本地唤醒引擎保持工作;闲置时暂停完整识别、降低视觉频率。保留短时内存音频预卷(初始0.5~1秒)避免唤醒后吞掉指令开头,静音时清除缓冲。[关键词检测官方文档](https://k2-fsa.github.io/sherpa/onnx/kws/index.html)
- 活跃会话内允许免唤醒接续,初始闲置超时20秒后回到待机,参数可调。多人时其他人的普通谈话不应自动抢占;以唤醒/显式切换为主要入口。
- 记录阵列实际采样率、通道和采样格式,STT/TTS边界显式重采样;避免把原始麦克风/回放参考通道当成处理后语音。Ubuntu固定设备标识和录放音路由,不依赖重启后会变化的默认声卡序号。
- DeepSeek输出区分最终回答、思考内容、工具调用与工具结果,只将面向用户的回答交给TTS;数字/日期/单位和Markdown做轻量朗读归一化。
- P1按键启动,P2再加唤醒。语音活动检测、说完判断、唤醒是不同环节。
- 打断时取消旧回复生成、TTS和待播缓冲,丢弃旧轮次迟到结果,不能暂停后继续放旧回复。
- 分别测安静、设备外放、背景音乐、风扇噪声;P4加入运动噪声,装壳后重测。
- 默认简短自然回复;等待时及时更新表情,长回复按语义分段播放。
- 明确待机、在听、思考、说话、静音、离线状态。专注/夜间默认不主动开口,主动问候后续再加。
- 网络失败给简短提示,本地按键、静音和屏幕继续工作,不反复播旧回复。
- 麦克风、音箱、电机尽量机械隔离;软件静音和真实物理断麦需明确区分。
## 6. 朝向与机械
DoA是声源来向,不代表身份或距离。阵列固定底座,摄像头随头部转动。
状态:待机 → 有效唤醒 → 可靠DoA粗转 → 匹配人脸 → 锁定 → 丢失短暂保持 → 超时待机。多人先按轮流发言处理;同方向多人或重叠说话时保持目标/请求轮流,不凭DoA猜身份。
### 多人能力与避免返工
- 基础多人:同画面维护多个临时track_id,记录位置和最后出现时间;用带时间戳的DoA与人脸位置关联当前发言目标,设置切换滞后。走位/遮挡后track_id可能变化,不能充当永久身份。
- 读取DoA时核对固件、波束选择和单位。XVF3800可返回多个波束角度,它们不是“几个人的身份/独立语音”;不要直接把第一个角度当发言者。优先用与当前处理后音频对应的选中波束,查不到可靠对应时允许拒判。[官方主机控制代码](https://github.com/respeaker/reSpeaker_XVF3800_USB_4MIC_ARRAY/blob/master/python_control/xvf_host.py)
- 首版可靠身份入口:手动/对话确认切换到已建档的user_id;无法确认时使用unknown/guest。看到熟人不等于确认他正在说话。
- 显式报名字用于个性化档案选择,不是身份认证,不能据此解锁敏感信息或权限。信任等级与user_id分开,未来增加认证时不改普通偏好存储。
- 可选人脸试验:OpenCV YuNet检测+SFace特征作为候选,需用户主动录入、相似度阈值和未知人拒判。低频识别,平时跟踪;不用于门锁/支付或敏感身份认证。[OpenCV官方教程](https://docs.opencv.org/5.0/tutorials/dnn/dnn_face/dnn_face.html)
- 注册特征本地保存,可查看和删除;识别不确定时不读取/写入私人记忆。群体会话默认仅共享明确公开的上下文,不主动播报私密记录。
- 预留IdentityProvider接口:输入时间戳、track_id、候选身份、置信度与来源;输出确认的user_id或unknown。后续声纹模块可接入此接口,不改记忆表结构。
- 声纹认人、声音与人脸可靠绑定、重叠语音分离属于更高难度阶段,不承诺通过增加一块阵列即可解决。第一版不做全场多人同时自由插话。
- 调试候选:3~5°死区、丢失保持1~2秒;速度/加速度实机调节。
- 坐标约定:从设备视角向右为正。标定阵列零点、摄像头中心、电机零点;统一DoA单位和方向。
- 人脸像素位置经相机内参/标定换算成相对角度,再加头部角度估计,不能把像素直接当绝对角度。
- 普通位置舵机先做平滑目标角度,不默认再加内环PID;无反馈时只有估计位置。
- 摄像头与麦克风有位置偏移,近距离DoA和画面方位不完全重合;先粗转,再以视觉纠偏。运动过程中按时间戳使用对应角度估计,避免拿旧图配新角度。无反馈舵机的首版身份匹配优先在稳定停转后进行。
- 步进需独立驱动器、明确STEP/DIR等接口,补回零/失步/软限位。
- 只做左右一轴,用户要求摄像头可用总行程至少180°;初始工作范围设为[-90°, +90°],屏幕与摄像头共用转动头部,麦克风固定底座。不要求连续360°旋转。
- 执行器实际机械行程须大于工作范围,以留软/硬限位余量;采购候选可考察标称270°的位置舵机,但型号、真实行程及噪声仍待核对。不能把普通标称180°舵机两端硬顶当作已满足要求,也不选无角度定位反馈的连续旋转舵机来直接代替位置舵机。
- 转轴/轴承承担结构负载;USB摄像头线、屏幕/MCU线缆在左右端点均要有弯曲余量,避免拉扯插头。有限180°往返先用柔软线缆和固定应力释放,不把滑环列为必需采购件。
- P4增加行程验收:实测摄像头左右端点至少相差180°,端点不碰撞、不拉线;低速往返100次检查线缆、USB掉线、抖动和供电。上电及重连仍须受限速和限位约束。
- MCU独立限位和断联停止;失联先停止更新轨迹,保持/卸力按结构实测,避免盲目断电造成坠落。
- 电机独立合适供电支路并正确共地,选合适线径/端子/去耦,不由ESP32板载电源或面包板供大电流。
## 7. 串口协议与恢复
先用UTF-8单行JSON、换行分帧,字符串换行由JSON转义。115200起步。Linux可能ttyUSB/ttyACM,Windows为COM,使用可配置稳定设备标识。
```json
{"v":1,"seq":101,"type":"expression","state":"listening"}
{"v":1,"seq":102,"type":"motion","yaw_deg":20,"max_speed_deg_s":25}
{"v":1,"seq":102,"type":"ack","status":"accepted"}
```
- 表情和运动分开;转向目标最新值优先,不排队执行过时动作。
- 定义版本、字段范围、最大帧长(初始1KB)、坏帧丢弃和超时恢复。
- seq关联请求与确认;重试不能重复动作。accepted仅表示收到,无传感器不能报告实测已到位。
- 心跳500ms、失联2秒触发本地停止作为初始候选参数,实测后定稿。
- MCU重启发hello/能力信息,重连恢复当前状态,不回放历史运动。
- 字体和表情素材本地存储,串口不传全屏视频;WiFi/MQTT旁路暂不做。
## 8. 记忆、费用与数据
P3用SQLite,Mem0和向量库不是前置条件。从建表起就包含users、sessions、memories;记忆带owner_user_id、scope(private/shared)、来源会话/轮次、时间和确认状态。查询和写入均强制身份过滤,未知身份只用访客临时上下文。视觉track_id、会话session_id、永久user_id分开。
| 类型 | 保存策略 |
|---|---|
| 明确偏好 | 结构化键值,来源、确认状态、更新时间,新值替换旧值 |
| 临时事项 | 带时间与过期规则;记住事项不等于实现提醒调度 |
| 对话摘要 | 限长、按需检索、可清除,不默认永久保存逐字稿 |
- 支持记住/修改/忘掉/查看;模型推测不当作确认事实。
- 默认显式切换身份;人脸只提供候选,经当前发言者关联及确认后才启用对应记忆。切换身份清理上一人的私有检索上下文;异步任务绑定创建时的user_id/session_id,避免迟到结果写入新用户。
- 删除同时覆盖会话上下文、摘要和未来索引,防止删库后仍引用。
- 回复后异步写记忆,检索有超时;记忆失败不阻塞对话。
- 真实使用中检索不足再评估Mem0 + Chroma,支持不代表无需配置测试。[Mem0官方文档](https://docs.mem0.ai/components/vectordbs/dbs/chroma)
- 本地STT/TTS记录耗时与资源,不产生语音API调用费;统计LLM/按需视觉及未来云端后备费用,按实际日用量估月费并讨论上限。
- 默认不存原始音视频;视觉按需上传。密钥保存在本机配置,不写日志;提供静音和相机关闭入口。
## 9. 米家接入
P5通过Home Assistant统一调用。按实际设备比较官方Xiaomi Home和Xiaomi Miot Auto,核实地区、网关、本地/云端路径,不提前采购网关。[小米官方集成](https://github.com/XiaoMi/ha_xiaomi_home)
先接一盏现有灯:意图 → 工具/实体白名单 → 参数校验 → HA执行 → 状态确认 → 回复。请求受理和设备已改变分开描述,超时明确未确认。高风险设备不默认加入。
工具执行与语音回复生命周期分开:用户打断播报不意味着已发出的设备操作被撤销。每次动作保留执行ID和状态;超时先查状态,不盲目重试;优先使用“设为开/关”而非“切换”以降低重复执行风险。摄像头中的文字和检索记忆作为数据,不能自行扩大工具权限。
## 10. 运行维护与当前下一步
- 固定依赖版本,记录板卡SKU、固件、通道、引脚及接线图。
- Ubuntu优先先以普通用户的本机环境打通音频/USB,再确定常驻部署,暂不增加容器设备映射。核对Ubuntu版本、Python兼容性和CPU指令要求;模型文件授权与运行时授权分别记录。
- 日志保存耗时、错误、费用、连接事件并轮转,不默认保存完整私人对话。
- P2后配置开机启动、异常重启、音频/串口重连,测试拔插、断网、主机重启恢复。
- 已确认Ubuntu和四类缺失外设,不再重复询问。继续确认Ubuntu版本、USB接口和使用距离;按清单核价音频/屏幕/摄像头。基础多人和多用户数据结构纳入本次开发,自动身份能力以实测为准。
- 不等待上述答案也能先推进表情和协议设计,通用原型件按缺口采购。
- 本次只更新规划和采购条件;未安装依赖、重装系统、购买硬件或做实机测试。