RAG 实践总结:14 天从零搭建企业知识库问答系统
最近花了 14 天(每天 2 小时),用 RAG 技术搭了一套企业内部知识库问答系统。这篇文章把整个过程梳理了一遍,包含完整的逻辑流程图、核心代码片段、以及我在实践里踩过的坑。
背景
我是一名在企业做系统导入和管理的 IT 人员,日常工作经常要查阅大量内部文档(制度、流程、规范)。每次都要打开文档翻半天,效率很低。
大型语言模型(LLM)虽然能回答问题,但它的知识截止于训练数据,无法知道企业内部的具体制度。如果直接把文档喂给大模型,又有 Token 限制——一次塞不了太长文本。
这就需要用到 RAG(Retrieval-Augmented Generation,检索增强生成) 技术。
什么是 RAG
RAG 的核心思想很简单:不要让大模型凭记忆回答,而是先检索,再回答。
对比传统方法:
| 方式 | 做法 | 问题 |
|---|---|---|
| 直接问大模型 | “报销流程是什么?” | 大模型不知道你公司制度 |
| 把文档塞进 Prompt | “根据以下文档回答问题:……” | 文档太长会超出 Token 限制 |
| RAG | 先搜索相关片段,再把片段给大模型 | 既知道内容,又不超限制 |
核心流程拆解
第一步:文档切片(Document Splitting)
原始文档不能整篇塞进去,需要切成小段,每段几百字。
from langchain_text_splitters import RecursiveCharacterTextSplitter
splitter = RecursiveCharacterTextSplitter(chunk_size=300, chunk_overlap=100)
chunks = splitter.split_documents(documents)
chunk_size=300:每段约 300 字chunk_overlap=100:相邻两段有 100 字重叠,避免关键信息被切断- 切片的粒度直接影响检索效果——太大则噪音多,太小则信息不完整
第二步:向量化存入(Embedding + Vector Store)
计算机看不懂文字,需要把文字转成数字——也就是向量。
"报销需要发票" → [0.12, -0.45, 0.78, ...] ← 1024 维向量
- 用通义千问的
text-embedding-v3模型,每段文字转成一个 1024 维的向量 - 存入 Chroma(本地向量数据库),后续搜索时基于语义相似度匹配,而不是关键词
语义搜索的优势:搜”怎么报销”和”费用如何申请”,虽然关键词不同,但语义相近,都能找到”报销流程”相关的片段。
第三步:检索 + 生成(Retrieve + Generate)
用户提问时走以下流程:
- 把用户的问题也转成向量
- 在 Chroma 中搜索最相似的 3-5 个片段
- 把检索到的片段拼到 Prompt 里,发给大模型
{"role": "system", "content": "你是企业内部知识库助手,根据提供的文档回答问题。"}
{"role": "user", "content": "文档内容:\n[检索到的 3 个片段]\n\n问题:报销需要什么材料"}
这样大模型既有了参考资料,又不会因为全文太长而超出上下文窗口。
我实践时遇到的问题
1. LangChain 版本变化
旧教程里的导入路径在新版中改了:
# 旧版
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.document_loaders import Docx2txtLoader
from langchain.vectorstores import Chroma
# 新版(需要装对应子包)
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_community.document_loaders import Docx2txtLoader
from langchain_community.vectorstores import Chroma
2. 依赖包缺失
新手最常遇到的报错就是 ModuleNotFoundError,解决方法就是缺什么装什么:
pip install langchain langchain-community langchain-text-splitters chromadb dashscope
3. 回答不准确时的调优
| 问题 | 解决办法 |
|---|---|
| 回答太笼统 | 调小 chunk_size(从 500 降到 300),让每个片段更聚焦 |
| 信息遗漏 | 调大 k(从 3 调到 5),检索更多片段参考 |
| 编造答案 | 在 System Prompt 中加一句”找不到就说没有” |
我用到的技术栈
| 技术 | 用途 |
|---|---|
| Python | 胶水语言,把所有环节串起来 |
| 通义千问(qwen-turbo) | 回答用户问题的核心大模型 |
| 通义千问 Embedding | 把文字转成向量 |
| LangChain | 封装了切片、向量化、检索的框架 |
| ChromaDB | 轻量本地向量数据库 |
| OpenAI SDK | 兼容模式调用通义千问 API |
| python-docx / PyPDF2 | 读取 Word 和 PDF 文件 |
最终成果
14 天,每天 2 小时,做出了一个企业知识库问答系统:
python rag_chatbot.py
请输入文档路径:公司考勤请假及费用报销管理制度.docx
文档已处理,共 23 个片段
请输入问题:请假流程是什么?
回答:根据文档,请假需提前填写请假单,经主管审批后提交人事备案。
请输入问题:出差补贴标准是多少?
回答:文档中提到出差补贴按城市级别划分,一类城市每天 200 元,二类城市每天 150 元。
总结
RAG 是当前企业落地 AI 最实用的技术路线,没有之一。它不需要微调模型,不需要 GPU,只需要普通的 API 调用就能实现基于私有知识库的问答。
对我这种有企业 IT 背景的人来说,RAG 天然契合:我懂企业文档有多乱、流程有多复杂,而 RAG 能解决这些痛点。
下一步计划:
- 支持上传多份文档同时查询
- 用 FastAPI 封装成 Web 服务
- 部署上线让团队真正用起来
全部代码已开源在 GitHub,欢迎交流。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 LYQC23的个人小站!