# 配风计划审查功能 - 实现方案

## 架构设计

采用**自定义编排器 + 3个独立 DeepAgent**的架构（而非 deepagents 的 subagent 模式），原因是用户要求"固定3个子智能体、按固定流程并行检查"，自定义编排器保证确定性并行执行，而 deepagents 的 subagent 由 LLM 决定何时调用，不够确定。

```
POST /api/vent/review/pdf
        │
        ▼
  stream_review() 编排器
        │
  1. PDF文本提取 (PyPDF2 → PaddleOCR)
  2. 创建3个 DeepAgent 实例
  3. asyncio 并行执行
  4. 流式 yield SSE 进度事件
  5. 汇总合并结果
   ┌───────┬───────┬───────┐
   ▼       ▼       ▼
Agent1  Agent2  Agent3
表单审查 数据一致性 计算核验
```

## 新增/修改文件清单

### 1. `requirements.txt` — 新增依赖
```
pypdf>=5.0
paddleocr>=2.9
paddlepaddle>=3.0
```

### 2. `tools/pdf_tools.py` — 新建 PDF 提取工具
- `extract_pdf_text(file_path)`: PyPDF2 提取 → 失败则 PaddleOCR
- `save_upload_file(upload_file)`: 保存上传文件到临时目录

### 3. `tools/calc_tools.py` — 新建本地需风量计算工具
按《煤矿安全规程》和 AQ 1056 标准，实现各用风地点类型的计算工具：

| 工具函数 | 用途 |
|---------|------|
| `calc_face_air_volume_by_gas(q_gas, k_gas)` | 采煤面-按瓦斯涌出量 Q=100×q×K |
| `calc_face_air_volume_by_workers(n)` | 采煤面-按人数 Q=4×N |
| `calc_face_air_volume_by_wind_speed(v, s)` | 采煤面-按风速 Q=60×S×v |
| `calc_face_air_volume_max(...)` | 采煤面-取最大值 |
| `calc_tunnel_air_volume_by_gas(q_gas, k_gas)` | 掘进面-按瓦斯 Q=100×q×K |
| `calc_tunnel_air_volume_by_explosives(a)` | 掘进面-按炸药 Q=25×A |
| `calc_tunnel_air_volume_by_workers(n)` | 掘进面-按人数 Q=4×N |
| `calc_tunnel_air_volume_by_wind_speed(v, s)` | 掘进面-按风速 Q=60×S×v |
| `calc_chamber_air_volume(...)` | 硐室-机电设备配风 |
| `calc_other_air_volume_by_wind_speed(v, s)` | 其他巷道-按风速 |
| `calc_effective_area(max_control, min_control, avg_height)` | 有效断面积计算 |

每个工具返回列式：`{formula, steps, result}` 结构化数据，供 LLM 对比。

### 4. `agents/review_agent.py` — 新建审查 Agent 工厂
基于现有 `vent_agent.py` 的模式，复用 `_get_model()` 和 `FilesystemBackend`：

- **`create_form_review_agent()`** → 子智能体1：基本形式审查
  - Skills: `skills/vent-plan-review-form`
  - Tools: `write_todos`
  - 审查内容：版本、签字、编制时间、计算过程完整性、语病逻辑

- **`create_data_consistency_agent()`** → 子智能体2：数据一致性审查
  - Skills: `skills/vent-plan-review-data`
  - Tools: `write_todos` + (MCP 工具预留接口)
  - 审查内容：用风地点完整性、瓦斯/CO2一致性、工作面参数、风速温度匹配

- **`create_calc_verification_agent()`** → 子智能体3：计算核验
  - Skills: `skills/vent-plan-review-calc`
  - Tools: `write_todos` + 所有 calc_tools 函数
  - 审查内容：逐地点核验需风量计算，输出表格

- **`create_summary_agent()`** → 汇总 Agent
  - 汇总3个子智能体的审查结果，生成最终审查报告

- **`stream_review(file, message, session_id)`** → 核心编排器异步生成器
  - 提取 PDF → 创建3个 Agent → `asyncio.gather` 并行执行 → yield SSE 事件 → 汇总

### 5. `skills/vent-plan-review-form/SKILL.md` — 新建
形式审查技能，包含：
- 版本审查规则（月份匹配检查）
- 签字审查规则（四类签字人：编制人、通风科长、通风副总、总工程师）
- 编制时间规则（配风计划月份的上个月）
- 计算过程完整性检查
- 语病逻辑检查规则

### 6. `skills/vent-plan-review-data/SKILL.md` — 新建
数据一致性审查技能，包含：
- 用风地点完整性检查标准
- 瓦斯/CO2数据一致性校验方法
- 工作面参数与作业规程一致性校验
- 风速与温度数据匹配规则
- MCP 查询接口预留说明

### 7. `skills/vent-plan-review-calc/SKILL.md` — 新建
计算核验技能，包含：
- 各用风地点类型对应的计算公式
- 核验步骤和判定标准
- 输出格式规范（表格）

### 8. `api/routes.py` — 修改
新增端点：
```python
@router.post("/api/vent/review/pdf")
async def api_review(
    file: UploadFile = File(),
    session_id: str | None = Form(default=None),
    message: str | None = Form(default=None)
):
    return StreamingResponse(
        stream_review(file, message, session_id),
        media_type="text/event-stream",
        headers={
            "Cache-Control": "no-cache",
            "Connection": "keep-alive",
            "X-Accel-Buffering": "no"
        }
    )
```

## SSE 事件类型设计

| type | 描述 | 关键字段 |
|------|------|---------|
| `progress` | 进度描述（LLM 翻译后的文字） | `message`, `agent?` |
| `agent_start` | 子智能体开始审查 | `agent` (form-review/data-check/calc-verify) |
| `agent_done` | 子智能体审查完成 | `agent`, `content` (摘要) |
| `agent_error` | 子智能体审查出错 | `agent`, `message` |
| `token` | 汇总报告的 token 流 | `content` |
| `done` | 审查结束 | `session_id` |
| `error` | 整体错误 | `message` |

## 关键技术细节

1. **PDF 文本提取**：优先 PyPDF2（pypdf），若提取内容为空或过短则启用 PaddleOCR（需先将 PDF 每页转为图片）
2. **并行执行**：使用 `asyncio.Queue` 收集各 Agent 的进度事件，编排器从队列读取并 yield SSE
3. **模型复用**：复用 `vent_agent.py` 的 `_get_model()` 函数，确保模型配置一致
4. **Skills 加载**：复用 `FilesystemBackend(virtual_mode=True)` 模式，skills 路径为 `skills/vent-plan-review-*`
5. **计算工具**：每个工具返回结构化 JSON（公式 + 步骤 + 结果），让 LLM 能直接对比"配风计划值"与"实际计算值"
6. **MCP 预留**：子智能体2的工具中预留 MCP 查询接口，当前以 TODO 注释标注，后续对接时直接替换

## 实现顺序

1. `tools/pdf_tools.py` — PDF 提取
2. `tools/calc_tools.py` — 计算工具
3. `skills/vent-plan-review-form/SKILL.md` — 表单审查技能
4. `skills/vent-plan-review-data/SKILL.md` — 数据一致性技能
5. `skills/vent-plan-review-calc/SKILL.md` — 计算核验技能
6. `agents/review_agent.py` — Agent 工厂 + 编排器
7. `api/routes.py` — 新增端点
8. `requirements.txt` — 更新依赖