# 配风计划审查 - Summary Agent 汇总延迟优化方案

## 问题
3 个子智能体完成后，从「正在生成最终审查报告...」到 LLM 输出第一个 token 卡顿约 3 分钟。
`summary_input` 约 15,000 字符。

## 根因
1. **主要**：DeepSeek v4 Pro 大模型处理 ~7,000 token 输入的 prefill 阶段耗时长
2. **次要**：Summary Agent 的 `create_deep_agent()` 编译 LangGraph 状态图未预热
3. **潜在**：3 个子智能体刚结束大量 API 调用后，summary 请求可能排队

---

## 修改计划

### 1. Summary Agent 使用独立快速模型 `deepseek-v4-flash` 🔥🔥🔥

**文件：`.env`**
- 新增配置项：`SUMMARY_MODEL=deepseek-v4-flash`

**文件：`agents/review_agent.py`**
- 新增 `_get_summary_model()` 函数（约 25 行），从 `.env` 读取 `SUMMARY_MODEL` 配置，fallback 到 `DEEPAGENT_MODEL`
- 修改 `create_summary_agent()`（第 410-430 行）：`model=_get_model()` → `model=_get_summary_model()`

**逻辑**：子智能体继续用 `deepseek-v4-pro` 保证分析质量，summary 用 flash 模型——汇总任务本质是格式化重组已有内容，flash 完全够用，TTFT 预计从 ~3min 降至 ~15-30s。

### 2. 预热所有 Review Agent 🔥🔥

**文件：`main.py`**（`_warmup_agents()` 函数，第 41-56 行）
- 新增 import：`from agents.review_agent import get_form_review_agent, get_data_consistency_agent, get_calc_verification_agent, get_summary_agent`
- 在 `_warmup_agents()` 末尾依次调用 4 个 review agent 的 getter
- 用 `try/except` 包裹每个调用，单个失败不影响其他

**效果**：消除首次请求 ~10-30s 的图编译开销。

### 3. 轻度压缩子智能体输出 🔥

**文件：`agents/review_agent.py`**
- 新增 `_compress_result(text: str, max_chars: int = 8000) -> str` 函数（约 30 行）
  - 若文本 ≤ `max_chars`，直接返回
  - 否则按优先级保留：表格块（`|---|` 标记的行）→ 标题行（`##`/`###`）→ 列表项 → 正文
  - 去除冗余空行（>2 个连续换行压缩为 2 个）
  - 末尾追加 `...[已截断，完整内容见子智能体原始输出]`
- 在构建 `summary_input` 前（第 865 行之前），对每个 result 调用 `_compress_result()`

**效果**：降低输入 token 数，进一步减少 prefill 耗时，同时保留核心结构化数据。

### 4. 等待期间心跳进度 🔥

**文件：`agents/review_agent.py`**（`stream_review()` 函数，第 897-917 行附近）
- 在 `summary_agent.astream()` 调用前，创建一个心跳 `asyncio.Task`：
  - 每隔 5 秒通过 `asyncio.Queue` 发送 heartbeat 事件
  - 主循环收到第一个 token 时取消心跳任务
- 在事件循环中新增 `heartbeat` 事件处理：yield `_sse_event("progress", message="模型正在处理中（已等待 XX 秒）...", agent="system")`

**效果**：用户能看到系统仍在工作，消除"卡死"错觉。前端已有的 progress 事件处理可复用，无需改前端。

### 5. 添加模型超时配置 🔥

**文件：`.env`**
- 新增：`OPENAI_TIMEOUT=180`（3 分钟超时）

**文件：`agents/vent_agent.py`**（`_get_model()` 函数，第 100-135 行）
- 新增读取 `OPENAI_TIMEOUT` 环境变量
- 传递给 `init_chat_model(..., timeout=timeout)`

**文件：`agents/review_agent.py`**（新增的 `_get_summary_model()`）
- 同样读取并传递 `timeout`

**效果**：防止异常情况下无限挂起。

---

## 涉及文件汇总

| 文件 | 改动量 | 改动类型 |
|------|--------|---------|
| `.env` | +2 行 | 新增配置项 |
| `agents/vent_agent.py` | ~5 行 | `_get_model()` 添加 timeout 参数 |
| `agents/review_agent.py` | ~80 行 | 新增 `_get_summary_model()`、`_compress_result()`、心跳协程；修改 `create_summary_agent()` |
| `main.py` | ~15 行 | `_warmup_agents()` 添加 review agent 预热 |

## 预期效果
- **TTFT**：从 ~3 分钟降至 **15-30 秒**（flash 模型 + 轻度压缩）
- **首次请求**：消除额外 10-30 秒编译开销（预热）
- **UX**：等待期间有心跳提示，不再感觉"卡死"
- **健壮性**：超时保护防止无限挂起