基于 LangChain-Chatchat 实现本地知识库问答应用快速上手
基于 LangChain-Chatchat 搭建本地知识库问答应用的完整流程。涵盖环境配置、模型下载(ChatGLM3-6B、BGE 系列)、配置文件详解、一键启动方法及 WebUI 使用。文章深入解析了 RAG 原理、向量数据库选型(FAISS/Milvus/PGVector)、模型量化优化策略及常见故障排查方案,旨在提供一套可离线运行、支持中文场景的开源私有化部署解决方案,适用于企业级数据安全与知识管理需求。

基于 LangChain-Chatchat 搭建本地知识库问答应用的完整流程。涵盖环境配置、模型下载(ChatGLM3-6B、BGE 系列)、配置文件详解、一键启动方法及 WebUI 使用。文章深入解析了 RAG 原理、向量数据库选型(FAISS/Milvus/PGVector)、模型量化优化策略及常见故障排查方案,旨在提供一套可离线运行、支持中文场景的开源私有化部署解决方案,适用于企业级数据安全与知识管理需求。

LangChain-Chatchat 是一个基于 ChatGLM 等大语言模型与 Langchain 等应用框架实现的开源、可离线部署的检索增强生成 (RAG) 大模型知识库项目。其目标期望建立一套对中文场景与开源模型支持友好、可离线运行的知识库问答解决方案。
本项目受相关开源项目启发,建立了全流程可使用开源模型实现的本地知识库问答应用。最新版本中通过接入 Vicuna, Alpaca, LLaMA, Koala, RWKV 等模型,依托于 Langchain 框架支持通过 API 服务或 WebUI 进行操作。
依托于本项目支持的开源 LLM 与 Embedding 模型,可实现全部使用开源模型离线私有部署。同时支持 OpenAI GPT API 的调用,并将在后续持续扩充对各类模型及模型 API 的接入。
过程包括:
top k 个prompt 中LLM 生成回答
从文档处理角度来看,实现流程如下:

