Files
AIclinicalresearch/docs/03-业务模块/PKB-个人知识库/00-系统设计/企业级医学知识库_综合技术解决方案 V2.md
HaHafeng dfc0fe0b9a feat(pkb): Integrate pgvector and create Dify replacement plan
Summary:
- Migrate PostgreSQL to pgvector/pgvector:pg15 Docker image
- Successfully install and verify pgvector 0.8.1 extension
- Create comprehensive Dify-to-pgvector migration plan
- Update PKB module documentation with pgvector status
- Update system documentation with pgvector integration

Key changes:
- docker-compose.yml: Switch to pgvector/pgvector:pg15 image
- Add EkbDocument and EkbChunk data model design
- Design R-C-R-G hybrid retrieval architecture
- Add clinical data JSONB fields (pico, studyDesign, regimen, safety, criteria, endpoints)
- Create detailed 10-day implementation roadmap

Documentation updates:
- PKB module status: pgvector RAG infrastructure ready
- System status: pgvector 0.8.1 integrated
- New: Dify replacement development plan (01-Dify替换为pgvector开发计划.md)
- New: Enterprise medical knowledge base solution V2

Tested: PostgreSQL with pgvector verified, frontend and backend functionality confirmed
2026-01-20 00:00:58 +08:00

8.2 KiB
Raw Permalink Blame History

企业级医学知识库 (EKB) 综合技术解决方案

版本: v2.0 (增强版:临床数据全要素结构化)
核心目标: 构建高精度、可追溯、基于医学证据的企业级知识库
技术栈: Node.js, Python, PostgreSQL (pgvector), DeepSeek, pymupdf4llm
设计范式: R-C-R-G (Router - Concurrent - Rerank - Generate)

1. 总体架构设计

本方案采用 "Postgres-Only" 极简架构,利用 Node.js 进行业务编排Python 进行文档解析,外部 API 提供 AI 算力。

1.1 核心组件

  1. 解析层 (Python Microservice)
    • 核心工具pymupdf4llm
    • 作用:将 PDF含复杂表格转换为 Markdown 格式,保留结构化语义。
  2. 存储层 (PostgreSQL 15+)
    • 三维信息架构
      1. 文献属性信息 (Metadata)PMID、IF分、期刊等。
      2. 文献关键内容信息 (Clinical Data)PICO、用药方案、不良反应、入排标准、终点指标等JSONB存储
      3. 向量信息 (Vector):全文切片的语义向量。
  3. 计算层 (Node.js + External APIs)
    • Embedding:调用 text-embedding-v4 或 BGE-M3 API。
    • Rerank:调用 qwen-rerank API。
    • Reasoning:调用 DeepSeek V3 进行全要素提取和答案生成。
  4. 文件层 (OSS)
    • 存储原始 PDF 和生成的 Markdown 文件。

2. 数据模型设计 (存储方案)

利用 PostgreSQL 的强大扩展性,我们在单库中实现多种数据类型的融合存储,构建健壮的临床数据库

2.1 数据库 Schema (Prisma 描述)

// 1. 文档主表:承载 "属性信息" 与 "关键内容信息"
model EkbDocument {
id String @id @default(uuid())
projectId String // 业务隔离

// --- A. 文档属性信息 (Metadata) - 用于基础筛选 ---
title String
abstract String? @db.Text // 原始摘要
pmid String? @unique
doi String?
journal String?
authors String[]
publishYear Int // 用于 "2024年最新" 筛选
ifScore Float? // 用于 "高分文献" 筛选
docType String // 指南/RCT/综述/病例报告

// --- B. 文档关键内容信息 (Clinical Data) - AI 提取的结构化金矿 ---
// 使用 JSONB 存储,支持 GIN 索引,实现 "SQL 级" 的精准查询

// 1. PICO 要素
// { "P": "晚期NSCLC", "I": "Keytruda", "C": "化疗", "O": "OS, PFS" }
pico Json?

// 2. 研究设计与样本
// { "design": "Phase III RCT", "sampleSize": 500, "blinding": "Double-blind" }
studyDesign Json?

// 3. 药物与剂量 (Regimen)
// [ { "drug": "Pembrolizumab", "dose": "200mg", "freq": "Q3W" } ]
regimen Json?

// 4. 安全性与不良反应 (Safety)
// { "ae_all": ["Rash", "Fatigue"], "ae_grade34": ["Pneumonitis"], "dropout_rate": "5%" }
safety Json?

// 5. 入排标准 (Criteria)
// { "inclusion": ["Age >= 18", "EGFR -"], "exclusion": ["Autoimmune disease"] }
criteria Json?

// 6. 观察指标 (Endpoints)
// { "primary": ["PFS"], "secondary": ["OS", "ORR"], "results": {"PFS_HR": 0.5} }
endpoints Json?

// --- C. 系统信息 ---
fileKey String // PDF OSS 路径
mdKey String? // Markdown OSS 路径
status String // PENDING, PROCESSED, FAILED

chunks EkbChunk[]

// --- 索引优化 ---
@@index([projectId])
@@index([publishYear])
@@index([ifScore])
// GIN 索引:让 JSON 字段支持高速查询 (e.g. 搜特定不良反应)
@@index([pico], type: Gin)
@@index([regimen], type: Gin)
@@index([safety], type: Gin)
}

