Files
AIclinicalresearch/docs/02-通用能力层/03-RAG引擎/01-知识库引擎架构设计.md
HaHafeng 40c2f8e148 feat(rag): Complete RAG engine implementation with pgvector
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
2026-01-21 20:24:29 +08:00

36 KiB
Raw Permalink Blame History

知识库引擎架构设计

文档版本: v1.2
创建日期: 2026-01-20
最后更新: 2026-01-20
能力定位: 通用能力层
状态: 🔄 升级中Dify → PostgreSQL + pgvector
核心原则: 提供基础能力(乐高积木),不做策略选择


📋 概述

能力定位

知识库引擎是平台的核心通用能力,提供知识库相关的基础能力(乐高积木),供业务模块根据场景自由组合。

核心设计原则

┌─────────────────────────────────────────────────────────────┐
│                                                             │
│   ✅ 提供基础能力(乐高积木)                                 │
│   ❌ 不做策略选择(组装方案由业务模块决定)                    │
│   ⚡️ 入库必须异步(防止 HTTP 超时)                           │
│   💰 提取按需开启(控制 LLM 调用成本)                        │
│                                                             │
│   原因:                                                     │
│   • 不同业务场景需要不同的知识库使用策略                       │
│   • 小知识库10个文件可能直接全文塞给 LLM 更好              │
│   • 大知识库1000+文件)必须用 RAG 向量检索                  │
│   • 有的场景需要 摘要筛选 → Top-K 全文 的两阶段策略           │
│   • 策略选择是业务逻辑,不是基础设施                          │
│                                                             │
└─────────────────────────────────────────────────────────────┘

基础能力清单

能力分类 基础能力 说明
文档入库 submitIngestTask() 异步入库,返回 taskId
getIngestStatus() 获取入库任务状态和进度
全文获取 getDocumentFullText() 获取单个文档全文
getAllDocumentsText() 获取知识库所有文档全文
摘要获取 getDocumentSummary() 获取单个文档摘要
getAllDocumentsSummaries() 获取知识库所有文档摘要
向量检索 vectorSearch() 基于 pgvector 的语义检索
关键词检索 keywordSearch() 基于 pg_bigm 的中文精确检索
混合检索 hybridSearch() 向量 + 关键词 + RRF 融合
重排序 rerank() 🆕 基于 Qwen-Rerank 的精排序
管理操作 deleteDocument() 删除文档
clearKnowledgeBase() 清空知识库

⚠️ 注意:不提供 chat() 方法!问答策略由业务模块根据场景决定。


🎯 业务模块策略选择

知识库引擎提供基础能力,业务模块根据场景自由组合:

策略示例

┌─────────────────────────────────────────────────────────────┐
│                    业务模块层(策略选择)                      │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│   PKB 个人知识库                                             │
│   ├─ 小知识库(< 20 文档)→ 全文模式                         │
│   │   getAllDocumentsText() → 直接塞给 LLM                  │
│   └─ 大知识库100+ 文档)→ RAG 模式                         │
│       hybridSearch() → 检索 Top-K → LLM 回答                │
│                                                             │
│   AIA AI智能问答                                             │
│   └─ 摘要筛选 + Top-K 全文                                   │
│       getAllDocumentsSummaries() → LLM 筛选 Top 5           │
│       → getDocumentFullText() × 5 → LLM 回答                │
│                                                             │
│   ASL 智能文献                                               │
│   └─ 向量检索 + Rerank                                       │
│       vectorSearch(topK=50) → Rerank(topK=10) → 返回        │
│                                                             │
│   RVW 稿件审查                                               │
│   └─ 全文比对查重                                            │
│       getAllDocumentsText() → 逐篇相似度计算                 │
│                                                             │
├─────────────────────────────────────────────────────────────┤
│                    通用能力层(提供积木)                      │
│   ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐     │
│   │ 全文获取  │ │ 摘要获取  │ │ 向量检索  │ │ 关键词检索│     │
│   └──────────┘ └──────────┘ └──────────┘ └──────────┘     │
│   ┌──────────┐ ┌──────────┐ ┌──────────┐                   │
│   │ 文档入库  │ │ 混合检索  │ │ 文档删除  │                   │
│   └──────────┘ └──────────┘ └──────────┘                   │
└─────────────────────────────────────────────────────────────┘

