# 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 直连正常,不需要代理。