// 2. 切片表:向量信息 + 文本内容
model EkbChunk {
id String @id @default(uuid())
documentId String

// --- D. 切片内容 ---
content String @db.Text // Markdown 格式的切片文本
pageNumber Int // 溯源锚点
sectionType String? // 标记切片来源Title, Abstract, Methods, Results, Discussion

// --- E. 向量信息 ---
// 使用 Unsupported 类型支持 pgvector
embedding Unsupported("vector(1024)")?

document EkbDocument @relation(fields: [documentId], references: [id], onDelete: Cascade)
}

3. 数据处理流水线 (Ingestion Pipeline)

此流程负责将非结构化的 PDF 转化为结构化的数据库记录。

步骤一:解析与转换 (Python)

  • 工具pymupdf4llm
  • 输入PDF 文件流。
  • 输出Markdown 文本(保留表格结构)。

步骤二:全要素智能提取 (DeepSeek)

这是构建健壮数据库的关键一步。

  • 操作:将全文 Markdown或前 10k token丢给 DeepSeek V3。
  • Prompt"你是一个医学数据专家。请阅读这篇文献,严格按照以下 JSON 格式提取关键信息。如果文中未提及,字段留空。
    1. pico: { P, I, C, O }
    2. studyDesign: { design (如RCT), sampleSize (数字), blinding }
    3. regimen: 提取主要药物名称、剂量、给药频率。
    4. safety: 提取主要不良反应Adverse Events及严重不良反应。
    5. criteria: 简要概括核心入选和排除标准。
    6. endpoints: 主要和次要观察指标。

输出必须是纯 JSON。"

  • 存储:解析返回的 JSON分别填入 EkbDocument 的对应字段。

步骤三:切片与向量化 (Node.js)

  • 切片器RecursiveCharacterTextSplitter。
  • 增强策略:在切片 content 前面加上元数据头。例如:[Design: RCT] [Sample: 500] ...原文...。这能显著增加向量检索的召回率。
  • 存储:存入 EkbChunk。

4. 检索与问答策略 (增强版 R-C-R-G)

有了结构化数据,我们的检索策略从“模糊搜”升级为“精准筛 + 模糊搜”。

4.1 Router (意图路由)

用户提问后,调用 LLM 判断意图并提取结构化参数

  1. 安全性查询 -> 提取不良反应关键词 (e.g., "Rash")。
  2. 方案对比 -> 提取药物名称 (e.g., "Keytruda")。
  3. 高质筛选 -> 提取样本量阈值 (e.g., "n > 100")。

4.2 Concurrent Retrieval (并发混合召回)

Node.js 并行执行以下查询,最后取并集:

  • 路径 A (SQL 精准筛选 - 新增杀手锏)
    利用 JSONB 字段进行逻辑过滤。
    • Query: SELECT id FROM EkbDocument WHERE safety->>'ae_all' ILIKE '%Pneumonitis%' (找提到肺炎副作用的)
    • Query: SELECT id FROM EkbDocument WHERE (studyDesign->>'sampleSize')::int > 100 (找大样本研究)
  • 路径 B (向量检索)
    在路径 A 圈定的 ID 范围内,执行 ORDER BY embedding <=> query_vec。
  • 路径 C (关键词检索)
    使用 ts_rank 捕捉专有名词。

4.3 Rerank (重排序)

  • 工具qwen-rerank API。
  • 策略:输入用户问题 + 混合召回的 Top 50 切片。

4.4 Generate (生成与溯源)

  • 模型DeepSeek V3/R1。
  • 优势:此时 LLM 拿到的 Context 不仅有文本切片还可以注入该文档的结构化信息如样本量、PICO使得回答更加立体。

5. 实施关键检查点

  1. JSONB 性能PostgreSQL 的 JSONB 查询非常快,但务必建立 GIN 索引(如 @@index([safety], type: Gin)),否则全表扫描会很慢。
  2. 提取成本:全要素提取会消耗更多 Input Token。按 1000 篇文献算DeepSeek V3 成本约为 20-30 元人民币,完全可接受。
  3. 数据清洗AI 提取的 JSON 可能会有格式错误Node.js 端需要加一层 try-catch 和简单的格式校验(如 JSON.parse 失败重试)。

6. 总结

这套升级后的方案,不仅是一个知识库,更是一个轻量级的 RWE (真实世界证据) 数据库

  • 查询能力质变:从只能问“文章说了什么”,升级为能问“有哪些文章是用 200mg 剂量的”或“有哪些三期临床涉及了亚洲人”。
  • 应用场景扩展:支持自动生成 Meta 分析草稿竞品安全性对比表指南用药推荐汇总 等高级应用。