LangChain-ChatChat+Ollama+Qwen 搭建企业级私有化RAG问答系统
1. 为什么你需要一个企业级的私有化RAG问答系统?
想象一下这个场景:你是一家公司的技术负责人,手里有一大堆产品手册、技术文档、内部流程文件,还有各种会议纪要和客户沟通记录。每当新员工入职,或者销售同事需要快速查找某个产品的技术参数时,大家要么在成堆的文件夹里翻找,要么在聊天记录里大海捞针。更头疼的是,有些核心的技术文档和客户数据,你根本不敢放到公网上的AI服务里去问,万一泄露了怎么办?
这就是我们今天要解决的问题。RAG,也就是检索增强生成,它能让AI模型在回答问题时,不是凭空瞎编,而是先去你指定的知识库里找答案,然后结合找到的资料来生成回复。这就像给AI配了一个超级大脑和一座私人图书馆,回答既准确又有据可查。
而“企业级私有化”这几个字,是重中之重。这意味着整个系统,从AI大脑(大模型)到知识库,全都运行在你自己的服务器或电脑上,数据不出内网,完全自主可控。对于金融、法律、医疗、政务这些对数据安全有严苛要求的行业来说,这是唯一的选择。
我之前帮好几家公司搭过类似的系统,发现大家最怕的就是两件事:一是部署太复杂,看了半天教程还是跑不起来;二是用起来效果不好,回答要么不准,要么慢。所以,这次我决定把踩过的坑都总结出来,手把手带你用 LangChain-ChatChat、Ollama 和国产的 Qwen 大模型,搭建一个真正能用、好用、安全的企业级私有化RAG问答系统。整个过程不需要连接任何外部AI服务,你的数据从头到尾都待在最安全的地方。
2. 搭建前的核心准备:环境与工具全解析
工欲善其事,必先利其器。在开始敲命令之前,我们得先把“厨房”收拾好。这里我会详细解释每个工具是干嘛的,以及为什么选它们,让你知其然也知其所以然,后面出了问题也能自己排查。
2.1 虚拟环境:用 Conda 给你的项目一个“独立房间”
玩过 Python 的朋友可能都经历过“依赖地狱”:项目A需要 TensorFlow 2.8,项目B需要 TensorFlow 2.4,装来装去最后环境全乱套了。Conda 就是来解决这个问题的,它能为每个项目创建一个独立的虚拟环境,相当于给每个项目一套独立的“水电煤”系统,互不干扰。
安装与配置细节:
- 下载安装:去 Anaconda 官网下载安装包,建议安装时勾选“Add Anaconda to my PATH environment variable”(将Anaconda添加到环境变量)。这样以后在命令行里就能直接使用
conda命令了,省去手动配置的麻烦。 - 验证安装:打开你的命令行(Windows 用 PowerShell 或 CMD,Mac/Linux 用 Terminal),输入
conda --version。如果能看到版本号,恭喜你,第一步成功了。 - 创建专属环境:我们为这个 RAG 项目单独创建一个环境,命名为
rag_qwen,并指定 Python 版本为 3.10(这是 LangChain-ChatChat 兼容性较好的版本)。
执行后输入conda create -n rag_qwen python=3.10y确认。环境创建好后,用下面命令激活它:
你会看到命令行提示符前面变成了conda activate rag_qwen(rag_qwen),这说明你已经进入这个“独立房间”了,之后所有操作都在这里进行。
提示:如果你在 Windows 上激活环境时遇到报错,可以尝试先运行
conda init powershell(如果你用 PowerShell)或conda init cmd.exe,然后重新打开命令行窗口。
2.2 模型容器:Ollama,你的本地模型“管家”
Ollama 是我最近特别爱用的一个工具,它把大模型的下载、加载和运行变得像安装手机 App 一样简单。你不用再去关心复杂的模型文件、CUDA版本匹配这些让人头大的事情。Ollama 支持很多开源模型,包括我们这次要用的 Qwen。
安装与基础操作:
- 一键安装:访问 Ollama 官网,下载对应你操作系统的安装包,直接安装即可。安装完成后,通常它会自动在后台启动一个服务。
- 验证服务:打开命令行,输入
ollama --version查看版本。更重要的,我们可以用ollama list看看当前有哪些模型。刚开始这个列表是空的,因为还没下载任何模型。 - 核心概念理解:Ollama 通过一个简单的 REST API(默认在
http://localhost:11434)提供服务。这意味着,无论是 LangChain-ChatChat 还是你自己写的程序,都可以通过发送 HTTP 请求来和它管理的模型对话。这种设计让集成变得非常灵活。
2.3 国产主力模型:为什么选择 Qwen?
在原始文章里,用的是 DeepSeek 的在线 API。虽然方便,但数据要出公网,不符合我们“私有化”的核心要求。所以,我们换成完全本地运行的 Qwen。
Qwen(通义千问)是阿里云开源的系列大模型,性能强劲,对中文支持尤其出色。更重要的是,它有专门为 Ollama 优化的版本,量化做得很好,能在消费级硬件上流畅运行。比如 qwen2.5:7b 这个 70 亿参数的版本,在我的 32GB 内存笔记本上跑起来毫无压力,回答速度也很快。选择国产模型,在中文理解、文化背景和后续获取支持上,都有天然优势。
下载 Qwen 模型: 在已经激活的 rag_qwen 环境下的命令行中,执行:
ollama pull qwen2.5:7b
这个命令会从 Ollama 的模型库中下载 Qwen2.5 的 7B 参数版本。下载时间取决于你的网速,模型大约 4-5 GB。完成后,再用 ollama list 命令,就能看到 qwen2.5:7b 已经躺在你的模型列表里了。
2.4 文本向量化引擎:Embedding 模型的选择
RAG 的核心是“检索”,而检索的基础是把文本转换成计算机能理解的“向量”(一组数字)。这个转换工作就由 Embedding 模型来完成。一个好的 Embedding 模型,能让语义相近的文本(如“汽车”和“轿车”)的向量在空间里也挨得很近,这样检索时才找得准。
我们同样使用 Ollama 来托管 Embedding 模型。这里我推荐两个经过实战检验的模型:
- nomic-embed-text:一个通用的多语言 Embedding 模型,效果均衡,速度不错。
- mxbai-embed-large:在检索任务上表现尤其出色,如果你对答案的相关性要求极高,可以选它。
下载 Embedding 模型:
ollama pull nomic-embed-text
ollama pull mxbai-embed-large
3. 核心框架部署:LangChain-ChatChat 详解与配置
前面都是准备工作,现在主角登场了。LangChain-ChatChat(后面简称 ChatChat)是一个基于 LangChain 框架的优秀开源项目,它把 RAG 系统里那些繁琐的步骤——文档加载、切分、向量化、存储、检索、生成——全都打包好了,还提供了一个非常漂亮的 Web 界面。我们要做的,就是把它“请”进来,然后告诉它我们的“管家”(Ollama)和“大脑”(Qwen)在哪里。
3.1 安装 LangChain-ChatChat
确保你现在还在 rag_qwen 的 Conda 环境里。为了提高包下载速度,我们先设置一下国内的 PyPI 镜像源:
pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple
然后,使用 pip 安装 ChatChat。这里我建议安装完成后顺便更新到最新版:
pip install -U langchain-chatchat
这个命令会安装 ChatChat 及其所有依赖。安装过程可能需要几分钟,耐心等待即可。
3.2 初始化项目与关键配置
安装完成后,我们需要初始化项目,生成默认的配置文件。
chatchat init
执行这个命令后,它会在当前目录下创建一个 Langchain-Chatchat 的文件夹,里面包含了项目所有的配置文件和目录结构。这是最关键的一步,我们接下来要修改的配置文件都在这里。
核心配置文件:configs/model_config.py 这个文件决定了整个系统使用哪些模型以及从哪里调用它们。我们需要对它进行“大手术”。
-
配置 LLM 模型(Qwen):找到
llm_model_dict配置部分。我们需要添加一个 Ollama 平台的配置,指向我们本地运行的 Qwen 模型。# 在 llm_model_dict 字典中添加或修改如下配置 "qwen-local": { "platform_type": "ollama", # 指定平台类型为 ollama "model_name": "qwen2.5:7b", # Ollama 中拉取的模型名称 "api_base_url": "http://localhost:11434/v1", # Ollama 的 API 地址 "api_key": "EMPTY", # Ollama 无需密钥,但需要填个占位符 }同时,找到
LLM_MODEL这个变量,将其值改为我们刚定义的"qwen-local"。这告诉系统默认使用我们本地的 Qwen 模型。 -
配置 Embedding 模型:找到
embedding_model_dict配置部分。同样,添加 Ollama 托管的 Embedding 模型。# 在 embedding_model_dict 字典中添加 "nomic-embed": { "platform_type": "ollama", "model_name": "nomic-embed-text", "api_base_url": "http://localhost:11434/v1", "api_key": "EMPTY", }然后,将
EMBEDDING_MODEL变量的值改为"nomic-embed"。 -
关闭不必要的模型平台:在配置文件中,你可能会看到
xinference,vllm等其它平台的配置。为了确保系统不会去错误地尝试连接它们,可以将这些平台的platform_type设置为空字符串"",或者将其api_base_url注释掉。重点是确保ollama的配置是正确的。
3.3 启动前的最终检查与知识库初始化
配置文件改好后,我们先不急着启动 Web 服务。ChatChat 提供了一个非常棒的功能:初始化一个测试知识库。这个知识库包含了一些预设的文档,让我们能立刻体验 RAG 的效果。
chatchat kb --create-test
执行这个命令,它会自动下载一些示例文档(比如 LangChain-ChatChat 项目本身的 README 和 Issues),进行切分、向量化,并存入向量数据库(默认是 Chroma)。这个过程会花一些时间,你可以看到处理进度。完成后,我们就有了一个可以查询的初始知识库。
4. 启动系统与初体验:从聊天到知识库问答
万事俱备,只欠东风。让我们启动这个完全私有化的 AI 助手。
4.1 一键启动所有服务
ChatChat 使用 chatchat start -a 命令,可以同时启动后端 API 服务和前端 Web 界面,非常方便。
chatchat start -a
如果一切配置正确,你会看到一系列服务启动的日志,最后提示 Application startup complete.。此时,打开你的浏览器,访问 http://localhost:8501(默认端口),就能看到 ChatChat 的 Web 界面了。
可能遇到的坑与解决方案:
- 端口冲突:如果 8501 端口被占用,可以在启动命令中指定其他端口,如
chatchat start -a --port 7860。 - 依赖包版本冲突:这是最常遇到的问题。如果启动时报错,比如某个模块找不到或者方法不兼容,错误信息通常会告诉你哪个包有问题。你可以尝试用
pip install -U [包名]==[指定版本]来安装或降级到兼容的版本。我在实战中遇到过httpx、pydantic的版本问题,按照错误提示搜索一下,一般都能在项目的 GitHub Issues 里找到解决方案。
4.2 功能界面导览与基础测试
Web 界面通常分为几个主要区域:
- 对话模式选择:这里有“LLM 对话”和“知识库问答”两个核心模式。
- 模型切换:在侧边栏或设置里,可以检查并确认当前使用的 LLM 是不是我们配置的
qwen-local,Embedding 模型是不是nomic-embed。 - 知识库管理:在这里你可以创建新的知识库、上传文档、查看已处理的文档列表。
让我们做个简单测试:
- 纯聊天模式:切换到“LLM 对话”,问它“你是谁?”。它应该会以 Qwen 的口吻回答,证明本地大模型已成功接入。
- 知识库问答模式:切换到“知识库问答”,确保右侧选择了我们刚才初始化的
test知识库。然后问一个关于 LangChain-ChatChat 项目的问题,比如“这个项目的主要功能是什么?”。如果配置正确,它的回答应该不是泛泛而谈,而是能引用项目 README 中的具体描述。这证明 RAG 链路完全跑通了!
5. 构建企业级知识库:从零到一的实战
测试通过,意味着我们的“发动机”和“底盘”都没问题了。接下来,我们要给它装上真正的“货物”——也就是企业自己的知识。
5.1 知识库创建与文档上传
在 Web 界面的“知识库管理”中,点击“新建知识库”。给你的知识库起个名字,比如 公司产品手册。向量数据库类型和 Embedding 模型保持默认即可(它会使用我们在 model_config.py 里设置的默认 Embedding 模型)。
创建成功后,进入该知识库,点击“上传文件”。ChatChat 支持丰富的格式:
- 文本类:
.txt,.md,.html - 办公文档:
.pdf,.docx,.pptx,.xlsx - 数据文件:
.csv
上传实战技巧:
- PDF 处理:对于扫描版的 PDF(图片格式),ChatChat 需要依赖 OCR 功能。确保你安装了
paddleocr或easyocr等包。如果是文字版 PDF,则可以直接提取。 - 大文件处理:上传一个几百页的 PDF 时,系统会先进行“文本提取”和“分割”。这个过程可能会比较耗时,耐心等待进度条完成。你可以同时上传多个文件,它们会进入队列依次处理。
- 文档分割策略:这是影响 RAG 效果的关键。ChatChat 默认会根据标点、换行进行分割。对于结构严谨的文档(如 API 文档),这个效果很好。但对于段落很长的文档,你可能需要调整分割器(在配置文件中可以设置
CHUNK_SIZE和OVERLAP_SIZE),让每个“文本块”大小适中,既包含完整信息,又不至于太长。
5.2 向量化与检索流程深度解析
当你点击“向量化”或系统自动处理上传文件时,背后发生了这些事情:
- 加载与清洗:系统读取文件,去除无关的格式标记。
- 文本分割:将长文档切成一个个小片段(chunk)。
- 向量化:每个文本片段通过我们配置的
nomic-embed-text模型,被转换成一个高维向量(比如768维)。 - 存储:这个向量,连同原始的文本片段,被存储到向量数据库(如 Chroma)中。向量数据库的核心能力是“相似度搜索”,它能快速找到和问题向量最相似的文本向量。
当用户提问时:
- 问题文本同样被 Embedding 模型转换成向量。
- 系统在向量数据库中搜索与问题向量最相似的 K 个文本片段(K 通常可配置,比如 5 个)。
- 将这 K 个文本片段作为“参考材料”,和原始问题一起,构造成一个详细的提示(Prompt),发送给 Qwen 模型。
- Qwen 模型基于这些参考材料生成最终答案。
这个过程就是 RAG 的灵魂,它让模型回答有据可依,极大减少了“胡言乱语”的情况。
5.3 效果优化:Prompt 与参数调优
如果发现答案不太准,可以从以下几个方面调整:
- 检索数量:在知识库问答的设置中,可以调整“返回匹配文本条数”。默认可能是 5,如果你发现答案总是遗漏关键信息,可以尝试调到 7 或 8。但注意,太多会增加模型负担,也可能引入噪音。
- Prompt 模板:ChatChat 的 Prompt 模板是可以修改的。在
configs/prompt_config.py中,你可以找到KNOWLEDGE_BASE_PROMPT_TEMPLATE。这个模板定义了如何将检索到的文本和问题组合起来送给模型。你可以微调它的措辞,比如加入“请严格根据以下资料回答”这样的强约束语句。 - 相似度阈值:可以设置一个最低相似度分数,过滤掉那些相关性太低的检索结果,避免无关信息干扰模型。
6. 企业级进阶:权限、集成与高可用考量
一个玩具级的系统和企业级可用的系统,差距往往就在这些进阶功能上。
6.1 实现简单的权限管理
开源版本的 ChatChat Web 界面本身不提供多用户和权限管理。但在企业内网环境下,我们可以通过一些“组合拳”来实现基础管控:
- 网络层隔离:将 ChatChat 服务部署在内网某台服务器上,通过防火墙规则,只允许特定 IP 段(如公司办公网)访问其端口(8501)。
- 反向代理与认证:使用 Nginx 或 Apache 作为反向代理,在代理层配置 HTTP 基础认证(.htpasswd),为系统增加一层用户名/密码保护。
- 知识库物理隔离:为不同部门创建不同的知识库,如
knowledge_base_A、knowledge_base_B。虽然 Web 界面都能看到,但可以通过内部规定,要求员工只查询自己部门的知识库。更彻底的做法是,部署多个 ChatChat 实例,每个实例连接不同的向量数据库和知识库目录,并通过不同的端口或域名访问,实现完全隔离。
6.2 系统集成:API 调用与二次开发
ChatChat 启动的不仅是 Web 界面,还有一个功能完整的后端 API 服务(默认端口 7861)。这意味着你可以把它集成到自己的企业应用里,比如内部办公系统、客服机器人等。
API 调用示例(使用 Python requests):
import requests
import json
def ask_rag(question, knowledge_base_name="公司产品手册"):
url = "http://localhost:7861/local_doc_qa/local_doc_chat"
payload = {
"question": question,
"knowledge_base_name": knowledge_base_name,
"history": []
}
headers = {'Content-Type': 'application/json'}
response = requests.post(url, data=json.dumps(payload), headers=headers)
return response.json()
# 调用示例
answer = ask_rag("我们旗舰产品的主要优势是什么?")
print(answer["result"])
通过调用这些 API,你可以实现自动化问答、批量处理查询、将问答能力嵌入工作流等高级功能。
6.3 性能与高可用部署建议
当知识库文档达到数千甚至数万份时,或者并发用户数增多时,就需要考虑性能优化。
- 向量数据库升级:默认的 Chroma 轻量好用,但在海量数据下,可以考虑换成专业的向量数据库,如 Milvus、Qdrant 或 Weaviate。这些数据库支持分布式部署、更高效的索引和检索算法。ChatChat 的配置文件中通常支持更换向量数据库类型。
- 模型服务分离:将 Ollama(模型服务)和 ChatChat(应用服务)部署在不同的服务器上。Ollama 服务器可以配备更强的 GPU,专门负责模型推理;ChatChat 服务器负责处理 Web 请求和业务逻辑。两者通过内网 API 调用。
- 负载均衡:如果用户量很大,可以在多台服务器上部署 ChatChat 的无状态应用实例,前面用 Nginx 做负载均衡。而向量数据库和模型服务(Ollama)作为共享的后端服务。
7. 避坑指南与效能提升
结合我多次部署的经验,这里汇总几个最容易踩坑的地方和提升效率的技巧。
- Ollama 模型加载慢或内存不足:首次启动加载 Qwen 模型时,会占用较多内存并需要一些时间。确保你的服务器有足够的内存(7B模型建议至少16GB可用内存)。如果内存紧张,可以尝试 Ollama 提供的更小量化版本的模型,如
qwen2.5:3b。 - 文档处理失败:如果上传某些 PDF 或图片文件后,系统提示处理失败或提取不到文字。首先检查文件本身是否加密或损坏。其次,确保安装了完整的 OCR 依赖(如
paddlepaddle,paddleocr)。可以在命令行尝试用paddleocr命令测试一下图片识别是否正常。 - 回答质量不佳:如果模型回答看起来没有参考知识库,或者参考错了。首先去“知识库管理”里,找到对应的知识库,使用“搜索测试”功能,直接输入你的问题,看看系统检索出来的文本片段是否相关。如果不相关,问题可能出在 Embedding 模型或文档分割上。可以尝试换用
mxbai-embed-large模型,或者调整文档的分块大小和重叠度。 - 利用系统缓存:ChatChat 和 Ollama 都有缓存机制。对于相同的问题,第二次提问速度会快很多。在生产环境中,可以考虑在应用层增加一个问答缓存,将常见问题的答案缓存起来,进一步提升响应速度。
- 定期更新与维护:开源项目迭代很快。定期关注 LangChain-ChatChat 和 Ollama 的 GitHub 仓库,看看是否有重要的更新、Bug 修复或新模型支持。更新前,务必在测试环境进行验证。
这套基于 LangChain-ChatChat + Ollama + Qwen 的方案,我已在多个对数据安全有严格要求的企业内部环境中成功部署。它最大的优势就是“闭环”:从数据摄入、处理、存储到问答生成,全流程都在内网完成,没有任何数据泄露风险。同时,得益于 Ollama 和 ChatChat 的优秀设计,整个系统的复杂度和维护成本被降到了很低。你可以从一个小型的、为单个部门服务的知识库开始,随着需求的增长,再逐步扩展到更复杂的架构。
更多推荐



所有评论(0)