代码示例

场景 1PKB 小知识库10个文件→ 全文模式

// PKB 模块:小知识库直接全文
async function pkbSmallKbChat(kbId: string, query: string) {
  const kbEngine = new KnowledgeBaseEngine(prisma);
  
  // 获取所有文档全文
  const docs = await kbEngine.getAllDocumentsText(kbId);
  
  // 直接塞给 LLM
  const context = docs.map(d => `## ${d.filename}\n${d.extractedText}`).join('\n\n---\n\n');
  
  const systemPrompt = `你是医学专家。以下是知识库的完整内容:\n\n${context}`;
  return llmChat(systemPrompt, query);
}

场景 2AIA 摘要筛选 + Top-K 全文

// AIA 模块:摘要筛选 + 全文精读
async function aiaSmartChat(kbIds: string[], query: string) {
  const kbEngine = new KnowledgeBaseEngine(prisma);
  
  // 1. 获取所有文档摘要
  const summaries = await kbEngine.getAllDocumentsSummaries(kbIds);
  
  // 2. LLM 筛选最相关的 Top 5 文档
  const topDocIds = await llmSelectTopK(summaries, query, 5);
  
  // 3. 获取 Top 5 文档全文
  const fullTexts = await Promise.all(
    topDocIds.map(id => kbEngine.getDocumentFullText(id))
  );
  
  // 4. 基于全文回答
  const context = fullTexts.map(d => `## ${d.filename}\n${d.text}`).join('\n\n');
  return llmChat(context, query);
}

场景 3ASL 大规模文献检索

// ASL 模块:向量检索 + Rerank
async function aslLiteratureSearch(kbIds: string[], query: string) {
  const kbEngine = new KnowledgeBaseEngine(prisma);
  
  // 1. 向量检索 Top 50
  const candidates = await kbEngine.vectorSearch(kbIds, query, 50);
  
  // 2. Rerank 精排 Top 10
  const reranked = await rerankService.rerank(candidates, query, 10);
  
  // 3. 返回带引用的结果
  return reranked.map(r => ({
    content: r.content,
    source: r.documentName,
    score: r.score,
  }));
}

场景 4RVW 稿件查重

// RVW 模块:全文比对
async function rvwPlagiarismCheck(manuscriptText: string, kbId: string) {
  const kbEngine = new KnowledgeBaseEngine(prisma);
  
  // 获取所有文献全文
  const docs = await kbEngine.getAllDocumentsText(kbId);
  
  // 逐篇比对相似度
  const similarities = docs.map(d => ({
    document: d,
    similarity: calculateTextSimilarity(manuscriptText, d.extractedText),
  }));
  
  // 返回可疑重复段落
  return similarities
    .filter(s => s.similarity > 0.3)
    .sort((a, b) => b.similarity - a.similarity);
}

🏗️ 整体架构

架构图

