🎯 派洞察——科研文献智能 RAG 知识库系统

🔍 知识库检索模块

模块定位:知识库检索模块是系统的核心检索引擎,提供基于混合检索技术的智能文档搜索功能,支持语义理解和权限控制。

🎯 核心目标

  • 混合检索:结合关键词检索和语义向量检索,提供更精准的搜索结果
  • 智能理解:支持自然语言查询,理解用户搜索意图
  • 权限控制:根据用户身份和组织标签进行结果过滤
  • 高性能:优化检索性能,支持大规模文档库
  • 可扩展:支持多种检索算法和排序策略

📊 一、功能需求

🔍 混合检索

🔤 功能描述:提供基于关键词和语义向量的混合检索功能,结合两种检索方式的优势,提供更精准的搜索结果。

🔧 检索功能:

  • 支持关键词全文检索
  • 支持语义向量相似度检索
  • 自动融合两种检索结果
  • 支持自定义结果数量(topK参数)

🛡️ 权限控制

🔐 功能描述:根据用户的登录状态和组织标签,对检索结果进行权限过滤,确保用户只能访问其有权限查看的内容。

🔧 权限功能:

  • 登录用户:返回用户有权限访问的所有内容
  • 匿名用户:仅返回公开内容
  • 组织标签过滤:根据用户组织标签筛选结果
  • 私有内容保护:确保私有内容不被未授权访问

📊 结果排序

📈 功能描述:对检索结果进行智能排序,将最相关的内容优先展示给用户。

🔧 排序策略:

  • 相关性评分排序
  • 时间权重排序
  • 用户行为权重
  • 综合评分计算

📝 结果格式化

🎨 功能描述:将检索结果格式化为统一的响应结构,便于前端解析和展示。

🔧 格式功能:

  • 统一的JSON响应格式
  • 包含文档元信息(文件MD5、分片ID等)
  • 包含内容预览和评分
  • 包含权限信息(用户ID、组织标签、公开状态)

🛠️ 二、技术方案

🔍 混合检索技术

🔤 关键词检索:使用全文检索引擎(如Elasticsearch)进行基于关键词的文档检索。

🎯 向量检索:使用向量数据库(如Milvus、Pinecone)进行基于语义向量的相似度检索。

🔄 结果融合:采用加权融合算法,将关键词检索和向量检索的结果进行智能合并。

🧠 语义理解

📝 文本向量化:使用预训练语言模型(如BERT、Sentence-BERT)将文档和查询转换为向量表示。

🎯 相似度计算:使用余弦相似度等算法计算查询向量与文档向量的相似度。

🔧 语义增强:通过同义词扩展、查询重写等技术增强检索效果。

🔐 权限控制机制

👤 用户身份验证:通过JWT token验证用户身份,获取用户ID和组织标签信息。

🏷️ 组织标签过滤:根据用户的组织标签,过滤检索结果,确保内容安全。

🔒 权限层级:支持公开、组织内、私有等多层级权限控制。

📊 性能优化

缓存机制:使用Redis缓存热门查询和检索结果,减少重复计算。

🚀 异步处理:采用异步方式处理复杂的向量计算和结果融合。

📈 索引优化:优化数据库索引和向量索引,提升检索效率。

📝 三、关键流程

🔍 1. 混合检索流程

🔄 流程步骤

  1. 🔍 接收查询:接收用户搜索查询字符串和topK参数
  2. 身份验证:验证用户身份(如果有token)
  3. 🔤 关键词检索:执行基于关键词的全文检索
  4. 🎯 向量检索:执行基于语义向量的相似度检索
  5. 🔄 结果融合:将两种检索结果进行智能融合
  6. 🛡️ 权限过滤:根据用户权限过滤检索结果
  7. 📊 结果排序:对融合后的结果进行相关性排序
  8. 📤 返回结果:返回格式化的检索结果

接口设计

请求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. 权限控制流程

🔄 流程步骤

  1. 🔍 Token提取:从请求头中提取JWT token(如果有)
  2. 身份验证:验证token有效性,获取用户ID
  3. 🏷️ 权限获取:获取用户的组织标签和角色信息
  4. 🔍 结果检索:执行混合检索获取初步结果
  5. 🛡️ 权限过滤:根据用户权限过滤检索结果
  6. 📤 结果返回:返回用户有权限查看的内容

📊 3. 结果融合流程

🔄 流程步骤

  1. 📊 获取结果:获取关键词检索和向量检索的结果
  2. ⚖️ 权重计算:为两种检索结果分配权重
  3. 🔄 结果合并:将两种结果按照权重进行融合
  4. 📈 重新排序:对融合后的结果进行统一排序
  5. ✂️ 结果截断:根据topK参数截取最终结果

📝 4. 日志记录流程

🔄 流程步骤

  1. 🚀 开始监控:启动性能监控器
  2. 📝 业务日志:记录检索开始和参数信息
  3. 执行检索:执行混合检索操作
  4. 操作记录:记录用户操作和结果状态
  5. 📊 性能记录:记录检索耗时和结果数量
  6. 🏁 结束监控:结束性能监控

🗃️ 四、依赖的数据结构设计

📁 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='文档向量存储表';