Langchain-Chatchat知识库构建与管理
【免费下载链接】Langchain-Chatchat 项目地址: https://gitcode.com/gh_mirrors/lang/Langchain-Chatchat
本文深入探讨了Langchain-Chatchat作为基于本地知识库的RAG问答系统的核心文档处理能力。文章系统性地介绍了项目的多格式文档加载器体系、智能文本分割策略、向量化处理与相似度检索机制,以及知识库维护与版本管理等关键技术组件。通过模块化的加载器设计,系统能够处理从常见文本文件到复杂扫描文档的各种格式,并针对中文文本特点进行了专门优化。
文档加载与文本分割策略
Langchain-Chatchat作为基于本地知识库的RAG问答系统,其核心能力建立在高效的文档处理和文本分割基础之上。本文将深入探讨项目中文档加载与文本分割的实现策略、技术细节以及最佳实践。
多格式文档加载器体系
Langchain-Chatchat实现了全面的文档格式支持,通过模块化的加载器设计,能够处理从常见文本文件到复杂扫描文档的各种格式。
支持的文档格式分类
项目通过LOADER_DICT配置字典定义了丰富的文档格式支持:
LOADER_DICT = {
"UnstructuredHTMLLoader": ['.html', '.htm'],
"MHTMLLoader": ['.mhtml'],
"UnstructuredMarkdownLoader": ['.md'],
"JSONLoader": [".json"],
"JSONLinesLoader": [".jsonl"],
"CSVLoader": [".csv"],
"RapidOCRPDFLoader": [".pdf"],
"RapidOCRDocLoader": ['.docx', '.doc'],
"RapidOCRPPTLoader": ['.ppt', '.pptx'],
"RapidOCRLoader": ['.png', '.jpg', '.jpeg', '.bmp'],
"UnstructuredFileLoader": ['.eml', '.msg', '.rst', '.rtf', '.txt', '.xml',
'.epub', '.odt','.tsv'],
# ... 更多加载器配置
}
自定义OCR加载器实现
针对扫描文档和图像内容,项目实现了基于RapidOCR的自定义加载器:
class RapidOCRPDFLoader(UnstructuredFileLoader):
def _get_elements(self) -> List:
def pdf2text(filepath):
import fitz # pyMuPDF
ocr = get_ocr()
doc = fitz.open(filepath)
resp = ""
for i, page in enumerate(doc):
text = page.get_text("")
resp += text + "\n"
# OCR处理图片内容
img_list = page.get_image_info(xrefs=True)
for img in img_list:
if xref := img.get("xref"):
# 过滤小图片,提高处理效率
if ((bbox[2] - bbox[0]) / page.rect.width < PDF_OCR_THRESHOLD[0]
or (bbox[3] - bbox[1]) / page.rect.height < PDF_OCR_THRESHOLD[1]):
continue
# OCR处理图片文本
result, _ = ocr(img_array)
if result:
ocr_result = [line[1] for line in result]
resp += "\n".join(ocr_result)
return resp
智能文本分割策略
文本分割是RAG系统的关键环节,Langchain-Chatchat提供了多种分割策略以适应不同的文本类型和语言特点。
中文优化文本分割器
项目专门针对中文文本特点实现了ChineseTextSplitter:
class ChineseTextSplitter(CharacterTextSplitter):
def __init__(self, pdf: bool = False, sentence_size: int = 250, **kwargs):
super().__init__(**kwargs)
self.pdf = pdf
self.sentence_size = sentence_size
def split_text(self, text: str) -> List[str]:
# 中文标点符号分割规则
text = re.sub(r'([;;.!?。!?\?])([^"』"])', r"\1\n\2", text)
text = re.sub(r'(\.{6})([^"』"])', r"\1\n\2", text) # 英文省略号
text = re.sub(r'(\…{2})([^"』"])', r"\1\n\2", text) # 中文省略号
ls = [i for i in text.split("\n") if i]
# 递归分割过长文本
for ele in ls:
if len(ele) > self.sentence_size:
# 多级分割逻辑
ele1 = re.sub(r'([,,.]["』"]{0,2})([^,,.])', r'\1\n\2', ele)
ele1_ls = ele1.split("\n")
# ... 进一步分割处理
return ls
递归字符分割器
ChineseRecursiveTextSplitter提供了更智能的分层分割策略:
class ChineseRecursiveTextSplitter(RecursiveCharacterTextSplitter):
def __init__(self, separators: Optional[List[str]] = None, **kwargs):
super().__init__(**kwargs)
self._separators = separators or [
"\n\n", # 空行分割
"\n", # 换行分割
"。|!|?", # 句子结束符
"\.\s|\!\s|\?\s", # 英文句子结束符
";|;\s", # 分号分割
",|,\s" # 逗号分割
]
def _split_text(self, text: str, separators: List[str]) -> List[str]:
# 递归分割实现
separator = separators[-1]
for i, _s in enumerate(separators):
if re.search(_s, text):
separator = _s
new_separators = separators[i + 1:]
break
splits = self._split_with_regex(text, separator)
# 递归处理过长片段
for s in splits:
if self._length_function(s) < self._chunk_size:
final_chunks.append(s)
else:
if new_separators:
other_info = self._split_text(s, new_separators)
final_chunks.extend(other_info)
else:
final_chunks.append(s)
return final_chunks
配置参数与性能优化
关键配置参数
在kb_config.py中定义了文本处理的核心参数:
| 参数名 | 默认值 | 说明 |
|---|---|---|
CHUNK_SIZE | 250 | 单段文本最大长度 |
OVERLAP_SIZE | 50 | 相邻文本重合长度 |
ZH_TITLE_ENHANCE | False | 中文标题增强功能 |
PDF_OCR_THRESHOLD | (0.6, 0.6) | PDF图片OCR阈值 |
文本分割器配置
text_splitter_dict = {
"ChineseRecursiveTextSplitter": {
"source": "huggingface",
"tokenizer_name_or_path": "",
},
"SpacyTextSplitter": {
"source": "huggingface",
"tokenizer_name_or_path": "gpt2",
},
"RecursiveCharacterTextSplitter": {
"source": "tiktoken",
"tokenizer_name_or_path": "cl100k_base",
},
"MarkdownHeaderTextSplitter": {
"headers_to_split_on": [
("#", "head1"),
("##", "head2"),
("###", "head3"),
("####", "head4"),
]
},
}
实际应用示例
文档加载流程
代码实现示例
# 创建知识库文件实例
kb_file = KnowledgeFile(
filename="document.pdf",
knowledge_base_name="my_kb",
loader_kwargs={}
)
# 加载文档内容
docs = kb_file.file2docs()
# 配置文本分割器
text_splitter = make_text_splitter(
splitter_name="ChineseRecursiveTextSplitter",
chunk_size=250,
chunk_overlap=50,
llm_model="chatglm3-6b"
)
# 执行文本分割
splited_docs = text_splitter.split_documents(docs)
最佳实践建议
-
格式选择策略:
- 纯文本文件使用
UnstructuredFileLoader - 扫描PDF使用
RapidOCRPDFLoader - 结构化数据使用对应的专用加载器
- 纯文本文件使用
-
分割参数调优:
- 中文文档推荐使用
ChineseRecursiveTextSplitter - 根据模型上下文长度调整
CHUNK_SIZE - 保持适当的
OVERLAP_SIZE以确保上下文连贯性
- 中文文档推荐使用
-
性能优化:
- 启用
ZH_TITLE_ENHANCE提升中文文档处理质量 - 合理设置
PDF_OCR_THRESHOLD避免处理无关小图片 - 使用多线程处理大批量文档
- 启用
通过上述文档加载与文本分割策略,Langchain-Chatchat能够高效处理各种格式的文档内容,为后续的向量化和检索问答提供高质量的文本基础。这种模块化、可配置的设计使得系统能够适应不同的应用场景和性能要求。
向量化处理与相似度检索机制
Langchain-Chatchat 的向量化处理与相似度检索机制是整个知识库系统的核心技术组件,它负责将文本数据转换为高维向量表示,并通过高效的相似度计算实现精准的知识检索。这一机制的设计直接决定了知识库问答系统的性能和准确性。
向量化处理流程
Langchain-Chatchat 采用多层次的向量化处理策略,支持多种嵌入模型和向量数据库,为不同场景提供灵活的解决方案。
嵌入模型支持
系统支持多种嵌入模型,包括本地部署的预训练模型和在线API服务:
| 模型类型 | 示例模型 | 特点 | 适用场景 |
|---|---|---|---|
| 本地模型 | BGE-large-zh、text2vec | 离线部署、数据安全 | 企业内部部署 |
| 在线API | OpenAI、Azure | 高性能、易用 | 云端服务 |
| 开源模型 | Sentence-BERT | 可定制、免费 | 研究开发 |
向量化处理流程
核心代码实现
系统通过 embed_texts 函数实现文本向量化处理:
def embed_texts(
texts: List[str],
embed_model: str = EMBEDDING_MODEL,
to_query: bool = False,
) -> BaseResponse:
'''
对文本进行向量化。返回数据格式:BaseResponse(data=List[List[float]])
'''
try:
if embed_model in list_embed_models(): # 使用本地Embeddings模型
from server.utils import load_local_embeddings
embeddings = load_local_embeddings(model=embed_model)
return BaseResponse(data=embeddings.embed_documents(texts))
if embed_model in list_online_embed_models(): # 使用在线API
config = get_model_worker_config(embed_model)
worker_class = config.get("worker_class")
embed_model = config.get("embed_model")
worker = worker_class()
if worker_class.can_embedding():
params = ApiEmbeddingsParams(texts=texts, to_query=to_query, embed_model=embed_model)
resp = worker.do_embeddings(params)
return BaseResponse(**resp)
return BaseResponse(code=500, msg=f"指定的模型 {embed_model} 不支持 Embeddings 功能。")
except Exception as e:
logger.error(e)
return BaseResponse(code=500, msg=f"文本向量化过程中出现错误:{e}")
相似度检索机制
相似度检索是知识库系统的核心功能,Langchain-Chatchat 实现了高效的向量相似度计算和结果筛选机制。
检索算法原理
系统采用余弦相似度作为主要的相似度度量标准,通过以下公式计算查询向量与文档向量的相似度:
$$ \text{similarity} = \frac{\vec{q} \cdot \vec{d}}{|\vec{q}| \cdot |\vec{d}|} $$
其中 $\vec{q}$ 是查询向量,$\vec{d}$ 是文档向量。
多向量数据库支持
Langchain-Chatchat 支持多种向量数据库,每种数据库都有其独特的优势和适用场景:
| 向量数据库 | 特点 | 适用场景 | 性能指标 |
|---|---|---|---|
| FAISS | 高性能、内存索引 | 中小规模数据 | 毫秒级检索 |
| Milvus | 分布式、可扩展 | 大规模数据 | 高并发支持 |
| PGVector | 关系型集成 | 已有PostgreSQL环境 | ACID事务 |
| ChromaDB | 轻量级、易用 | 开发测试 | 快速部署 |
检索流程优化
核心检索实现
系统通过 do_search 方法实现相似度检索:
def do_search(self,
query: str,
top_k: int,
score_threshold: float = SCORE_THRESHOLD,
) -> List[Tuple[Document, float]]:
"""
搜索知识库子类实自己逻辑
"""
# 向量化查询文本
query_vector = self.embed_query(query)
# 在向量数据库中搜索相似文档
results = self.vector_store.similarity_search_with_score(
query=query,
k=top_k,
score_threshold=score_threshold
)
# 处理搜索结果
filtered_results = []
for doc, score in results:
if score >= score_threshold:
filtered_results.append((doc, score))
return filtered_results
性能优化策略
为了提高检索效率和准确性,系统实现了多种优化策略:
1. 向量归一化处理
系统对所有向量进行L2归一化处理,确保相似度计算的准确性:
def normalize(embeddings: List[List[float]]) -> np.ndarray:
'''
sklearn.preprocessing.normalize 的替代(使用 L2),避免安装 scipy, scikit-learn
'''
norm = np.linalg.norm(embeddings, axis=1)
norm = np.reshape(norm, (norm.shape[0], 1))
norm = np.tile(norm, (1, len(embeddings[0])))
return np.divide(embeddings, norm)
2. 分数阈值过滤
通过可配置的分数阈值,过滤低相关性结果,提高检索质量:
# 配置参数示例
VECTOR_SEARCH_TOP_K = 5 # 最大返回结果数
SCORE_THRESHOLD = 0.5 # 相似度阈值(0-1之间)
3. 批量处理优化
支持批量文本向量化,减少API调用次数,提高处理效率:
def embed_documents(
docs: List[Document],
embed_model: str = EMBEDDING_MODEL,
to_query: bool = False,
) -> Dict:
"""
将 List[Document] 向量化,转化为 VectorStore.add_embeddings 可以接受的参数
"""
texts = [x.page_content for x in docs]
metadatas = [x.metadata for x in docs]
embeddings = embed_texts(texts=texts, embed_model=embed_model, to_query=to_query).data
if embeddings is not None:
return {
"texts": texts,
"embeddings": embeddings,
"metadatas": metadatas,
}
实际应用示例
以下是一个完整的向量化与检索流程示例:
# 1. 创建知识库服务
kb_service = KBServiceFactory.get_service("my_knowledge_base", "faiss")
# 2. 添加文档到知识库
docs = [
Document(page_content="Langchain-Chatchat是一个基于本地知识库的问答系统", metadata={"source": "intro.md"}),
Document(page_content="向量化处理是将文本转换为数值向量的过程", metadata={"source": "vectorization.md"})
]
kb_service.add_doc(knowledge_file, docs)
# 3. 执行相似度检索
query = "什么是文本向量化"
results = kb_service.search_docs(
query=query,
top_k=3,
score_threshold=0.6
)
# 4. 处理检索结果
for doc, score in results:
print(f"相似度: {score:.3f}, 内容: {doc.page_content[:100]}...")
技术特点与优势
Langchain-Chatchat 的向量化处理与相似度检索机制具有以下显著特点:
- 多模型支持:兼容多种嵌入模型和向量数据库,提供灵活的部署方案
- 高性能检索:优化算法实现毫秒级响应,支持大规模数据检索
- 精准过滤:可配置的分数阈值确保检索结果的相关性
- 易于扩展:模块化设计支持新的向量数据库和嵌入模型快速集成
- 生产就绪:完善的错误处理和日志记录,适合生产环境部署
通过这一机制,Langchain-Chatchat 能够高效地将用户查询与知识库内容进行匹配,为后续的LLM生成提供准确的上下文信息,从而实现高质量的问答体验。
多格式文件支持与处理流程
Langchain-Chatchat 作为一个功能强大的知识库问答系统,其核心能力之一就是对多种文件格式的全面支持。系统通过精心设计的文档加载器架构,能够处理从常见的文本文件到复杂的办公文档、图像文件等超过30种不同格式的文件类型。这种多格式支持能力使得用户可以将各种来源的知识资料无缝整合到知识库中,为后续的向量化处理和智能问答提供丰富的原材料。
支持的文件格式范围
Langchain-Chatchat 通过 LOADER_DICT 配置字典定义了丰富的文件格式支持,涵盖了办公文档、图像、代码、数据文件等多个类别:
| 文件类型 | 支持格式 | 主要加载器 |
|---|---|---|
| 办公文档 | .docx, .doc, .ppt, .pptx, .xlsx, .xls, .xlsd | RapidOCRDocLoader, RapidOCRPPTLoader, UnstructuredExcelLoader |
| PDF文档 | .pdf | RapidOCRPDFLoader |
| 图像文件 | .png, .jpg, .jpeg, .bmp | RapidOCRLoader |
| 文本文件 | .txt, .md, .rst, .rtf, .xml | UnstructuredFileLoader, UnstructuredMarkdownLoader |
| 网页文件 | .html, .htm, .mhtml | UnstructuredHTMLLoader, MHTMLLoader |
| 数据文件 | .csv, .json, .jsonl, .tsv | CSVLoader, JSONLoader, JSONLinesLoader |
| 电子书 | .epub | UnstructuredEPubLoader |
| 邮件文件 | .eml, .msg | UnstructuredEmailLoader |
| 编程文件 | .py, .ipynb | PythonLoader, NotebookLoader |
| 其他格式 | .odt, .srt, .toml, .enex | 对应专用加载器 |
文档处理核心流程
多格式文件的处理遵循一个标准化的流水线作业模式,确保不同类型文件都能被正确解析和向量化:
1. 文件上传与保存
当用户通过Web界面或API上传文件时,系统首先将文件保存到知识库对应的目录结构中:
def _save_files_in_thread(files: List[UploadFile], knowledge_base_name: str, override: bool):
"""多线程保存上传文件到知识库目录"""
file_path = get_file_path(knowledge_base_name=knowledge_base_name, doc_name=filename)
if not os.path.isdir(os.path.dirname(file_path)):
os.makedirs(os.path.dirname(file_path))
with open(file_path, "wb") as f:
f.write(file_content)
2. 格式识别与加载器选择
系统根据文件扩展名自动选择对应的文档加载器:
def get_LoaderClass(file_extension):
"""根据文件扩展名获取对应的加载器类"""
for LoaderClass, extensions in LOADER_DICT.items():
if file_extension in extensions:
return LoaderClass
3. 内容提取与OCR处理
对于不同类型的文件,系统采用不同的内容提取策略:
PDF文件处理 - 结合文本提取和OCR识别:
class RapidOCRPDFLoader(UnstructuredFileLoader):
def pdf2text(filepath):
doc = fitz.open(filepath)
for page in doc:
text = page.get_text("") # 提取文本内容
# 对图片内容进行OCR识别
img_list = page.get_image_info(xrefs=True)
for img in img_list:
result, _ = ocr(img_array) # OCR识别
Office文档处理 - 支持Word、PPT的文本和图片内容:
class RapidOCRDocLoader(UnstructuredFileLoader):
def doc2text(filepath):
doc = Document(filepath)
for block in iter_block_items(doc):
if isinstance(block, Paragraph):
resp += block.text.strip() + "\n" # 提取段落文本
images = block._element.xpath('.//pic:pic') # 提取图片
for image in images:
result, _ = ocr(np.array(image)) # OCR识别图片文字
图像文件处理 - 纯OCR识别:
class RapidOCRLoader(UnstructuredFileLoader):
def img2text(filepath):
ocr = get_ocr()
result, _ = ocr(filepath) # 直接进行OCR识别
if result:
ocr_result = [line[1] for line in result]
return "\n".join(ocr_result)
4. 文本预处理与分割
提取后的文本内容经过预处理后,使用中文优化的文本分割器进行分块:
def make_text_splitter(splitter_name: str = "ChineseTextSplitter",
chunk_size: int = 250,
chunk_overlap: int = 50):
"""创建文本分割器实例"""
text_splitter = ChineseTextSplitter(
chunk_size=chunk_size,
chunk_overlap=chunk_overlap
)
return text_splitter
class ChineseTextSplitter(CharacterTextSplitter):
def split_text(self, text: str) -> List[str]:
# 中文特定的分句逻辑
text = re.sub(r'([;;.!?。!?\?])([^"'"'"'])'', r"\1\n\2", text)
# 更复杂的分句和分段处理
return processed_chunks
5. 向量化与存储
分割后的文本块通过嵌入模型转换为向量,并存储到向量数据库中:
def files2vs(kb_name: str, kb_files: List[KnowledgeFile]):
"""将文件内容向量化并存储"""
for kb_file in kb_files:
docs = kb_file.file2docs() # 提取文档
texts = kb_file.docs2texts(docs) # 分割文本
embeddings = embed_model.embed_documents(texts) # 生成嵌入向量
vector_store.add_texts(texts, embeddings) # 存储到向量库
高级特性与优化
智能编码检测
对于文本文件,系统自动检测文件编码,避免乱码问题:
def get_loader(loader_name: str, file_path: str, loader_kwargs: Dict = None):
if loader_name == "CSVLoader":
# 自动检测文件编码
with open(file_path, 'rb') as struct_file:
encode_detect = chardet.detect(struct_file.read())
loader_kwargs["encoding"] = encode_detect["encoding"]
增量更新机制
系统支持文件的增量更新,避免重复处理未修改的文件:
def file2docs(self, refresh: bool = False):
"""带缓存的文档加载,避免重复处理"""
if self.docs is None or refresh:
loader = get_loader(loader_name=self.document_loader_name,
file_path=self.filepath)
self.docs = loader.load() # 仅当需要时重新加载
return self.docs
多线程处理
支持多文件并行处理,提高大规模知识库构建效率:
def files2docs_in_thread(files: List[KnowledgeFile], **kwargs) -> Generator:
"""多线程文档处理"""
params = [{"file": file, **kwargs} for file in files]
for result in run_in_thread_pool(process_file, params=params):
yield result
处理性能优化策略
针对不同文件类型,系统采用了多种性能优化策略:
- PDF文件:使用混合文本提取和按需OCR,避免对纯文本PDF进行不必要的OCR处理
- 大型文档:支持分页处理和进度跟踪,避免内存溢出
- 图像文件:集成高效的RapidOCR引擎,提供快速的文字识别能力
- 批量处理:多线程并行处理,充分利用多核CPU性能
错误处理与容错机制
系统具备完善的错误处理机制,确保单个文件处理失败不会影响整个知识库:
try:
kb_file = KnowledgeFile(filename=file_name, knowledge_base_name=knowledge_base_name)
docs = kb_file.file2docs()
except Exception as e:
logger.error(f"文件 {file_name} 处理失败: {e}")
failed_files[file_name] = str(e)
continue # 继续处理其他文件
这种多格式文件支持架构使得Langchain-Chatchat能够处理企业环境中各种类型的知识文档,从技术手册、产品文档到扫描的合同文件,为用户构建全面而准确的知识库系统提供了坚实的技术基础。
知识库维护与版本管理
在Langchain-Chatchat项目中,知识库的维护与版本管理是确保RAG系统稳定运行和数据一致性的关键环节。该系统提供了完整的知识库生命周期管理功能,包括版本控制、数据迁移、备份恢复和一致性维护等核心能力。
知识库版本管理架构
Langchain-Chatchat采用多层次的版本管理策略,通过数据库记录、文件系统监控和向量库同步三个维度来维护知识库状态:
文件版本控制机制
系统通过KnowledgeFileModel模型实现文件级别的版本控制,每个文件都维护完整的版本信息:
| 字段名 | 类型 | 描述 | 示例值 |
|---|---|---|---|
| file_version | Integer | 文件版本号 | 1 |
| file_mtime | Float | 文件修改时间戳 | 1704038400.0 |
| file_size | Integer | 文件大小(字节) | 10240 |
| docs_count | Integer | 切分文档数量 | 25 |
| custom_docs | Boolean | 是否自定义文档 | false |
版本控制的核心逻辑体现在文件更新时的自动版本递增:
def update_doc(self, kb_file: KnowledgeFile, docs: List[Document] = [], **kwargs):
"""更新文档内容并递增版本号"""
if docs:
# 检查文件是否已存在
existing_file = self.exist_doc(kb_file.filename)
if existing_file:
# 递增版本号
new_version = existing_file.file_version + 1
kb_file.file_version = new_version
else:
kb_file.file_version = 1
# 更新文件元数据
kb_file.file_mtime = os.path.getmtime(kb_file.file_path)
kb_file.file_size = os.path.getsize(kb_file.file_path)
kb_file.docs_count = len(docs)
# 执行向量库更新
self._update_vector_store(kb_file, docs)
数据迁移与同步策略
系统提供多种迁移模式以适应不同的维护场景:
各种迁移模式的具体用途:
| 模式 | 适用场景 | 操作描述 | 风险等级 |
|---|---|---|---|
| recreate_vs | 版本升级、数据损坏 | 完全清空并重建向量库 | 高 |
| update_in_db | 常规维护、配置变更 | 基于数据库记录更新向量库 | 中 |
| increment | 日常更新、新增文件 | 只处理新增或修改的文件 | 低 |
数据库备份与恢复
系统支持通过SQLite数据库备份实现知识库状态的完整保存:
def import_from_db(sqlite_path: str = None) -> bool:
"""从备份数据库导入数据到当前系统"""
try:
con = sql.connect(sqlite_path)
con.row_factory = sql.Row
cur = con.cursor()
# 获取所有表名
tables = [x["name"] for x in cur.execute(
"select name from sqlite_master where type='table'").fetchall()]
# 遍历所有模型并导入数据
models = list(Base.registry.mappers)
for model in models:
table = model.local_table.fullname
if table not in tables:
continue
with session_scope() as session:
for row in cur.execute(f"select * from {table}").fetchall():
data = {k: row[k] for k in row.keys() if k in model.columns}
if "create_time" in data:
data["create_time"] = parse(data["create_time"])
session.add(model.class_(**data))
return True
except Exception as e:
logger.error(f"数据库导入失败: {e}")
return False
一致性维护机制
系统提供两种一致性维护工具来确保文件系统与数据库的同步:
1. 数据库文档清理 (prune_db_docs)
def prune_db_docs(kb_names: List[str]):
"""删除数据库中存在但本地文件已不存在的文档记录"""
for kb_name in kb_names:
kb = KBServiceFactory.get_service_by_name(kb_name)
if kb is not None:
files_in_db = kb.list_files()
files_in_folder = list_files_from_folder(kb_name)
# 找出需要删除的文件(在数据库但不在本地)
files_to_delete = list(set(files_in_db) - set(files_in_folder))
for file_name in files_to_delete:
kb_file = KnowledgeFile(filename=file_name, knowledge_base_name=kb_name)
kb.delete_doc(kb_file, not_refresh_vs_cache=True)
kb.save_vector_store()
2. 本地文件清理 (prune_folder_files)
def prune_folder_files(kb_names: List[str]):
"""删除本地存在但数据库中不存在的文件"""
for kb_name in kb_names:
kb = KBServiceFactory.get_service_by_name(kb_name)
if kb is not None:
files_in_db = kb.list_files()
files_in_folder = list_files_from_folder(kb_name)
# 找出需要删除的文件(在本地但不在数据库)
files_to_delete = list(set(files_in_folder) - set(files_in_db))
for file_name in files_to_delete:
os.remove(get_file_path(kb_name, file_name))
版本管理最佳实践
1. 定期备份策略
# 创建数据库备份
cp knowledge_base/info.db knowledge_base/backup/info_$(date +%Y%m%d).db
# 备份向量库文件
tar -czf vector_store_backup_$(date +%Y%m%d).tar.gz knowledge_base/vector_store/
2. 版本升级流程
# 版本升级时的标准操作流程
def upgrade_knowledge_base():
# 1. 创建备份
create_backup()
# 2. 执行数据库迁移
migrate_database()
# 3. 重建向量库(如果需要)
if need_recreate_vs:
folder2db(kb_names, mode="recreate_vs")
else:
# 4. 或者进行增量更新
folder2db(kb_names, mode="increment")
# 5. 验证数据一致性
validate_consistency()
3. 监控与告警配置 系统应该监控以下关键指标:
- 文件版本一致性
- 向量库与数据库同步状态
- 存储空间使用情况
- 备份完整性
通过上述完善的版本管理和维护机制,Langchain-Chatchat确保了知识库数据的可靠性、一致性和可维护性,为生产环境的大规模应用提供了坚实的技术保障。
总结
Langchain-Chatchat通过完善的文档加载、文本分割、向量化处理和知识库维护机制,构建了一个高效可靠的知识库问答系统。系统支持超过30种文件格式,采用智能的OCR处理和中文优化分割策略,确保文本处理的质量和效率。多层次的版本管理、数据迁移和一致性维护机制为生产环境的大规模应用提供了坚实保障。这种模块化、可配置的设计使得系统能够适应不同的应用场景和性能要求,为用户构建全面而准确的知识库系统提供了完整的技术解决方案。
【免费下载链接】Langchain-Chatchat 项目地址: https://gitcode.com/gh_mirrors/lang/Langchain-Chatchat
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



