☰
LangChain+ChatGLM-6B+本地知识库:RAG问答系统搭建全流程指南
2026/10/14 11:36:54 网站建设 项目流程

简介:RAG智能问答系统项目实战包,基于RAG模型整合LangChain、ChatGLM-6B与本地知识库,面向希望掌握检索增强生成技术的中高级开发者,用于解决大模型在垂直领域问答中知识局限与准确率不足的痛点。压缩包内含73个文件,包括Python源码(.py)、模型缓存(.pickle)、说明文档(.md/.txt)、示例图片(.jpg)等类型,分别对应系统运行、检索缓存、使用指南与效果展示,整套资源约17.67MB。目前已吸引958人学习参考。项目不仅提供完整的系统源码,还附带流程教程、FAQ、更新记录与Docker部署文件,从环境配置、文本分割、模型加载到界面启动均给出可参照步骤。读者既能直接复现基础RAG对话,也能基于本地知识库扩展定制,有效缩短从理论到落地的距离。

1. RAG是什么,为什么本地知识库这么搭成了标配

RAG(检索增强生成)这几年已经从论文里的概念变成了私有化知识问答落地最稳的方案,核心思路不是让大模型硬记你的业务文档,而是在每次提问时先从本地知识库里检索出相关片段,再把这些片段作为上下文交给生成模型去组织答案。这个标题里的组合——LangChain加ChatGLM-6B加本地知识库,恰好是三段式标准的落地形态:LangChain负责编排检索和调用链,ChatGLM-6B负责理解问题并生成回答,本地知识库负责把企业文档变成可检索的向量索引。对于手里有一堆PDF、Word、Markdown文档,又不想把数据传到外部API的团队来说,这套方案是当前性价比很高的私有化问答起点。

适合谁来做这件事?一类是后端工程师,想把内部文档做成问答入口;另一类是算法工程师,打算在开源模型基础上快速验证RAG效果;还有一类是刚接触大模型应用开发的人,需要一个能从零跑通的完整工程参考。整条链路涉及环境安装、模型加载、文本切块、向量检索、Prompt拼接等多个环节,每一个都有参数可调、有坑可踩,下面按我实际搭建的顺序展开讲。

2. 先理解这条问答链路的四个角色,再动手搭环境

2.1 RAG在LangChain里到底是怎么被编排的

常见的做法是先用LangChain的文档加载器把本地文件读成文本,然后按固定块大小做切分,再调用Embedding模型把文本块转成向量写入向量数据库。用户提问时,把问题向量化后在向量库里做相似度检索,取出排名靠前的文本块,连同原始问题一起拼进Prompt,最后送ChatGLM-6B生成答案。这一个完整流程恰好对应我标题里的三个技术点,缺一个都不太好跑通。

为什么要用LangChain而不是自己从头写?核心原因是它已经把“加载-切分-向量化-检索-生成”这套流程封装成了可替换组件。比如今天用ChatGLM-6B,明天想换其他模型,只需要改模型加载那几行;迁移知识库数据时,向量库的类型和连接参数也能做到尽量少改应用逻辑。下面我会按这个编排结构逐步给出最小可跑的实现。

2.2 环境与硬件选型:先看资源约束再选部署方案

在真正开始写代码之前,有一件事必须先评估清楚,那就是本机资源。ChatGLM-6B是指6B参数的模型,FP16精度加载大概要占用12GB左右的显存,用INT4量化的方式可以压到6GB上下。如果你的机器只有8GB显存,建议直接用量化版本;16GB显存则可以加载FP16的完整精度。内存方面建议32GB起步,因为除了模型,向量库和Python进程还会吃不少内存。

依赖库和工具版本建议按下表对照安装,其中Python版本使用3.9或3.10比较稳妥:

组件用途建议
Python运行环境3.9/3.10,避免3.12初期兼容问题
langchain编排检索生成链路0.0.3xx版本段,API较稳
chatglm-6b生成模型通过transformers加载,考虑量化版本
chromadb / faiss向量存储本地验证用Chroma最简单
sentence-transformersEmbedding中文场景建议采用m3e或bge系列
torch深度学习框架与CUDA版本对应的2.x版本

