最近花了 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)

用户提问时走以下流程:

  1. 把用户的问题也转成向量
  2. 在 Chroma 中搜索最相似的 3-5 个片段
  3. 把检索到的片段拼到 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,欢迎交流。