┌─────────────────────────────────────────────────────────────────┐
│                   业务模块层(策略选择)                          │
│   ┌─────────┐  ┌─────────┐  ┌─────────┐  ┌─────────┐           │
│   │   PKB   │  │   AIA   │  │   ASL   │  │   RVW   │           │
│   │ 全文/RAG │  │摘要+全文 │  │向量+Rerank│ │ 全文比对 │           │
│   └────┬────┘  └────┬────┘  └────┬────┘  └────┬────┘           │
│        │            │            │            │                 │
│        │  根据场景自由组合基础能力                │                 │
│        └────────────┴────────────┴────────────┘                 │
│                          │                                      │
│                          ▼                                      │
├─────────────────────────────────────────────────────────────────┤
│                 知识库引擎(通用能力层 - 提供积木)                 │
│   ┌─────────────────────────────────────────────────────────┐   │
│   │                 KnowledgeBaseEngine                      │   │
│   │   提供基础能力,不做策略选择                               │   │
│   ├─────────────────────────────────────────────────────────┤   │
│   │                                                          │   │
│   │   ┌────────────────────────────────────────────────┐    │   │
│   │   │              文档入库能力                        │    │   │
│   │   │  ingestDocument() / ingestBatch()              │    │   │
│   │   └────────────────────────────────────────────────┘    │   │
│   │                                                          │   │
│   │   ┌────────────────────────────────────────────────┐    │   │
│   │   │              内容获取能力                        │    │   │
│   │   │  getDocumentFullText() / getAllDocumentsText() │    │   │
│   │   │  getDocumentSummary() / getAllDocumentsSummaries()│   │   │
│   │   └────────────────────────────────────────────────┘    │   │
│   │                                                          │   │
│   │   ┌────────────────────────────────────────────────┐    │   │
│   │   │              检索能力                            │    │   │
│   │   │  vectorSearch() / keywordSearch() / hybridSearch()│   │   │
│   │   └────────────────────────────────────────────────┘    │   │
│   │                                                          │   │
│   └─────────────────────────────────────────────────────────┘   │
│                          │                                      │
│                          ▼                                      │
│   ┌─────────────────────────────────────────────────────────┐   │
│   │              文档处理引擎(独立通用能力)                    │   │
│   │   PDF/Word/Excel/PPT → Markdown                          │   │
│   └─────────────────────────────────────────────────────────┘   │
├─────────────────────────────────────────────────────────────────┤
│                        数据存储层                                │
│   ┌─────────────────────────────────────────────────────────┐   │
│   │          PostgreSQL + pgvector (Postgres-Only)           │   │
│   │   ┌───────────────┐    ┌───────────────────────────┐    │   │
│   │   │ EkbDocument   │    │ EkbChunk                  │    │   │
│   │   │ (文档 + JSONB)│───>│ (切片 + vector(1024))     │    │   │
│   │   └───────────────┘    └───────────────────────────┘    │   │
│   └─────────────────────────────────────────────────────────┘   │
└─────────────────────────────────────────────────────────────────┘

🏗️ 关键技术决策

1. 入库异步化Postgres-Only 架构)

文档入库是耗时操作10-60秒必须异步处理以避免 HTTP 超时。

// 提交入库任务(立即返回 taskId
const { taskId } = await kbEngine.submitIngestTask({
  kbId: 'kb-123',
  file: pdfBuffer,
  filename: 'research.pdf',
});

// 轮询任务状态
const status = await kbEngine.getIngestStatus(taskId);
// { status: 'processing', progress: 45, error: null }

技术实现:基于 pg-boss 队列,详见 Postgres-Only异步任务处理指南

2. 💰 成本控制策略

