代码剥离 - 助手本体、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:四条路径验证 两份旧报告加了状态说明(结论仍有效但选型已变), 并修正了随代码移走而失效的引用与复现命令。
114 lines
5.2 KiB
Markdown
114 lines
5.2 KiB
Markdown
# P0 验证报告 · DeepSeek API
|
||
|
||
日期:2026-09-14。机器:N5095 / Ubuntu 24.04.3 / Python 3.13.5。
|
||
脚本:`~/workspace/ai-companion/p0/verify_deepseek.py`。结果:**11/11 通过**。
|
||
|
||
复现:
|
||
|
||
```bash
|
||
set -a; . ~/.config/ai_assistant/env; set +a
|
||
cd ~/workspace/ai-companion && python3 p0/verify_deepseek.py
|
||
```
|
||
|
||
密钥存放:`~/.config/ai_assistant/env`(权限 600,不在项目目录内,不进版本管理)。
|
||
|
||
## 结论摘要
|
||
|
||
| # | 项目 | 结果 |
|
||
|---|---|---|
|
||
| 0 | 模型清单 | 仅 `deepseek-flash`、`deepseek-v4-pro` |
|
||
| 1a | 纯文本流式 | 可用 |
|
||
| 1b | 思考内容分离 | on 模式有 `reasoning_content`;off 模式无 |
|
||
| 1c | 首 token 延迟 | **P50 = 786ms,P95 = 1100ms**(N=8) |
|
||
| 2a | 流式工具调用 | 可用,参数 JSON 正确 |
|
||
| 2b | 工具结果回灌 | 可用 |
|
||
| 2c | 思考模式约束 | 开启时**必须回传 `reasoning_content`** |
|
||
| 3a | **图片输入** | **可用**,正确读出图中数字 |
|
||
| 4a | 中途断开(打断) | 无异常 |
|
||
| 4b | 超时 | 正确抛出 `TimeoutError` |
|
||
| 4c | 错误模型名 | HTTP 400,可作启动自检 |
|
||
|
||
## 逐条说明
|
||
|
||
### 1. 模型名:方案文档正确,Pipecat 默认值错误
|
||
|
||
`GET /v1/models` 实际返回:
|
||
|
||
```json
|
||
[{"id": "deepseek-flash"}, {"id": "deepseek-v4-pro"}]
|
||
```
|
||
|
||
- 方案文档 §2 记的 `deepseek-flash` **正确**。
|
||
- **Pipecat 的 `DeepSeekLLMService` 默认模型是 `deepseek-v4-flash`,该模型不存在**,直接用会 400。
|
||
实例化时必须显式覆盖为 `deepseek-flash`。
|
||
|
||
### 2. 思考模式必须显式关闭(重要)
|
||
|
||
`deepseek-flash` 默认开启思考模式。此时 API 要求**把上一轮 assistant 消息里的
|
||
`reasoning_content` 原样回传**,否则任何多轮对话与工具回灌都返回:
|
||
|
||
```
|
||
400 invalid_request_error: The `reasoning_content` in the thinking mode must be passed back to the API.
|
||
```
|
||
|
||
实测三种手工构造 assistant 消息的写法(`content=None` / `content=""` / 不带 tools)**全部 400**;
|
||
只有回传服务端返回的原始 assistant 消息才通过。
|
||
|
||
**影响**:多数框架的上下文层按 OpenAI 格式存储消息,不保留 `reasoning_content`——
|
||
一旦开启思考模式,Pipecat 的上下文管理与工具循环会持续踩这个坑。
|
||
|
||
**决定**:会话主路径传 `"thinking": {"type": "disabled"}`。两条理由:
|
||
|
||
1. 彻底消除 `reasoning_content` 回传要求,上下文层可安全裁剪消息;
|
||
2. 开启时**第一个流式 chunk 是 `reasoning_content` 而非 `content`**,若直接送 TTS 会念出思考过程。
|
||
关闭后两者合一,无需分流。
|
||
|
||
Pipecat 该服务的默认值恰好是 `DeepSeekThinkingConfig(type="disabled")`,与本结论一致。
|
||
若将来要开思考以提升回答质量,必须同时改造上下文层保证 `reasoning_content` 不丢。
|
||
|
||
### 3. 首 token 延迟
|
||
|
||
N=8,短问答,`thinking=disabled`:**P50 = 786ms,P95 = 1100ms**(min 515 / max 1100)。
|
||
|
||
对照方案 P1 验收目标"短问答结束到首段有声回复 P50≤2 秒、P95≤4 秒",
|
||
LLM 占约 0.8 秒,**余下约 1.2 秒预算**留给 STT 收尾判定 + TTS 首段合成。这个余量是否够,
|
||
取决于本地 TTS 的 RTF(待测,见下)。
|
||
|
||
注:thinking 开关对首包时间影响不大(约 700ms vs 718ms),但关闭后总耗时更短,因为不再生成思考 token。
|
||
|
||
### 4. 图片输入可用(P5 的意外好消息)
|
||
|
||
`deepseek-flash` 接受 `image_url` 的 base64 data URI,正确读出图中文字("7391")。
|
||
|
||
方案 §P5 的视觉问答不需要另找模型,按需抓拍 → 缩放 → base64 上传即可。
|
||
**未测**:视觉请求的 TTFT(预估显著长于纯文本)、大图 token 消耗、并发下的表现。
|
||
按需视觉是按次计费项,接 P5 时需单独测成本。
|
||
|
||
### 5. 工具调用链路完整
|
||
|
||
流式工具调用可用,`finish_reason="tool_calls"`,参数 JSON 正确。
|
||
回灌工具结果后模型能生成自然语言确认("客厅的灯已经打开了")。
|
||
这是 P5 米家控制的基础链路,已验证通畅。
|
||
|
||
**注意**:回灌时 `tool_call_id` 必须用服务端返回的真实值,assistant 消息必须用服务端返回的原始对象,不能手工构造。
|
||
|
||
### 6. 打断与超时
|
||
|
||
- **打断**(收到若干 chunk 后主动 close):无异常抛出,连接正常释放。对应方案"打断时取消旧回复生成"的客户端能力成立。
|
||
- **超时**:非流式长生成 + 2 秒预算,正确抛出 `TimeoutError`。
|
||
- 流式下 socket 超时不会因首包快而触发——**"打断"和"超时"必须分开实现检测**,不能只做一种。
|
||
|
||
### 7. 计费与缓存
|
||
|
||
`usage` 返回 `prompt_cache_hit_tokens` / `prompt_cache_miss_tokens`,实测命中 256/398。
|
||
系统提示词固定可吃到缓存,对月费有利。方案 §8 要求的费用统计应记录这两个字段。
|
||
|
||
## 遗留与未验证
|
||
|
||
- 视觉请求的延迟与 token 成本未测。
|
||
- 长上下文(多轮 + 记忆注入)下的延迟退化未测。
|
||
- 并发请求未测(多用户场景下的表现)。
|
||
- 本次仅验证 API 链路,**未接入 Pipecat、未写任何管线代码**。
|
||
- 本机 `github.com` / `huggingface.co` 直连不通,需走本地 mihomo 代理 `127.0.0.1:7890`
|
||
或国内镜像。DeepSeek API 直连正常,不需要代理。
|