这里有一个容易踩的细节:LangChain版本迭代比较激进,不同大版本的API可能有变化,比如链式调用从LLMChain逐步迁移到LCEL表达式的写法。建议安装后先锁定大版本,README里常用示例代码在特定版本下验证过,就不要轻易升级库。

2.3 基础安装的几个命令和踩过的坑

安装这一步看似简单,实际需要留心的点在于torch与CUDA的匹配。如果你之前装过深度学习环境,直接复用即可;如果是从零开始,首选用pip安装与自身显卡驱动匹配的torch版本,例如CUDA 11.8对应的命令是:

pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118

这里有一个血泪经验:先装torch再装transformers,不要先装transformers再回来补torch。顺序反了容易出现依赖解析混乱。接着安装其余依赖:

pip install langchain chromadb sentence-transformers transformers accelerate

FFmpeg这个工具也建议顺手装上,因为部分文档加载器在处理媒体或特殊格式文件时依赖它,后面运行到音频或视频提取时会直接报错找不到可执行文件。装完后可以用一个简单的Python命令验证关键库是否可用,比如打印transformers和torch的版本信息。如果报CUDA不可用,优先检查torch版本与显卡驱动的匹配关系,这一步是很多后面奇奇怪怪报错的总根源。

3. 跑通最小RAG链路:加载模型、建知识库、答出第一句

3.1 用Transformer直接加载ChatGLM-6B的代码骨架

标题里提到的项目源码,核心就是从模型加载开始到生成回答为止的一段串联代码。我一般先把模型加载单独抽出来做一个模块,方便后面替换不同型号模型。使用HuggingFace Transformers加载ChatGLM-6B的最简代码大概是这样的:

from transformers import AutoTokenizer, AutoModel model_name = "chatglm-6b" # 实际使用本地权重目录路径 tokenizer = AutoTokenizer.from_pretrained(model_name, trust_remote_code=True) model = AutoModel.from_pretrained(model_name, trust_remote_code=True).half().cuda() model.eval() def generate_answer(prompt, history=[]): response, history = model.chat(tokenizer, prompt, history=history) return response, history

逻辑说明:trust_remote_code=True这一步不能省略,因为ChatGLM-6B的模型结构代码是通过远程代码方式加载的;.half()是把模型转为半精度存储,显存占用减半,GPU不支持半精度时忽略这一步;model.chat()传入的是tokenizer、当前问题和历史对话列表。参数方面,max_length、top_p和temperature可以通过model.chat()的额外参数传入,初跑阶段不急着调,先确认链路通不通。

3.2 知识库最小样例:给三篇短文建一个向量索引

只加载模型还不足以叫RAG,需要先让知识库里的文档内容可以检索。我从一个很小的样例开始验证,先准备三份几十行的纯文本文件放在knowledge_base目录下,内容关于产品说明和内部流程,代码使用LangChain的目录加载器读取:

from langchain.document_loaders import TextLoader from langchain.text_splitter import RecursiveCharacterTextSplitter from langchain.embeddings import HuggingFaceEmbeddings from langchain.vectorstores import Chroma loaders = TextLoader("knowledge_base/a.txt", encoding="utf-8") docs = loaders.load() splitter = RecursiveCharacterTextSplitter(chunk_size=200, chunk_overlap=50) texts = splitter.split_documents(docs) embeddings = HuggingFaceEmbeddings(model_name="m3e-base") vectorstore = Chroma.from_documents(texts, embeddings, persist_directory="./vector_db")

代码逻辑说明:先用TextLoader读取单个文件,这里只是为了验证链路,多文件可以用DirectoryLoader批量读取;RecursiveCharacterTextSplitter按200字符一个块切分,块与块之间重叠50字符,保证语义不因为切断而断裂;向量化采用的是m3e-base模型,适合中文场景。参数调整方面,chunk_size越大、每块语义越完整,但检索准确性可能下降;chunk_overlap太小会让跨块的关键信息丢失。第一次跑时不要贪大,先用小块数据跑通,再逐步贴近真实数据规模。

3.3 把检索结果拼进Prompt,让模型开始使用知识库

向量索引建好之后,查询侧做的是相似度检索再拼接Prompt。用LangChain内置的检索QA链是最直接的做法,代码段如下:

