Files
AIclinicalresearch/docs/03-业务模块/ASL-AI智能文献/06-技术文档/工具3终极架构审查与研发规范.md
HaHafeng dc6b292308 docs(asl): Complete Tool 3 extraction workbench V2.0 development plan (v1.5)
ASL Tool 3 Development Plan:
- Architecture blueprint v1.5 (6 rounds of architecture review, 13 red lines)
- M1/M2/M3 sprint checklists (Skeleton Pipeline / HITL Workbench / Dynamic Template Engine)
- Code patterns cookbook (9 chapters: Fan-out, Prompt engineering, ACL, SSE dual-track, etc.)
- Key patterns: Fan-out with Last Child Wins, Optimistic Locking, teamConcurrency throttling
- PKB ACL integration (anti-corruption layer), MinerU Cache-Aside, NOTIFY/LISTEN cross-pod SSE
- Data consistency snapshot for long-running extraction tasks

Platform capability:
- Add distributed Fan-out task pattern development guide (7 patterns + 10 anti-patterns)
- Add system-level async architecture risk analysis blueprint
- Add PDF table extraction engine design and usage guide (MinerU integration)
- Add table extraction source code (TableExtractionManager + MinerU engine)

Documentation updates:
- Update ASL module status with Tool 3 V2.0 plan readiness
- Update system status document (v6.2) with latest milestones
- Add V2.0 product requirements, prototypes, and data dictionary specs
- Add architecture review documents (4 rounds of review feedback)
- Add test PDF files for extraction validation

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-23 22:49:16 +08:00

