init: RAG 知识库服务初始提交

- 后端 API(Flask + Gunicorn)
- RAG 引擎(混合检索 + 云端 Reranker + 引用溯源)
- 文档解析(MinerU + 多格式支持)
- Docker 生产部署配置
- 排除前端项目、敏感配置、模型文件
This commit is contained in:
lacerate551
2026-06-04 17:35:27 +08:00
commit 100d1a06eb
158 changed files with 64534 additions and 0 deletions

125
knowledge/index.py Normal file
View File

@@ -0,0 +1,125 @@
"""
知识库管理器 - BM25索引管理 Mixin
提供 BM25 关键词检索索引的管理功能,包括索引的加载、保存和重建。
BM25 是一种基于概率检索模型的排序函数,适合中文关键词检索。
每个向量库对应一个独立的 BM25 索引,使用 jieba 进行中文分词。
主要方法:
- get_bm25_index: 获取或加载 BM25 索引
- save_bm25_index: 保存 BM25 索引到磁盘
- rebuild_bm25_index: 从向量库重建 BM25 索引
"""
import os
import logging
from typing import Optional
from .base import BM25Index
logger = logging.getLogger(__name__)
class IndexMixin:
"""
BM25索引管理 Mixin
提供 BM25 索引的生命周期管理,支持:
- 索引的懒加载(首次访问时从磁盘加载)
- 索引的持久化(保存到 .pkl 文件)
- 索引的重建(从向量库同步)
依赖属性(需由主类提供):
- self.bm25_base_path: BM25 索引存储路径
- self._bm25_indexes: BM25 索引缓存字典
"""
def get_bm25_index(self, kb_name: str) -> BM25Index:
"""
获取或加载 BM25 索引
如果索引已在内存中,直接返回。
否则尝试从磁盘加载,加载失败则创建空索引。
Args:
kb_name: 向量库名称
Returns:
BM25Index 实例
Note:
索引文件路径: {bm25_base_path}/{kb_name}.pkl
"""
if kb_name not in self._bm25_indexes:
self._bm25_indexes[kb_name] = BM25Index()
bm25_path = os.path.join(self.bm25_base_path, f"{kb_name}.pkl")
if os.path.exists(bm25_path):
self._bm25_indexes[kb_name].load(bm25_path)
return self._bm25_indexes[kb_name]
def save_bm25_index(self, kb_name: str) -> None:
"""
保存 BM25 索引到磁盘
将指定向量库的 BM25 索引序列化保存到 .pkl 文件。
Args:
kb_name: 向量库名称
"""
if kb_name in self._bm25_indexes:
bm25_path = os.path.join(self.bm25_base_path, f"{kb_name}.pkl")
self._bm25_indexes[kb_name].save(bm25_path)
logger.info(f"保存 BM25 索引: {kb_name}")
def rebuild_bm25_index(self, kb_name: str) -> bool:
"""
重建 BM25 索引
从 ChromaDB 向量库中读取所有文档,重新构建 BM25 索引。
用于文档变更后同步索引状态。
Args:
kb_name: 向量库名称
Returns:
重建成功返回 True失败返回 False
Warning:
大量文档时重建可能耗时较长。
"""
try:
collection = self.get_collection(kb_name)
if not collection:
return False
result = collection.get()
bm25_index = BM25Index()
if result['ids']:
bm25_index.add_documents(
ids=result['ids'],
documents=result['documents'],
metadatas=result['metadatas']
)
self._bm25_indexes[kb_name] = bm25_index
self.save_bm25_index(kb_name)
logger.info(f"重建 BM25 索引: {kb_name}, 文档数: {len(result['ids'])}")
return True
except Exception as e:
logger.error(f"重建 BM25 索引失败: {e}")
return False
def _rebuild_bm25_index(self, kb_name: str) -> None:
"""
重建指定向量库的 BM25 索引(内部方法)
兼容旧代码的内部方法,直接调用 rebuild_bm25_index。
Args:
kb_name: 向量库名称
"""
self.rebuild_bm25_index(kb_name)