# RVW V2.0 产品升级开发计划 > **文档版本:** v1.2 > **创建日期:** 2026-02-17 > **最后更新:** 2026-02-17 > **维护者:** 开发团队 > **项目代号:** "数据侦探" + "柔性架构" > **目标周期:** 4周(含缓冲) > **优先级:** P0 > **审查状态:** ✅ 已通过终审,纳入专家建议 (v1.2) --- ## 📋 目录 1. [项目概述](#1-项目概述) 2. [升级目标与范围](#2-升级目标与范围) 3. [技术架构设计](#3-技术架构设计) 4. [功能需求详述](#4-功能需求详述) 5. [分阶段实施计划](#5-分阶段实施计划) 6. [验收标准](#6-验收标准) 7. [风险管理](#7-风险管理) 8. [后续迭代规划](#8-后续迭代规划) 9. [附录](#9-附录) --- ## 1. 项目概述 ### 1.1 背景 当前 RVW 模块(V1.0/V3.2)是一个基于 LLM 的"文档阅读器",能较好地完成稿约规范性(11项标准)和方法学评估(20个检查点)。然而,在面对**中文核心期刊**(对政治安全和数据造假零容忍)和**高水平英文期刊**(对学术深度的要求)时,系统存在以下痛点: | 痛点 | 影响 | 紧迫度 | |------|------|--------| | **数据验证能力缺失** | 无法识别表格中的数据造假(P值捏造、合计错误) | 🔴 高 | | **架构僵化** | 无法针对不同期刊配置不同的审稿流程 | 🟡 中 | | **PDF解析瓶颈** | 复杂表格在PDF中识别率低,导致计算不可行 | 🔴 高 | ### 1.2 升级策略 采用 **"垂直切片 (Vertical Slice)"** 策略,不追求大而全,集中兵力攻克核心技术壁垒: - **以"数据侦探"功能为矛** —— 刺穿技术壁垒,实现Word表格的审计级验证 - **以"Skills架构"为盾** —— 构建系统底座,支持能力原子化和配置驱动 ### 1.3 核心指标 | 指标 | 当前 | 目标 | |------|------|------| | 表格数据提取准确率 | ~70%(PDF) | **≥98%**(Word) | | 算术错误检出率 | 0% | **≥95%** | | P值逻辑错误检出率 | 0% | **≥80%** | | 上传到出报告时间 | ~2分钟 | **≤3分钟**(含数据验证) | --- ## 2. 升级目标与范围 ### 2.1 MVP 范围定义(V2.0) | 维度 | ✅ MVP 包含 | ❌ MVP 不包含 | |------|------------|--------------| | **文件格式** | Word (.docx) 仅支持 | .doc、PDF、图片扫描件 | | **文件限制** | ≤ 20MB,单表 ≤ 500 行 | 超大文件、超长表格 | | **表格类型** | 三线表 (Standard Tables) | 跨页断裂表、极复杂嵌套表 | | **验证深度** | L1 (算术) + L2 (基础统计) + 🆕 L2.5 (一致性取证) | L3 (复杂回归逻辑)、L4 (跨表一致性) | | **统计方法** | T检验、卡方检验、🆕 回归一致性(SE 三角验证)、SD>Mean 检查 | ANOVA、配对检验、生存分析、非参数检验 | | **Skill 数量** | DataForensicsSkill + EditorialSkill | 政治审查、竞品对标 | | **配置方式** | 硬编码默认Profile | 动态Profile管理UI | | **前端交互** | 静态报告(新增数据验证Tab) | 交互式Chat、在线修改表格 | > ⚠️ **格式限制说明**:MVP 阶段仅支持 .docx 格式。若用户上传 .doc 文件,前端提示"请使用 Word 另存为 .docx 格式后重新上传"。此决策基于 LibreOffice 容器化复杂度高、收益低的评估,V2.1 将评估 Pandoc 等替代方案。 ### 2.2 与 V1.0 的关系 | 能力 | V1.0 | V2.0 | |------|------|------| | 稿约规范性评估(11项) | ✅ 保留 | ✅ 封装为 EditorialSkill | | 方法学评估(20个检查点) | ✅ 保留 | ✅ 封装为 MethodologySkill | | 数据表格验证 | ❌ 无 | ✅ **新增 DataForensicsSkill** | | Skills 架构 | ❌ 无 | ✅ **新增** | | Word 导出 | ✅ 保留 | ✅ 保留 | --- ## 3. 技术架构设计 ### 3.1 总体架构 ``` ┌─────────────────────────────────────────────────────────────────┐ │ 输入层 (Input Layer) │ │ 稿件 (Word/PDF) + 期刊配置 (Journal Profile) │ └─────────────────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────────────┐ │ Layer 1: 护栏中间件 (Middleware Guardrails) │ │ 🛡️ Pre-Hook: 格式校验、敏感词扫描(V2.1 政治审查) │ │ 🛡️ Post-Hook: 幻觉检测(V2.1) │ └─────────────────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────────────┐ │ Layer 2: 审稿编排引擎 (The Core) │ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │ │ Skills │ │ Skill │ │ Shared │ │ │ │ Registry │ │ Router │ │ Context │ │ │ │ 技能注册表 │ │ 动态路由 │ │ 共享上下文 │ │ │ └─────────────┘ └─────────────┘ └─────────────┘ │ └─────────────────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────────────┐ │ Layer 3: 原子能力库 (Skills Library) │ │ │ │ ┌──────────────────┐ ┌──────────────────┐ │ │ │ 🐍 DataForensics │ │ 📋 Editorial │ │ │ │ Skill │ │ Skill │ │ │ │ (Python计算) │ │ (稿约规范性) │ │ │ └──────────────────┘ └──────────────────┘ │ │ │ │ ┌──────────────────┐ ┌──────────────────┐ │ │ │ 🔬 Methodology │ │ 🧠 MedicalLogic │ ← V2.1 │ │ │ Skill │ │ Skill │ │ │ │ (方法学评估) │ │ (常识校验) │ │ │ └──────────────────┘ └──────────────────┘ │ └─────────────────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────────────┐ │ 输出层 (Output Layer) │ │ 📊 SOP 引擎(静态审稿报告) ← V2.0 MVP │ │ 💬 ReAct 引擎(交互式对话) ← V2.2 规划 │ └─────────────────────────────────────────────────────────────────┘ ``` ### 3.2 数据流图 ``` ┌─────────────────────────────────────────────────────────────────────────┐ │ 用户上传 .docx │ └─────────────────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────────────┐ │ Node.js Backend (reviewService) │ │ ┌──────────────────────────────────────────────────────────────┐ │ │ │ 1. 调用 Python 提取文本 (ExtractionClient, HTTP 120s) │ │ │ │ 2. 推送到 pg-boss 队列 (rvw_review_task) │ │ │ └──────────────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────────────────┘ │ pg-boss 异步调度 ▼ ┌─────────────────────────────────────────────────────────────────────────┐ │ reviewWorker (异步执行) │ │ ┌──────────────────────────────────────────────────────────────┐ │ │ │ 3. DataForensicsSkill → 调用 Python API (HTTP 60s) │ │ │ │ 4. EditorialSkill → 调用 LLM │ │ │ │ 5. MethodologySkill → 调用 LLM │ │ │ │ 6. 汇总结果 → 存储到 ReviewTask.contextData │ │ │ └──────────────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────────────┐ │ Python Service (extraction_service) │ │ ┌──────────────────────────────────────────────────────────────┐ │ │ │ 现有: /api/extract/docx (文本提取, mammoth/python-docx) │ │ │ │ 🆕 新增: /api/v1/forensics/analyze_docx │ │ │ │ - python-docx 表格提取 │ │ │ │ - pandas 数据处理 │ │ │ │ - scipy 统计验证 (🆕 需新增依赖) │ │ │ │ - 返回 HTML 片段 + R1C1 坐标 │ │ │ └──────────────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────────────────┘ ``` **通信机制说明**: | 通信路径 | 方式 | 超时 | 说明 | |---------|------|------|------| | reviewService → pg-boss | 异步队列 | - | ✅ 已有,任务调度 | | ExtractionClient → Python | HTTP 同步 | 60-120s | ✅ 已有,文本提取 | | DataForensicsSkill → Python | HTTP 同步 | 60s | 🆕 新增,表格验证 | > 📋 **架构复用**:V2.0 复用现有 pg-boss 异步架构,DataForensicsSkill 作为 reviewWorker 中的一个步骤执行,与 EditorialSkill/MethodologySkill 平级。 ### 3.3 Skill 接口标准 ```typescript // backend/src/modules/rvw/skills/core/types.ts interface SkillContext { taskId: string; documentContent: string; // Markdown 格式的文档内容 documentPath?: string; // 原始文件路径(用于Python处理) tables?: TableData[]; // 提取的表格数据 methods?: string[]; // 检测到的统计方法 previousResults?: SkillResult[]; // 前置Skill的结果 } interface SkillResult { skillId: string; status: 'success' | 'warning' | 'error' | 'timeout'; // 新增 timeout 状态 score?: number; // 0-100 评分 issues: Issue[]; // 发现的问题列表 data?: any; // 结构化数据 executionTime: number; // 执行耗时(ms) timedOut?: boolean; // 是否超时 } interface Issue { severity: 'ERROR' | 'WARNING' | 'INFO'; type: string; // 问题类型代码 message: string; // 人类可读描述 location?: { // 问题位置 tableId?: string; cellRef?: string; // R1C1 坐标格式,如 "R3C4" paragraph?: number; }; evidence?: any; // 证据数据 } interface Skill { id: string; name: string; description: string; timeout: number; // 🆕 超时时间(ms),默认 30000 run(context: SkillContext, config?: any): Promise; } // 🆕 Skill 执行配置 interface SkillExecutionConfig { defaultTimeout: number; // 默认 30000ms (30s) maxRetries: number; // 默认 0(不重试) continueOnError: boolean; // 单个 Skill 失败是否继续,默认 true } ``` > 📋 **R1C1 坐标系统**:所有单元格位置使用 R1C1 格式(如 `R3C4` 表示第3行第4列),确保前后端定位一致。前端根据此坐标直接高亮对应 `` 元素。 ### 3.4 Profile 配置结构 ```typescript // MVP 阶段:硬编码默认配置 // V2.1 阶段:迁移到数据库 interface JournalProfile { id: string; name: string; // 如 "中华医学超声杂志" skills: string[]; // 要执行的Skill列表 strictness: 'STRICT' | 'STANDARD' | 'LENIENT'; config?: { dataForensics?: { checkLevel: 'L1' | 'L1_L2' | 'L1_L2_L3'; tolerancePercent: number; // 容错百分比,默认 0.1 }; editorial?: { // 稿约规范性配置 }; }; } // MVP 默认 Profile const DEFAULT_PROFILE: JournalProfile = { id: 'default', name: '通用期刊', skills: ['DataForensicsSkill', 'EditorialSkill'], strictness: 'STANDARD', config: { dataForensics: { checkLevel: 'L1_L2', tolerancePercent: 0.1 } } }; ``` --- ## 4. 功能需求详述 ### 4.1 数据侦探 (DataForensicsSkill) #### 4.1.1 Word 表格精准提取 | 需求ID | 需求描述 | 优先级 | |--------|---------|--------| | FR-1.1 | 识别 Word 文档中的所有表格对象 | P0 | | FR-1.2 | 处理合并单元格(Forward Fill 策略) | P0 | | FR-1.3 | 关联表格 Caption(向前回溯提取 "Table X. xxx") | P0 | | FR-1.4 | 文件格式校验(仅接受 .docx,≤20MB) | P0 | | FR-1.5 | 单表行数限制(≤500行,超出跳过并警告) | P1 | > ⚠️ **FR-1.4 变更说明**:原计划通过 LibreOffice 支持 .doc 格式,经评估 Docker 容器化复杂度过高(需 headless 模式、字体配置、进程池管理),决定 MVP 阶段仅支持 .docx。.doc 支持推迟到 V2.1 评估 Pandoc 等替代方案。 **合并单元格处理示例**: ``` 原始表格: | Group A | Group B | |-------|--------|---------| | Male | Female | | | 50 | 45 | 60 | Forward Fill 后: | Group A | Group A | Group B | |---------|---------|---------| | Male | Female | | | 50 | 45 | 60 | ``` #### 4.1.2 L1 算术自洽性验证 | 需求ID | 需求描述 | 优先级 | |--------|---------|--------| | FR-2.1 | 识别 n (%) 格式,验证 n/N 是否等于 % | P0 | | FR-2.2 | 识别 Total 列,验证是否等于其他列之和 | P0 | | FR-2.3 | 容错范围:±0.1%(可配置) | P0 | **验证逻辑示例**: ```python # 输入: "45 (50.0%)",Total N = 90 # 计算: 45 / 90 = 0.5 = 50.0% ✅ 通过 # 输入: "45 (60.0%)",Total N = 90 # 计算: 45 / 90 = 0.5 = 50.0% ≠ 60.0% ❌ 错误 ``` #### 4.1.3 L2 统计学复核 | 需求ID | 需求描述 | 支持状态 | |--------|---------|---------| | FR-3.1 | 独立样本 T 检验 P 值逆向验证 | ✅ MVP | | FR-3.2 | 卡方检验 P 值逆向验证 | ✅ MVP | | FR-3.3 | CI 与 P 值逻辑一致性检查 | ✅ MVP | | FR-3.4 | ANOVA 多组比较 | ❌ V2.1 | | FR-3.5 | 配对 T 检验 / McNemar | ❌ V2.1 | | FR-3.6 | 生存分析 (Log-rank, Cox) | ❌ V2.2 | | FR-3.7 | 非参数检验 (Mann-Whitney, Wilcoxon) | ❌ V2.1 | | FR-3.8 | 回归分析 (Logistic, Cox, Linear) | ❌ V2.2 | **CI 与 P 值逻辑检查(黄金法则)**: ``` 对于 OR/HR/RR 数据: - 若 95% CI 跨越 1.0(如 0.8-1.2)→ P 值必须 ≥ 0.05 - 若 95% CI 不跨越 1.0(如 1.1-1.5)→ P 值必须 < 0.05 违反此规则 = 数据逻辑矛盾,高度疑似造假 ``` #### 4.1.4 方法学定位(确定性规则优先) 采用**正则匹配优先,LLM兜底**的策略,减少幻觉风险: ```python # 确定性规则 METHOD_PATTERNS = { "t-test": r"(t[\s-]?test|student.*test|independent.*sample|独立样本)", "chi-square": r"(chi[\s-]?square|χ2|卡方|pearson.*chi)", "anova": r"(anova|analysis\s+of\s+variance|方差分析)", "logistic": r"(logistic\s+regression|逻辑回归|二元回归)", "cox": r"(cox\s+regression|cox\s+proportional|生存分析|比例风险)", "mann-whitney": r"(mann[\s-]?whitney|wilcoxon|秩和检验)", } def extract_methods(text: str) -> list: """优先使用正则匹配,仅在无结果时调用LLM""" found = [] for method, pattern in METHOD_PATTERNS.items(): if re.search(pattern, text, re.IGNORECASE): found.append(method) # 如果正则无结果,可选调用LLM(V2.1增强) if not found: found = llm_extract_methods(text) # 兜底 return found ``` ### 4.2 Skills 架构 #### 4.2.1 Skill 注册与发现 | 需求ID | 需求描述 | 优先级 | |--------|---------|--------| | FR-4.1 | 实现 SkillRegistry 注册表 | P0 | | FR-4.2 | 支持 Skill 按 ID 获取 | P0 | | FR-4.3 | 支持 Skill 列表查询 | P1 | #### 4.2.2 Skill 编排执行 | 需求ID | 需求描述 | 优先级 | |--------|---------|--------| | FR-5.1 | 根据 Profile 依次执行 Skills | P0 | | FR-5.2 | 前置 Skill 结果传递给后续 Skill | P0 | | FR-5.3 | 单个 Skill 失败不影响其他 Skill | P0 | | FR-5.4 | 执行结果汇总存储到 contextData | P0 | | FR-5.5 | 🆕 Skill 执行超时熔断(30s) | P0 | | FR-5.6 | 🆕 DataForensics 失败时降级执行 | P0 | #### 4.2.3 🆕 超时熔断机制 ```typescript // backend/src/modules/rvw/skills/core/executor.ts async function executeWithTimeout(skill: Skill, context: SkillContext): Promise { const timeout = skill.timeout || 30000; // 默认 30s try { const result = await Promise.race([ skill.run(context), new Promise((_, reject) => setTimeout(() => reject(new Error('Skill execution timeout')), timeout) ) ]); return result; } catch (error) { if (error.message === 'Skill execution timeout') { logger.warn({ skillId: skill.id, timeout }, 'Skill execution timed out'); return { skillId: skill.id, status: 'timeout', issues: [{ severity: 'WARNING', type: 'SKILL_TIMEOUT', message: `${skill.name} 执行超时,已跳过` }], executionTime: timeout, timedOut: true }; } throw error; } } ``` #### 4.2.4 🆕 Fallback 降级机制 当 DataForensicsSkill(Word 表格提取)失败时,系统不应完全中断,而是降级运行: ``` 正常流程: DataForensicsSkill ✅ → EditorialSkill → MethodologySkill → 完整报告 Fallback 流程(提取失败时): DataForensicsSkill ❌ → EditorialSkill → MethodologySkill → 部分报告 ↑ 记录失败原因,报告中显示: "数据验证功能暂不可用:[具体原因] 建议:请检查 Word 文件格式或联系管理员" ``` **前端展示**: - 数据验证 Tab 显示警告状态(黄色) - 清晰说明失败原因 - 不影响其他审稿结果的展示 ### 4.3 前端展示 #### 4.3.1 数据验证报告 | 需求ID | 需求描述 | 优先级 | |--------|---------|--------| | FR-6.1 | TaskDetail 新增"数据验证"Tab | P0 | | FR-6.2 | 🆕 直接渲染后端返回的 HTML 片段 | P0 | | FR-6.3 | 错误列表展示(按严重程度排序) | P0 | | FR-6.4 | 🆕 根据 R1C1 坐标高亮单元格 | P1 | | FR-6.5 | 错误类型图标和颜色区分 | P1 | | FR-6.6 | 🆕 提取失败时的降级展示 | P0 | #### 4.3.2 🆕 后端渲染一致性保障 为确保前端表格显示与后端数据提取 100% 一致,采用"后端渲染"策略: ```typescript // 后端返回的表格数据结构 interface TableRenderData { id: string; // 表格ID caption: string; // 表格标题 html: string; // 🆕 预渲染的 HTML 片段 data: string[][]; // 原始二维数组(备用) issues: Issue[]; // 问题列表,含 R1C1 坐标 } // 前端高亮实现 function highlightCell(tableId: string, cellRef: string) { // cellRef 格式: "R3C4" -> 第3行第4列 const [, row, col] = cellRef.match(/R(\d+)C(\d+)/); const cell = document.querySelector( `#${tableId} td[data-coord="R${row}C${col}"]` ); cell?.classList.add('highlight-error'); } ``` **HTML 片段示例**: ```html
Table 1. Baseline Characteristics
Variable Group A Group B
Age 45.2 ± 12.3 48 (60.0%)
``` #### 4.3.3 🆕 问题严重程度分级(终审建议) 为避免"狼来了"效应,系统对发现的问题进行严格分级: | 级别 | 图标 | 标准 | 示例 | |------|------|------|------| | **🔴 Error** | ❌ | 数据确定性错误,几乎不可能是舍入/格式问题 | 算术加和不等、P 值严重矛盾(算出 <0.001,报告 >0.05)、SD > Mean(正值指标) | | **🟡 Warning** | ⚠️ | 疑似问题,可能是舍入误差或格式差异 | P 值轻微偏差(±0.01)、Table 1 P 值分布过于完美、无法验证仅提示 | | **🔵 Info** | ℹ️ | 提示信息,非错误 | 未检测到统计方法、跳过大表格 | **前端展示规则**: - Error: 红色高亮 + 置顶展示 + 必须关注 - Warning: 黄色高亮 + 建议审阅 - Info: 灰色 + 可折叠 **容错阈值配置**(终审建议): ```python # 舍入误差容错 P_VALUE_TOLERANCE = 0.01 # P值允许 ±0.01 差异 P_VALUE_RELATIVE_TOL = 0.05 # 或相对误差 ±5% CI_TOLERANCE_PERCENT = 0.02 # CI 端点允许 ±2% 相对误差 # 只有超出容错阈值才报 Error,否则报 Warning ``` --- ## 5. 分阶段实施计划 ### 5.1 总体时间线 ``` Week 1 Week 2 Week 3 Week 4 ├─────────────┼─────────────┼─────────────┼─────────────┤ │ Python 核心 │ Node.js架构 │ 前端 + 联调 │ 测试 + 上线 │ │ L1 算术验证 │ Skills封装 │ 报告UI开发 │ Bug修复 │ │ 表格提取 │ L2统计补充 │ 全链路测试 │ 文档更新 │ └─────────────┴─────────────┴─────────────┴─────────────┘ ``` ### 5.2 Week 1: Python 核心能力(Day 1-5) **目标**:输入 .docx 文件,Python API 能返回"第几张表第几行算错了" + HTML 预渲染片段 | Day | 任务 | 产出物 | 负责人 | |-----|------|--------|--------| | **Day 1** | 环境准备 | 依赖配置完成 | Python | | | - 更新 python-extraction 镜像 | requirements.txt 更新 | | | | - 引入 python-docx, pandas, scipy | | | | | - 文件大小/格式校验逻辑 | | | | **Day 2** | 表格提取器开发 | DocxTableExtractor 类 | Python | | | - 解析 Word DOM 结构 | | | | | - 处理合并单元格(Forward Fill) | | | | | - 关联表格 Caption | | | | | - 🆕 生成 HTML 片段(含 data-coord 属性) | | | | **Day 3** | L1 算术验证器 + 🆕 L2.5 一致性取证 | ArithmeticValidator + ConsistencyValidator 类 | Python | | | - n (%) 格式解析 | | | | | - Sum/Total 校验 | | | | | - 容错逻辑(±0.1%) | | | | | - 🆕 返回 R1C1 坐标定位 | | | | | - 🆕 **SE 三角验证**(回归系数/OR/HR 一致性) | | | | | - 🆕 **SD > Mean 检查**(正值指标启发式规则) | | | | | - 🆕 **CI 字符串清洗器**(处理多种分隔符格式) | | | | **Day 4** | API 封装 | /api/v1/forensics/analyze_docx | Python | | | - 请求/响应格式定义 | | | | | - 🆕 返回 HTML + JSON 双格式 | | | | | - 错误处理(含降级提示) | | | | | - 日志记录 | | | | **Day 5** | 单元测试 + 联调 | 测试用例通过 | Python | | | - 准备 5 个测试稿件(.docx) | | | | | - 验证提取准确率 | | | | | - 🆕 验证 HTML 渲染一致性 | | | | | - 修复发现的问题 | | | **关键交付物**: - `extraction_service/forensics/extractor.py` - 表格提取器(含 HTML 生成) - `extraction_service/forensics/validator.py` - 算术验证器 - `extraction_service/forensics/consistency.py` - 🆕 一致性取证验证器(SE 三角、SD>Mean) - `extraction_service/forensics/api.py` - API 路由 - `POST /api/v1/forensics/analyze_docx` 接口可用 **依赖变更**(`requirements.txt` / `requirements-prod.txt`): ```diff # 现有依赖(已满足) python-docx==1.1.0 # ✅ Docx 读取 pandas>=2.0.0 # ✅ 表格处理 # 新增依赖 + scipy>=1.11.0 # 🆕 T检验、卡方检验逆向计算 ``` > 📋 **v1.1 变更**:移除 LibreOffice 配置,Day 1 更加轻量化。新增 HTML 片段生成,确保前后端渲染一致性。 ### 5.3 Week 2: Node.js 架构 + L2 统计(Day 6-10) **目标**:后端通过 Skills 模式执行审稿,不再硬编码逻辑 | Day | 任务 | 产出物 | 负责人 | |-----|------|--------|--------| | **Day 6** | L2 统计验证器 | StatValidator 类 | Python | | | - T 检验逆向计算 | | | | | - 卡方检验逆向计算 | | | | | - CI vs P 值逻辑检查 | | | | **Day 7** | Skill 接口定义 | types.ts, registry.ts | Node.js | | | - 定义 Skill 接口 | | | | | - 实现 SkillRegistry | | | | | - 实现 SkillExecutor | | | | **Day 8** | DataForensicsSkill | DataForensicsSkill.ts | Node.js | | | - 调用 Python API | | | | | - 结果转换为 SkillResult | | | | | - 错误处理 | | | | **Day 9** | EditorialSkill 封装 | EditorialSkill.ts | Node.js | | | - 封装现有 editorialService | | | | | - 适配 Skill 接口 | | | | **Day 10** | ReviewService 改造 | reviewService.ts 更新 | Node.js | | | - 引入 Profile 配置 | | | | | - 使用 SkillExecutor 执行 | | | | | - 存储 contextData | | | **关键交付物**: - `backend/src/modules/rvw/skills/core/` - 核心框架 - `backend/src/modules/rvw/skills/library/` - Skill 实现 - ReviewService 支持 Skills 模式 ### 5.4 Week 3: 前端开发 + 联调(Day 11-15) **目标**:用户能看到专业的"数据体检报告" | Day | 任务 | 产出物 | 负责人 | |-----|------|--------|--------| | **Day 11** | 数据验证 Tab | DataForensicsTab.tsx | Frontend | | | - Tab 切换逻辑 | | | | | - 数据获取 Hook | | | | **Day 12** | 表格渲染组件 | ForensicsTable.tsx | Frontend | | | - 表格 HTML 渲染 | | | | | - 单元格高亮支持 | | | | **Day 13** | 错误列表组件 | IssueList.tsx | Frontend | | | - 按严重程度排序 | | | | | - 点击定位功能 | | | | | - 错误类型图标 | | | | **Day 14** | 全链路联调 | E2E 测试通过 | 全员 | | | - 上传 → Python → Node → 前端 | | | | | - 修复集成问题 | | | | **Day 15** | UI 优化 | 样式完善 | Frontend | | | - 响应式适配 | | | | | - 加载状态 | | | | | - 空状态处理 | | | **关键交付物**: - `frontend-v2/src/modules/rvw/components/DataForensicsTab.tsx` - `frontend-v2/src/modules/rvw/components/ForensicsTable.tsx` - `frontend-v2/src/modules/rvw/components/IssueList.tsx` ### 5.5 Week 4: 测试与上线(Day 16-20) **目标**:稳定发布,文档完善 | Day | 任务 | 产出物 | 负责人 | |-----|------|--------|--------| | **Day 16** | 功能测试 | 测试报告 | QA | | | - 正常流程测试 | | | | | - 边界情况测试 | | | | | - 错误处理测试 | | | | **Day 17** | 性能测试 | 性能报告 | QA | | | - 100 页 Word 文档测试 | | | | | - 并发上传测试 | | | | **Day 18** | Bug 修复 | Bug 清零 | 开发 | | | - 修复测试发现的问题 | | | | **Day 19** | 文档更新 | 更新完成 | 全员 | | | - 更新模块状态文档 | | | | | - API 文档补充 | | | | | - 用户使用指南 | | | | **Day 20** | 上线部署 | 生产环境可用 | DevOps | | | - 更新 Docker 镜像 | | | | | - SAE 部署 | | | | | - 监控配置 | | | --- ## 6. 验收标准 ### 6.1 功能验收 | 验收项 | 标准 | 验证方法 | |--------|------|---------| | **表格提取准确率** | ≥98%(三线表) | 10份标准稿件测试 | | **L1 算术检测** | 能检出 Sum 错误(如 50+50=90) | 构造错误稿件测试 | | **L2 P值检测** | 能检出 P 值逻辑错误 | 构造矛盾稿件测试 | | **CI vs P 逻辑** | 能检出 CI 与 P 值矛盾 | 构造矛盾稿件测试 | | **Skills 架构** | 代码中无硬编码审稿逻辑 | 代码审查 | | **前端展示** | 错误高亮清晰可见 | UI 走查 | ### 6.2 性能验收 | 验收项 | 标准 | 验证方法 | |--------|------|---------| | **处理时间** | 单文档 ≤ 60秒(100页内) | 计时测试 | | **并发处理** | 支持 5 个文档同时处理 | 压力测试 | | **稳定性** | 连续 20 个文档无崩溃 | 稳定性测试 | ### 6.3 代码验收 | 验收项 | 标准 | |--------|------| | **TypeScript 类型** | 无 any 类型滥用 | | **错误处理** | 所有 async 函数有 try-catch | | **日志规范** | 使用 logger 服务 | | **云原生规范** | 符合项目开发规范 | ### 6.4 🆕 非功能性需求 (NFRs) | 需求 | 指标 | 验证方法 | |------|------|---------| | **文件大小限制** | 上传文件 ≤ 20MB | 前端校验 + 后端拦截 | | **表格行数限制** | 单表 ≤ 500 行 | 后端校验,超出跳过并警告 | | **Python 服务并发** | 支持 10 个并发请求 | 压力测试 | | **Skill 执行超时** | 单个 Skill ≤ 30s | 熔断机制 | | **HTTP 调用超时** | Node.js → Python ≤ 60s | 配置校验 | | **格式兼容性** | 仅 .docx,.doc 前端提示转换 | 功能测试 | > 📋 **并发说明**:移除 LibreOffice 后,Python 服务为纯 CPU 计算,无进程池管理开销,并发能力提升。建议初始配置 10 并发,根据生产环境压测调整。 --- ## 7. 风险管理 ### 7.1 技术风险 | 风险 | 可能性 | 影响 | 缓解措施 | |------|--------|------|---------| | 合并单元格处理复杂度超预期 | 🟡 中 | 🔴 高 | Day 2 重点攻关,预留 Day 5 缓冲 | | P 值逆向计算精度不够 | 🟡 中 | 🟡 中 | 设置合理阈值(差异 > 0.05 才报错) | | 🆕 用户上传 .doc 文件被拒 | 🟡 中 | 🟡 中 | 前端清晰提示,提供转换指导 | | 🆕 HTML 渲染在不同浏览器表现不一致 | 🟢 低 | 🟡 中 | 使用标准 HTML table 标签,避免复杂 CSS | | Python 镜像体积过大 | 🟡 中 | 🟢 低 | 优化依赖,使用多阶段构建 | > 📋 **v1.1 变更**:移除 LibreOffice 相关风险(容器化、性能),新增 .doc 拒绝和浏览器兼容性风险。整体风险等级降低。 ### 7.2 进度风险 | 风险 | 可能性 | 影响 | 缓解措施 | |------|--------|------|---------| | Week 1 延期 | 🟡 中 | 🔴 高 | Week 4 有缓冲天数 | | 联调发现重大问题 | 🟡 中 | 🟡 中 | Day 14 提前联调 | | 测试人力不足 | 🟢 低 | 🟡 中 | 开发自测覆盖基础用例 | ### 7.3 应急预案 - **如果 Week 1 严重延期**:砍掉 L2 统计验证,仅保留 L1 算术验证 - **如果前端来不及**:直接使用后端 HTML 片段,简化高亮交互 - **如果 Skills 架构复杂度过高**:MVP 阶段暂不封装,直接调用 - **🆕 如果 DataForensics 频繁失败**:启用降级模式,优先保证 EditorialSkill 正常运行 --- ## 8. 后续迭代规划 ### 8.1 V2.1 迭代(预计 4 周) **主题**:扩展统计验证能力 + 护栏中间件 + 格式兼容 | 功能 | 描述 | 优先级 | |------|------|--------| | **ANOVA 验证** | 多组比较 P 值验证 | P0 | | **配对检验** | Paired T-test, McNemar | P0 | | **非参数检验** | Mann-Whitney, Wilcoxon | P0 | | **🆕 .doc 格式支持** | 评估 Pandoc 替代方案 | P1 | | **方法学章节定位** | 自动提取"统计分析"段落 | P1 | | **政治护栏** | 敏感词扫描(Pre-Hook) | P1 | | **Profile 管理 UI** | 期刊配置界面 | P2 | ### 8.2 V2.2 迭代(预计 6 周) **主题**:复杂统计 + 交互式对话 | 功能 | 描述 | 优先级 | |------|------|--------| | **生存分析验证** | Log-rank, Cox 回归 | P0 | | **回归分析验证** | Logistic, Linear, Cox | P0 | | **跨表一致性检查** | 多表数据交叉验证 | P1 | | **ReAct 对话引擎** | 交互式审稿问答 | P1 | | **MedicalLogicSkill** | 医学常识校验(pgvector) | P2 | | **BenchmarkSkill** | 竞品对标(联动 ASL) | P2 | ### 8.3 V2.3 迭代(预计 4 周) **主题**:高级功能 + 独立产品 | 功能 | 描述 | 优先级 | |------|------|--------| | **PDF 支持** | 基于视觉模型的表格识别 | P1 | | **图片查重** | 图片相似度检测 | P2 | | **独立产品打包** | 独立部署版本 | P2 | | **审稿人管理** | 多审稿人协作 | P3 | --- ## 9. 附录 ### 9.1 Python API 接口规范 **Endpoint**: `POST /api/v1/forensics/analyze_docx` **Request**: ```json { "file_url": "oss://.../manuscript.docx", "config": { "check_level": "L1_L2", "tolerance_percent": 0.1, "max_table_rows": 500 } } ``` **Response(成功)**: ```json { "success": true, "methods_found": ["t-test", "chi-square"], "tables": [ { "id": "tbl_0", "caption": "Table 1. Baseline Characteristics", "type": "BASELINE", "row_count": 10, "col_count": 5, "html": "...
Table 1...
Variable
", "issues": [ { "severity": "ERROR", "type": "ARITHMETIC_ERROR", "cell_ref": "R3C4", "message": "计算百分比 (48.0%) 与报告值 (50.0%) 不符", "evidence": { "calculated": 48.0, "reported": 50.0, "n": 24, "N": 50 } } ], "data": [ ["Variable", "Group A", "Group B", "P-value"], ["Age", "45.2 ± 12.3", "44.8 ± 11.9", "0.82"] ] } ], "execution_time_ms": 1234 } ``` **Response(失败/降级)**: ```json { "success": false, "error": { "code": "EXTRACTION_FAILED", "message": "Word 文档结构异常,无法提取表格", "details": "表格嵌套过深,超出解析能力" }, "fallback_available": true, "execution_time_ms": 234 } ``` > 📋 **v1.1 新增**: > - 响应中增加 `html` 字段,包含预渲染的 HTML 片段 > - 单元格包含 `data-coord` 属性用于前端高亮定位 > - 新增失败响应格式,支持前端降级展示 ### 9.2 数据库变更 ```prisma // prisma/schema.prisma 变更 model ReviewTask { // ... 现有字段 ... // V2.0 新增 contextData Json? // Skills 执行结果汇总 profileId String? // 使用的 Profile ID skillsExecuted String[] // 已执行的 Skill 列表 } ``` ### 9.3 目录结构 ``` backend/src/modules/rvw/ ├── routes/index.ts ├── controllers/reviewController.ts ├── services/ │ ├── reviewService.ts # 主服务(改造) │ ├── editorialService.ts # 保留 │ └── methodologyService.ts # 保留 ├── skills/ # 🆕 新增 │ ├── core/ │ │ ├── types.ts # 接口定义 │ │ ├── registry.ts # 注册表 │ │ └── executor.ts # 执行器 │ ├── library/ │ │ ├── DataForensicsSkill.ts # 数据侦探 │ │ ├── EditorialSkill.ts # 稿约规范性 │ │ └── MethodologySkill.ts # 方法学评估 │ └── profiles/ │ └── default.ts # 默认配置 ├── workers/reviewWorker.ts └── types/index.ts extraction_service/ # Python 微服务(现有) ├── main.py # FastAPI 入口 ├── extractors/ # 现有提取器 │ ├── pdf_extractor.py │ ├── docx_extractor.py │ └── ... ├── forensics/ # 🆕 新增模块 │ ├── __init__.py │ ├── extractor.py # Word 表格提取 │ ├── html_renderer.py # HTML 片段生成(含 data-coord) │ ├── validator.py # 算术/统计验证 │ └── api.py # FastAPI 路由 ├── requirements.txt # 开发依赖(+ scipy) └── requirements-prod.txt # 生产依赖(+ scipy) frontend-v2/src/modules/rvw/ ├── pages/Dashboard.tsx ├── components/ │ ├── TaskDetail.tsx # 修改(新增 Tab) │ ├── DataForensicsTab.tsx # 🆕 新增 │ ├── ForensicsTable.tsx # 🆕 新增 │ ├── IssueList.tsx # 🆕 新增 │ └── ... └── types/index.ts # 更新类型 ``` ### 9.4 测试数据准备清单 MVP 开发前需准备以下测试稿件(全部为 .docx 格式): | # | 稿件类型 | 用途 | 状态 | |---|---------|------|------| | 1 | 标准三线表稿件(正确) | 基准测试 | ⬜ 待准备 | | 2 | 含算术错误的稿件 | L1 验证测试 | ⬜ 待准备 | | 3 | 含 P 值错误的稿件 | L2 验证测试 | ⬜ 待准备 | | 4 | 含 CI vs P 矛盾的稿件 | 逻辑检查测试 | ⬜ 待准备 | | 5 | 复杂合并单元格稿件 | 边界测试 | ⬜ 待准备 | | 6 | 100 页长稿件 | 性能测试 | ⬜ 待准备 | | 7 | 🆕 超大表格稿件(>500行) | 限制测试 | ⬜ 待准备 | | 8 | 🆕 损坏/异常 Word 文件 | 降级测试 | ⬜ 待准备 | > 📋 **v1.1 变更**:移除 .doc 格式测试,新增超大表格和异常文件测试用例。 ### 9.5 Python 依赖变更清单 **现有依赖(已满足,无需修改)**: | 依赖 | 版本 | 用途 | 状态 | |------|------|------|------| | `python-docx` | 1.1.0 | Word 文档解析、表格提取 | ✅ 已有 | | `pandas` | ≥2.0.0 | DataFrame 处理、数据清洗 | ✅ 已有 | | `pdfplumber` | 0.10.3 | 备用 PDF 处理 | ✅ 已有 | | `fastapi` | 0.104.1 | API 框架 | ✅ 已有 | | `loguru` | 0.7.2 | 日志 | ✅ 已有 | **需新增依赖**: | 依赖 | 版本 | 用途 | 大小 | |------|------|------|------| | `scipy` | ≥1.11.0 | T检验、卡方检验统计计算 | ~30MB | **requirements.txt 变更**: ```diff # 在 pandas 行后添加 pandas>=2.0.0 # 表格处理 + scipy>=1.11.0 # 统计验证(T检验、卡方检验) ``` > 📋 **依赖说明**:scipy 是 numpy 生态的标准统计库,与现有 pandas 兼容良好,不会引入冲突。 ### 9.6 相关文档索引 | 文档 | 路径 | 说明 | |------|------|------| | PRD | `00-系统设计/RVW V2.0 MVP 产品需求文档 (PRD).md` | 产品需求 | | 架构方案 | `00-系统设计/RVW V2.0 架构升级方案:基于 Skills 的柔性审稿引擎.md` | 技术架构 | | 技术设计 | `00-系统设计/RVW V2.0 数据侦探:Word 优先架构技术设计文档.md` | 详细设计 | | 实施计划 | `00-系统设计/RVW V2.0 融合实施作战计划:架构与功能的统一.md` | 原始计划 | | V1.0 状态 | `00-模块当前状态与开发指南.md` | 当前状态 | --- **文档版本:** v1.1.1 **创建日期:** 2026-02-17 **下次更新:** Week 1 结束后更新进度 **状态:** 📋 待启动(团队审查通过,代码一致性已校验) --- ## 📝 变更记录 | 日期 | 版本 | 变更内容 | 作者 | |------|------|---------|------| | 2026-02-17 | v1.0 | 初始版本,整合 PRD + 架构 + 技术设计 + 审查建议 | 开发团队 | | 2026-02-17 | v1.1 | 根据团队深度审查报告更新 | 开发团队 | | | | ✅ 移除 LibreOffice,仅支持 .docx 格式 | | | | | ✅ 新增 Python 返回 HTML 片段 + R1C1 坐标 | | | | | ✅ 新增 Skill 执行 30s 超时熔断机制 | | | | | ✅ 新增 DataForensics 失败降级机制 | | | | | ✅ 新增 NFRs(文件≤20MB,单表≤500行,并发10) | | | | | ✅ 明确 Node.js ↔ Python HTTP 60s 超时 | | | | | ✅ 更新测试用例清单 | | | 2026-02-17 | v1.1.1 | 根据实际代码校验更新 | 开发团队 | | | | ✅ 修正数据流图:复用现有 pg-boss 异步架构 | | | | | ✅ 明确 ExtractionClient 已有 HTTP 通信机制 | | | | | ✅ 新增 scipy 依赖说明(统计验证必需) | | | | | ✅ 补充 Python 依赖变更清单(附录 9.5) | |