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>
6.5 KiB
🔍 深度架构审查与排雷指南:工具 3 全文智能提取 V1.2
审查人: 资深架构师 & 资深研发工程师
审查对象: 《工具 3:全文智能提取工作台 V2.0 开发计划 (v1.2 融合PKB版)》
审查结论: 战略方向(对接 PKB)极佳!但在领域驱动边界(DDD)、大模型上下文污染、队列扇出模式(Fan-out)及鉴权生命周期上存在高危漏洞,需立即修正。
🚨 致命隐患一:跨 Schema 直接查询打破了微服务边界
❌ 计划中的问题 (Task 3.3b & 7.4)
计划中提到:PkbBridgeService 直接通过 Prisma Client 查询 pkb_schema.PkbDocument。
架构灾难预警: 这是一个典型的“大泥球(Big Ball of Mud)”反模式。虽然现在 PKB 和 ASL 在同一个 PostgreSQL 实例里,但它们分属不同的 Schema。如果直接在 ASL 的代码里写 prisma.pkbDocument.findFirst(),两个模块的底层数据结构将被强行物理耦合。未来一旦 PKB 模块修改了表结构,或者做微服务拆分,ASL 将瞬间崩溃。
✅ 架构师修正方案:建立“防腐层 (ACL)”
绝不允许跨业务域直接读写数据库!必须通过 Service 内部方法调用(进程内调用) 或 依赖注入 来实现。
- 在 PKB 模块暴露一个内部只读服务接口,例如 PkbExportService.ts。
- ASL 的 PkbBridgeService 只能调用 PkbExportService.getDocumentsForAsl() 来获取所需的数据(storageKey, extractedText)。
- 收益: 这样 ASL 拿到的是 DTO(数据传输对象),而不是 Prisma 的底层 Model 实例,彻底解耦。
🚨 致命隐患二:双解析引擎导致的“大模型上下文污染”
❌ 计划中的问题 (Task 2.2)
计划中设计的流水线是:输入 A (PKB 的 pymupdf4llm 纯文本) + 输入 B (MinerU 提取的高保真 HTML 表格),然后一起丢给 DeepSeek-V3 提取数据。
算法灾难预警: PKB 里的 extractedText(由 pymupdf 提取)中,其实已经包含了一份“排版完全错乱的垃圾表格文本”。如果你把这段错乱的文本,连同 MinerU 完美的 HTML 表格一起喂给 LLM,大模型的注意力机制会被严重干扰。它很可能会在两份冲突的数据中产生“幻觉”,导致提取出的数值张冠李戴。
✅ 研发修正方案:在 Prompt 中建立“强制隔离区”
必须在 DynamicPromptBuilder 组装 User Prompt 时,对 LLM 下达极其严厉的隔离指令:
# 待处理文献素材
<FULL_TEXT>
{PKB_Extracted_Text}
</FULL_TEXT>
<HIGH_FIDELITY_TABLES>
{MinerU_HTML_Tables}
</HIGH_FIDELITY_TABLES>
# 特别警告 (CRITICAL WARNING)
<FULL_TEXT> 区域中的表格数据可能因解析原因存在行列错位。
**当您提取任何基线特征、人数、结局指标等表格数据时,必须【绝对优先】且【仅】参考 <HIGH_FIDELITY_TABLES> 区域的内容!** 只有当高保真表格中找不到数据时,才允许在正文文本中寻找。
🚨 致命隐患三:pg-boss 批处理的任务粒度过粗
❌ 计划中的问题 (Task 2.3)
计划中 extractBatch(jobId) 负责处理一次性勾选的 100 篇文献,并在内部使用了 P-Queue 控制并发。
容错灾难预警: 如果这 100 篇文献作为一个单一的 pg-boss Job,当提取到第 99 篇时,Node.js 容器因为内存溢出(OOM)重启了,或者服务器断电。pg-boss 会判定整个 Job 失败并从第 1 篇开始重试!这将导致极其严重的时间浪费和 API Token 烧毁。
✅ 架构师修正方案:采用“扇出模式 (Fan-out Workflow)”
后台任务的粒度必须细化到**“单篇文献”**。
- 父任务 (Manager Job): 用户点击开始,创建一个父任务。父任务扫描这 100 篇文献,向 pg-boss 队列派发 100 个子任务 (Child Jobs),然后父任务结束。
- 子任务 (Worker Job): 专门处理 extractOne(literatureId)。如果第 99 篇失败了,pg-boss 只会重试第 99 篇的子任务,前面 98 篇的成果绝对安全。
- SSE 进度追踪: SSE 监听器不再监听单一的 Job,而是监听 AslExtractionTask 表中 successCount + failedCount 的变化。
🚨 致命隐患四:前端 PDF 签名 URL (Signed URL) 过期问题
❌ 计划中的问题 (Task 5.3)
计划写道:“遵循 OSS 规范使用签名 URL,1 小时过期。在左侧 iframe 中预览 PDF”。
体验灾难预警: 工具 3 是一个重度“人机协同 (HITL)”工作台。医生复核 50 篇文献可能需要好几天,他们经常会让浏览器 Tab 挂在后台。如果用户吃个午饭回来(超过 1 小时),继续点击下一篇文献或查看当前 PDF 时,左侧的 iframe 会直接抛出 403 Forbidden(签名已过期),严重打断心流。
✅ 研发修正方案:动态获取与刷新策略
绝对不能在 Step 1 列表接口里就把 URL 签好发给前端。
- 懒加载签名 (Lazy Signing): 只有当医生点击“复核提单”,抽屉打开、需要渲染左侧 PDF 时,前端才发起一个轻量级请求 GET /api/v1/asl/extraction/results/:id/pdf-url,实时获取只有 10 分钟有效期的专属 URL 赋给 iframe。
- 前端拦截: 如果 iframe 加载失败或返回 403,前端组件自动捕获并静默重新请求上述接口刷新 URL,对用户完全透明。
💡 额外架构加分项 (Nice-to-Haves)
除了排雷,为了让 V2.0 真正达到企业级水准,建议加入以下设计:
- SSE 初次连接状态同步 (Hydration on Connect):
当用户刷新页面重建 SSE 连接时,后端必须在建立连接的第一时间(握手阶段),下发一个包含当前完整进度和最后 50 条日志的 sync 事件。否则用户只能干等下一个增量日志触发,页面会有一段时间是“空白”的。 - 零成本标优 (Cost Saving Tag):
既然因为复用 PKB 省去了大量 pymupdf4llm 的算力成本和时间,建议在终端日志 (Terminal) 里高亮打印:
[System] Fast-path engaged: Reused full-text Markdown from PKB. Saved ~12s.
这不仅能让用户感知到系统的高效,也能在展示产品时凸显技术优势。
📋 总结
计划在合并了 PKB 之后整体非常精彩,极大精简了业务流。请团队重点调整 Prisma 跨模块调用的解耦方式 和 pg-boss 的子任务分发机制,确保底层基座稳固后,再进入 Sprint 1 的开发。