行为 默认 LLM 调用 成本
解析 + 切片 + 向量化 开启 低(仅 Embedding API
摘要生成 关闭
临床要素提取PICO 关闭
// 默认行为:只做向量化(零 LLM 成本)
await kbEngine.submitIngestTask({ kbId, file, filename });

// ASL 智能文献场景:开启完整提取
await kbEngine.submitIngestTask({
  kbId, file, filename,
  options: {
    enableSummary: true,           // 💰 可选
    enableClinicalExtraction: true // 💰 可选
  }
});

3. 🔧 中文关键词检索方案

PostgreSQL 默认分词对中文支持不佳,采用 pg_bigmBigram 方案:

方案 原理 中文效果 说明
tsvector 分词 需额外中文分词插件
pg_trgm 3-gram 一般 英文为主
pg_bigm 2-gram 优秀 专为 CJK 文字优化
-- 开启插件
CREATE EXTENSION IF NOT EXISTS pg_bigm;

-- 创建索引
CREATE INDEX bigm_idx ON "ekb_schema"."EkbChunk" 
USING gin (content gin_bigm_ops);

-- 查询(支持中文精确匹配)
SELECT * FROM "EkbChunk" WHERE content LIKE '%帕博利珠%';
-- 可匹配:"帕博利珠单抗"、"帕博利珠注射液" 等

-- 相似度查询
SELECT *, bigm_similarity(content, '帕博利珠单抗') as score
FROM "EkbChunk" 
WHERE content LIKE '%帕博利珠%'
ORDER BY score DESC;

优势

  • 对医学专有名词召回率高
  • 不需要复杂语义评分(向量检索已做语义互补)
  • 追求"查全率"和"精确匹配"

📦 代码结构

目录规划

backend/src/common/rag/
├── index.ts                      # 统一导出
├── KnowledgeBaseEngine.ts        # 统一入口类(基础能力)
│
├── services/
│   ├── ChunkService.ts           # 文档切片服务
│   ├── EmbeddingService.ts       # 向量化服务(阿里云 DashScope
│   ├── SummaryService.ts         # 摘要生成服务(💰 可选)
│   ├── ClinicalExtractionService.ts  # 临床要素提取(💰 可选)
│   ├── VectorSearchService.ts    # 向量检索服务pgvector
│   ├── KeywordSearchService.ts   # 关键词检索服务pg_trgm
│   ├── HybridSearchService.ts    # 混合检索服务RRF 融合)
│   └── RerankService.ts          # 🆕 重排序服务Qwen-Rerank
│
├── workers/
│   └── ingestWorker.ts           # ⚡️ 异步入库 Workerpg-boss
│
├── types/
│   ├── index.ts                  # 类型定义
│   ├── chunk.types.ts
│   ├── search.types.ts
│   └── document.types.ts
│
├── utils/
│   ├── rrfFusion.ts              # RRF 算法
│   └── jsonParser.ts             # JSON 容错解析
│
└── __tests__/                    # 单元测试
    ├── embedding.test.ts
    ├── chunk.test.ts
    └── search.test.ts

基础能力 API

// KnowledgeBaseEngine.ts
export class KnowledgeBaseEngine {
  constructor(private prisma: PrismaClient) {}

  // ==================== 文档入库(异步) ====================
  
  /**
   * ⚡️ 提交入库任务(立即返回 taskId
   * 详见Postgres-Only异步任务处理指南
   */
  async submitIngestTask(params: {
    kbId: string;
    userId: string;
    file: Buffer;
    filename: string;
    options?: {
      enableSummary?: boolean;           // 💰 默认 false
      enableClinicalExtraction?: boolean; // 💰 默认 false
      chunkSize?: number;
      chunkOverlap?: number;
    };
  }): Promise<{ taskId: string; documentId: string }>;

  /**
   * 获取入库任务状态
   */
  async getIngestStatus(taskId: string): Promise<{
    status: 'pending' | 'processing' | 'completed' | 'failed';
    progress: number;  // 0-100
    error?: string;
  }>;

  // ==================== 内容获取(全文) ====================

  /**
   * 获取单个文档全文
   */
  async getDocumentFullText(documentId: string): Promise<DocumentText>;

  /**
   * 获取知识库所有文档全文
   */
  async getAllDocumentsText(kbId: string): Promise<DocumentText[]>;

  /**
   * 批量获取多个知识库的所有文档全文
   */
  async getAllDocumentsTextBatch(kbIds: string[]): Promise<DocumentText[]>;

  // ==================== 内容获取(摘要) ====================

  /**
   * 获取单个文档摘要
   */
  async getDocumentSummary(documentId: string): Promise<DocumentSummary>;

  /**
   * 获取知识库所有文档摘要
   */
  async getAllDocumentsSummaries(kbId: string): Promise<DocumentSummary[]>;

  /**
   * 批量获取多个知识库的所有文档摘要
   */
  async getAllDocumentsSummariesBatch(kbIds: string[]): Promise<DocumentSummary[]>;

  // ==================== 检索能力 ====================

  /**
   * 向量检索(语义搜索)
   */
  async vectorSearch(
    kbIds: string[],
    query: string,
    topK?: number
  ): Promise<SearchResult[]>;

  /**
   * 关键词检索pg_bigm 中文精确匹配)
   */
  async keywordSearch(
    kbIds: string[],
    query: string,
    topK?: number
  ): Promise<SearchResult[]>;

  /**
   * 混合检索(向量 + 关键词 + RRF 融合)
   */
  async hybridSearch(
    kbIds: string[],
    query: string,
    topK?: number,
    options?: {
      vectorWeight?: number;
      keywordWeight?: number;
      filters?: SearchFilters;
    }
  ): Promise<SearchResult[]>;

  /**
   * 🆕 重排序Qwen-Rerank API
   */
  async rerank(
    documents: SearchResult[],
    query: string,
    topK?: number
  ): Promise<SearchResult[]>;

  // ==================== 管理操作 ====================

  /**
   * 删除文档(级联删除切片和向量)
   */
  async deleteDocument(documentId: string): Promise<void>;

  /**
   * 删除知识库所有文档
   */
  async clearKnowledgeBase(kbId: string): Promise<void>;

  /**
   * 获取知识库统计信息
   */
  async getKnowledgeBaseStats(kbId: string): Promise<{
    documentCount: number;
    chunkCount: number;
    totalTokens: number;
  }>;

  // ==================== ❌ 不提供 chat() 方法 ====================
  // 策略由业务模块根据场景决定
}

🔄 核心流程

文档入库流程Ingest

用户上传 PDF/Word/...
         │
         ▼
┌─────────────────────────────────────────────────────────────┐
│  Step 1: 文档处理引擎                                        │
│  ┌─────────────────────────────────────────────────────┐    │
│  │  DocumentProcessor.toMarkdown(file)                  │    │
│  │  • PDF → pymupdf4llm                                 │    │
│  │  • Word → mammoth                                    │    │
│  │  • Excel → pandas                                    │    │
│  │  输出Markdown 文本                                  │    │
│  └─────────────────────────────────────────────────────┘    │
└─────────────────────────────────────────────────────────────┘
         │
         ▼
┌─────────────────────────────────────────────────────────────┐
│  Step 2: 文本切片                                            │
│  ┌─────────────────────────────────────────────────────┐    │
│  │  ChunkService.split(markdown)                        │    │
│  │  • 递归字符切分                                       │    │
│  │  • chunkSize: 512, overlap: 50                       │    │
│  │  输出Chunk[]                                        │    │
│  └─────────────────────────────────────────────────────┘    │
└─────────────────────────────────────────────────────────────┘
         │
         ▼
┌─────────────────────────────────────────────────────────────┐
│  Step 3: 摘要生成(可选)                                     │
│  ┌─────────────────────────────────────────────────────┐    │
│  │  SummaryService.generate(fullText)                   │    │
│  │  • LLM 生成 200-500 字摘要                            │    │
│  │  输出summary 字段                                   │    │
│  └─────────────────────────────────────────────────────┘    │
└─────────────────────────────────────────────────────────────┘
         │
         ▼
┌─────────────────────────────────────────────────────────────┐
│  Step 4: 临床要素提取(可选)                                 │
│  ┌─────────────────────────────────────────────────────┐    │
│  │  ClinicalExtractionService.extract(fullText)         │    │
│  │  • PICO、用药方案、安全性数据等                        │    │
│  │  • LLM 提取 + JSON 容错解析                           │    │
│  │  输出ClinicalData (JSONB)                          │    │
│  └─────────────────────────────────────────────────────┘    │
└─────────────────────────────────────────────────────────────┘
         │
         ▼
┌─────────────────────────────────────────────────────────────┐
│  Step 5: 向量化                                              │
│  ┌─────────────────────────────────────────────────────┐    │
│  │  EmbeddingService.embedBatch(chunks.map(c => c.text))│    │
│  │  • 阿里云 text-embedding-v3                          │    │
│  │  • 1024 维向量                                        │    │
│  │  输出number[][]                                     │    │
│  └─────────────────────────────────────────────────────┘    │
└─────────────────────────────────────────────────────────────┘
         │
         ▼
┌─────────────────────────────────────────────────────────────┐
│  Step 6: 存储                                                │
│  ┌─────────────────────────────────────────────────────┐    │
│  │  PostgreSQL + pgvector                               │    │
│  │  • EkbDocument: 文档元数据 + 摘要 + 临床数据 (JSONB)  │    │
│  │  • EkbChunk: 切片文本 + 向量 (vector(1024))          │    │
│  └─────────────────────────────────────────────────────┘    │
└─────────────────────────────────────────────────────────────┘

🗄️ 数据模型

📌 数据模型详见04-数据模型设计.md

本文档不再重复定义数据模型,请以上述文档为准。该文档包含:

  • 四层架构设计原则
  • EkbDocument / EkbChunk 完整 Prisma Schema
  • 索引设计HNSW、pg_bigm、GIN
  • contentType 枚举定义
  • metadata / structuredData JSONB 结构
  • 各类型使用示例

📊 策略选择指南

根据知识库规模选择策略

知识库规模 文档数量 估算 Tokens 推荐策略 基础能力组合
微型 1-10 < 30K 全文塞给 LLM getAllDocumentsText()
小型 10-30 30K-80K 全文 + 长上下文模型 getAllDocumentsText() + Qwen-Long
中型 30-100 80K-300K 摘要筛选 + Top-K 全文 getAllDocumentsSummaries() + getDocumentFullText()
大型 100+ > 300K RAG 向量检索 hybridSearch()

根据场景选择策略

场景 推荐策略 原因
精准问答 全文模式 无信息丢失
快速检索 向量检索 速度快
综合分析 摘要筛选 + 全文 兼顾广度和深度
文献综述 混合检索 + Rerank 召回率高
查重对比 全文比对 精确匹配

🔗 与其他通用能力的关系

依赖关系图

┌─────────────────────────────────────────────────────────────┐
│                    知识库引擎 (本模块)                        │
│                                                             │
│   平台依赖:                                                  │
│   ┌─────────────────────────────────────────────────────┐   │
│   │  ⚡️ 异步任务处理pg-boss                           │   │
│   │  • 入库任务队列                                       │   │
│   │  • 详见Postgres-Only异步任务处理指南                 │   │
│   └─────────────────────────────────────────────────────┘   │
│                                                             │
│   ┌─────────────────────────────────────────────────────┐   │
│   │  文档处理引擎                                         │   │
│   │  • 调用 DocumentProcessor.toMarkdown()              │   │
│   │  • 获取 PDF/Word/Excel 的 Markdown 文本              │   │
│   └─────────────────────────────────────────────────────┘   │
│                                                             │
│   ┌─────────────────────────────────────────────────────┐   │
│   │  LLM 网关(💰 可选调用)                               │   │
│   │  • 摘要生成enableSummary: true                   │   │
│   │  • 临床要素提取enableClinicalExtraction: true     │   │
│   └─────────────────────────────────────────────────────┘   │
│                                                             │
│   ┌─────────────────────────────────────────────────────┐   │
│   │  存储服务                                            │   │
│   │  • 调用 storage.upload() / storage.download()       │   │
│   │  • 存储原始文档到 OSS                                │   │
│   └─────────────────────────────────────────────────────┘   │
│                                                             │
│   外部依赖:                                                  │
│   ┌─────────────────────────────────────────────────────┐   │
│   │  阿里云 DashScope API                                │   │
│   │  • text-embedding-v3 (向量化)                       │   │
│   │  • qwen-rerank (重排序)                              │   │
│   └─────────────────────────────────────────────────────┘   │
└─────────────────────────────────────────────────────────────┘

📅 开发计划

分阶段实施(推荐)

详见:03-分阶段实施方案.md

阶段 内容 工期 状态
Phase 1 MVP 入库 + 向量检索 + 全文获取 3 天 🔜 待开始
Phase 2 增强 + 关键词检索 + 混合检索 + rerank 2 天 📋 规划中
Phase 3 完整 + 异步入库 + 摘要 + PICO 3 天 📋 规划中

核心原则:先跑通 MVP让业务走起来再逐步完善。

技术实现参考

详见:02-pgvector替换Dify计划.md


📚 相关文档


📅 更新日志

v1.2 (2026-01-20)

架构审核优化:

  • 入库异步化ingestDocument()submitIngestTask() + getIngestStatus(),基于 pg-boss 队列
  • 💰 成本控制:摘要生成、临床要素提取默认关闭,按需开启
  • 🔧 中文检索:关键词检索从 tsvector 改为 pg_bigm,专为 CJK 文字优化
  • 🆕 新增能力:独立暴露 rerank() 重排序能力Qwen-Rerank API
  • 📦 代码结构:新增 workers/ingestWorker.tsRerankService.ts
  • 📋 分阶段实施:新增 MVP → 增强 → 完整 三阶段方案

v1.1 (2026-01-20)

设计原则重大更新:

  • 明确"提供基础能力,不做策略选择"原则
  • 移除 chat() 方法,策略由业务模块决定
  • 🆕 新增 getDocumentFullText() / getAllDocumentsText() 全文获取
  • 🆕 新增 getDocumentSummary() / getAllDocumentsSummaries() 摘要获取
  • 🆕 新增业务模块策略选择示例PKB/AIA/ASL/RVW
  • 🆕 新增策略选择指南(按规模、按场景)
  • 📝 数据模型添加 summarytokenCount 字段

v1.0 (2026-01-20)

  • 初始版本

维护人: 技术架构师
最后更新: 2026-01-20