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
This commit is contained in:
2026-01-21 20:24:29 +08:00
parent 1f5bf2cd65
commit 40c2f8e148
338 changed files with 11014 additions and 1158 deletions

View File

@@ -0,0 +1,86 @@
# **知识库引擎数据模型 (v2.0) 最终审查报告**
审查对象: \[04-数据模型设计.md\] (v2.0 版本)
审查结论: ✅ 通过 (Approved)
评价等级: 🌟 优秀 (Excellent)
适用阶段: MVP \-\> 长期生产环境
## **1\. 核心问题的回答**
### **Q1: 还有什么问题吗?**
基本没有逻辑硬伤。 现在的设计非常稳健。
唯一需要注意的是 Prisma 与 pgvector 的磨合细节(我在下文的"实施避坑指南"中列出了)。
### **Q2: 是否过度设计?是否浪费?**
**绝对没有。**
* 空间浪费?零。
PostgreSQL 的 NULL JSONB 字段存储开销极小(仅几个比特的位图标记)。如果你不填 structuredData它就不占空间。
* 开发浪费?负数。
相比于“先写死,以后改表结构”,现在的设计让你在未来 1 年内都不需要执行 prisma migrate 修改数据库结构。这反而节省了大量的运维和迁移成本。
* 计算浪费?零。
Layer 0 (纯文本 RAG) 是必经之路。你没有做任何多余的计算步骤,只是预留了存放未来 AI 提取结果的“容器”。
## **2\. 亮点解析 (为什么这是一个好设计)**
### **🏆 亮点 1Layer 0 的“保底”哲学**
你明确了 "即使没有任何结构化数据RAG 检索也必须能工作"。
这对于创业公司至关重要。这意味着我们可以先把文件扔进去Layer 0系统就能跑起来。等以后有空了或者有钱调用更贵的 LLM 了,再回过头来“清洗”出 Layer 4 的数据,而不需要重新上传文件。
### **🏆 亮点 2fileHash 的精准切入**
在 EkbDocument 中加入 fileHash 是神来之笔。
* **场景**:用户上传了一篇《肺癌指南.pdf》过了一周又上传了一次。
* **优势**:系统直接检测 Hash发现已存在瞬间秒传完成。既提升了用户体验又节省了昂贵的 OCR 解析费和 Embedding 费用。
### **🏆 亮点 3切片级 Metadata (EkbChunk.metadata)**
这是很多成熟 RAG 系统后期才会加的功能,你在设计阶段就想到了。
* **场景**:搜“帕博利珠单抗的副作用”。
* **优势**:如果没有切片级元数据,可能搜到的是“副作用”这个词在目录里的切片。有了元数据,我们可以给正文切片加权,降权目录切片。
## **3\. 实施避坑指南 (关键!)**
虽然设计很完美,但在写代码落地时,这 3 个细节请务必注意:
### **🔧 细节 1Prisma 不会自动创建向量索引**
schema.prisma 里写了 Unsupported("vector(1024)"),但 npx prisma migrate **不会**自动帮你创建 HNSW 索引。
必须做的动作:
在执行完 migrate 后,必须手动运行以下 SQL或者创建一个空的 migration 专门放 SQL
\-- 必须手动执行!否则检索速度会很慢
CREATE INDEX idx\_ekb\_chunk\_embedding ON "ekb\_schema"."EkbChunk"
USING hnsw (embedding vector\_cosine\_ops)
WITH (m \= 16, ef\_construction \= 64);
### **🔧 细节 2fileHash 的作用域选择**
代码示例里写的是 where: { kbId, fileHash }。
这意味着:同一个知识库内去重。
* **如果用户 A 上传了文件 X用户 B 也上传了文件 X系统会存两份。**
* **建议**:对于 2 人团队,暂时维持这个逻辑是安全的(避免跨用户的数据泄露风险)。未来如果存储成本飙升,可以改为全局去重(但需要复杂的文件引用计数逻辑)。**目前保持现状即可。**
### **🔧 细节 3JSONB 的查询性能**
虽然加了 GIN 索引,但查询深层 JSON 字段(如 structuredData-\>'pico'-\>\>'I')的语法比较繁琐。
建议:在 KnowledgeBaseEngine 中封装好常用的查询构建器,不要让业务层直接拼 SQL。
## **4\. MVP 开发优先级建议**
基于这份设计,你的 MVP 开发清单应该非常清晰:
1. **Day 1**: 创建数据库表 (prisma migrate) \+ 手动创建 HNSW 索引。
2. **Day 2**: 实现 ingestDocument 接口。
* 只实现 Layer 0 (提取文本) \+ Layer 1 (基础信息)。
* structuredData 暂时存 null。
3. **Day 3**: 实现 vectorSearch 接口。
* 暂不处理 JSONB 过滤,先跑通纯向量检索。
**结论:** 这是一个**可进可退、丰俭由人**的优秀架构。请立即冻结设计,开始编码!🚀