Files
AIclinicalresearch/docs/03-业务模块/RVW-稿件审查系统/04-开发计划/RVW V2.0 产品升级开发计划.md
HaHafeng e785969e54 feat(rvw): Implement RVW V2.0 Data Forensics Module - Day 6 StatValidator
Summary:
- Implement L2 Statistical Validator (CI-P consistency, T-test reverse)
- Implement L2.5 Consistency Forensics (SE Triangle, SD>Mean check)
- Add error/warning severity classification with tolerance thresholds
- Support 5+ CI formats parsing (parentheses, brackets, 95% CI prefix)
- Complete Python forensics service (types, config, validator, extractor)

V2.0 Development Progress (Week 2 Day 6):
- Day 1-5: Python service setup, Word table extraction, L1 arithmetic validator
- Day 6: L2 StatValidator + L2.5 consistency forensics (promoted from V2.1)

Test Results:
- Unit tests: 4/4 passed (CI-P, SE Triangle, SD>Mean, T-test)
- Real document tests: 5/5 successful, 2 reasonable WARNINGs

Status: Day 6 completed, ready for Day 7 (Skills Framework)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-17 22:15:27 +08:00

1028 lines
43 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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.
# 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<SkillResult>;
}
// 🆕 Skill 执行配置
interface SkillExecutionConfig {
defaultTimeout: number; // 默认 30000ms (30s)
maxRetries: number; // 默认 0不重试
continueOnError: boolean; // 单个 Skill 失败是否继续,默认 true
}
```
> 📋 **R1C1 坐标系统**:所有单元格位置使用 R1C1 格式(如 `R3C4` 表示第3行第4列确保前后端定位一致。前端根据此坐标直接高亮对应 `<td>` 元素。
### 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)
# 如果正则无结果可选调用LLMV2.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<SkillResult> {
const timeout = skill.timeout || 30000; // 默认 30s
try {
const result = await Promise.race([
skill.run(context),
new Promise<never>((_, 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 降级机制
当 DataForensicsSkillWord 表格提取)失败时,系统不应完全中断,而是降级运行:
```
正常流程:
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 id="tbl_0" class="forensics-table">
<caption>Table 1. Baseline Characteristics</caption>
<tr>
<td data-coord="R1C1">Variable</td>
<td data-coord="R1C2">Group A</td>
<td data-coord="R1C3">Group B</td>
</tr>
<tr>
<td data-coord="R2C1">Age</td>
<td data-coord="R2C2">45.2 ± 12.3</td>
<td data-coord="R2C3" class="has-issue">48 (60.0%)</td> <!-- 错误单元格 -->
</tr>
</table>
```
#### 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 id=\"tbl_0\" class=\"forensics-table\"><caption>Table 1...</caption><tr><td data-coord=\"R1C1\">Variable</td>...</tr></table>",
"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 | |