Core Components: - PDFStorageService with Dify/OSS adapters - LLM12FieldsService with Nougat-first + dual-model + 3-layer JSON parsing - PromptBuilder for dynamic prompt assembly - MedicalLogicValidator with 5 rules + fault tolerance - EvidenceChainValidator for citation integrity - ConflictDetectionService for dual-model comparison Prompt Engineering: - System Prompt (6601 chars, Section-Aware strategy) - User Prompt template (PICOS context injection) - JSON Schema (12 fields constraints) - Cochrane standards (not loaded in MVP) Key Innovations: - 3-layer JSON parsing (JSON.parse + json-repair + code block extraction) - Promise.allSettled for dual-model fault tolerance - safeGetFieldValue for robust field extraction - Mixed CN/EN token calculation Integration Tests: - integration-test.ts (full test) - quick-test.ts (quick test) - cached-result-test.ts (fault tolerance test) Documentation Updates: - Development record (Day 2-3 summary) - Quality assurance strategy (full-text screening) - Development plan (progress update) - Module status (v1.1 update) - Technical debt (10 new items) Test Results: - JSON parsing success rate: 100% - Medical logic validation: 5/5 passed - Dual-model parallel processing: OK - Cost per PDF: CNY 0.10 Files: 238 changed, 14383 insertions(+), 32 deletions(-) Docs: docs/03-涓氬姟妯″潡/ASL-AI鏅鸿兘鏂囩尞/05-寮€鍙戣褰?2025-11-22_Day2-Day3_LLM鏈嶅姟涓庨獙璇佺郴缁熷紑鍙?md
45 KiB
AIclinicalresearch 现有系统技术摸底报告
报告日期: 2025-11-06
报告人: 技术团队
报告目的: 全面梳理现有系统已完成的功能、技术架构、数据库设计和代码实现,为后续架构讨论提供基础
📊 执行摘要
项目基本信息
| 项目 | 信息 |
|---|---|
| 项目名称 | AI科研助手(AIclinicalresearch) |
| 开发周期 | 2025-10-10 至今(约1个月) |
| 开发模式 | 敏捷迭代,MVP优先 |
| 当前阶段 | 里程碑1-1.5完成,Phase2/3完成,稿件审查完成 |
| 代码量 | 后端 |
| 完成度 | 核心功能85%,基础架构100% |
核心成果
✅ 已完成5大核心功能模块 ✅ 完整的技术架构体系 ✅ 成熟的AI集成能力 ✅ 完善的文档体系
🎯 已完成功能清单
1. AI智能问答系统(里程碑1核心)
1.1 智能体配置系统
完成时间: Day 10-11
核心能力:
- ✅ 12个智能体的YAML配置框架
- ✅ 动态Prompt模板加载(System + User)
- ✅ 变量替换和条件渲染
- ✅ 热更新支持
- ✅ 模型参数配置(temperature, maxTokens, topP)
已开发智能体:
- 选题评价智能体 - 四维度评价框架(创新性、临床价值、科学性、可行性)
配置文件:
backend/config/agents.yaml(348行)backend/prompts/topic_evaluation_system.txt(143行)backend/prompts/topic_evaluation_user.txt(12行)
技术架构:
// 智能体服务层
backend/src/services/agentService.ts
- loadAgentConfig() // 加载智能体配置
- getAgentById() // 获取智能体详情
- renderPrompt() // 渲染Prompt模板
- 支持变量替换:{{projectBackground}}, {{userInput}}
- 支持条件渲染:{{#if}}...{{/if}}
1.2 多轮对话系统
完成时间: Day 12-14
核心能力:
- ✅ 上下文组装(System + 历史 + 用户输入)
- ✅ 支持最近100条历史消息
- ✅ 智能的上下文注入策略
- ✅ 流式输出(SSE,打字机效果)
- ✅ 非流式输出(普通模式)
技术实现:
// 对话服务层
backend/src/services/conversationService.ts (381行)
// 上下文组装策略
if (isFirstMessage) {
// 首次消息:完整模板(项目背景 + 用户问题 + 知识库)
userPrompt = renderTemplate({
projectBackground,
userInput,
knowledgeBaseContext
});
} else {
// 后续消息:只发送新内容
userPrompt = knowledgeBaseContext
? `${userInput}\n\n## 参考文献\n${knowledgeBaseContext}`
: userInput;
}
// 流式输出
for await (const chunk of adapter.chatStream(messages)) {
reply.raw.write(`data: ${JSON.stringify(chunk)}\n\n`);
}
API端点:
POST /api/v1/conversations/:id/messages/stream- 发送消息(流式)POST /api/v1/conversations/:id/messages- 发送消息(非流式)GET /api/v1/conversations/:id- 获取对话详情
1.3 LLM适配器系统
完成时间: Day 12-13
核心能力:
- ✅ 统一的LLM接口抽象(ILLMAdapter)
- ✅ 3个LLM模型支持:DeepSeek-V3、Qwen3-72B、Qwen-Long
- ✅ 流式和非流式两种模式
- ✅ 完整错误处理和Token统计
- ✅ 工厂模式实现,易于扩展
技术架构:
// 适配器接口
backend/src/adapters/types.ts
interface ILLMAdapter {
chat(messages, options): Promise<Response>
chatStream(messages, options): AsyncGenerator<Chunk>
}
// 具体实现
backend/src/adapters/
├── DeepSeekAdapter.ts (150行) - DeepSeek-V3
├── QwenAdapter.ts (162行) - Qwen3-72B + Qwen-Long
└── LLMFactory.ts (75行) - 工厂类
模型对比:
| 模型 | 定位 | 优势 | Token限制 | 成本 |
|---|---|---|---|---|
| DeepSeek-V3 | 主力 | 性价比极高 | 64K | ¥1/百万 |
| Qwen3-72B | 备用 | 中文理解好 | 128K | ¥4/百万 |
| Qwen-Long | 全文 | 1M超长上下文 | 1M | ¥5/百万 |
1.4 项目管理系统
完成时间: Day 8-9
核心能力:
- ✅ 项目CRUD(创建、读取、更新、删除)
- ✅ 项目背景管理(动态注入到AI对话)
- ✅ 软删除机制
- ✅ 用户项目关联
数据模型:
model Project {
id String @id @default(uuid())
userId String
name String
description String? @db.Text // 项目背景
background String? @db.Text // 详细背景
researchType String? // 研究类型
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
deletedAt DateTime? // 软删除
user User @relation(fields: [userId], references: [id])
conversations Conversation[]
@@index([userId, deletedAt])
}
API端点:
POST /api/v1/projects- 创建项目GET /api/v1/projects- 获取项目列表GET /api/v1/projects/:id- 获取项目详情PUT /api/v1/projects/:id- 更新项目DELETE /api/v1/projects/:id- 删除项目
2. 个人知识库系统(里程碑1核心)
2.1 知识库管理
完成时间: Day 18-22
核心能力:
- ✅ 知识库CRUD
- ✅ 文档上传(PDF、Word、TXT、Markdown)
- ✅ 文档状态追踪(uploading → parsing → indexing → completed/error)
- ✅ 配额管理(每用户3个知识库,每库50个文档)
- ✅ 文件格式和大小限制(最大10MB)
技术集成:
- Dify平台 - RAG知识库管理
- Qdrant向量数据库 - Dify内置
- 多租户架构 - 每个知识库独立Dataset
数据模型:
model KnowledgeBase {
id String @id @default(uuid())
userId String
name String
description String? @db.Text
difyDatasetId String @unique // 映射到Dify Dataset
documentCount Int @default(0)
totalSize BigInt @default(0)
totalTokens BigInt @default(0) // Phase2新增
tokenLimit BigInt @default(980000) // Phase2新增
documentLimit Int @default(50) // Phase2新增
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
user User @relation(fields: [userId], references: [id])
documents Document[]
@@index([userId])
}
model Document {
id String @id @default(uuid())
knowledgeBaseId String
name String
originalName String
fileType String
fileSize BigInt
difyDocumentId String @unique // 映射到Dify Document
status String // uploading/parsing/indexing/completed/error
errorMessage String? @db.Text
// Phase2新增:全文存储
fullText String? @db.Text
tokenCount Int?
charCount Int?
extractionMethod String? // nougat/pymupdf/mammoth
extractionQuality Float?
detectedLanguage String? // chinese/english
uploadedAt DateTime @default(now())
processedAt DateTime?
knowledgeBase KnowledgeBase @relation(fields: [knowledgeBaseId], references: [id])
@@index([knowledgeBaseId, status])
}
API端点:
POST /api/v1/knowledge-bases- 创建知识库GET /api/v1/knowledge-bases- 获取知识库列表GET /api/v1/knowledge-bases/:id- 获取详情PUT /api/v1/knowledge-bases/:id- 更新知识库DELETE /api/v1/knowledge-bases/:id- 删除知识库POST /api/v1/knowledge-bases/:kbId/documents- 上传文档GET /api/v1/knowledge-bases/:kbId/documents- 获取文档列表DELETE /api/v1/documents/:id- 删除文档POST /api/v1/documents/:id/reprocess- 重新处理文档
2.2 RAG检索系统(里程碑1.5优化)
完成时间: Day 23-27
核心能力:
- ✅ 语义检索(Dify API)
- ✅ 多知识库联合检索
- ✅ @知识库功能(前端下拉选择)
- ✅ 检索结果注入到LLM上下文
- ✅ 智能引用系统(100%准确溯源)
优化成果:
| 指标 | 优化前 | 优化后 | 提升 |
|---|---|---|---|
| 检索数量 | 3 chunks | 15 chunks | 5倍 |
| Chunk大小 | 500 tokens | 1500 tokens | 3倍 |
| 总覆盖 | 1,500 tokens | 22,500 tokens | 15倍 |
| 覆盖页数 | ~1页 | ~15-20页 | 15-20倍 |
| 覆盖率 | ~5% | ~40-50% | 8-10倍 |
智能引用系统:
// 后端自动收集引用信息
interface Citation {
index: number;
documentName: string;
segmentIndex: number;
score: number;
content: string;
}
// AI回答格式
根据[来源1]和[来源5]的研究,阿尔兹海默病主要特征包括:
1. 记忆力减退[来源1][来源3]
2. 认知功能下降[来源5]
---
📚 **参考文献**
[1] 📄 **阿尔兹海默综述2023.pdf** - 第3段 (相关度95%)
"阿尔兹海默病是一种神经退行性疾病..."
前端视觉优化:
[来源N]:蓝色高亮badge(#1890ff)- 鼠标悬停:背景变深(#bae7ff)
- 点击跳转:平滑滚动到引用详情
- 详情闪烁:黄色高亮2秒(#fffbe6)
2.3 全文阅读模式(Phase2)
完成时间: Day 28-32
核心能力:
- ✅ Python微服务:文档提取服务
- ✅ 多格式支持:PDF、Docx、Txt
- ✅ 智能提取:Nougat(英文学术) + PyMuPDF(兜底+中文) + Mammoth(Docx)
- ✅ 语言检测:自动识别中英文,优化提取策略
- ✅ Token管理:精确计数,双重限制(50文件 + 980K tokens)
- ✅ 全文存储:数据库保存完整文本
- ✅ 智能文档选择:基于Token容量的智能推荐
技术架构:
┌─────────────────────────────────────────────┐
│ Frontend (React) │
│ - 文档上传 │
│ - 容量显示(双进度条) │
│ - 实时进度 │
└──────────────┬──────────────────────────────┘
│ REST API
┌──────────────▼──────────────────────────────┐
│ Backend (Node.js + Fastify) │
│ - ExtractionClient │
│ - TokenService │
│ - 智能文档选择 │
└──────────────┬──────────────────────────────┘
│ HTTP
┌──────────────▼──────────────────────────────┐
│ Python Microservice (FastAPI) │
│ ├── PyMuPDF (快速,中文友好) │
│ ├── Nougat (学术论文,高质量) │
│ ├── Mammoth (Docx → Markdown) │
│ ├── Language Detector │
│ └── Quality Evaluator │
└─────────────────────────────────────────────┘
提取策略:
// 语言检测 → 选择提取方法
if (language === 'chinese') {
// 中文PDF:PyMuPDF(快速)
text = await pymupdf.extract(pdf);
} else {
// 英文PDF:Nougat(高质量) + 降级PyMuPDF
try {
text = await nougat.extract(pdf);
if (quality < 0.7) throw new Error('Quality too low');
} catch {
// 自动降级
text = await pymupdf.extract(pdf);
}
}
Python微服务文件结构:
extraction_service/
├── main.py (509行) - FastAPI主服务
├── services/
│ ├── pdf_extractor.py (242行) - PDF提取总协调
│ ├── pdf_processor.py (280行) - PyMuPDF实现
│ ├── language_detector.py (120行) - 语言检测
│ ├── nougat_extractor.py (242行) - Nougat实现
│ ├── docx_extractor.py (253行) - Docx提取
│ └── txt_extractor.py (316行) - Txt提取(多编码)
├── requirements.txt
└── README.md
Backend集成:
// ExtractionClient.ts (268行)
export class ExtractionClient {
async extractDocument(
filePath: string,
fileType: string
): Promise<ExtractionResult> {
// 调用Python微服务
const response = await axios.post(
`${this.baseUrl}/api/extract/${fileType}`,
formData
);
return response.data;
}
}
// TokenService.ts (243行)
export class TokenService {
calculateTokens(text: string): number {
const encoder = encoding_for_model("gpt-4");
const tokens = encoder.encode(text);
return tokens.length;
}
canUploadDocument(
kbId: string,
newDocTokens: number
): Promise<boolean> {
// 检查文档数量(≤50)
// 检查Token容量(≤980K)
}
}
API端点:
POST /api/v1/knowledge-bases/:id/document-selection- 智能文档选择GET /api/v1/knowledge-bases/:id/capacity- 获取容量信息
3. 批处理模式(Phase3)
3.1 核心能力
完成时间: Day 29(6小时)
定位: 任务式交互(非对话),结构化数据提取器
核心功能:
- ✅ 预设模板:临床研究信息提取(8字段)
- ✅ 自定义模板:用户提示词 → 文本块显示
- ✅ 批量处理:3-50篇文献
- ✅ 固定3并发(p-queue)
- ✅ 失败重试机制
- ✅ Excel导出(双Sheet设计)
数据模型:
model BatchTask {
id String @id @default(uuid())
userId String
name String
templateType String // preset/custom
templateId String? // 预设模板ID
customPrompt String? @db.Text
modelType String // deepseek-v3/qwen3/qwen-long
concurrency Int @default(3)
status String // processing/completed/failed
totalCount Int
completedCount Int @default(0)
failedCount Int @default(0)
startedAt DateTime?
completedAt DateTime?
duration Int? // 秒
user User @relation(fields: [userId], references: [id])
results BatchResult[]
@@index([userId, status])
}
model BatchResult {
id String @id @default(uuid())
taskId String
documentId String // 关联Document
documentName String
status String // success/failed
extractedData Json? // 提取的结构化数据
rawOutput String? @db.Text
errorMessage String? @db.Text
processingTime Int? // 毫秒
tokenUsage Int?
task BatchTask @relation(fields: [taskId], references: [id])
@@index([taskId, status])
}
预设模板(临床研究信息提取):
| 字段 | 类型 | 说明 |
|---|---|---|
| research_purpose | text | 研究目的 |
| research_design | text | 研究设计(RCT/队列研究等) |
| research_subjects | text | 研究对象(纳入/排除标准) |
| sample_size | text | 样本量(保留原文描述) |
| intervention_group | text | 干预组 |
| control_group | text | 对照组 |
| results_data | longtext | 结果及数据 |
| oxford_level | text | 牛津评级(1a/1b/2a/2b/3a/3b/4/5) |
技术实现:
// batchService.ts (421行)
export class BatchService {
async executeBatchTask(
taskId: string,
documentIds: string[],
templateType: 'preset' | 'custom',
options: BatchOptions
): Promise<void> {
// 1. 加载模板或自定义Prompt
const template = await this.loadTemplate(templateType, options);
// 2. 并发执行(固定3并发)
const queue = new PQueue({ concurrency: 3 });
const promises = documentIds.map(docId =>
queue.add(() => this.processDocument(docId, template))
);
// 3. 等待所有任务完成
const results = await Promise.allSettled(promises);
// 4. 统计和保存
await this.updateTaskStatistics(taskId, results);
}
async processDocument(
docId: string,
template: Template
): Promise<BatchResult> {
// 1. 获取文档全文
const document = await this.getDocument(docId);
// 2. 构造LLM消息
const messages = [
{ role: 'system', content: template.systemPrompt },
{ role: 'user', content: `${template.userPrompt}\n\n${document.fullText}` }
];
// 3. 调用LLM
const response = await llm.chat(messages);
// 4. 解析JSON(预设模板)或保存文本(自定义)
const extractedData = template.type === 'preset'
? this.parseJSON(response.content)
: response.content;
return {
documentId: docId,
status: 'success',
extractedData,
rawOutput: response.content
};
}
}
// jsonParser.ts (145行) - 容错的JSON解析
export function extractJSON(text: string): object {
// 支持多种格式
// 1. 纯JSON:{ "key": "value" }
// 2. 带前言:这是结果:\n{ ... }
// 3. 代码块:```json\n{ ... }\n```
// 4. 带后缀:{ ... }\n\n以上是结果
}
API端点:
POST /api/v1/batch/execute- 执行批处理任务GET /api/v1/batch/tasks/:taskId- 获取任务状态GET /api/v1/batch/tasks/:taskId/results- 获取任务结果POST /api/v1/batch/tasks/:taskId/retry-failed- 重试失败项GET /api/v1/batch/templates- 获取所有模板
效率提升:
- 手动处理:10篇 × 10分钟 = 100分钟
- 批处理模式:10篇 × 平均20秒 = ~7分钟
- 提升约14倍效率 🚀
4. 稿件审查功能(Day 30独立开发)
4.1 核心能力
完成时间: Day 30(1天)
定位: 独立的稿件智能审查系统
核心功能:
- ✅ 双维度评估:稿约规范性(11项) + 方法学评估(3部分)
- ✅ 智能分析:基于真实期刊标准(中华医学超声杂志)
- ✅ 完整流程:上传Word → 提取文本 → AI评估 → 生成报告 → 导出PDF
- ✅ 用户体验:渐变卡片、拖拽上传、实时进度、颜色编码
评估标准:
稿约规范性评估(11项):
- 文题(Title)
- 作者(Authors)
- 中文摘要(Chinese Abstract)
- 英文摘要(English Abstract)
- 中文关键词(Chinese Keywords)
- 英文关键词(English Keywords)
- 正文(Main Text)
- 参考文献(References)
- 图表(Figures and Tables)
- 利益冲突(Conflict of Interest)
- 伦理审查(Ethics Approval)
方法学评估(3部分):
- 科研设计(Research Design)
- 统计方法(Statistical Methods)
- 统计分析(Statistical Analysis)
数据模型:
model ReviewTask {
id String @id @default(uuid())
userId String
fileName String
fileType String
fileSize BigInt
status String // processing/completed/failed
modelType String // deepseek-v3/qwen3/qwen-long
// 评估结果
editorialScore Float? // 稿约规范性总分
editorialResult Json? // 详细评估结果
methodologyScore Float? // 方法学总分
methodologyResult Json? // 详细评估结果
errorMessage String? @db.Text
processingTime Int? // 毫秒
createdAt DateTime @default(now())
completedAt DateTime?
user User @relation(fields: [userId], references: [id])
@@index([userId, status])
}
Prompt设计:
// 稿约规范性评估Prompt (210行)
// prompts/editorial_review_system.txt
您是一位专业的医学期刊编辑,您的任务是按照《中华医学超声杂志》的稿约要求,对提交的稿件进行规范性评估。
评估维度:
1. 文题
- 检查点:准确性、简明性、规范性
- 评分标准:0-10分
2. 作者
- 检查点:作者信息完整性、排序、单位标注
- 评分标准:0-10分
...(共11个维度)
输出格式(JSON):
{
"overall_score": 85.5,
"items": [
{
"dimension": "文题",
"score": 9.0,
"status": "符合",
"issues": [],
"suggestions": []
},
...
]
}
// 方法学评估Prompt (231行)
// prompts/methodology_review_system.txt
您是一位专业的医学统计学专家,您的任务是评估医学研究稿件的方法学质量。
评估维度:
1. 科研设计
- 研究类型识别
- 设计合理性
- 样本量计算
2. 统计方法
- 方法选择
- 参数设置
- 假设检验
3. 统计分析
- 结果呈现
- 图表规范
- 结论合理性
技术实现:
// reviewService.ts (437行)
export class ReviewService {
async reviewManuscript(
userId: string,
file: File,
modelType: ModelType
): Promise<ReviewTask> {
// 1. 上传文件并创建任务
const task = await this.createTask(userId, file);
// 2. 提取文档全文(调用Python微服务)
const fullText = await extractionClient.extractDocument(file);
// 3. 稿约规范性评估
const editorialResult = await this.evaluateEditorial(fullText, modelType);
// 4. 方法学评估
const methodologyResult = await this.evaluateMethodology(fullText, modelType);
// 5. 保存结果
await this.updateTaskResult(task.id, {
editorialScore: editorialResult.overall_score,
editorialResult: editorialResult,
methodologyScore: methodologyResult.overall_score,
methodologyResult: methodologyResult
});
return task;
}
}
API端点:
POST /api/v1/review/upload- 上传稿件并开始审查GET /api/v1/review/tasks/:taskId- 查询任务状态GET /api/v1/review/tasks/:taskId/report- 获取完整报告GET /api/v1/review/tasks- 获取任务列表(分页)DELETE /api/v1/review/tasks/:taskId- 删除任务
前端组件:
// ReviewPage.tsx (625行) - 主页面
// 包含:上传区 + 进度条 + 报告展示 + PDF导出
// ScoreCard.tsx - 分数卡片(颜色编码)
// EditorialReview.tsx - 稿约规范性评估详情
// MethodologyReview.tsx - 方法学评估详情
🏗️ 技术架构总览
1. 技术栈
后端技术栈
核心框架:
- Node.js 18+
- TypeScript 5.x
- Fastify 4.x (高性能HTTP框架)
数据层:
- PostgreSQL 15+ (关系数据库)
- Prisma 5.x (ORM)
- Redis (缓存,待集成)
AI集成:
- DeepSeek-V3 (主力LLM,¥1/百万tokens)
- Qwen3-72B (备用LLM,¥4/百万tokens)
- Qwen-Long (超长上下文,1M tokens)
- Dify (RAG平台,向量检索)
文件处理:
- @fastify/multipart (文件上传)
- @dqbd/tiktoken (Token计数)
- axios (HTTP客户端)
并发控制:
- p-queue (队列管理)
配置管理:
- js-yaml (YAML解析)
- dotenv (环境变量)
前端技术栈
核心框架:
- React 18
- TypeScript 5.x
- Vite 5.x (构建工具)
UI组件:
- Ant Design 5.x (主要UI库)
- TailwindCSS (工具类CSS)
- React Router 6 (路由)
状态管理:
- Zustand (轻量级状态管理)
数据请求:
- Axios (HTTP客户端)
- EventSource (SSE流式输出)
辅助工具:
- react-markdown (Markdown渲染)
- rehype-raw (HTML渲染)
- html2canvas + jsPDF (PDF导出)
- xlsx (Excel导出)
Python微服务
核心框架:
- FastAPI (高性能异步框架)
- uvicorn (ASGI服务器)
PDF处理:
- PyMuPDF (fitz) - 快速通用
- pdfplumber - 表格提取
- nougat-ocr - 学术论文高质量提取
Docx处理:
- mammoth - 转Markdown
- python-docx - 结构化读取
文本处理:
- chardet - 编码检测
- langdetect - 语言检测
工具:
- python-multipart - 文件上传
- python-dotenv - 配置管理
2. 数据库设计
核心表结构(13个表)
用户相关(1个表):
model User {
id String @id @default(uuid())
email String @unique
password String // bcrypt加密
name String?
avatarUrl String?
role String @default("user")
status String @default("active")
kbQuota Int @default(3)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
项目管理(1个表):
model Project {
id String @id @default(uuid())
userId String
name String
description String? @db.Text
background String? @db.Text
researchType String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
deletedAt DateTime?
@@index([userId, deletedAt])
}
对话系统(2个表):
// 项目对话
model Conversation {
id String @id @default(uuid())
projectId String
agentId String
title String?
metadata Json?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
deletedAt DateTime?
}
model Message {
id String @id @default(uuid())
conversationId String
role String // user/assistant
content String @db.Text
model String? // deepseek-v3/qwen3/qwen-long
metadata Json? // 知识库引用等
createdAt DateTime @default(now())
}
// 通用对话(智能问答)
model GeneralConversation {
id String @id @default(uuid())
userId String
title String?
metadata Json?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
deletedAt DateTime?
}
model GeneralMessage {
id String @id @default(uuid())
conversationId String
role String
content String @db.Text
model String?
metadata Json?
createdAt DateTime @default(now())
}
知识库系统(2个表):
model KnowledgeBase {
id String @id @default(uuid())
userId String
name String
description String? @db.Text
difyDatasetId String @unique
documentCount Int @default(0)
totalSize BigInt @default(0)
totalTokens BigInt @default(0)
tokenLimit BigInt @default(980000)
documentLimit Int @default(50)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@index([userId])
}
model Document {
id String @id @default(uuid())
knowledgeBaseId String
name String
originalName String
fileType String
fileSize BigInt
difyDocumentId String @unique
status String
errorMessage String? @db.Text
// 全文存储
fullText String? @db.Text
tokenCount Int?
charCount Int?
extractionMethod String?
extractionQuality Float?
detectedLanguage String?
uploadedAt DateTime @default(now())
processedAt DateTime?
@@index([knowledgeBaseId, status])
}
批处理系统(2个表):
model BatchTask {
id String @id @default(uuid())
userId String
name String
templateType String
templateId String?
customPrompt String? @db.Text
modelType String
concurrency Int @default(3)
status String
totalCount Int
completedCount Int @default(0)
failedCount Int @default(0)
startedAt DateTime?
completedAt DateTime?
duration Int?
@@index([userId, status])
}
model BatchResult {
id String @id @default(uuid())
taskId String
documentId String
documentName String
status String
extractedData Json?
rawOutput String? @db.Text
errorMessage String? @db.Text
processingTime Int?
tokenUsage Int?
@@index([taskId, status])
}
稿件审查(1个表):
model ReviewTask {
id String @id @default(uuid())
userId String
fileName String
fileType String
fileSize BigInt
status String
modelType String
editorialScore Float?
editorialResult Json?
methodologyScore Float?
methodologyResult Json?
errorMessage String? @db.Text
processingTime Int?
createdAt DateTime @default(now())
completedAt DateTime?
@@index([userId, status])
}
运营管理(1个表):
model AdminLog {
id String @id @default(uuid())
adminId String
action String
targetType String?
targetId String?
details Json?
ipAddress String?
userAgent String?
createdAt DateTime @default(now())
@@index([adminId, createdAt])
@@index([action, createdAt])
}
总统计:13个表,~80个字段
3. 代码结构
后端代码结构
backend/
├── config/
│ └── agents.yaml (348行) - 智能体配置
├── prompts/ (441行)
│ ├── topic_evaluation_system.txt (143行)
│ ├── topic_evaluation_user.txt (12行)
│ ├── editorial_review_system.txt (210行)
│ └── methodology_review_system.txt (231行)
├── src/
│ ├── adapters/ (387行) - LLM适配器
│ │ ├── types.ts (57行)
│ │ ├── DeepSeekAdapter.ts (150行)
│ │ ├── QwenAdapter.ts (162行)
│ │ └── LLMFactory.ts (18行)
│ ├── clients/ (~550行) - 外部服务客户端
│ │ ├── DifyClient.ts (282行)
│ │ └── ExtractionClient.ts (268行)
│ ├── config/ (56行)
│ │ └── env.ts - 环境配置
│ ├── controllers/ (~2,700行) - 控制器
│ │ ├── projectController.ts
│ │ ├── agentController.ts (197行)
│ │ ├── conversationController.ts (247行)
│ │ ├── chatController.ts
│ │ ├── knowledgeBaseController.ts
│ │ ├── documentController.ts
│ │ ├── batchController.ts (429行)
│ │ └── reviewController.ts (265行)
│ ├── services/ (~3,000行) - 业务逻辑
│ │ ├── projectService.ts
│ │ ├── agentService.ts (232行)
│ │ ├── conversationService.ts (381行)
│ │ ├── knowledgeBaseService.ts
│ │ ├── documentService.ts
│ │ ├── batchService.ts (421行)
│ │ ├── reviewService.ts (437行)
│ │ └── tokenService.ts (243行)
│ ├── templates/ (145行)
│ │ └── clinicalResearch.ts - 批处理预设模板
│ ├── utils/ (145行)
│ │ └── jsonParser.ts - 容错JSON解析
│ ├── routes/ (~250行) - 路由
│ │ ├── projects.ts
│ │ ├── agents.ts
│ │ ├── conversations.ts
│ │ ├── chatRoutes.ts
│ │ ├── knowledgeBases.ts
│ │ ├── batchRoutes.ts
│ │ └── reviewRoutes.ts
│ ├── middleware/ (~50行)
│ │ └── validateProject.ts
│ └── index.ts (主入口)
├── prisma/
│ ├── schema.prisma (~600行)
│ └── migrations/
├── package.json
└── tsconfig.json
总计:~12,000行代码
前端代码结构
frontend/
├── src/
│ ├── api/ (~1,500行) - API封装
│ │ ├── projectApi.ts
│ │ ├── agentApi.ts (76行)
│ │ ├── conversationApi.ts
│ │ ├── chatApi.ts
│ │ ├── knowledgeBaseApi.ts
│ │ ├── batchApi.ts (147行)
│ │ ├── reviewApi.ts (319行)
│ │ └── request.ts (axios配置)
│ ├── components/ (~5,000行)
│ │ ├── chat/ (~3,000行)
│ │ │ ├── MessageList.tsx (含智能引用)
│ │ │ ├── MessageInput.tsx (含@知识库)
│ │ │ ├── ModelSelector.tsx
│ │ │ ├── ModeSelector.tsx
│ │ │ ├── FullTextMode.tsx
│ │ │ ├── DeepReadMode.tsx
│ │ │ ├── BatchMode.tsx
│ │ │ ├── TaskDefinition.tsx
│ │ │ ├── DocumentSelection.tsx
│ │ │ ├── BatchProgress.tsx
│ │ │ ├── PresetTable.tsx
│ │ │ ├── CustomTable.tsx
│ │ │ ├── BatchResults.tsx
│ │ │ └── CapacityIndicator.tsx
│ │ ├── knowledge/ (~800行)
│ │ │ ├── KnowledgeBaseList.tsx
│ │ │ ├── DocumentList.tsx
│ │ │ ├── DocumentUpload.tsx
│ │ │ ├── CreateKBDialog.tsx
│ │ │ └── EditKBDialog.tsx
│ │ ├── review/ (~500行)
│ │ │ ├── ScoreCard.tsx
│ │ │ ├── EditorialReview.tsx
│ │ │ └── MethodologyReview.tsx
│ │ ├── ProjectSelector.tsx
│ │ ├── CreateProjectDialog.tsx
│ │ └── EditProjectDialog.tsx
│ ├── pages/ (~2,500行)
│ │ ├── HomePage.tsx
│ │ ├── AgentChatPage.tsx
│ │ ├── ChatPage.tsx
│ │ ├── KnowledgePage.tsx
│ │ ├── ReviewPage.tsx (625行)
│ │ └── HistoryPage.tsx
│ ├── stores/ (~400行)
│ │ ├── useProjectStore.ts
│ │ └── useKnowledgeBaseStore.ts
│ ├── hooks/ (~400行)
│ │ ├── useChatMode.ts
│ │ ├── useDeepReadState.ts
│ │ └── useBatchTask.ts (198行)
│ ├── layouts/ (~200行)
│ │ └── MainLayout.tsx
│ ├── types/ (~300行)
│ │ ├── chat.ts
│ │ └── index.ts
│ └── App.tsx
├── package.json
└── vite.config.ts
总计:~10,000行代码
Python微服务结构
extraction_service/
├── services/
│ ├── pdf_extractor.py (242行)
│ ├── pdf_processor.py (280行)
│ ├── language_detector.py (120行)
│ ├── nougat_extractor.py (242行)
│ ├── docx_extractor.py (253行)
│ └── txt_extractor.py (316行)
├── main.py (509行)
├── requirements.txt
└── README.md
总计:~2,100行代码
📊 数据流架构
1. AI对话流程
用户输入
↓
前端 ChatPage/AgentChatPage
↓ POST /api/v1/conversations/:id/messages/stream
后端 conversationController
↓
conversationService
├→ agentService.getAgent() - 获取智能体配置
├→ projectService.getProject() - 获取项目背景
├→ conversationService.getHistory() - 获取历史对话
├→ knowledgeBaseService.search() - 知识库检索(可选)
└→ 组装上下文(System + 历史 + 项目背景 + 知识库 + 用户输入)
↓
LLMFactory.getAdapter(modelType)
↓
DeepSeekAdapter / QwenAdapter
↓ HTTP (SSE Stream)
OpenAI API / DashScope API
↓ (流式返回)
后端 conversationService
├→ 实时写入数据库(messages表)
└→ SSE流式返回前端
↓
前端 MessageList
└→ 实时渲染(打字机效果)
2. 知识库RAG流程
用户上传文档
↓
前端 DocumentUpload
↓ POST /api/v1/knowledge-bases/:id/documents
后端 documentController
↓
documentService.uploadDocument()
├→ 保存文件到临时目录
├→ 调用Python微服务提取文本 (Phase2)
├→ 计算Token数 (Phase2)
├→ 检查容量限制 (Phase2)
├→ 上传到Dify (RAG索引)
├→ 保存全文到数据库 (Phase2)
└→ 更新知识库统计
↓
后台轮询Dify处理状态
└→ 更新document.status
---
用户@知识库提问
↓
前端 MessageInput (选择知识库)
↓ POST /api/v1/conversations/:id/messages/stream
后端 conversationService
↓
knowledgeBaseService.search(kbIds, query)
├→ 对每个知识库调用Dify检索API
├→ 返回Top 15相关文档片段
├→ 格式化:【知识库:xxx】\n1. [相关度XX%] 内容...
└→ 收集引用信息 (Phase 1.5)
↓
注入到LLM上下文
├→ 指导AI使用[来源N]标准编号
└→ 追加引用清单(HTML格式)
↓
前端 MessageList
├→ 解析引用标记
├→ 高亮显示[来源N]
├→ 点击跳转到引用详情
└→ 详情区域高亮闪烁
3. 批处理流程
用户选择文献 + 配置任务
↓
前端 BatchMode
↓ POST /api/v1/batch/execute
后端 batchController
↓
batchService.executeBatchTask()
├→ 创建BatchTask记录
├→ 加载预设模板或自定义Prompt
└→ 异步执行批处理
↓
并发队列(p-queue,固定3并发)
├→ processDocument(doc1)
├→ processDocument(doc2)
└→ processDocument(doc3)
↓ 每个文档处理
├→ 获取文档全文(database)
├→ 构造LLM消息(System + User + 文档全文)
├→ 调用LLM API
├→ 解析JSON(预设)或保存文本(自定义)
└→ 保存BatchResult记录
↓
后台更新任务统计
└→ completedCount, failedCount, status
---
前端轮询任务状态
↓ GET /api/v1/batch/tasks/:taskId (每5秒)
后端返回任务进度
├→ status, totalCount, completedCount, failedCount
└→ 预估剩余时间
↓
任务完成后
↓ GET /api/v1/batch/tasks/:taskId/results
后端返回完整结果
├→ 预设模板:8列表格
├→ 自定义模板:3列文本块
└→ 失败项列表
↓
前端 BatchResults
├→ 渲染结果表格
├→ 导出Excel(双Sheet)
└→ 重试失败项
💾 数据统计
代码量统计
| 模块 | 文件数 | 代码行数 | 占比 |
|---|---|---|---|
| 后端主代码 | 38 | ~12,000 | 50% |
| 前端主代码 | 75 | ~10,000 | 42% |
| Python微服务 | 8 | ~2,100 | 8% |
| 总计 | 121 | ~24,100 | 100% |
数据库统计
| 类别 | 数量 |
|---|---|
| 表 | 13 |
| 字段 | ~80 |
| 索引 | ~20 |
| 关系 | 15 |
API端点统计
| 模块 | 端点数 |
|---|---|
| 项目管理 | 5 |
| 智能体管理 | 4 |
| 对话系统 | 8 |
| 知识库管理 | 12 |
| 批处理系统 | 5 |
| 稿件审查 | 5 |
| 总计 | 39 |
🎯 已验证的技术能力
1. AI集成能力 ✅
- ✅ 多模型支持:DeepSeek-V3、Qwen3-72B、Qwen-Long
- ✅ 流式输出:SSE实时传输,打字机效果
- ✅ 上下文管理:智能组装,历史对话,项目背景
- ✅ 错误处理:完整的重试机制和降级策略
- ✅ Token优化:精确计数,成本控制
2. RAG能力 ✅
- ✅ 向量检索:Dify + Qdrant,语义搜索
- ✅ 多知识库:联合检索,结果合并
- ✅ 智能引用:100%准确溯源,可点击跳转
- ✅ 覆盖率优化:从5%提升到40-50%(15倍提升)
3. 文档处理能力 ✅
- ✅ 多格式支持:PDF、Docx、Txt
- ✅ 智能提取:Nougat(学术论文) + PyMuPDF(兜底) + Mammoth(Docx)
- ✅ 语言检测:中英文自动识别,优化提取策略
- ✅ 质量评估:提取质量评分,自动降级
- ✅ 大文件处理:支持50MB+文档
4. 并发控制能力 ✅
- ✅ 队列管理:p-queue,固定3并发
- ✅ 容错机制:Promise.allSettled,单个失败不影响其他
- ✅ 进度追踪:实时统计,预估剩余时间
- ✅ 失败重试:失败项可单独重试
5. 数据管理能力 ✅
- ✅ 关系数据库:PostgreSQL + Prisma ORM
- ✅ 数据隔离:用户级、项目级隔离
- ✅ 软删除:关键数据可恢复
- ✅ 事务管理:ACID保证
- ✅ 索引优化:查询性能优化
📈 性能指标
已测试的性能数据
| 指标 | 数值 | 说明 |
|---|---|---|
| API响应时间 | < 500ms | 普通API端点 |
| LLM首字响应 | < 3s | DeepSeek-V3 |
| 流式输出延迟 | < 100ms | SSE chunk延迟 |
| 文档上传速度 | ~5MB/s | 10MB文档约2秒 |
| PDF提取速度(PyMuPDF) | ~2页/秒 | 20页PDF约10秒 |
| PDF提取速度(Nougat) | ~0.5页/秒 | 20页PDF约40秒 |
| Docx提取速度 | ~1秒/MB | 10MB Docx约10秒 |
| Token计数速度 | ~10ms/1000字 | Tiktoken |
| 批处理速度 | ~20秒/文档 | 3并发平均 |
| RAG检索延迟 | < 1s | Dify检索 |
成本指标
| 项目 | 成本 | 说明 |
|---|---|---|
| LLM API成本(DeepSeek-V3) | ¥1/百万tokens | 主力模型 |
| LLM API成本(Qwen3) | ¥4/百万tokens | 备用模型 |
| LLM API成本(Qwen-Long) | ¥5/百万tokens | 全文模式 |
| 单次对话成本 | ¥0.001-0.01 | 500-5000 tokens |
| 全文精读成本(50篇) | ¥0.5-1 | 100K-200K tokens |
| 批处理成本(50篇) | ¥0.3-0.5 | 60K-100K tokens |
| 稿件审查成本 | ¥0.05-0.1 | 10K-20K tokens |
🚧 技术债务清单
高优先级(建议优先处理)
-
日志系统
- 现状:大量console.log用于调试
- 建议:引入日志级别控制(winston/pino)
- 影响:生产环境日志管理
-
错误码体系
- 现状:部分API缺少详细错误信息
- 建议:统一错误码和错误消息
- 影响:前端错误处理和用户体验
-
类型定义完善
- 现状:部分使用了
any类型 - 建议:补充完整的TypeScript类型定义
- 影响:代码可维护性
- 现状:部分使用了
-
Redis缓存集成
- 现状:已配置但未使用
- 建议:缓存热点数据(智能体配置、知识库列表)
- 影响:性能优化
中优先级(可在里程碑2-3处理)
-
单元测试
- 现状:缺少系统性测试
- 建议:核心业务逻辑添加单元测试
- 影响:代码质量和重构信心
-
WebSocket实时推送
- 现状:批处理进度使用HTTP轮询
- 建议:改为WebSocket实时推送
- 影响:用户体验优化
-
文档处理并行化
- 现状:文档提取串行处理
- 建议:并行提取多个文档
- 影响:批量上传性能
-
API限流
- 现状:无限流机制
- 建议:添加限流中间件
- 影响:防止API滥用
🎉 核心成就
1. 快速迭代能力
- ✅ 1个月内完成5大核心功能模块
- ✅ 每周都有可见成果
- ✅ 技术验证全部通过
2. AI集成深度
- ✅ 3个LLM模型完整集成
- ✅ 流式输出体验优秀
- ✅ RAG检索效果显著
3. 文档处理能力
- ✅ Python微服务高质量提取
- ✅ 多格式全面支持
- ✅ 智能降级策略可靠
4. 代码质量
- ✅ TypeScript全覆盖
- ✅ 清晰的三层架构
- ✅ 良好的模块解耦
5. 文档完善
- ✅ 详细的PRD文档
- ✅ 完整的技术文档
- ✅ 丰富的开发日志(60+篇)
📝 总结
现有系统的优势
-
技术架构成熟
- 清晰的三层架构(Controller → Service → Database)
- 良好的模块化设计
- 完整的LLM适配器抽象
-
功能完整性高
- AI对话系统:✅ 完整可用
- 知识库系统:✅ 完整可用(RAG + 全文)
- 批处理系统:✅ 完整可用
- 稿件审查:✅ 完整可用
-
AI能力突出
- 多模型支持,灵活切换
- RAG检索准确,溯源清晰
- 智能引用100%准确
-
工程质量良好
- TypeScript全覆盖
- Prisma ORM,类型安全
- 清晰的代码结构
现有系统的局限
-
架构层面
- ❌ 缺少SSA、ST、DC模块(最新需求)
- ❌ 未考虑私有化部署和单机版
- ❌ 未考虑微服务架构和K8s
- ❌ 未考虑模块化售卖
-
技术栈层面
- ❌ 缺少R语言集成(SSA需要)
- ❌ 缺少API网关
- ❌ 缺少Electron单机版
-
数据库层面
- ❌ 单一数据库,未考虑Schema隔离
- ❌ 未考虑多租户架构
-
部署层面
- ❌ 仅支持云端SaaS,未考虑其他3种部署模式
- ❌ 未考虑容器化部署(K8s)
🔮 下一步建议
基于现有系统的技术摸底,建议:
-
明确开发阶段
- 当前处于"阶段一:模块化单体"
- 是否立即规划"阶段二:微服务拆分"?
- 是否立即规划Electron单机版?
-
明确模块优先级
- DC模块(数据清洗):核心差异化
- ASL模块(AI智能文献):已有部分PRD
- SSA模块(智能统计分析):需要R语言
- ST模块(统计分析工具):相对简单
-
明确架构演进路径
- 是否遵循白皮书的分阶段实施?
- 是否立即引入K8s和API网关?
- 是否立即引入R语言和Python微服务?
-
明确文档更新策略
- 立即更新哪些P0级文档?
- 如何整合现有文档和最新需求?
报告完成日期: 2025-11-06
报告维护者: 技术团队
下一步: 讨论总体技术架构、文档体系构建、分步骤实施