🎯 派洞察——科研文献智能 RAG 知识库系统
🔍 知识库检索模块
模块定位:知识库检索模块是系统的核心检索引擎,提供基于混合检索技术的智能文档搜索功能,支持语义理解和权限控制。
🎯 核心目标
- ✅ 混合检索:结合关键词检索和语义向量检索,提供更精准的搜索结果
- ✅ 智能理解:支持自然语言查询,理解用户搜索意图
- ✅ 权限控制:根据用户身份和组织标签进行结果过滤
- ✅ 高性能:优化检索性能,支持大规模文档库
- ✅ 可扩展:支持多种检索算法和排序策略
📊 一、功能需求
🔍 混合检索
🔤 功能描述:提供基于关键词和语义向量的混合检索功能,结合两种检索方式的优势,提供更精准的搜索结果。
🔧 检索功能:
- 支持关键词全文检索
- 支持语义向量相似度检索
- 自动融合两种检索结果
- 支持自定义结果数量(topK参数)
🛡️ 权限控制
🔐 功能描述:根据用户的登录状态和组织标签,对检索结果进行权限过滤,确保用户只能访问其有权限查看的内容。
🔧 权限功能:
- 登录用户:返回用户有权限访问的所有内容
- 匿名用户:仅返回公开内容
- 组织标签过滤:根据用户组织标签筛选结果
- 私有内容保护:确保私有内容不被未授权访问
📊 结果排序
📈 功能描述:对检索结果进行智能排序,将最相关的内容优先展示给用户。
🔧 排序策略:
- 相关性评分排序
- 时间权重排序
- 用户行为权重
- 综合评分计算
📝 结果格式化
🎨 功能描述:将检索结果格式化为统一的响应结构,便于前端解析和展示。
🔧 格式功能:
- 统一的JSON响应格式
- 包含文档元信息(文件MD5、分片ID等)
- 包含内容预览和评分
- 包含权限信息(用户ID、组织标签、公开状态)
🛠️ 二、技术方案
🔍 混合检索技术
🔤 关键词检索:使用全文检索引擎(如Elasticsearch)进行基于关键词的文档检索。
🎯 向量检索:使用向量数据库(如Milvus、Pinecone)进行基于语义向量的相似度检索。
🔄 结果融合:采用加权融合算法,将关键词检索和向量检索的结果进行智能合并。
🧠 语义理解
📝 文本向量化:使用预训练语言模型(如BERT、Sentence-BERT)将文档和查询转换为向量表示。
🎯 相似度计算:使用余弦相似度等算法计算查询向量与文档向量的相似度。
🔧 语义增强:通过同义词扩展、查询重写等技术增强检索效果。
🔐 权限控制机制
👤 用户身份验证:通过JWT token验证用户身份,获取用户ID和组织标签信息。
🏷️ 组织标签过滤:根据用户的组织标签,过滤检索结果,确保内容安全。
🔒 权限层级:支持公开、组织内、私有等多层级权限控制。
📊 性能优化
⚡ 缓存机制:使用Redis缓存热门查询和检索结果,减少重复计算。
🚀 异步处理:采用异步方式处理复杂的向量计算和结果融合。
📈 索引优化:优化数据库索引和向量索引,提升检索效率。
📝 三、关键流程
🔍 1. 混合检索流程
🔄 流程步骤
- 🔍 接收查询:接收用户搜索查询字符串和topK参数
- ✅ 身份验证:验证用户身份(如果有token)
- 🔤 关键词检索:执行基于关键词的全文检索
- 🎯 向量检索:执行基于语义向量的相似度检索
- 🔄 结果融合:将两种检索结果进行智能融合
- 🛡️ 权限过滤:根据用户权限过滤检索结果
- 📊 结果排序:对融合后的结果进行相关性排序
- 📤 返回结果:返回格式化的检索结果
接口设计
请求URL
1
| GET /api/v1/search/hybrid?query=人工智能的发展&topK=10
|
请求参数
1 2
| query: 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 11
| CREATE 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 7
| CREATE 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 10
| CREATE 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='文档向量存储表';
|