from langchain.chains import RetrievalQA from langchain.llms import HuggingFacePipeline llm = HuggingFacePipeline(pipeline=model_as_pipeline) qa_chain = RetrievalQA.from_chain_type( llm=llm, retriever=vectorstore.as_retriever(search_kwargs={"k": 3}), return_source_documents=True ) user_query = "内部培训的报名流程是什么?" result = qa_chain({"query": user_query}) print(result["result"])

这段代码里model_as_pipeline需要先用transformers的TextStreamer把之前的模型实例包装成Pipeline对象,属于标准写法不再展开。关键参数是k,它代表每次检索取回多少个文本块送给模型。k值太小答案可能残缺,k值太大会塞进太多无关内容反而干扰生成,3到5是常见起步区间。return_source_documents=True可以帮助我们看到模型回答时引用了哪些文本片段,这在排查答非所问时非常有用。运行到这里,一条最小可见的RAG链路就通了,接下来要解决的是把链路从“能跑”变成“好用”。

4. 把本地知识库真正打理好:切块、向量化、索引的质量决定回答质量

4.1 文本加载的格式覆盖与编码处理

很多资料里的Demo都喜欢只用Markdown文件演示,但实际落地时手里往往混着PDF、Word、扫描件,还有从Web后台导出的HTML。常见做法是给不同格式配备各自的加载器:PDF用PyPDFLoader,Word用Docx2txtLoader,网页用UnstructuredHTMLLoader。以PDF加载为例:

from langchain.document_loaders import PyPDFLoader loader = PyPDFLoader("manual.pdf") pages = loader.load_and_split()

load_and_split()返回的是按页分割的Document列表,每页作为独立文档,方便后续从回答反查来源位置。编码方面,文本型文件统一指定encoding="utf-8",遇到GBK编码的历史文件可以先转码再做切分,否则会出现加载失败或乱码。扫描版PDF必须走OCR流程转成文本才能进入知识库,这是个常见的认知差,需要提前说明,否则后面检索效果会很差。

4.2 切分策略:我们团队最终采用的混合规则

切分是整个知识库工程里最值得花时间调的部分,直接决定了检索命中质量。我见到最多的问题是用固定字数硬切,结果语义断开严重,比如把一段逻辑完整的操作说明从中间截开,检索时只取到一半,生成答案自然残缺。实践中建议分两级思考:类目边界优先,比如每个大章节、每个表格、每个标题下内容自成一块,再在块内按chunk_size做二次切分。

这里有一个具体的设定可以参考:

参数建议值说明
chunk_size300~500(中文按字符)语义完整与检索精度的折中
chunk_overlap60~100保证跨块上下文信息不丢失
标题/表格优先合并按文档结构先切一级再细分避免语义断点
切分后清洗去除空行、表格制表符降低向量噪声

参数只有这四个,但实际效果差距很大。我建议切完后打印几段随机样本看连续性,确认没有出现“半句话”和断裂的表格,再进入向量化阶段。检索效果出问题,八成都能在切分这一步找到原因。

4.3 中文Embedding模型的选型和向量库落地

两个中文场景最常见的Embedding选择是m3e-base和bge-large-zh,前者轻量、部署快,后者在中文语义匹配上精度更稳但显存占用也更高。如果你的服务器跑的是CPU推理,建议选m3e-base,300MB级别模型可以接受;如果GPU资源宽裕,bge-large-zh带来的检索精度提升值得投入。

向量库也做一个简单对比,看场景选择:

向量库优点适合阶段
Chroma零配置,本地文件持久化原型验证、个人开发
FAISS检索性能高,支持批量导入千万级以下向量检索
Milvus分布式架构、支持高并发团队级知识库服务

我在本地验证阶段几乎都使用Chroma,一个persist_directory参数就能让向量持久化到磁盘。等自行评估并发量上来了,再迁移到FAISS或Milvus,迁移成本主要在重新走一遍向量化,没有业务逻辑层面的改动。这一步的重点是不要为了“听起来技术先进”而直接上分布式,前期单机更省时间。

5. 高频问题排查:检索生成不对的四个典型状况

5.1 模型回答总是“绕开”知识库内容,自说自话