0.2.10 版本。docker run -d --gpus all -p 80:8501 isafetech/chatchat:0.2.10
docker run -d --gpus all -p 80:8501 uswccr.ccs.tencentyun.com/chatchat/chatchat:0.2.10
docker run -d --gpus all -p 80:8501 registry.cn-beijing.aliyuncs.com/chatchat/chatchat:0.2.10
注意:本项目有一个非常完整的官方仓库,README 只是一个简单的介绍,仅仅是入门教程,能够基础运行。如果你想要更深入地了解本项目,或者想对本项目做出贡献,请移步 GitHub 界面。
该项目是一个可以实现完全本地化推理的知识库增强方案,重点解决数据保护、私域化部署的企业痛点。本开源方案采用 Apache License,可以免费商用,无需付费。
我们支持市面上主流的本地大语言模型和 Embedding 模型,支持开源的本地部署。支持列表详见官方文档。
首先,确保你的机器安装了 Python 3.8 - 3.11(强烈推荐使用 Python 3.11)。
$ python --version
Python 3.11.7
接着,创建一个虚拟环境,并在虚拟环境内安装项目的依赖。
# 拉取仓库
$ git clone https://github.com/chatchat-space/Langchain-Chatchat.git
# 进入目录
$ cd Langchain-Chatchat
# 安装全部依赖
$ pip install -r requirements.txt
$ pip install -r requirements_api.txt
$ pip install -r requirements_webui.txt
# 默认依赖包括基本运行环境(FAISS 向量库)。如果要使用 milvus/pg_vector 等向量库,请将 requirements.txt 中相应依赖取消注释再安装。
如果在安装 pip install -r requirements.txt 时遇到报错:
distutils.errors.DistutilsError: Command '['/Users/didiyu/ENTER/envs/chain/bin/python', '-m', 'pip', '--disable-pip-version-check', 'wheel', '--no-deps', '-w', '/var/folders/yd/mp5rd9bx1x3670cth1fp7n180000gn/T/tmpkl7z5ekl', '--quiet', 'setuptools_scm']' returned non-zero exit status 1.
[end of output]
note: This error originates from a subprocess, and is likely not a problem with pip.
error: metadata-generation-failed
× Encountered error while generating package metadata.
╰─> See above for output.
note: This is an issue with the package mentioned above, not pip.
hint: See above for details.
step1: pip install setuptools_scm
step 2: pip install wavedrom -i https://pypi.tuna.tsinghua.edu.cn/simple
参考链接:
请注意,LangChain-Chatchat 0.2.x 系列是针对 Langchain 0.0.x 系列版本的,如果你使用的是 Langchain 0.1.x 系列版本,需要降级您的 Langchain 版本。
如需在本地或离线环境下运行本项目,需要首先将项目所需的模型下载至本地,通常开源 LLM 与 Embedding 模型可以从 HuggingFace 下载。
以本项目中默认使用的 LLM 模型 ChatGLM3-6B 与 Embedding 模型 BGE-large-zh 为例:
下载模型需要先安装 Git LFS,然后运行:
$ git lfs install
$ git clone https://huggingface.co/THUDM/chatglm3-6b
$ git clone https://huggingface.co/BAAI/bge-large-zh
git clone https://www.modelscope.cn/ZhipuAI/chatglm3-6b.git
git clone https://www.modelscope.cn/Xorbits/bge-large-zh.git
git clone https://www.modelscope.cn/AI-ModelScope/bge-large-zh-v1.5.git
FlagEmbedding 专注于检索增强 LLM 领域,目前包括以下项目:
在这个项目中,发布了 BGE-M3,它是第一个具有多功能、多语言和多粒度特性的文本检索模型。
在本项目中,为了提高单一检索模式的性能,提出了一种新的自知识蒸馏方法。优化了批处理策略,支持大批处理大小,这可以在对长文本或大型语言模型进行向量微调时简单使用。我们还构建了一个用于文档检索的数据集,并提出了一个简单的策略来提高长文本的建模能力。
在这个项目中,发布了 Visualized-BGE。通过引入 image token embedding,Visualized-BGE 可以被用来编码混合图文数据。它可以被应用在广泛的多模态检索任务中,包括但不限于:多模态知识检索,多模态查询的图像检索等。
我们通过 QLoRA 微调将 Llama-3-8B-Instruct 的上下文长度从 8K 扩展到 80K。整个训练过程非常高效,在一台 8xA800 (80G) GPU 机器上仅需要 8 个小时。该模型在 NIHS、主题检索和长上下文语言理解等广泛的评估任务中表现出卓越的性能;同时,它在短上下文中也很好地保留了其原有的能力。
由于有限的上下文窗口长度,有效利用长上下文信息是对大型语言模型的一个巨大挑战。Activation Beacon 将 LLM 的原始激活压缩为更紧凑的形式,以便它可以在有限的上下文窗口中感知更长的上下文。它是一种有效、高效、兼容、低成本(训练)的延长 LLM 上下文长度的方法。
模型合并被用于提高单模型的性能。我们发现这种方法对大型语言模型和文本向量模型也很有用,并设计了'语言模型鸡尾酒'方案,其自动计算融合比例去融合基础模型和微调模型。利用 LM-Cocktail 可以缓解灾难性遗忘问题,即在不降低通用性能的情况下提高目标任务性能。
LLM-Embedder 向量模型是根据 LLM 的反馈进行微调的。它可以支持大型语言模型的检索增强需求,包括知识检索、记忆检索、示例检索和工具检索。
交叉编码器将对查询和答案相关性分数,这比向量模型 (即双编码器) 更准确,但比向量模型更耗时。因此,它可以用来对嵌入模型返回的前 k 个文档重新排序。
BGE Embedding 是一个通用向量模型。我们使用对比学习在大规模成对数据上训练模型。你可以按照我们的指南在本地数据上微调嵌入模型。 我们还提供了一个在线演示。请注意,预训练的目标是重构文本,预训练后的模型无法直接用于相似度计算,需要进行微调之后才可以用于相似度计算。
注意 BGE 使用 CLS 的表征作为整个句子的表示,如果使用了错误的方式(如 mean pooling) 会导致效果很差。
| Model | Language | 类型 | Description | query instruction for retrieval |
|---|---|---|---|---|
| BAAI/bge-m3 | Multilingual | 推理 微调 | 多功能(向量检索,稀疏检索,多表征检索)、多语言、多粒度(最大长度 8192) | |
| LM-Cocktail | English | 微调 | 微调的 Llama 和 BGE 模型,可以用来复现 LM-Cocktail 论文的结果 | |
| BAAI/llm-embedder | English | 推理 微调 | 专为大语言模型各种检索增强任务设计的向量模型 | 详见 README |
| BAAI/bge-reranker-large | Chinese and English | 推理 微调 | 交叉编码器模型,精度比向量模型更高但推理效率较低 | |
| BAAI/bge-reranker-base | Chinese and English | 推理 微调 | 交叉编码器模型,精度比向量模型更高但推理效率较低 | |
| BAAI/bge-large-en-v1.5 | English | 推理 微调 | 1.5 版本,相似度分布更加合理 | Represent this sentence for searching relevant passages: |
| BAAI/bge-base-en-v1.5 | English | 推理 微调 | 1.5 版本,相似度分布更加合理 | Represent this sentence for searching relevant passages: |
| BAAI/bge-small-en-v1.5 | English | 推理 微调 | 1.5 版本,相似度分布更加合理 | Represent this sentence for searching relevant passages: |
| BAAI/bge-large-zh-v1.5 | Chinese | 推理 微调 | 1.5 版本,相似度分布更加合理 | 为这个句子生成表示以用于检索相关文章: |
| BAAI/bge-base-zh-v1.5 | Chinese | 推理 微调 | 1.5 版本,相似度分布更加合理 | 为这个句子生成表示以用于检索相关文章: |
| BAAI/bge-small-zh-v1.5 | Chinese | 推理 微调 | 1.5 版本,相似度分布更加合理 | 为这个句子生成表示以用于检索相关文章: |
ChatGLM3-6B 是 ChatGLM 系列最新一代的开源模型,在保留了前两代模型对话流畅、部署门槛低等众多优秀特性的基础上,ChatGLM3-6B 引入了如下特性:
pip install protobuf 'transformers>=4.30.2' cpm_kernels 'torch>=2.0' gradio mdtex2html sentencepiece accelerate
from modelscope import snapshot_download
model_dir = snapshot_download("ZhipuAI/chatglm3-6b", revision="v1.0.0")
git lfs install
git clone https://www.modelscope.cn/ZhipuAI/chatglm3-6b.git
from modelscope import AutoTokenizer, AutoModel, snapshot_download
model_dir = snapshot_download("ZhipuAI/chatglm3-6b", revision="v1.0.0")
tokenizer = AutoTokenizer.from_pretrained(model_dir, trust_remote_code=True)
model = AutoModel.from_pretrained(model_dir, trust_remote_code=True).half().cuda()
model = model.eval()
response, history = model.chat(tokenizer, "你好", history=[])
print(response)
response, history = model.chat(tokenizer, "晚上睡不着应该怎么办", history=history)
print(response)
按照下列方式初始化自己的知识库和简单的复制配置文件。
$ python copy_config_example.py
$ python init_database.py --recreate-vs
import logging
import os
import langchain
import tempfile
import shutil
#是否显示详细日志
log_verbose = False
langchain.verbose = False
#通常情况下不需要更改以下内容
#日志格式
LOG_FORMAT = "%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)s: %(message)s"
logger = logging.getLogger()
logger.setLevel(logging.INFO)
logging.basicConfig(format=LOG_FORMAT)
#日志存储路径
LOG_PATH = os.path.join(os.path.dirname(os.path.dirname(__file__)), "logs")
if not os.path.exists(LOG_PATH):
os.mkdir(LOG_PATH)
#临时文件目录,主要用于文件对话
BASE_TEMP_DIR = os.path.join(tempfile.gettempdir(), "chatchat")
try:
shutil.rmtree(BASE_TEMP_DIR)
except Exception:
pass
os.makedirs(BASE_TEMP_DIR, exist_ok=True)
import os
#默认使用的知识库
DEFAULT_KNOWLEDGE_BASE = "samples"
#默认向量库/全文检索引擎类型。可选:faiss, milvus(离线) & zilliz(在线), pgvector, chromadb 全文检索引擎 es
DEFAULT_VS_TYPE = "faiss"
#缓存向量库数量(针对 FAISS)
CACHED_VS_NUM = 1
#缓存临时向量库数量(针对 FAISS),用于文件对话
CACHED_MEMO_VS_NUM = 10
#知识库中单段文本长度 (不适用 MarkdownHeaderTextSplitter)
CHUNK_SIZE = 250
#知识库中相邻文本重合长度 (不适用 MarkdownHeaderTextSplitter)
OVERLAP_SIZE = 50
#知识库匹配向量数量
VECTOR_SEARCH_TOP_K = 3
#知识库匹配的距离阈值,一般取值范围在 0-1 之间,SCORE 越小,距离越小从而相关度越高。
#但有用户报告遇到过匹配分值超过 1 的情况,为了兼容性默认设为 1,在 WEBUI 中调整范围为 0-2
SCORE_THRESHOLD = 1.0
#默认搜索引擎。可选:bing, duckduckgo, metaphor
DEFAULT_SEARCH_ENGINE = "duckduckgo"
#搜索引擎匹配结题数量
SEARCH_ENGINE_TOP_K = 3
import os
#可以指定一个绝对路径,统一存放所有的 Embedding 和 LLM 模型。
#每个模型可以是一个单独的目录,也可以是某个目录下的二级子目录。
#如果模型目录名称和 MODEL_PATH 中的 key 或 value 相同,程序会自动检测加载,无需修改 MODEL_PATH 中的路径。
MODEL_ROOT_PATH = ""
#选用的 Embedding 名称
EMBEDDING_MODEL = "bge-large-zh-v1.5"
#Embedding 模型运行设备。设为 "auto" 会自动检测 (会有警告),也可手动设定为 "cuda","mps","cpu","xpu" 其中之一。
EMBEDDING_DEVICE = "auto"
#选用的 reranker 模型
RERANKER_MODEL = "bge-reranker-large"
#是否启用 reranker 模型
USE_RERANKER = False
RERANKER_MAX_LENGTH = 1024
#如果需要在 EMBEDDING_MODEL 中增加自定义的关键字时配置
EMBEDDING_KEYWORD_FILE = "keywords.txt"
EMBEDDING_MODEL_OUTPUT_PATH = "output"
#要运行的 LLM 名称,可以包括本地模型和在线模型。列表中本地模型将在启动项目时全部加载。
#列表中第一个模型将作为 API 和 WEBUI 的默认模型。
#在这里,我们使用目前主流的两个离线模型,其中,chatglm3-6b 为默认加载模型。
#如果你的显存不足,可使用 Qwen-1_8B-Chat, 该模型 FP16 仅需 3.8G 显存。
#prompt 模板使用 Jinja2 语法,简单点就是用双大括号代替 f-string 的单大括号
#本配置文件支持热加载,修改 prompt 模板后无需重启服务。
#LLM 对话支持的变量:
#- input: 用户输入内容
#知识库和搜索引擎对话支持的变量:
#- context: 从检索结果拼接的知识文本
#- question: 用户提出的问题
#Agent 对话支持的变量:
#- tools: 可用的工具列表
#- tool_names: 可用的工具名称列表
#- history: 用户和 Agent 的对话历史
#- input: 用户输入内容
#- agent_scratchpad: Agent 的思维记录
import sys
from configs.model_config import LLM_DEVICE
#httpx 请求默认超时时间(秒)。如果加载模型或对话较慢,出现超时错误,可以适当加大该值。
HTTPX_DEFAULT_TIMEOUT = 300.0
#API 是否开启跨域,默认为 False,如果需要开启,请设置为 True
#is open cross domain
OPEN_CROSS_DOMAIN = False
#各服务器默认绑定 host。如改为"0.0.0.0"需要修改下方所有 XX_SERVER 的 host
DEFAULT_BIND_HOST = "0.0.0.0" if sys.platform != "win32" else "127.0.0.1"
#webui.py server
WEBUI_SERVER = {
"host": DEFAULT_BIND_HOST,
"port": 8501,
}
按照以下命令启动项目:
$ python startup.py -a
如果正常启动,你将能看到以下界面:

对于消费级显卡,建议对 LLM 进行量化处理:
MAX_TOKENS 或 TOP_K,尝试使用量化模型,或更换更大显存的 GPU。model_config.py 中的路径是否正确,确保模型文件完整。CHUNK_SIZE 和 OVERLAP_SIZE,优化切片策略;检查 Embedding 模型是否适配当前语言。LangChain-Chatchat 提供了一个灵活、可扩展的 RAG 解决方案,特别适合企业级私有化部署。通过合理配置模型参数和向量库,可以构建高效的本地知识库问答系统。随着开源生态的发展,未来将支持更多模型和更丰富的应用场景。

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online
生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online
基于 Mermaid.js 实时预览流程图、时序图等图表,支持源码编辑与即时渲染。 在线工具,Mermaid 预览与可视化编辑在线工具,online
解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online