96 lines
6.2 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.
# **🎯 终极架构审查与研发红线规范:工具 3 全文智能提取 V2.0**
**文档性质:** 架构定稿与研发执行标准
**审查基准:** 《Postgres-Only 异步任务处理指南 (v1.1)》、《通用能力层清单 (v2.4)》
**适用对象:** 后端研发、前端研发、测试工程师
**核心宗旨:** 确保工具 3 在分布式环境下的高可用性,彻底对齐平台现有的 Postgres-Only 规范,消除并发死锁、状态撕裂与算力浪费。
## **🚨 核心研发红线 (Sprint 1 强制执行)**
在进入代码编写前,所有研发人员必须对齐以下三条底层红线:
1. **Payload 绝对轻量化:** pg-boss 的 Job Data 中,**绝对不允许**传入 PDF 文件的 Base64 或 extractedText 全文。只能传递 { taskId, resultId, pkbDocumentId }。所需的大文本必须在 Worker 启动后,通过 ID 实时从 DB 或 OSS 拉取。
2. **严格的计算卸载:** Node.js 进程绝对不碰任何文档实体的解析计算pymupdf4llm 或 MinerU。所有解析动作必须通过 HTTP 路由给独立的 Python 微服务 (extraction\_service) 执行。
3. **过期时间兜底:** 由于大模型提取长文本耗时较长,在推送 asl\_extraction\_child 任务时expireInMinutes 强制设置为 **30 分钟**,防止任务被系统意外判死。
## **🛠️ 后端架构排雷与对齐方案**
### **1\. 废弃单机并发控制,拥抱全局队列限流**
* **❌ 错误做法:** 在 ExtractionService 内部使用 P-Queue 控制 MinerU 并发。在多实例Pods部署下这会导致真实的 API 请求量翻倍,瞬间引发 429 熔断和重试风暴。
* **✅ 标准解法:** 把并发控制权交还给数据库。针对昂贵的 MinerU 解析,单独拆分一个子队列 asl\_mineru\_extract配置严格的全局并发数
// 全局只允许同时有 2 个 MinerU 解析任务在跑,跨所有 Node.js 实例生效
jobQueue.process('asl\_mineru\_extract', { teamConcurrency: 2 }, async (job) \=\> { ... })
### **2\. Fan-out 扇出模式下的并发写入安全**
* **❌ 错误做法:** 查询父任务 \-\> successCount \+ 1 \-\> 更新父任务。100 个子任务并发完成时会导致严重的计数丢失Race Condition
* **✅ 标准解法 (原子递增)** 所有聚合数据的回写,必须 100% 使用 Prisma 的原子操作,并结合**幂等性**检查:
// 1\. 幂等性检查
const existing \= await prisma.aslExtractionResult.findUnique({ where: { id: resultId }});
if (existing.status \=== 'completed') return { success: true };
// 2\. 事务内的原子递增
await prisma.$transaction(\[
prisma.aslExtractionResult.update({ where: { id: resultId }, data: { status: 'completed' } }),
prisma.aslExtractionTask.update({
where: { id: taskId },
data: { successCount: { increment: 1 }, totalTokens: { increment: tokens } }
})
\]);
### **3\. 错误处理边界:永久失败 vs 自动重试**
* **业务痛点:** 严格遵循《Postgres-Only 指南》规范1直接 throw error会导致在遇到“PKB源文件被删除”等不可逆错误时pg-boss 盲目重试 3 次,白白消耗资源。
* **✅ 标准解法 (异常分级路由)** 在 Worker 中必须明确区分“可恢复错误”与“致命错误”:
try {
await doExtraction();
} catch (error) {
if (error instanceof PkbDocumentNotFoundError || error.name \=== 'PdfCorruptedError') {
// 致命错误:更新业务状态为 error直接 return success 欺骗 pg-boss 停止重试
await prisma.aslExtractionResult.update({
where: { id: resultId }, data: { status: 'error', errorMessage: error.message }
});
return { success: false, reason: 'Permanent Failure, aborted retry.' };
}
// 临时错误 (429/网络抖动):直接 throw让 pg-boss 自动指数退避重试
throw error;
}
### **4\. 极致落实 Clean Data 缓存机制**
* **业务痛点:** MinerU 表格解析极度昂贵且耗时。
* **✅ 标准解法:** 必须前置检查 OSS 缓存,避免重复计算。
const cleanDataKey \= \`pkb/${kbId}/${docId}\_mineru\_clean.html\`;
try {
const html \= await storage.download(cleanDataKey); // 优先读取缓存 (\<1秒)
return html;
} catch (e) {
const html \= await callPythonMinerUService(pdfKey); // Fallback: 真正调用
await storage.upload(cleanDataKey, Buffer.from(html)); // 同步存入 Clean Data
return html;
}
## **💻 前端架构排雷与对齐方案**
### **1\. 通信机制的优雅混合 (React Query \+ SSE)**
* **业务痛点:** 前端到底是采用 SSE 维持连接,还是用 React Query 轮询?混用会导致状态撕裂。
* **✅ 标准解法:**
* **主业务流控制 (Step 进度、成功/失败跳页)** 严格遵守《Postgres-Only 指南》步骤5。使用 useTaskStatus (React Query) 的 refetchInterval 进行串行稳健轮询。
* **视觉反馈增强 (终端日志流)** 引入 SSE 单向通道,仅用于给 \<ProcessingTerminal /\> 组件灌入实时的打字机日志流。即使 SSE 意外断开,也不会阻断主线业务流。
### **2\. 人机协作 (HITL) 抽屉的死锁解套**
* **业务痛点:** 若 AI 提取的 Quote 模糊匹配失败(置信度 \< 0.8),前端标红警告。但如果医生强行认为 AI 提取的没错,系统没有提供放行的交互,导致数据卡在 Pending 状态。
* **✅ 标准解法:** 抽屉内的错误警告框必须配套两个处理按钮:
1. \[强制认可\]:消除警告,在 payload 中标记 quote\_force\_accepted: true。
2. \[手动修改数值\]:医生直接修改 Input 框,系统自动给旧的错误 Quote 画上删除线,并提示“已转为人工干预,原文引用取消强绑定”。
### **3\. 规避签名 URL 过期导致的 403 报错**
* **业务痛点:** 医生复核 50 篇文献需要很长时间,预签名的 OSS PDF 链接容易过期。
* **✅ 标准解法:** 绝对禁止在加载列表时批量生成并缓存签名 URL。采用**懒加载**:仅当医生点击某行文献的“复核提单”并展开右侧抽屉时,前端才实时请求获取一个有效期为 10 分钟的临时 URL 赋给 iframe。