这个问题现象很明显:模型生成了一段内容,知识库里的关键信息根本没被用上,像是模型在靠自己的记忆硬答。原因一般是检索质量差,召回的TopK片段与问题相关性低。排查时先打印source_documents看返回了哪些文本块,如果文本块本身确实不相关,说明问题出在检索侧,常见解决办法是增加k值并从Embedding模型和chunk_size两个方向调;如果文本块相关但生成结果没用上,那就是Prompt里对模型角色的引导不够,需要强调“请基于提供的文档内容回答,不要使用外部知识”。

5.2 启动阶段直接爆显存,模型加载到一半被系统Kill

加载ChatGLM-6B时报CUDA out of memory,绝大多数情况不是模型太大,而是加载方式没做限制。一个有效手段是先加载为float16,再限制transformers的显存分配策略,代码写法是加载前设置环境变量:

export PYTORCH_CUDA_ALLOC_CONF=max_split_size_mb:128

另一个高频原因是把Embedding模型和ChatGLM同时常驻GPU显存。常见做法是Embedding模型放在CPU上跑,只把ChatGLM放到GPU,推理速度其实损失有限,因为知识库是离线索引阶段才需要Embedding计算,在线问答阶段只对少量查询文本做一次嵌入。把这句话记住,能帮很多人省下换显卡的钱。

5.3 中文乱码导致切出来的块面目全非

原文加载后打印出来全是乱码,检索结果自然不可用。常见原因是文件本身的编码不是UTF-8,Excel导出的CSV是GBK、老Word文档是ANSI。解决流程是先用Python的chardet或charset-normalizer识别文件编码,再以对应编码读取后统一转为UTF-8再交给加载器。这里提醒一句:源码里如果硬编码了编码格式,换台机器、换批文件就会翻车,建议加载路径里统一做一次编码探测和转换。

5.4 回答质量时好时坏,同一问题换个说法就答不上来

如果知识库的权威内容里确实包含答案,但换个问法就检不到,常见原因是问句与文档表述的词汇不一致。两个方向的调整:一是切换更强的中文Embedding模型;二是对用户问题进行一次改写,把口语化问句处理成更贴近文档表述的检索式问题,这块可以用ChatGLM自身做改写再走检索,效果通常比直接拿原文查更好。这里的代价是多一次模型调用,推理时间会增加数秒,需要在效果和响应速度之间取舍。

6. 让Demo走向可用:验证方法与两个有价值的小技巧

从标题里的“流程教程”角度看,项目源码是现成的参考,但对真正拿去做项目的人来说,最重要的是学会自己验证和优化。

先说验证方法。不要只测一两句看起来顺的问题,建议准备三组测试集:第一组是知识库中原话能直接答出的问题,验证检索基础能力;第二组是把原话换个表述的变体问题,验证语义泛化能力;第三组是知识库中不存在的领域外问题,验证系统不会硬编答案。每组至少十道问题,记录回答准确率、检索命中的片段以及响应延迟。只有跑过这样的验证,才能判断系统是否真的可用。我见到很多项目上线前只拿演示问题走一遍,上线后真实用户一问就露馅,这是最不值得犯的错误。

两个技巧帮助系统进一步落地:

第一个技巧是给检索结果加一条“引用来源”的输出,也就是把source_documents里的文件名和页码拼到回答末尾。这个做法的价值不仅仅是合规,更重要的是用户能自己复核答案。实操上只需要在RetrievalQA之后根据result["source_documents"]做一个格式拼接,几行代码的事情,体验提升明显。

第二个技巧是做一个标准化的“空知识库回退”。当检索到的最高相似度得分低于阈值时,直接告诉用户“当前知识库中未找到相关资料”,而不是把不相关内容硬塞给模型去生成。这个阈值需要根据实际测试集的分布来确定,过高会误判、过低会导致模型瞎编。我看到不少系统在这个细节上翻车,补上这一条之后会具备一定的专业产品气质。

坦白说,我自己第一次跑通这套链路时在切分参数上反反复复调了两天。后来习惯固定一个原则:先跑通再优化,一次只改一个变量,记下效果再动下一个。RAG系统的坑大多藏在数据和参数的细节里,别人踩过你绕开就行。希望这篇笔记能帮你少走一段弯路,祝你本地知识库一次搭通。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询