新增 Pipecat 传输层实验报告;方案 §10 记录当前卡点

背景:方案文档写"Pipecat 作为唯一会话管线框架",但核实后发现
代码里它只在 requirements.txt 里(零引用)。于是做实验验证架构问题:
Pipecat 该用多深——只做传输(A),还是按框架 service 模型重构(B)。

新增 P0-Pipecat传输层实验报告.md

- 传输层跑通:信令(47–280ms)、ICE 连通、data channel、双向媒体轨
- 帧路由未通:自定义处理器的 process_frame 调用次数为 0,
  连自己注入的 StartFrame 都没进去;引擎从未运行
- 现象:连接全对、音轨协商成功、助手永远不说话,日志里一条错误都没有
- 记下 8 个集成坑,每个都表现为"什么都没发生"
- 结论:实验未能支持 A 方案,反而间接给了 B 更多理由;
  但根因未定位,两种可能必须区分(接线错误 vs 模型不兼容)

方案 §10 更新

- 第 1 步改为"服务端 WebRTC 入口 + 客户端骨架",状态标注为
  "传输层跑通、帧路由未通"
- 新增 1b 步:查清帧路由根因 → 定 A/B 方案,标为当前卡点
- header 加注实验状态与 A/B 待定
- 架构图补传输层,标注"实验,帧路由未通"

顺带修正

- 局域网于当日重新编址(192.168.0.x → 172.16.1.x),
  架构图里的服务器地址更新
