派洞察 - 知识库检索模块
🎯 派洞察——科研文献智能 RAG 知识库系统
🔍 知识库检索模块
模块定位:知识库检索模块是系统的核心检索引擎,提供基于混合检索技术的智能文档搜索功能,支持语义理解和权限控制。
🎯 核心目标
- ✅ 混合检索:结合关键词检索和语义向量检索,提供更精准的搜索结果
- ✅ 智能理解:支持自然语言查询,理解用户搜索意图
- ✅ 权限控制:根据用户身份和组织标签进行结果过滤
- ✅ 高性能:优化检索性能,支持大规模文档库
- ✅ 可扩展:支持多种检索算法和排序策略
📊 一、功能需求
🔍 混合检索
🔤 功能描述:提供基于关键词和语义向量的混合检索功能,结合两种检索方式的优势,提供更精准的搜索结果。
🔧 检索功能:
- 支持关键词全文检索
- 支持语义向量相似度检索
- 自动融合两种检索结果
- 支持自定义结果数量(topK参数)
🛡️ 权限控制
🔐 功能描述:根据用户的登录状态和组织标签,对检索结果进行权限过滤,确保用户只能访问其有权限查看的内容。
🔧 权限功能:
- 登录用户:返回用户有权限访问的所有内容
- 匿名用户:仅返回公开内容
- 组织标签过滤:根据用户组织标签筛选结果
- 私有内容保护:确保私有内容不被未授权访问
📊 结果排序
📈 功能描述:对检索结果进行智能排序,将最相关的内容优先展示给用户。
🔧 排序策略:
- 相关性评分排序
- 时间权重排序
- 用户行为权重
- 综合评分计算
📝 结果格式化
🎨 功能描述:将检索结果格式化为统一的响应结构,便于前端解析和展示。
🔧 格式功能:
- 统一的JSON响应格式
- 包含文档元信息(文件MD5、分片ID等)
- 包含内容预览和评分
- 包含权限信息(用户ID、组织标签、公开状态)
🛠️ 二、技术方案
🔍 混合检索技术
🔤 关键词检索:使用全文检索引擎(如Elasticsearch)进行基于关键词的文档检索。
🎯 向量检索:使用向量数据库(如Milvus、Pinecone)进行基于语义向量的相似度检索。
🔄 结果融合:采用加权融合算法,将关键词检索和向量检索的结果进行智能合并。
🧠 语义理解
📝 文本向量化:使用预训练语言模型(如BERT、Sentence-BERT)将文档和查询转换为向量表示。
🎯 相似度计算:使用余弦相似度等算法计算查询向量与文档向量的相似度。
🔧 语义增强:通过同义词扩展、查询重写等技术增强检索效果。
🔐 权限控制机制
👤 用户身份验证:通过JWT token验证用户身份,获取用户ID和组织标签信息。
🏷️ 组织标签过滤:根据用户的组织标签,过滤检索结果,确保内容安全。
🔒 权限层级:支持公开、组织内、私有等多层级权限控制。
📊 性能优化
⚡ 缓存机制:使用Redis缓存热门查询和检索结果,减少重复计算。
🚀 异步处理:采用异步方式处理复杂的向量计算和结果融合。
📈 索引优化:优化数据库索引和向量索引,提升检索效率。
📝 三、关键流程
🔍 1. 混合检索流程
🔄 流程步骤
- 🔍 接收查询:接收用户搜索查询字符串和topK参数
- ✅ 身份验证:验证用户身份(如果有token)
- 🔤 关键词检索:执行基于关键词的全文检索
- 🎯 向量检索:执行基于语义向量的相似度检索
- 🔄 结果融合:将两种检索结果进行智能融合
- 🛡️ 权限过滤:根据用户权限过滤检索结果
- 📊 结果排序:对融合后的结果进行相关性排序
- 📤 返回结果:返回格式化的检索结果
接口设计
请求URL1
GET /api/v1/search/hybrid?query=人工智能的发展&topK=10
请求参数1
2query: String // 搜索查询字符串(必需)
topK: int // 返回结果数量(可选,默认10)
请求头(可选)1
Authorization: Bearer JWT_TOKEN
成功响应1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24{
"code": 200,
"message": "success",
"data": [
{
"fileMd5": "abc123def456",
"chunkId": 1,
"textContent": "人工智能是未来科技发展的核心方向。",
"score": 0.92,
"userId": "user123",
"orgTag": "TECH_DEPT",
"isPublic": true
},
{
"fileMd5": "def456ghi789",
"chunkId": 2,
"textContent": "机器学习算法的不断进步推动了人工智能的发展。",
"score": 0.88,
"userId": "user456",
"orgTag": "RESEARCH_TEAM",
"isPublic": false
}
]
}
失败响应1
2
3
4
5{
"code": 500,
"message": "检索失败: 错误信息",
"data": []
}
🔐 2. 权限控制流程
🔄 流程步骤
- 🔍 Token提取:从请求头中提取JWT token(如果有)
- ✅ 身份验证:验证token有效性,获取用户ID
- 🏷️ 权限获取:获取用户的组织标签和角色信息
- 🔍 结果检索:执行混合检索获取初步结果
- 🛡️ 权限过滤:根据用户权限过滤检索结果
- 📤 结果返回:返回用户有权限查看的内容
📊 3. 结果融合流程
🔄 流程步骤
- 📊 获取结果:获取关键词检索和向量检索的结果
- ⚖️ 权重计算:为两种检索结果分配权重
- 🔄 结果合并:将两种结果按照权重进行融合
- 📈 重新排序:对融合后的结果进行统一排序
- ✂️ 结果截断:根据topK参数截取最终结果
📝 4. 日志记录流程
🔄 流程步骤
- 🚀 开始监控:启动性能监控器
- 📝 业务日志:记录检索开始和参数信息
- ⚡ 执行检索:执行混合检索操作
- ✅ 操作记录:记录用户操作和结果状态
- 📊 性能记录:记录检索耗时和结果数量
- 🏁 结束监控:结束性能监控
🗃️ 四、依赖的数据结构设计
📁 1. 文件主表 (file_upload)
字段设计1
2
3
4
5
6
7
8
9
10
11
12| 🔑 字段 | 📋 类型 | 📝 描述 |
| --- | --- | --- |
| `id` | INT | 🆔 主键,文件上传记录 ID |
| `file_md5` | VARCHAR(32) | 🔤 文件的MD5值,作为主键唯一标识文件 |
| `file_name` | VARCHAR(255) | 📄 文件的原始名称 |
| `total_size` | BIGINT | 📊 文件总大小(字节) |
| `status` | INT | 📊 文件上传状态:0-上传中,1-已完成 |
| `user_id` | VARCHAR(64) | 👤 上传用户的标识符 |
| `org_tag` | VARCHAR(50) | 🏷️ 文件所属组织标签 |
| `is_public` | BOOLEAN | 🌍 文件是否公开 |
| `created_at` | TIMESTAMP | 📅 文件上传创建时间 |
| `merged_at` | TIMESTAMP | 🔄 文件合并完成时间 |
建表语句1
2
3
4
5
6
7
8
9
10
11CREATE TABLE file_upload (
file_md5 VARCHAR(32) PRIMARY KEY COMMENT '文件的MD5值,作为主键唯一标识文件',
file_name VARCHAR(255) NOT NULL COMMENT '文件的原始名称',
total_size BIGINT NOT NULL COMMENT '文件总大小(字节)',
status INT NOT NULL DEFAULT 0 COMMENT '文件上传状态:0-上传中,1-已完成',
user_id VARCHAR(64) NOT NULL COMMENT '上传用户的标识符',
org_tag VARCHAR(50) COMMENT '文件所属组织标签',
is_public BOOLEAN NOT NULL DEFAULT FALSE COMMENT '文件是否公开',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '文件上传创建时间',
merged_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '文件合并完成时间'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='文件上传记录表';
📄 2. 分片表 (chunk_info)
字段设计1
2
3
4
5
6
7| 🔑 字段 | 📋 类型 | 📝 描述 |
| --- | --- | --- |
| `id` | `BIGINT` | 🆔 主键,分块记录唯一标识 |
| `file_md5` | `VARCHAR(32)` | 🔤 关联的文件MD5值 |
| `chunk_index` | `INT` | 🔢 分块序号 |
| `chunk_md5` | `VARCHAR(32)` | 🔤 分块的MD5值 |
| `storage_path` | `VARCHAR(255)` | 🔗 分块在存储系统中的路径 |
建表语句1
2
3
4
5
6
7CREATE TABLE chunk_info (
id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '分块记录唯一标识',
file_md5 VARCHAR(32) NOT NULL COMMENT '关联的文件MD5值',
chunk_index INT NOT NULL COMMENT '分块序号',
chunk_md5 VARCHAR(32) NOT NULL COMMENT '分块的MD5值',
storage_path VARCHAR(255) NOT NULL COMMENT '分块在存储系统中的路径'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='文件分块信息表';
📄 3. 解析结果表 (document_vectors)
字段设计1
2
3
4
5
6
7
8
9
10| 🔑 字段 | 📋 类型 | 📝 描述 |
| --- | --- | --- |
| `vector_id` | `BIGINT` | 🆔 向量记录唯一标识 |
| `file_md5` | `VARCHAR(32)` | 🔤 关联的文件MD5值 |
| `chunk_id` | `INT` | 🔢 文本分块序号 |
| `text_content` | `TEXT` | 📄 文本内容 |
| `model_version` | `VARCHAR(32)` | 🔤 向量模型版本 |
| `user_id` | `VARCHAR(64)` | 👤 上传用户ID |
| `org_tag` | `VARCHAR(50)` | 🏷️ 文件所属组织标签 |
| `is_public` | `BOOLEAN` | 🌍 文件是否公开 |
建表语句1
2
3
4
5
6
7
8
9
10CREATE TABLE document_vectors (
vector_id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '向量记录唯一标识',
file_md5 VARCHAR(32) NOT NULL COMMENT '关联的文件MD5值',
chunk_id INT NOT NULL COMMENT '文本分块序号',
text_content TEXT COMMENT '文本内容',
model_version VARCHAR(32) COMMENT '向量模型版本',
user_id VARCHAR(64) NOT NULL COMMENT '上传用户ID',
org_tag VARCHAR(50) COMMENT '文件所属组织标签',
is_public BOOLEAN NOT NULL DEFAULT FALSE COMMENT '文件是否公开'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='文档向量存储表';

