Files
AIclinicalresearch/docs/03-业务模块/ASL-AI智能文献/04-开发计划/08b-工具3-M2-HITL工作台冲刺清单.md
HaHafeng 371fa53956 docs(asl): Upgrade Tool 3 architecture from Fan-out to Scatter+Aggregator (v2.0)
Architecture transformation:
- Replace Fan-out (Manager->Child->Last Child Wins) with Scatter+Aggregator pattern
- API layer directly dispatches N independent jobs (no Manager)
- Worker only writes its own Result row, never touches Task table (zero row-lock)
- Aggregator polls groupBy for completion + zombie cleanup (replaces Sweeper)
- Reduce red lines from 13 to 9, eliminate distributed complexity

Documents updated (10 files):
- 08-Tool3 main architecture doc: v2.0 rewrite (schema, Task 2.3/2.4, red lines, risks)
- 08d-Code patterns: rewrite sections 4.1-4.6 (API dispatch, SingleWorker, Aggregator)
- 08a-M1 sprint: rewrite M1-3 core (Worker+Aggregator), red lines, acceptance criteria
- 08b-M2 sprint: simplify SSE (NOTIFY/LISTEN downgraded to P2 optional)
- 08c-M3 sprint: milestone table wording update
- New: Scatter+Polling Aggregator pattern guide v1.1 (Level 2 cookbook)
- New: V2.0 architecture deep review and gap-fix report
- Updated: ASL module status, system status, capability layer index

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-24 22:11:09 +08:00