- 报告数量 4 → 5
This commit is contained in:
ylhan
2026-09-15 17:55:53 +08:00
parent bb4fa3028e
commit 2ef6fe215c
2 changed files with 167 additions and 6 deletions
@@ -5,7 +5,10 @@
> (独立 git 仓库),包括:助手本体、TTS 服务、P0 基准脚本、ESP32 固件、
> `README.md`(代码说明)、`部署说明.md`(运维)——这两份也在代码仓库。
>
> 更新:2026-09-15。状态:**助手本体已在服务器上实现并跑通**(端到端测试 16/16);设备侧(N5095 外设桥、ESP32)尚未开始。
> 更新:2026-09-15。状态:**助手本体已在服务器上实现并跑通**(端到端测试 16/16);
> **Pipecat 传输层实验已做,传输层通、帧路由未通**(见 §10 与
> `P0-Pipecat传输层实验报告.md`)——**A/B 架构方案待定**,这是当前卡点;
> 设备侧(N5095 外设桥、ESP32)尚未开始。
> 已确认:Ubuntu 24.04;N5095 / 16G 作为**客户端**;助手本体部署在 cadadmin-server(i9-14900K / 3090);麦克风、音箱、摄像头均未购;屏幕已于 09-14 到货并点亮(2.8 寸 ILI9341 触摸屏,非原定的 1.28 寸圆屏)。
> 核心目标:听得清、回应及时、可打断、表情明确、转头自然。
> 最新外形要求:屏幕不用太大;摄像头水平可用旋转总行程至少180°,按正前方左右各90°理解,不是镜头视场角180°。
@@ -22,7 +25,7 @@
>
> 变更后 N5095 只做 USB 外设接入与网络桥接,**不运行 STT/TTS/LLM 等重型推理**
> (轻量推理仍在本地,见 §1)。
> 详细部署现状见代码仓库里的 `部署说明.md`,实测数据见本目录的四份 P0 报告。
> 详细部署现状见代码仓库里的 `部署说明.md`,实测数据见本目录的五份 P0 报告。
## 1. 范围与待讨论事项
@@ -48,15 +51,16 @@
## 2. 总体架构
```text
┌─ cadadmin-server(192.168.0.20)—— 助手本体 ────────────────┐
┌─ cadadmin-server(172.16.1.101)—— 助手本体 ────────────────┐
│ 会话引擎(身份 → 记忆 → LLM → TTS) │
│ ├─ LLM:DeepSeek deepseek-flash(云端,关思考) │
│ ├─ TTS:Qwen3-TTS 1.7B(RTX 3090,独立 HTTP 服务 :18040) │
│ ├─ 传输:Pipecat SmallWebRTC :7860(实验,帧路由未通) │
│ ├─ STT:Zipformer 中英宽带 int8(CPU 4 线程) │
│ ├─ 记忆:SQLite(按 owner_user_id 强制隔离) │
│ └─ 身份:手动切换 + 访客兜底 │
└────────────────────────────────────────────────────────────┘
▲ WebRTC(计划) ▲ 手机/浏览器客户端
▲ WebRTC(实验中) ▲ 手机/浏览器客户端
│ 局域网 1–2ms │
┌─ N5095 / 16G —— 客户端 / 外设桥 ───────────────────────────┐
│ USB 麦克风阵列(固定底座)──处理后音频、DoA──┐ │
@@ -411,13 +415,34 @@ P5通过Home Assistant统一调用。按实际设备比较官方Xiaomi Home和Xi
| # | 步骤 | 状态 | 能验证什么 / 不能验证什么 |
|---|---|---|---|
| 0 | **音频边界定稿** | ✅ 2026-09-15 完成(见 §5) | 决定了客户端接口形态 |
| 1 | **服务端 WebRTC 入口**(Pipecat SmallWebRTC) | 未开始 | 让客户端有东西可连 |
| 2 | **N5095 客户端骨架** | 未开始 | 用**合成音频**即可跑通传输层:信令稳定性、帧格式、采样率边界、打断信号传递、**真实传输下的首音延迟** |
| 1 | **服务端 WebRTC 入口 + 客户端骨架** | 🔶 **传输层跑通,帧路由未通**(见 `P0-Pipecat传输层实验报告.md`) | 已验证:信令、ICE、data channel、双向媒体轨。**未验证:帧进不到自定义处理器,引擎从未运行** |
| 1b | **查清帧路由根因 → 定 A/B 方案** | **待办,当前卡点** | 根因决定 A 方案(Pipecat 只做传输)是否可行,还是必须转 B(按框架 service 模型重构) |
| 2 | **N5095 客户端骨架** | 🔶 雏形已有(`client/test_client.py`) | 非 trickle ICE、data channel 心跳、文件音频实时发送、回复录音都已实现。**不做 AEC/播客参考/打断**——那些要真实声卡 |
| 3 | **接入真实麦克风与音箱** | 阻塞:硬件未购 | 唯一能验证 AEC、打断、唤醒的一步,也是 P2 的全部内容 |
| 4 | **STT 中文识别正确率** | 阻塞:需录音 | 见下"最大功能风险" |
| 5 | ESP32 表情串口 | 硬件已到货,可独立推进 | 串口协议、表情渲染 |
| 6 | 摄像头、多人跟踪、电机 | 阻塞:硬件未购 | — |
### 第 1 步的实验结论(2026-09-15)
**传输层可用,但"把整条会话逻辑塞进一个 FrameProcessor"不是开箱即用的。**
自定义处理器被创建、`setup()` 被调用,但 **`process_frame` 调用次数为 0**——
连自己注入的 StartFrame 都没进去。现象是"连接全对、音轨协商成功、
但助手永远不说话,且日志里一条错误都没有"。
**这对 A/B 决策的影响**:实验前判断"Pipecat 的价值收敛到传输层",
现在要修正——**传输层与自定义逻辑之间的接缝比预想的深**。
B 方案恰恰绕开这个接缝(用框架原生 service,不由一个处理器吞掉全部)。
**但根因未定位**,两种可能必须区分:
- 若是接线错误(管线用法与 Pipecat 1.10 的实际约定不符)→ 接缝浅,A 仍可行
- 若是模型不兼容(该版本不接受这种用法)→ 接缝深,应转 B
实验同时挖出 **8 个 Pipecat 集成坑**(客户端需发 ping、offer 无媒体则不收集
ICE 候选、`run()` 要 WorkerParams、后台异常被静默吞掉等),
每个都表现为"什么都没发生",详见实验报告。
**第 2 步的边界要说清楚**:用合成音频能验证传输层,**验不了 AEC 和远场识别**——
那些必须等真实麦克风和音箱。但传输层能提前跑通,硬件一到就能直接接,
不用同时调两件事。