🎯 派洞察——科研文献智能 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. 文档分片表
字段设计
1 2 3 4 5 6 7 8 9 10 11 12
| | 🔑 **字段** | 📋 **类型** | 📝 **描述** | | --- | --- | --- | | `id` | `BIGINT` | 🆔 主键,分片ID | | `file_md5` | `VARCHAR(32)` | 📊 文件MD5哈希值 | | `chunk_id` | `INT` | 📑 分片序号 | | `text_content` | `TEXT` | 📝 分片文本内容 | | `vector_embedding` | `TEXT` | 🎯 向量嵌入(JSON格式) | | `user_id` | `VARCHAR(255)` | 👤 文档所有者ID | | `org_tag` | `VARCHAR(100)` | 🏷️ 组织标签 | | `is_public` | `BOOLEAN` | 🌐 是否公开 | | `created_at` | `TIMESTAMP` | 📅 创建时间 | | `updated_at` | `TIMESTAMP` | 🔄 更新时间 |
|
建表语句
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| CREATE TABLE document_chunks ( id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '分片唯一标识', file_md5 VARCHAR(32) NOT NULL COMMENT '文件MD5哈希值', chunk_id INT NOT NULL COMMENT '分片序号', text_content TEXT NOT NULL COMMENT '分片文本内容', vector_embedding TEXT COMMENT '向量嵌入(JSON格式)', user_id VARCHAR(255) NOT NULL COMMENT '文档所有者ID', org_tag VARCHAR(100) DEFAULT NULL COMMENT '组织标签', is_public BOOLEAN DEFAULT FALSE COMMENT '是否公开可见', created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', INDEX idx_file_md5 (file_md5) COMMENT '文件MD5索引', INDEX idx_user_id (user_id) COMMENT '用户ID索引', INDEX idx_org_tag (org_tag) COMMENT '组织标签索引', INDEX idx_is_public (is_public) COMMENT '公开状态索引', UNIQUE KEY uk_file_chunk (file_md5, chunk_id) COMMENT '文件分片唯一约束' ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='文档分片表';
|
📊 2. 检索日志表
字段设计
1 2 3 4 5 6 7 8 9 10 11
| | 🔑 **字段** | 📋 **类型** | 📝 **描述** | | --- | --- | --- | | `id` | `BIGINT` | 🆔 主键,日志ID | | `query` | `TEXT` | 🔍 查询字符串 | | `user_id` | `VARCHAR(255)` | 👤 用户ID(匿名用户为空) | | `result_count` | `INT` | 📊 返回结果数量 | | `search_type` | `ENUM('ANONYMOUS', 'AUTHENTICATED')` | 🎯 搜索类型 | | `response_time_ms` | `INT` | ⏱️ 响应时间(毫秒) | | `status` | `ENUM('SUCCESS', 'FAILURE')` | ✅ 搜索状态 | | `error_message` | `TEXT` | ❌ 错误信息 | | `created_at` | `TIMESTAMP` | 📅 创建时间 |
|
建表语句
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| CREATE TABLE search_logs ( id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '日志唯一标识', query TEXT NOT NULL COMMENT '查询字符串', user_id VARCHAR(255) DEFAULT NULL COMMENT '用户ID', result_count INT DEFAULT 0 COMMENT '返回结果数量', search_type ENUM('ANONYMOUS', 'AUTHENTICATED') NOT NULL COMMENT '搜索类型', response_time_ms INT DEFAULT NULL COMMENT '响应时间(毫秒)', status ENUM('SUCCESS', 'FAILURE') NOT NULL COMMENT '搜索状态', error_message TEXT COMMENT '错误信息', created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', INDEX idx_user_id (user_id) COMMENT '用户ID索引', INDEX idx_created_at (created_at) COMMENT '时间索引', INDEX idx_search_type (search_type) COMMENT '搜索类型索引' ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='检索日志表';
|
🎯 3. 向量索引配置表
字段设计
1 2 3 4 5 6 7 8 9 10
| | 🔑 **字段** | 📋 **类型** | 📝 **描述** | | --- | --- | --- | | `id` | `BIGINT` | 🆔 主键,配置ID | | `index_name` | `VARCHAR(100)` | 🏷️ 索引名称 | | `vector_dimension` | `INT` | 📐 向量维度 | | `similarity_metric` | `VARCHAR(20)` | 📏 相似度度量方式 | | `index_type` | `VARCHAR(50)` | 🎯 索引类型 | | `is_active` | `BOOLEAN` | ✅ 是否激活 | | `created_at` | `TIMESTAMP` | 📅 创建时间 | | `updated_at` | `TIMESTAMP` | 🔄 更新时间 |
|
建表语句
1 2 3 4 5 6 7 8 9 10 11 12
| CREATE TABLE vector_index_configs ( id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '配置唯一标识', index_name VARCHAR(100) NOT NULL UNIQUE COMMENT '索引名称', vector_dimension INT NOT NULL COMMENT '向量维度', similarity_metric VARCHAR(20) NOT NULL COMMENT '相似度度量方式', index_type VARCHAR(50) NOT NULL COMMENT '索引类型', is_active BOOLEAN DEFAULT TRUE COMMENT '是否激活', created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', INDEX idx_index_name (index_name) COMMENT '索引名称索引', INDEX idx_is_active (is_active) COMMENT '激活状态索引' ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='向量索引配置表';
|