187 lines
8.5 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# M2血肉丰满 — The HITL Workbench
> **所属:** 工具 3 全文智能提取工作台 V2.0
> **架构总纲:** `08-工具3-全文智能提取工作台V2.0开发计划.md`
> **代码手册:** `08d-工具3-代码模式与技术规范.md`(所有代码模式均在此手册中,开发时按需查阅)
> **前置依赖:** M1 全部完成(散装管线 + Aggregator 已验证、PKB ACL 已通、纯文本提取可跑通)
> **建议时间:** Week 2-38-9 天)
> **核心目标:** 接入 MinerU 视觉大模型提升表格准确率,完成前端最复杂的 HITL 审核抽屉,交付一个"完全可用"的 V1 产品。
---
## Demo 形态
完整的 V1 体验:前端有打字机风格的终端日志流、右侧滑出包含 Quote 高亮比对的审核抽屉、能导出标准科研 Excel 宽表。虽然不能自定义字段,但用标准 RCT 模板提取文献已经足够惊艳。
---
## 任务清单
### M2-1接入 MinerU 表格引擎 + Clean Data 缓存2 天)
**做什么:**
- `PdfProcessingPipeline.ts` 升级M1 的纯文本降级 → 完整双引擎流水线
- 从 PKB `snapshotStorageKey` 下载 PDF Buffer → 调用 MinerU Cloud API → 返回结构化 HTML 表格
- **MinerU Clean Data OSS 缓存**Cache-Aside调用前先检查 `pkb/{kbId}/{docId}_mineru_clean.html`,命中则 <1 秒返回
- Worker 内部串行 `await mineruClient.extractTables()`(无需独立子队列,`teamConcurrency: 10` 即为 MinerU 隐式并发上限)
**不做什么:**
- 不改散装架构M1 已稳定)
- 不做动态 PromptM3继续用写死的 RCT Schema
**验收标准:**
- [ ] MinerU 返回 HTML 表格,含 `<table>` + `colspan/rowspan`
- [ ] OSS 缓存命中时跳过 MinerU 调用(日志可见 "Cache hit"
- [ ] `teamConcurrency: 10` 全局并发控制生效MinerU 调用受此限制)
- [ ] MinerU 超时(>3min自动降级到纯文本
> 📖 缓存代码模式见架构总纲 Task 2.2
> 📖 研发红线 2计算卸载Node.js 禁碰 MinerU 解析,仅 HTTP 调用 Cloud API
---
### M2-2XML 隔离 Prompt + fuzzyQuoteMatch 算法1.5 天)
**做什么:**
- `DynamicPromptBuilder.ts`M2 阶段仅支持基座模板,不做动态 Schema
- User Prompt 中用 `<FULL_TEXT>``<HIGH_FIDELITY_TABLES>` XML 标签隔离双引擎输出
- System Prompt 中声明表格优先级规则
- `ExtractionValidator.ts`:实现 `fuzzyQuoteMatch` 算法
- `buildQuoteSearchScope()`MinerU HTML 用 `html-to-text` 剥离标签 + 拼接 pymupdf4llm Markdown
- Unicode NFKC 标准化 → 剥离非字母数字 → 精确包含检查 → Levenshtein ≤5% 容错
- 返回三级置信度≥0.95(绿色)/ 0.80-0.95(黄色)/ <0.80(红色)
**验收标准:**
- [ ] LLM 收到的 Prompt 中 `<FULL_TEXT>``<HIGH_FIDELITY_TABLES>` 标签正确隔离
- [ ] `fuzzyQuoteMatch` 搜索范围 = pymupdf4llm 全文 + MinerU 纯文本(非仅 Markdown
- [ ] 对 8 篇测试 PDF 的 Quote 验证误报率 < 5%
- [ ] LLM 引用 MinerU 表格中的数字(如 "410 (22.4%)")能被正确匹配
> 📖 XML 隔离设计见架构总纲 Task 2.1
> 📖 fuzzyQuoteMatch 代码见架构总纲 Task 2.3 补丁 1
> 📖 红线 8Quote 搜索池必须含 MinerU 文本
---
### M2-3SSE 终端日志流1 天)
**做什么:**
- `ExtractionController.ts` 新增 SSE 端点 `GET /tasks/:taskId/stream`
- SSE 事件类型:`sync`(首帧)、`log``error`
- **首帧 sync 降级方案**`recentLogs: []`(不依赖内存 logBuffer前端检测到空日志时打印 "--- 监控已重新连接 ---"
- `ProcessingTerminal.tsx` 组件深色终端风格来源颜色区分MinerU 蓝 / DeepSeek 紫 / System 绿)
- `useExtractionLogs.ts` Hook仅驱动日志区不影响主业务流
- SSE 使用**本 Pod 内存事件**即可Worker 和 API 在同一 Pod 时日志实时可达)
**M1 已完成的不动:**
- `useTaskStatus.ts`React Query 轮询 + groupBy 进度)继续驱动进度条和步骤跳转
- `complete` 检测完全由 React Query 轮询到 `status === 'completed'` 触发,不依赖 SSE
**[P2 可选] SSE 跨 Pod 广播 — NOTIFY/LISTEN**
> 散装架构下进度条由 React Query 轮询驱动SSE 仅为日志增强。
> 多 Pod 部署后若日志体验不佳,可后续实施 `SseNotifyBridge.ts`(代码见 08d §7.6)。
> M2 阶段不强制实施。
**验收标准:**
- [ ] SSE 连接后立即收到 `sync` 首帧
- [ ] 日志实时打字机效果(`[MinerU]``[DeepSeek]``[System]` 分色)
- [ ] SSE 断开后进度条不受影响React Query 继续轮询)
- [ ] 多 Pod 环境下 SSE 重连到其他 Pod → 显示 "监控已重新连接" 提示(本 Pod 无历史日志时)
> 📖 双轨制架构见架构总纲 Task 4.1
> 📖 SSE 降级方案见架构总纲 Task 2.4
> 📖 [P2 可选] NOTIFY/LISTEN 代码模式见 08d §7.6
---
### M2-4智能审核抽屉3 天)⚠️ M2 核心战役
**做什么:**
**Step A — ExtractionDrawer 主体1.5 天):**
- 700px 右侧抽屉4 大模块:基础元数据 / 基线特征 / RoB 2.0 / 结局指标
- `Collapse` 折叠面板懒渲染(默认仅展开"基础元数据"
- 每个字段下方展示 `QuoteBlock`:灰色背景 + 关键数字黄色 `<mark>` 高亮
- 字段可编辑,修改追踪到 `manualOverrides`
- 底部:[取消] + [核准保存] → `PUT /results/:resultId/review`
**Step B — HITL 死锁解套0.5 天):**
- Quote 红色警告旁新增 `[强制认可]` + `[手动修改数值]` 双按钮
- 所有红色警告必须被处置后 "核准保存" 才可点击
- `manualOverrides` 记录 `{ fieldName_quote_force_accepted: true }` 用于审计
**Step C — 性能优化0.5 天):**
- 每个 FieldGroup 用 `React.memo` 包裹
- 使用 Ant Design `Form.shouldUpdate` 精确控制字段级重渲染
- `manualOverrides` 通过 `Form.onValuesChange` 差量追踪
**Step D — 签名 URL 懒加载0.5 天):**
- "查看源 PDF" 按钮点击时才生成签名 URL10 分钟有效期)
- 前端 `usePdfViewer` Hook 监听 403 → 自动重签
**验收标准:**
- [ ] 抽屉打开 < 200msCollapse 懒渲染生效)
- [ ] Quote 三级置信度正确展示(绿/黄/红)
- [ ] 红色 Quote 的 [强制认可] 和 [手动修改数值] 按钮可用
- [ ] 未处置红色警告时 "核准保存" 按钮禁用
- [ ] 核准后该篇状态变为 Approved
- [ ] "查看源 PDF" → 10 分钟内可正常查看 → 过期后 403 自动重签
- [ ] 修改字段值后 `manualOverrides` 正确记录
> 📖 抽屉布局见架构总纲 Task 5.2
> 📖 HITL 解锁见架构总纲 Task 5.2 v1.4 修正
> 📖 签名 URL 见架构总纲 Task 5.3
---
### M2-5Excel 宽表导出0.5 天)
**做什么:**
- `ExtractionExcelExporter.ts`:标准科研 Excel 数据宽表
- 每个变量列右侧紧跟 `_quote` 原文列
- 仅导出 `reviewStatus = approved` 的文献
- 表头双行:第一行中文名,第二行英文 JSON Key
- `GET /tasks/:taskId/export` 端点
**验收标准:**
- [ ] 导出的 Excel 列顺序正确(变量 + Quote 交替)
- [ ] 仅含 Approved 文献
- [ ] 双行表头
> 📖 宽表格式见架构总纲 Task 2.5
---
### M2-6联调 + 集成测试1 天)
**做什么:**
- Step 1 → Step 2 → Step 3 完整流程走通(含 MinerU + 审核抽屉 + Excel
- fuzzyQuoteMatch 边界测试(连字符替换、空格差异、换行吞掉)
- 断点恢复测试(关闭浏览器 → 重新打开 → 恢复正确步骤)
- 散装 10 篇并发提取压力测试
**验收标准:**
- [ ] 8 篇测试 PDF 全链路跑通PKB → MinerU + LLM → 抽屉审核 → Excel 导出
- [ ] 中途关闭浏览器后恢复正确
- [ ] 10 篇并发无数据丢失、无重复
---
## M2 结束时的状态
```
✅ M1 全部 +
✅ MinerU 表格引擎 + OSS 缓存Worker 内部串行调用)
✅ XML 隔离 Prompt + 表格优先级
✅ fuzzyQuoteMatch 三级置信度验证
✅ SSE 终端日志双轨制React Query 轮询主驱 + SSE 本 Pod 日志增强)
✅ 完整审核抽屉Collapse + Quote + HITL 解锁 + 签名 URL
✅ Excel 宽表导出
⏳ [P2 可选] SSE NOTIFY/LISTEN 跨 Pod 广播(多 Pod 部署后按需实施)
❌ 无自定义字段(仅系统基座模板)
❌ 无 Prompt 注入防护(无用户输入,不需要)
❌ 无 E2E 自动化测试
```
> **M2 的核心价值:** 此时工具 3 已是一个"完全可用且高度可用"的产品。用标准 RCT 模板提取文献已经足够惊艳。如果项目赶进度,可以直接拿 M1+M2 给真实医生试用M3 作为 v2.1 后续迭代。