Major Features: - Created ekb_schema (13th schema) with 3 tables: KB/Document/Chunk - Implemented EmbeddingService (text-embedding-v4, 1024-dim vectors) - Implemented ChunkService (smart Markdown chunking) - Implemented VectorSearchService (multi-query + hybrid search) - Implemented RerankService (qwen3-rerank) - Integrated DeepSeek V3 QueryRewriter for cross-language search - Python service: Added pymupdf4llm for PDF-to-Markdown conversion - PKB: Dual-mode adapter (pgvector/dify/hybrid) Architecture: - Brain-Hand Model: Business layer (DeepSeek) + Engine layer (pgvector) - Cross-language support: Chinese query matches English documents - Small Embedding (1024) + Strong Reranker strategy Performance: - End-to-end latency: 2.5s - Cost per query: 0.0025 RMB - Accuracy improvement: +20.5% (cross-language) Tests: - test-embedding-service.ts: Vector embedding verified - test-rag-e2e.ts: Full pipeline tested - test-rerank.ts: Rerank quality validated - test-query-rewrite.ts: Cross-language search verified - test-pdf-ingest.ts: Real PDF document tested (Dongen 2003.pdf) Documentation: - Added 05-RAG-Engine-User-Guide.md - Added 02-Document-Processing-User-Guide.md - Updated system status documentation Status: Production ready
30 KiB
30 KiB
知识库引擎数据模型设计
文档版本: v2.0
最后更新: 2026-01-21
状态: ✅ 权威文档
说明: 本文档是知识库引擎数据模型的唯一权威来源,其他文档应引用本文档,避免重复定义。
1. 设计原则
1.1 核心理念
即使没有任何结构化数据,RAG 检索也必须能工作!
结构化数据是"锦上添花",不是"必须有"。
1.2 四层架构
┌─────────────────────────────────────────────────────────────┐
│ Layer 0: RAG 核心层(必须有,检索基础) │
│ ───────────────────────────────────── │
│ extractedText → 全文 Markdown │
│ chunks[] → 文本切片 │
│ embeddings[] → 向量嵌入 │
│ │
│ ✅ 只要有这一层,RAG 就能工作! │
├─────────────────────────────────────────────────────────────┤
│ Layer 1: 基础信息层(必须有,系统需要) │
│ ───────────────────────────────────── │
│ filename, fileType, fileSizeBytes, fileUrl │
│ status, errorMessage, createdAt, updatedAt │
│ │
│ ✅ 文件管理必需 │
├─────────────────────────────────────────────────────────────┤
│ Layer 2: 内容增强层(可选,提升体验) │
│ ───────────────────────────────────── │
│ summary → AI 生成摘要(快速预览) │
│ tokenCount → Token 数量(成本估算) │
│ pageCount → 页数 │
│ │
│ ✅ 有则更好,无也能用 │
├─────────────────────────────────────────────────────────────┤
│ Layer 3: 分类标签层(可选,用户自定义) │
│ ───────────────────────────────────── │
│ contentType → 内容类型(可 AI 自动识别) │
│ tags[] → 用户标签(用户自己打) │
│ category → 分类目录(用户自己选) │
│ │
│ ✅ 用户可以不管,系统也能运行 │
├─────────────────────────────────────────────────────────────┤
│ Layer 4: 结构化数据层(可选,精准查询) │
│ ───────────────────────────────────── │
│ metadata → 文献属性(pmid, doi, journal...) │
│ structuredData → 类型特定数据(pico, diagnosis...) │
│ │
│ ✅ 高级功能,专业用户/药企场景使用 │
└─────────────────────────────────────────────────────────────┘
1.3 设计目标
| 目标 | 实现方式 |
|---|---|
| 最小可用 | Layer 0-1 必须有,RAG 就能工作 |
| 渐进增强 | Layer 2-4 可选,有则更强 |
| 用户友好 | 什么都不填也能用 |
| 专业支持 | 专业用户可以填完整信息 |
| AI 辅助 | contentType、summary 可 AI 自动生成 |
| 灵活扩展 | JSONB 支持任意结构化数据 |
1.4 ER 关系图
┌─────────────────────────────────────────────────────────────────┐
│ EkbKnowledgeBase │
│ ───────────────────────────────────────────── │
│ id, name, description │
│ type (USER | SYSTEM) │
│ ownerId (userId 或 moduleId) │
│ config (JSONB: chunkSize, topK, enableRerank...) │
├─────────────────────────────────────────────────────────────────┤
│ 1:N
▼
┌─────────────────────────────────────────────────────────────────┐
│ EkbDocument │
│ ───────────────────────────────────────────── │
│ id, kbId(FK), userId │
│ filename, fileType, fileSizeBytes, fileUrl, fileHash │
│ extractedText, summary, tokenCount, pageCount │
│ contentType, tags[], category │
│ metadata(JSONB), structuredData(JSONB) │
├─────────────────────────────────────────────────────────────────┤
│ 1:N
▼
┌─────────────────────────────────────────────────────────────────┐
│ EkbChunk │
│ ───────────────────────────────────────────── │
│ id, documentId(FK) │
│ content, chunkIndex │
│ embedding (vector 1024) │
│ pageNumber, sectionType │
│ metadata(JSONB) ← 新增:切片级元数据 │
└─────────────────────────────────────────────────────────────────┘
2. EkbKnowledgeBase 模型(容器表)
2.1 设计目的
| 痛点 | 解决方案 |
|---|---|
| 无法区分用户私有库 vs 系统公共库 | type 字段:USER / SYSTEM |
| 无法管理"谁拥有这个库" | ownerId 字段:userId 或 moduleId |
| 无法为不同库配置不同 RAG 策略 | config JSONB:chunkSize, topK 等 |
| 用户配额管理(最多 3 个库) | 通过 type=USER 计数 |
2.2 Prisma Schema
model EkbKnowledgeBase {
id String @id @default(uuid())
name String // 知识库名称
description String? // 描述
// ===== 核心隔离字段 =====
type String @default("USER") // USER: 用户私有, SYSTEM: 系统公共
ownerId String // USER: userId, SYSTEM: moduleId (如 "ASL", "AIA")
// ===== 策略配置 (JSONB) =====
config Json? // { chunkSize, topK, enableRerank, embeddingModel }
// ===== 关联 =====
documents EkbDocument[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
// ===== 索引 =====
@@index([ownerId])
@@index([type])
@@schema("ekb_schema")
}
2.3 字段说明
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
id |
String | ✅ | UUID 主键 |
name |
String | ✅ | 知识库名称(如"我的文献库"、"ASL 系统文献库") |
description |
String | ❌ | 知识库描述 |
type |
String | ✅ | 类型:USER(用户私有)或 SYSTEM(系统公共) |
ownerId |
String | ✅ | 所有者 ID:用户库填 userId,系统库填模块 ID |
config |
Json | ❌ | 策略配置 JSONB |
2.4 type 枚举
| 值 | 说明 | ownerId 含义 |
|---|---|---|
USER |
用户私有知识库 | userId(创建者) |
SYSTEM |
系统公共知识库 | moduleId(如 "ASL", "AIA", "IIT") |
2.5 config 结构
interface KnowledgeBaseConfig {
// RAG 策略
chunkSize?: number; // 切片大小,默认 512
chunkOverlap?: number; // 切片重叠,默认 50
topK?: number; // 检索数量,默认 5
// 高级功能
enableRerank?: boolean; // 启用重排序
enableSummary?: boolean; // 自动生成摘要
enableClinicalExtraction?: boolean; // 临床数据提取
// 模型配置
embeddingModel?: string; // 嵌入模型版本
}
2.6 使用示例
// 用户创建个人知识库
await prisma.ekbKnowledgeBase.create({
data: {
name: '我的肺癌文献库',
type: 'USER',
ownerId: 'user-123',
config: { chunkSize: 512, topK: 5 }
}
});
// 系统创建 ASL 模块知识库
await prisma.ekbKnowledgeBase.create({
data: {
name: 'ASL 系统文献库',
type: 'SYSTEM',
ownerId: 'ASL',
config: { enableClinicalExtraction: true }
}
});
// 查询用户所有知识库(配额检查)
const userKbs = await prisma.ekbKnowledgeBase.count({
where: { type: 'USER', ownerId: 'user-123' }
});
if (userKbs >= 3) throw new Error('知识库配额已满');
3. EkbDocument 模型
3.1 Prisma Schema
model EkbDocument {
id String @id @default(uuid())
kbId String // 所属知识库
userId String // 上传者(冗余存储,方便快速查询)
// ===== Layer 1: 基础信息(必须)=====
filename String // 文件名
fileType String // pdf, docx, pptx, xlsx, md, txt
fileSizeBytes BigInt // 文件大小(字节)
fileUrl String // OSS 存储路径
fileHash String? // 文件 SHA256 哈希(用于秒传和去重)
status String @default("pending") // 处理状态
errorMessage String? @db.Text // 错误信息
// ===== Layer 0: RAG 核心(必须)=====
extractedText String? @db.Text // Markdown 全文
// ===== Layer 2: 内容增强(可选)=====
summary String? @db.Text // AI 摘要
tokenCount Int? // Token 数量
pageCount Int? // 页数
// ===== Layer 3: 分类标签(可选)=====
contentType String? // 内容类型
tags String[] // 用户标签
category String? // 分类目录
// ===== Layer 4: 结构化数据(可选)=====
metadata Json? // 文献属性 JSONB
structuredData Json? // 类型特定数据 JSONB
// ===== 关联 =====
knowledgeBase EkbKnowledgeBase @relation(fields: [kbId], references: [id], onDelete: Cascade)
chunks EkbChunk[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
// ===== 索引 =====
@@index([kbId])
@@index([userId])
@@index([status])
@@index([contentType])
@@index([fileHash]) // 支持秒传查询
@@index([tags], type: Gin)
@@index([metadata], type: Gin)
@@index([structuredData], type: Gin)
@@schema("ekb_schema")
}
3.2 字段说明
Layer 1: 基础信息(必须)
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
id |
String | ✅ | UUID 主键 |
kbId |
String | ✅ | 所属知识库 ID(外键) |
userId |
String | ✅ | 上传者用户 ID(冗余存储,便于快速查询) |
filename |
String | ✅ | 原始文件名 |
fileType |
String | ✅ | 文件类型:pdf, docx, pptx, xlsx, md, txt, csv |
fileSizeBytes |
BigInt | ✅ | 文件大小(字节) |
fileUrl |
String | ✅ | OSS 存储路径 |
fileHash |
String | ❌ | 文件 SHA256 哈希(用于秒传和去重) |
status |
String | ✅ | 处理状态:pending, processing, completed, failed |
errorMessage |
String | ❌ | 处理失败时的错误信息 |
Layer 0: RAG 核心(必须)
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
extractedText |
String | ❌* | Markdown 格式全文(处理完成后必须有) |
*注:上传时为空,处理完成后必须有值
Layer 2: 内容增强(可选)
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
summary |
String | ❌ | AI 生成的摘要 |
tokenCount |
Int | ❌ | 全文 Token 数量(用于成本估算) |
pageCount |
Int | ❌ | 文档页数 |
Layer 3: 分类标签(可选)
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
contentType |
String | ❌ | 内容类型标识(见第 5 节) |
tags |
String[] | ❌ | 用户自定义标签 |
category |
String | ❌ | 分类目录路径,如 "肿瘤科/肺癌" |
Layer 4: 结构化数据(可选)
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
metadata |
Json | ❌ | 文献属性(见第 7 节) |
structuredData |
Json | ❌ | 类型特定数据(见第 8 节) |
3.3 status 状态枚举
| 状态 | 说明 |
|---|---|
pending |
等待处理 |
processing |
正在处理(解析、向量化) |
completed |
处理完成 |
failed |
处理失败 |
3.4 fileHash 使用示例
// 计算文件哈希
import crypto from 'crypto';
function calculateFileHash(buffer: Buffer): string {
return crypto.createHash('sha256').update(buffer).digest('hex');
}
// 上传时检查是否已存在(秒传)
async function uploadWithDedup(kbId: string, file: Buffer, filename: string) {
const fileHash = calculateFileHash(file);
// 检查同一知识库内是否已存在相同文件
const existing = await prisma.ekbDocument.findFirst({
where: { kbId, fileHash }
});
if (existing) {
// 秒传:直接返回已存在的文档
return { type: 'duplicate', document: existing };
}
// 正常上传流程
const document = await prisma.ekbDocument.create({
data: { kbId, fileHash, filename, /* ... */ }
});
return { type: 'new', document };
}
4. EkbChunk 模型
4.1 Prisma Schema
model EkbChunk {
id String @id @default(uuid())
documentId String // 所属文档
// ===== 核心内容 =====
content String @db.Text // 切片文本(Markdown)
chunkIndex Int // 切片序号(从 0 开始)
// ===== 向量 =====
embedding Unsupported("vector(1024)")? // 向量嵌入
// ===== 溯源信息(可选)=====
pageNumber Int? // 页码(用于 PDF 溯源)
sectionType String? // 章节类型
// ===== 扩展元数据(可选)=====
metadata Json? // 切片级元数据 JSONB
document EkbDocument @relation(fields: [documentId], references: [id], onDelete: Cascade)
@@index([documentId])
@@index([metadata], type: Gin) // JSONB 索引
@@schema("ekb_schema")
}
4.2 字段说明
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
id |
String | ✅ | UUID 主键 |
documentId |
String | ✅ | 所属文档 ID |
content |
String | ✅ | 切片文本(Markdown 格式) |
chunkIndex |
Int | ✅ | 切片序号,从 0 开始 |
embedding |
vector(1024) | ❌* | 向量嵌入(向量化后必须有) |
pageNumber |
Int | ❌ | 来源页码(PDF 溯源) |
sectionType |
String | ❌ | 章节类型标识 |
metadata |
Json | ❌ | 切片级扩展元数据(见 4.4) |
4.3 sectionType 枚举(可选)
| 值 | 说明 |
|---|---|
title |
标题 |
abstract |
摘要 |
introduction |
引言 |
methods |
方法 |
results |
结果 |
discussion |
讨论 |
conclusion |
结论 |
references |
参考文献 |
table |
表格 |
figure |
图片说明 |
4.4 metadata 结构(切片级元数据)
interface ChunkMetadata {
// 考试题场景
isAnswer?: boolean; // 是否为答案切片
questionId?: number; // 所属题目 ID
chunkType?: 'question' | 'options' | 'answer' | 'explanation';
// 病历场景
section?: string; // 病历段落:主诉、现病史、检查结果等
// 通用
importance?: number; // 重要性权重 0-1
keywords?: string[]; // 关键词(用于加权检索)
}
使用示例:
// 考试题切片 - 题目
{
"content": "1. 关于帕博利珠单抗,下列说法正确的是?",
"metadata": { "chunkType": "question", "questionId": 1 }
}
// 考试题切片 - 选项
{
"content": "A. 派姆单抗 B. 纳武利尤单抗 C. 阿特珠单抗 D. 度伐利尤单抗",
"metadata": { "chunkType": "options", "questionId": 1 }
}
// 考试题切片 - 答案
{
"content": "正确答案:A。派姆单抗是帕博利珠单抗的通用名...",
"metadata": { "chunkType": "answer", "questionId": 1, "isAnswer": true }
}
// 检索时降低纯答案切片的权重
const results = await vectorSearch(query);
const reranked = results.map(r => ({
...r,
score: r.metadata?.isAnswer ? r.score * 0.5 : r.score
}));
5. 索引设计
5.1 向量索引(HNSW)
-- 创建 HNSW 索引(高性能近似最近邻)
CREATE INDEX idx_ekb_chunk_embedding ON ekb_schema.ekb_chunk
USING hnsw (embedding vector_cosine_ops)
WITH (m = 16, ef_construction = 64);
参数说明:
m = 16: 每层最大连接数ef_construction = 64: 构建时搜索范围
5.2 关键词索引(pg_bigm)
-- 安装 pg_bigm 扩展
CREATE EXTENSION IF NOT EXISTS pg_bigm;
-- 全文内容索引
CREATE INDEX idx_ekb_chunk_content_bigm ON ekb_schema.ekb_chunk
USING gin (content gin_bigm_ops);
-- 文档摘要索引
CREATE INDEX idx_ekb_document_summary_bigm ON ekb_schema.ekb_document
USING gin (summary gin_bigm_ops);
-- 提取文本索引
CREATE INDEX idx_ekb_document_text_bigm ON ekb_schema.ekb_document
USING gin (extracted_text gin_bigm_ops);
关键词查询示例:
-- 关键词搜索(支持中英文)
SELECT * FROM ekb_schema.ekb_chunk
WHERE content LIKE '%Pembrolizumab%'
ORDER BY likequery(content, 'Pembrolizumab') DESC;
-- 中文搜索
SELECT * FROM ekb_schema.ekb_chunk
WHERE content LIKE '%非小细胞肺癌%';
5.3 JSONB 索引(GIN)
-- 文献属性索引
CREATE INDEX idx_ekb_document_metadata ON ekb_schema.ekb_document
USING gin (metadata jsonb_path_ops);
-- 结构化数据索引
CREATE INDEX idx_ekb_document_structured ON ekb_schema.ekb_document
USING gin (structured_data jsonb_path_ops);
-- 标签数组索引
CREATE INDEX idx_ekb_document_tags ON ekb_schema.ekb_document
USING gin (tags);
JSONB 查询示例:
-- 按影响因子筛选
SELECT * FROM ekb_schema.ekb_document
WHERE (metadata->>'ifScore')::float > 10;
-- 按 PICO 干预措施筛选
SELECT * FROM ekb_schema.ekb_document
WHERE structured_data->'pico'->>'I' ILIKE '%Pembrolizumab%';
-- 按标签筛选
SELECT * FROM ekb_schema.ekb_document
WHERE tags @> ARRAY['肺癌', '免疫治疗'];
6. contentType 枚举
| 值 | 说明 | 适用场景 |
|---|---|---|
general |
通用文档(默认) | 任意文档 |
literature |
医学文献 | 论文、研究报告 |
case |
典型病历 | MDT 病例、教学病例 |
exam |
教学考试 | 试题、模拟题 |
drug |
药品资料 | 说明书、处方信息 |
guideline |
临床指南 | NCCN、CSCO 指南 |
note |
个人笔记 | 学习笔记、会议记录 |
protocol |
研究方案 | 临床试验方案 |
report |
工作报告 | 汇报材料、分析报告 |
7. metadata 结构(文献属性)
7.1 JSON Schema
interface Metadata {
// 基础信息
title?: string; // 文献标题
abstract?: string; // 原始摘要
// 标识符
pmid?: string; // PubMed ID
doi?: string; // DOI
nctId?: string; // ClinicalTrials.gov ID
// 来源信息
journal?: string; // 期刊名称
publisher?: string; // 出版商
authors?: string[]; // 作者列表
// 时间与评分
publishYear?: number; // 发表年份
publishDate?: string; // 发表日期 (YYYY-MM-DD)
ifScore?: number; // 影响因子
// 分类
docType?: string; // 文献类型:RCT, Meta, Review, Case, Guideline
keywords?: string[]; // 关键词
meshTerms?: string[]; // MeSH 词表
// 语言
language?: string; // 语言:en, zh, ...
}
7.2 示例
{
"title": "Pembrolizumab versus Chemotherapy for PD-L1–Positive Non–Small-Cell Lung Cancer",
"pmid": "27718847",
"doi": "10.1056/NEJMoa1606774",
"journal": "New England Journal of Medicine",
"authors": ["Reck M", "Rodriguez-Abreu D", "Robinson AG"],
"publishYear": 2016,
"ifScore": 176.079,
"docType": "RCT",
"keywords": ["NSCLC", "Pembrolizumab", "Immunotherapy"],
"language": "en"
}
8. structuredData 结构(类型特定数据)
8.1 医学文献 (literature)
interface LiteratureData {
// PICO 要素
pico?: {
P: string; // Population
I: string; // Intervention
C: string; // Comparison
O: string; // Outcome
};
// 研究设计
studyDesign?: {
design: string; // Phase III RCT, Meta-analysis, etc.
sampleSize: number; // 样本量
blinding: string; // Double-blind, Open-label
duration: string; // 研究周期
};
// 用药方案
regimen?: Array<{
drug: string; // 药物名称
dose: string; // 剂量
freq: string; // 频率
route: string; // 给药途径
}>;
// 安全性数据
safety?: {
ae_all: string[]; // 所有不良反应
ae_grade34: string[]; // 3-4级不良反应
dropout_rate: string; // 脱落率
};
// 入排标准
criteria?: {
inclusion: string[]; // 入选标准
exclusion: string[]; // 排除标准
};
// 观察指标
endpoints?: {
primary: string[]; // 主要终点
secondary: string[]; // 次要终点
results: Record<string, any>; // 结果数据
};
}
8.2 典型病历 (case)
interface CaseData {
// 诊断信息
diagnosis?: {
primary: string; // 主诊断
secondary: string[]; // 合并诊断
staging: string; // 分期
pathology: string; // 病理类型
biomarkers: Record<string, string>; // 生物标志物
};
// 治疗信息
treatment?: {
firstLine: string; // 一线治疗
secondLine: string; // 二线治疗
surgery: string; // 手术
radiation: string; // 放疗
response: string; // 疗效评价
duration: string; // 治疗周期
};
// 预后信息
prognosis?: {
pfs: string; // 无进展生存
os: string; // 总生存
status: string; // 当前状态
recurrence: string; // 复发情况
};
// 随访信息
followUp?: {
lastVisit: string; // 最后随访日期
nextPlan: string; // 下一步计划
notes: string; // 随访备注
};
}
8.3 教学考试 (exam)
interface ExamData {
// 题目列表
questions?: Array<{
id: number;
type: 'single' | 'multiple' | 'essay'; // 题型
content: string; // 题目内容
options?: string[]; // 选项(选择题)
}>;
// 答案列表
answers?: Array<{
id: number;
answer: string; // 答案
explanation: string; // 解析
}>;
// 知识点
knowledgePoints?: string[];
// 难度
difficulty?: 'easy' | 'medium' | 'hard';
// 来源
source?: string; // 题目来源
}
8.4 药品资料 (drug)
interface DrugData {
// 基础信息
genericName?: string; // 通用名
brandName?: string; // 商品名
manufacturer?: string; // 生产厂家
// 适应症
indication?: string[];
// 禁忌症
contraindication?: string[];
// 用法用量
dosage?: {
adult: string;
pediatric: string;
adjustment: string; // 剂量调整
};
// 药物相互作用
interaction?: string[];
// 警告
warnings?: string[];
// 不良反应
adverseReactions?: {
common: string[];
serious: string[];
};
}
8.5 临床指南 (guideline)
interface GuidelineData {
// 推荐意见
recommendations?: Array<{
content: string; // 推荐内容
level: string; // 证据级别 (1A, 2B, etc.)
strength: string; // 推荐强度
}>;
// 适用人群
population?: string;
// 发布机构
organization?: string; // NCCN, CSCO, ESMO
// 版本
version?: string;
// 更新要点
updates?: string[];
}
8.6 个人笔记 (note)
interface NoteData {
// 标签(与顶层 tags 字段可重复,这里可存更多)
tags?: string[];
// 分类
category?: string;
// 关联
relatedDocs?: string[]; // 关联文档 ID
// 提醒
reminder?: string; // 提醒日期
}
9. 使用示例
9.1 普通医生随手上传
// 医生直接拖文件上传,什么都不填
await kbEngine.submitIngestTask({
kbId: 'kb-123',
file: pdfBuffer,
filename: '某篇论文.pdf',
// 其他字段都不填
});
// 系统自动完成:
// ✅ extractedText → 提取全文
// ✅ chunks → 切片
// ✅ embeddings → 向量化
// ✅ summary → AI 摘要(可选开启)
// ✅ contentType → AI 自动识别(可选开启)
// 结果:RAG 检索完全可用!
9.2 医生想分类管理
// 医生上传时选择分类、打标签
await kbEngine.submitIngestTask({
kbId: 'kb-123',
file: pdfBuffer,
filename: 'KEYNOTE-024.pdf',
contentType: 'literature',
tags: ['肺癌', '免疫治疗', 'RCT'],
category: '肿瘤科/肺癌',
});
// 结果:可以按分类、标签筛选
9.3 药企专业录入
// 药企医学部专业人员完整填写
await kbEngine.submitIngestTask({
kbId: 'kb-456',
file: pdfBuffer,
filename: 'KEYNOTE-024.pdf',
contentType: 'literature',
tags: ['Pembrolizumab', 'NSCLC', 'Phase III'],
category: '临床研究/III期',
metadata: {
title: 'Pembrolizumab versus Chemotherapy...',
pmid: '27718847',
doi: '10.1056/NEJMoa1606774',
journal: 'NEJM',
authors: ['Reck M', 'Rodriguez-Abreu D'],
publishYear: 2016,
ifScore: 176.079,
docType: 'RCT',
},
options: { enableClinicalExtraction: true }
});
// AI 自动提取 structuredData:
// {
// pico: { P: '晚期NSCLC, PD-L1≥50%', I: 'Pembrolizumab', ... },
// studyDesign: { design: 'Phase III RCT', sampleSize: 305 },
// ...
// }
9.4 典型病历录入
await kbEngine.submitIngestTask({
kbId: 'kb-123',
file: docBuffer,
filename: '肺癌MDT病例.docx',
contentType: 'case',
tags: ['MDT', '肺癌', 'IVA期'],
category: '病例库/肺癌',
options: { enableClinicalExtraction: true }
});
// AI 自动提取 structuredData:
// {
// diagnosis: { primary: '非小细胞肺癌 IVA期', ... },
// treatment: { firstLine: '帕博利珠单抗 + 化疗', ... },
// ...
// }
10. 功能可用性矩阵
| 功能 | 只有 Layer 0-1 | + Layer 2 | + Layer 3 | + Layer 4 |
|---|---|---|---|---|
| 向量检索 | ✅ | ✅ | ✅ | ✅ |
| 关键词检索 | ✅ | ✅ | ✅ | ✅ |
| 混合检索 | ✅ | ✅ | ✅ | ✅ |
| 快速预览 | ❌ | ✅ 有摘要 | ✅ | ✅ |
| 分类筛选 | ❌ | ❌ | ✅ | ✅ |
| 标签筛选 | ❌ | ❌ | ✅ | ✅ |
| 年份筛选 | ❌ | ❌ | ❌ | ✅ |
| IF 筛选 | ❌ | ❌ | ❌ | ✅ |
| PICO 查询 | ❌ | ❌ | ❌ | ✅ |
11. 版本历史
| 版本 | 日期 | 变更内容 |
|---|---|---|
| v1.0 | 2026-01-20 | 初版:四层架构设计,支持多内容类型 |
| v2.0 | 2026-01-21 | 整合审查建议:增加 EkbKnowledgeBase 容器表、EkbDocument.fileHash 字段、EkbChunk.metadata 字段 |