RAG从零到一:企业级大模型知识库问答系统实战指南
2026/9/8 2:49:58 网站建设 项目流程

如果你正在做一个企业级大模型项目,有一个场景大概率会遇到:老板丢过来一批 PDF、Word、企业制度文档,说“把这些做成一个智能问答系统”,还要“答案必须准,不许瞎编”。

你第一反应可能是微调一个私有模型。但很快你会发现,微调的成本、周期、GPU 资源、数据标注量都高得惊人,而且微调模型本质上是在“背新知识”,它改不了模型“不知道就编”的本性。此时 RAG 提供的思路完全不同:模型不需要记住你的文档,它只需要在回答问题时,现场去你的知识库里检索相关片段,再根据这些片段组织答案。

这篇文章的目的很直接:帮你从零到一搭建一套完整的 RAG 项目,讲清楚工作原理,也覆盖企业落地时的工程细节。我不会只贴一堆概念,而是给你一套可以照着跑的代码、可验证的流程,以及我在实际项目中踩过的坑。

读完你应该能回答三个问题:

  1. RAG 到底是怎么工作的,和微调有什么区别?
  2. 一个最小的 RAG 系统,代码上需要哪几块?
  3. 从“能跑”到“好用”,企业级 RAG 还要补哪些课?

1. 为什么大模型应用绕不开 RAG

先说一个基本事实:大语言模型的知识截止时间是训练数据决定的。你问它 2024 年之后发生的事,它大概率不知道;你问它企业内部制度、某个产品的私有文档、某个项目的技术报告,它更不可能知道。硬问,它就会一本正经地生成一段看似合理、实际是编造的内容,这就是所谓的“幻觉”。

针对这个问题,业界有两条主流路线:

  • 微调(Fine-tuning):用业务数据继续训练模型,把知识“塞进”模型参数。适合改变模型的行为风格、输出格式、领域术语表达,但不适合频繁更新知识。
  • RAG(Retrieval-Augmented Generation,检索增强生成):不改变模型参数,而是在生成之前增加一个“检索”步骤,先从外部知识库找到与问题相关的资料,再把资料和问题一起交给模型,让模型“带着资料答题”。

两者不是互斥关系,但对企业最常见的“知识库问答”需求,RAG 是性价比高得多、落地速度也快得多的方案。原因很朴素:

  • 知识更新方便。今天改一篇文档,重新构建对应索引即可,不用重新训练模型。
  • 答案可溯源。RAG 可以把命中的原文片段作为依据返回给用户,这是微调难以做到的。
  • 资源门槛低。RAG 最大的计算开销在向量检索,这部分不需要训练大模型,普通 CPU 机器也能跑,GPU 只对生成阶段有需求,甚至可以直接调用 API 模型。

做深度学习的人常说“No Free Lunch”,RAG 同样如此。它没有解决所有问题,比如检索质量差时答案照样会错、上下文窗口被填充大量无关片段时模型反而会困惑。但这不妨碍它成为当前企业接入 LLM 最务实的起点。

RAG 的核心价值,一句话总结:它让模型的输出从“凭记忆发挥”变成“基于证据作答”

2. RAG 工作原理拆解:从“背课文”到“带着笔记答题”

我习惯用一个比喻来解释 RAG——它像一个开卷考试。

没有 RAG 的大模型,相当于闭卷考试。模型只能靠训练阶段“记下来的知识”答题,一旦题目超出记忆范围,就只能蒙。

有了 RAG,模型变成开卷考试:你给它一段提示词(Prompt),里面附带一份“参考笔记”,笔记内容来自企业知识库中与当前问题最相关的片段。模型作答时必须先读完笔记,再结合自己的语言组织能力写出答案。它依然不会的知识仍然不会,但它可以“照着笔记回答”它曾经不知道的内容。

把这个过程工程化,RAG 系统分为两个大阶段、五个小步骤。

2.1 索引阶段(离线构建)

索引阶段的任务是把原始文档处理成计算机可以快速检索的形式。

  1. 文档加载(Loading):读取 PDF、Word、Markdown、HTML、纯文本等格式的文档,转换成纯文本内容。
  2. 文本切分(Splitting/Chunking):把长文档切分成固定大小或语义完整的文本块,也就是 Chunk。切分的好坏直接影响后续检索效果。
  3. 向量化(Embedding):用 Embedding 模型把每个 Chunk 转换成一个高维向量。语义相近的文本,向量之间的距离也近。
  4. 存储(Storing):把向量和原文、元数据一起存入向量数据库,如 FAISS、Chroma、Milvus、pgvector 等。

2.2 查询阶段(在线推理)

查询阶段处理用户的每一次提问:

  1. 检索(Retrieval):把用户问题也用同一个 Embedding 模型转换成向量,然后在向量数据库中做相似度搜索,找出最相关的 Top-K 个 Chunk。
  2. 增强生成(Augmented Generation):把检索到的 Chunk 拼装进 Prompt,连同用户问题一起发送给 LLM,让 LLM 基于这些参考片段生成最终答案。

你直接问模型“我们公司的请假流程是什么”,模型答不上来。但如果你先把《员工手册》里关于请假制度的几个片断检索出来,再把它们粘进 Prompt,模型就能给你一条有条理的请假流程。这就是整个 RAG 最核心的机制,没有玄学,纯粹是工程组合。

技术上有几个细节值得注意:

  • Embedding 模型要统一。写入向量库和查询问题时,必须使用同一个 Embedding 模型,否则向量空间不对齐,检索结果会莫名其妙。
  • 相似度度量要选对。常见的有余弦相似度(Cosine Similarity)、欧氏距离、内积。绝大多数文本场景用余弦相似度最稳妥。
  • Top-K 要控制好。K 太小可能漏掉关键片段,K 太大则会把不相关的内容塞进提示词,稀释模型的注意力。

3. RAG 的四代演进:从朴素到 Agentic RAG

你在日常工作里听到的 RAG 其实已经不是同一种东西。过去一年左右,RAG 的架构经历了好几轮演进,搞懂这些概念能让你在项目方案设计时不被技术名词带偏。

3.1 朴素 RAG(Naive RAG)

这是最经典的“检索 + 生成”两段式架构:文档切块 -> 向量化 -> 向量检索 -> 拼 Prompt -> 生成。

优点是结构简单,适合快速验证;缺点是检索质量完全依赖 Chunk 切分和 Embedding 模型,面对复杂问题命中率不稳定。很多刚入门的人以为 RAG 就是这个样子,其实这只是起点。

3.2 高级 RAG(Advanced RAG)

针对朴素 RAG 的弱点,工程上做了大量优化。常见手段包括:

  • 查询改写:用户问题太模糊时,先用 LLM 把问题改写得更清晰,甚至拆解成多个子问题再检索。
  • 混合检索:同时用稀疏检索(BM25,擅长关键词精确匹配)和稠密检索(向量相似度,擅长语义匹配),再融合结果。
  • 重排序(Rerank):第一轮召回 Top-50 候选片段,用一个重排序模型对结果精排,只把最相关的 Top-5 交给 LLM。

这部分是企业级 RAG 的主要工作区,后面我会再展开。

3.3 模块化 RAG

模块化 RAG 的思路是:把检索、记忆、路由、查询改写、重排、验证等能力设计成可自由组合的模块,按需组装。

例如,系统先判断用户问题属于“闲聊”还是“知识库问答”,再决定走对话流程还是检索流程。或者对复杂问题先拆解成子问题,分别检索,最后汇总。类似 LangChain 的 LCEL 表达式语言,就是用来组合这些模块的。

3.4 Agentic RAG

最前沿的方向是把 RAG 和 Agent(智能体)结合:模型不只是被动接收检索结果,而是能够自主决定“要不要检索”“检索几次”“查完还不确定要不要追问用户”,甚至调用多个工具交叉验证。

从材料中也能看到,Agentic RAG(智能体式 RAG)已经成为热点方向。它的工程复杂度明显更高,通常涉及规划、工具调用、记忆管理,适合问答场景复杂、需要多轮验证的落地项目。

对多数团队的判断:如果你刚开始做知识库问答,不要一上来就追 Agentic RAG。先把朴素 RAG 跑通,再用高级 RAG 的混合检索 + Rerank 提升准确率,最后按需求引入 Agent 能力。RAG 是一项系统工程,检索质量、提示词设计、评估体系都比架构名词重要。

4. 环境准备与依赖选型

动手之前,先把环境准备好。本文示例采用 Python 技术栈,因为这是目前 LLM 生态最成熟的语言。

4.1 基础环境

  • Python 3.10 或以上版本,建议 3.10/3.11,部分依赖对 3.12 的兼容仍不稳定。
  • pip 包管理工具。
  • 可以访问 Embedding 模型和 LLM 服务的网络环境。如果使用开源模型私有化部署,需要准备 GPU 或足够的 CPU 内存。具体版本请以实际项目为准,这里演示通用思路。

4.2 技术选型说明

下面这些库是当前 RAG 项目常见的组合:

组件用途推荐选型
框架编排 RAG 流程LangChain / LlamaIndex
文档加载解析 PDF、Word 等LangChain 内置 Loader / unstructured
文本切分处理超长文本LangChain Text Splitter
向量数据库存储和检索向量Chroma(轻量)/ FAISS(单机)/ Milvus(生产)
Embedding文本转向量OpenAI Embedding 或开源模型 BGE、M3E 等
LLM最终答案生成OpenAI、通义、智谱或本地部署模型

第一次实践建议用 Chroma 或 FAISS,两者都能在本地快速跑通,不需要额外启动服务。

4.3 安装依赖

创建一个虚拟环境,并安装以下依赖:

python -m venv rag_env source rag_env/bin/activate # Windows 下使用 rag_env\Scripts\activate pip install langchain langchain-community langchain-openai chromadb faiss-cpu pypdf

如果你需要使用 OpenAI 的模型,再安装openai

pip install openai tiktoken

国内开发者如果希望降低模型调用成本,也可以选择开源或国产 Embedding 模型和 LLM 服务,LangChain 对各家都有对接封装,接口思路是类似的。

5. 零基础完整示例:先跑通一个最小 RAG 系统

我建议采用“最小可用”原则:先不管各种高级优化,用不到 100 行代码,把“加载文档 -> 切分 -> 向量化 -> 检索 -> 生成”整条链路跑通。这样做有两个好处:

  1. 你能直观感受每个环节的存在意义。
  2. 后续所有优化,都是在这一条主链路上做增强。

5.1 示例代码实现

先创建一个项目目录:

mkdir rag_demo cd rag_demo mkdir docs

把你要测试的文档(PDF 或 txt)放到docs目录下。这里假设你有一份company_policy.txt

创建主程序文件rag_pipeline.py

# 文件路径:rag_demo/rag_pipeline.py import os from langchain_community.document_loaders import TextLoader from langchain.text_splitter import RecursiveCharacterTextSplitter from langchain_community.embeddings import OpenAIEmbeddings from langchain_community.vectorstores import Chroma from langchain_openai import ChatOpenAI from langchain.prompts import ChatPromptTemplate from langchain.schema import StrOutputParser from langchain.schema.runnable import RunnablePassthrough # 1. 加载文档 loader = TextLoader("docs/company_policy.txt", encoding="utf-8") documents = loader.load() # 2. 文本切分 text_splitter = RecursiveCharacterTextSplitter( chunk_size=500, chunk_overlap=50, separators=["\n\n", "\n", "。", "!", "?", " ", ""] ) chunks = text_splitter.split_documents(documents) print(f"切分完成,共 {len(chunks)} 个文本块") # 3. 向量化 embedding_model = OpenAIEmbeddings( model="text-embedding-ada-002", openai_api_key=os.environ.get("OPENAI_API_KEY") ) # 4. 存储到向量数据库 vector_store = Chroma.from_documents( documents=chunks, embedding=embedding_model, persist_directory="./chroma_db" ) vector_store.persist() print("文档向量化并存储完成") # 5. 构建检索器 retriever = vector_store.as_retriever(search_kwargs={"k": 4}) # 6. 定义 Prompt prompt = ChatPromptTemplate.from_template( """你是一名企业知识库助手。请根据以下参考片段回答问题。 如果参考片段中没有足够信息,请明确回答“知识库中没有找到相关信息”,不要编造。 参考片段: {context} 问题:{question} """ ) # 7. 初始化 LLM llm = ChatOpenAI( model="gpt-4o-mini", temperature=0, openai_api_key=os.environ.get("OPENAI_API_KEY") ) # 8. 组装 RAG 链路 def format_docs(docs): return "\n\n".join([d.page_content for d in docs]) rag_chain = ( {"context": retriever | format_docs, "question": RunnablePassthrough()} | prompt | llm | StrOutputParser() ) # 9. 测试问答 question = "公司请假流程是什么?" response = rag_chain.invoke(question) print("用户问题:", question) print("系统回答:", response)

这段代码把 RAG 主链路完整呈现出来了。我拆开解释几个关键点。

文本切分参数chunk_size=500, chunk_overlap=50的含义是:每个文本块约 500 个字符,相邻两个块之间有 50 个字符的重叠。重叠的目的是避免一句话恰好被拦腰切断,导致语义不完整。后面我会专门说这个参数怎么调。

retriever | format_docs使用了 LangChain 的 LCEL 表达式。它表示:先从向量库检索出相关文档,再用format_docs函数把文档列表拼成纯文本,作为 Prompt 中的{context}变量。

temperature=0很重要。知识库问答要求确定性,温度过高会让模型发挥太多,出现偏离原文的表述。知识类场景我一般直接设成 0。

5.2 运行命令

export OPENAI_API_KEY="你的 API Key" python rag_pipeline.py

Windows 下用:

$env:OPENAI_API_KEY="你的 API Key" python rag_pipeline.py

5.3 预期输出

正常运行时会看到类似输出:

切分完成,共 12 个文本块 文档向量化并存储完成 用户问题: 公司请假流程是什么? 系统回答: 根据公司制度,员工请假需提前一天提交请假申请,经部门负责人审批后生效。特殊情况需及时电话通知上级......

到这一步,你的第一套 RAG 系统已经跑通了。

5.4 如何自行验证效果

跑通代码只是第一步,你需要验证检索环节是否真的找对了文档。建议在正式问答之前,先把检索结果打印出来检查,增加一段调试代码:

# 文件路径:rag_demo/debug_retrieval.py import os from langchain_community.embeddings import OpenAIEmbeddings from langchain_community.vectorstores import Chroma embedding_model = OpenAIEmbeddings( model="text-embedding-ada-002", openai_api_key=os.environ.get("OPENAI_API_KEY") ) vector_store = Chroma( persist_directory="./chroma_db", embedding_function=embedding_model ) retriever = vector_store.as_retriever(search_kwargs={"k": 4}) docs = retriever.invoke("公司请假流程是什么?") for i, doc in enumerate(docs): print(f"--- 第 {i + 1} 个检索结果 ---") print(doc.page_content) print()

如果检索结果和问题主题不相关,那么不管 LLM 多强,答案也不会对。记住这条经验:RAG 系统的天花板在检索质量,LLM 只是把检索到的内容翻译成答案。排查问题先查检索。

6. 从“能跑”到“好用”:企业级 RAG 进阶实践

最小系统跑通后,真正的挑战才开始。企业级 RAG 和 Demo 级 RAG 的差距,主要体现在检索质量、评估体系、性能和成本控制几个维度。

6.1 检索质量优化:混合检索 + Rerank

纯向量检索有一个明显短板:它擅长语义匹配,但不擅长精确匹配。比如你搜产品型号“A100-X”,向量检索可能返回一堆关于“A100”的泛泛内容,而 BM25 这种基于关键词的检索能精确命中型号字符串。

企业级系统通常采用“混合检索 + 重排序”方案:

  1. 第一路:向量检索召回 Top-50。
  2. 第二路:BM25 关键词检索召回 Top-50。
  3. 合并两路结果,去重。
  4. 使用 Rerank 模型对候选片段逐一打分,取 Top-5 交给 LLM。

从相关热词中也能看到,rag多路召回embedding rerank都是 RAG 实战中的高频关键词,说明这正是工程里大家关心的重点。

LangChain 中可以通过EnsembleRetriever实现混合检索思路:

# 文件路径:rag_demo/hybrid_retriever.py from langchain.retrievers import EnsembleRetriever from langchain_community.retrievers import BM25Retriever from langchain_community.vectorstores import Chroma from langchain_community.embeddings import OpenAIEmbeddings from langchain_community.document_loaders import TextLoader from langchain.text_splitter import RecursiveCharacterTextSplitter loader = TextLoader("docs/company_policy.txt", encoding="utf-8") documents = loader.load() text_splitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=50) chunks = text_splitter.split_documents(documents) # 构建稠密检索器(向量) embedding_model = OpenAIEmbeddings(model="text-embedding-ada-002") vector_store = Chroma.from_documents(chunks, embedding_model) dense_retriever = vector_store.as_retriever(search_kwargs={"k": 50}) # 构建稀疏检索器(BM25) bm25_retriever = BM25Retriever.from_documents(chunks) bm25_retriever.k = 50 # 融合成混合检索器 ensemble_retriever = EnsembleRetriever( retrievers=[bm25_retriever, dense_retriever], weights=[0.3, 0.7] ) # 测试一次检索 query = "公司请假流程是什么?" docs = ensemble_retriever.invoke(query) for i, doc in enumerate(docs[:5]): print(f"Top {i + 1}: {doc.page_content[:100]}")

需要说明的是,实际生产项目中我更推荐将 Rerank 单独作为一层。Rerank 模型通常是一个交叉编码器,把“问题 + 候选片段”拼接后打分,效果比双塔向量相似度更精确,但计算成本更高,所以只用于精排阶段是合理的工程取舍。

6.2 RAG 效果评估:别靠感觉,用 RAGAS

很多团队在开发 RAG 系统时有个通病:问几个问题觉得“回答得还行”,就直接上线。结果用户一用,各种答非所问。原因很简单——你测试的 5 个问题覆盖不了真实用户的上百种问法。

RAG 需要像传统搜索系统一样建立评测集。业界常用的评估框架是 RAGAS(Retrieval-Augmented Generation Assessment),它从三个核心维度衡量系统质量:

  • 忠实度(Faithfulness):回答是否严格基于检索到的上下文,有没有凭空编造。
  • 答案相关性(Answer Relevance):回答是否切题,是否回答了用户的真实问题。
  • 上下文相关性(Context Relevance):检索回来的文本块是不是真的和问题相关。

评估时需要准备一组“问题 - 标准答案”的测试集。如果已经有标准答案,还可以计算答案与标准答案的相似度。RAGAS 的用法大致如下:

pip install ragas
# 文件路径:rag_demo/evaluate_rag.py from ragas import evaluate from ragas.metrics import faithfulness, answer_relevancy, context_precision, context_recall from datasets import Dataset # 准备评估数据,需要从RAG链路中获取对应输出 eval_data = { "question": ["公司请假流程是什么?"], "answer": ["根据制度,员工需提前一天提交请假申请..."], "contexts": [["根据公司制度,员工请假需提前一天提交请假申请..."]], "ground_truth": ["员工提前一天提交申请,经部门负责人审批后生效。"] } dataset = Dataset.from_dict(eval_data) result = evaluate( dataset, metrics=[faithfulness, answer_relevancy, context_precision, context_recall] ) print(result)

建议把评估集成到代码发布流程中。每次修改切分策略、Embedding 模型或 Prompt 模板后,都要在固定评测集上跑一遍,对比指标变化,用数据而不是感觉来决定是否上线。

6.3 知识更新与索引管理

企业知识库是动态变化的,文档会新增、修改、删除。很多初版 RAG 项目会踩一个坑:向量库里存了旧数据,文档更新后没重建索引,导致答案还是旧的。

生产环境需要明确索引策略:

  • 小规模知识库(几百个文档以内):可以定期全量重建索引,简单可靠。
  • 大规模知识库:需要增量更新。新增文档直接写入向量库;修改文档时要先按文档 ID 删除旧向量,再写入新向量;删除文档时同步删除对应向量。

文档 ID 的规范尤其重要。推荐使用“来源文件路径 + 切分序号”作为向量记录的元数据,方便追溯和定向删除:

# 示意:为每个Chunk添加元数据 for idx, chunk in enumerate(chunks): chunk.metadata["doc_id"] = f"{chunk.metadata['source']}#{idx}"

6.4 安全与权限管理

RAG 系统直接面向企业知识内容,权限问题不能忽视。如果你的用户分为普通员工和管理层,不同级别可访问的文档不同,那么必须在检索阶段就做权限过滤,而不是在生成阶段靠提示词控制。否则,LLM 一旦检索到敏感内容,用户通过追问就可能套出越权信息。

实现上,可以在文档元数据中标记可见范围,检索时拼接过滤条件:

# 示意:按权限过滤检索结果 from langchain.schema import Document # 元数据示例:access_level = "admin" 或 "employee" filtered_docs = [d for d in docs if d.metadata.get("access_level", "employee") in user_roles]

从合规角度看,涉及用户个人数据、敏感商业信息时,建议在 RAG 上层再叠加审计模块,记录每个用户查询过哪些内容、模型返回了什么。这一点在政务、金融等合规要求高的 RAG 项目中尤其重要,相关材料中也能看到政务 RAG 知识库项目的实例。

6.5 成本控制与响应延迟

企业上线 RAG,逃不过两个指标:成本和延迟。

  • Embedding 调用次数:每次文档更新都要重新向量化,文档量大时会消耗大量 API 费用或 GPU 时间。可以引入缓存机制,对文本内容求哈希,一模一样的内容不重复计算向量。
  • 提示词长度:检索到的 Chunk 数量越多,Prompt 越长,Token 费用越高。实际项目中我一般控制 3 到 5 个 Chunk,单个 Chunk 500 字符左右,既能保证覆盖面,又不会让 Prompt 过长。
  • 缓存高频问题:相似的问题可以缓存答案,设置按天过期。这能显著降低 LLM 调用量,尤其适合问法相对固定的企业场景。

7. 常见问题与排查方法

我把 RAG 项目中最常遇到的几个问题整理成一张排查表。出现异常时,先看现象,再定位原因。

问题现象可能原因排查方式解决方案
答案明显与文档内容不符检索到的 Chunk 不相关打印检索结果,检查 Top-K 命中内容优化切分策略,引入混合检索或 Rerank
回答仍然在编造检索结果不足以支撑答案,或 Prompt 约束不足检查上下文片段是否完整覆盖问题要点在 Prompt 中明确要求“无信息时如实说明”;增加检索 Chunk 数
检索返回结果太少Chunk 切分过大,向量粒度太粗查看 Chunk 数量和各块长度分布调小 chunk_size,增加 chunk_overlap
检索结果语义接近但关键词不精确纯向量检索无法匹配精确词尝试查询“A100-X”这类型号或编号增加 BM25 稀疏检索做混合召回
文档更新后答案仍是旧内容向量库没有重建或增量更新检查向量库中记录的文档时间戳建立索引更新机制,文档变更后重建对应向量
Embedding 消耗费用过高每次启动都全量向量化检查代码是否重复创建向量库使用持久化向量库,并做文本内容哈希缓存
中文文档切出乱码或错词编码问题或切分器不识别中文标点检查原始文件编码统一保存为 UTF-8;切分器增加中文标点分隔符
LLM 返回内容过长或格式不符合预期没有在 Prompt 中约束输出格式检查 Prompt 模板增加“请用简洁段落回答”“输出 Markdown 列表”等约束

排错时的第一原则是“分层定位”:先确认检索层是否输出正确,再检查 LLM 层的生成是否忠实。不要一上来就去调 Prompt,你连模型拿到的原材料对不对都还没确认。

8. 企业级 RAG 工程落地最佳实践

不同团队做 RAG 的差异,往往不在算法理解,而在工程方法。下面这组建议来自实际项目沉淀,可以帮你少走弯路。

8.1 从业务问题出发选架构

很多项目失败的原因是技术选型脱离业务。先搞清楚你的知识库是什么形态:

  • 纯文本制度文档,问题相对固定,朴素 RAG 就够。
  • 文档格式复杂,包含大量表格、图片,需要先做版面解析,再做 RAG。
  • 问题复杂,经常需要多步推理,才需要考虑 Agentic RAG。

不要为了用新框架而用新框架。RAG 的成功标准是“用户能快速找到准确答案”,不是“我们的架构足够酷”。

8.2 对文档做预处理,而不是直接切块

原始 PDF 直接切块,效果一般不会好。企业文档常见问题包括:PDF 里有页眉页脚、表格被拆散、扫描件没有文本层。

建议在进入 RAG 链路之前,先做一轮文档清洗:

  • 去除页眉页脚、页码、水印文字。
  • 对表格做结构化解析,行和列保持对应关系。
  • 扫描件先做 OCR。
  • Markdown 格式的文档优先保留标题层级,切分时可以按标题切,保持语义完整。

这一步看似繁琐,却对最终效果有决定性影响。检索质量差,很多时候不是模型不行,是原始文档压根没解析好。

8.3 切分策略要按文档类型调整

没有万能切分参数。长文本和短文本、制度文档和技术手册,最优参数都不一样。

我的经验是:

  • 制度类文档,按章节语义切块,chunk_size=500左右比较稳妥。
  • 技术手册类,按 Markdown 标题层级切块,优先保证每个 Chunk 内容完整。
  • 对话记录或问答对,尽量保持一问一答一个 Chunk,不要拆散。

调参时围绕三个指标:检索命中率、答案忠实度、用户满意度。前两个可以通过评测集量化,最后一个是长期观察指标。

8.4 Prompt 模板要提前设计可复用结构

在实际项目中,Prompt 通常会被多个系统复用,建议把 Prompt 模板做成独立配置,不要散落在代码里。

一个生产级 RAG Prompt 至少应该包含:

  • 角色定位:你是企业知识库助手。
  • 任务说明:根据参考片段回答用户问题。
  • 语气与格式要求:简洁、专业、列表输出等。
  • 边界与兜底:信息不足时明确说明,不要编造。
  • 可溯源要求:列出引用的文档或片段来源。
你是一名企业知识库助手。请根据参考片段回答问题。 要求: 1. 优先使用参考片段中的信息,语言精练。 2. 如果参考片段信息不足,回复:“知识库中没有找到相关信息。” 3. 在回复末尾列出引用的文档来源编号。 参考片段: {context} 问题: {question} 来源列表: {source_info}

8.5 建立评测集和回归机制

这一点我会反复强调:RAG 上线后,效果只会随着文档更新、模型升级而漂移。没有评测集,就没有质量回归机制。

建议按业务场景整理 50 到 100 个高频问题作为评测集,覆盖:

  • 直接命中的简单问题。
  • 需要多片段拼装的复杂问题。
  • 知识库中不存在信息的越界问题。

每次改动系统后跑一遍评测集,把三个 RAGAS 指标记录下来。指标下降就回滚,指标上升再继续。

9. 从 RAG 到 Agentic RAG:值得关注的未来方向

文章最后谈一下方向问题。在我写这篇文章时,RAG 的下一个热点是 Agentic RAG,也就是把 RAG 从“一次检索、一次生成”的流水线,升级成“模型自主决定检索策略”的智能体。

典型场景是:用户问了一个复杂问题,比如“对比今年和去年公司营收变化原因”,普通 RAG 只会检索一次,很可能漏掉关键数据。而 Agentic RAG 中的模型可以自己规划:

  1. 先检索今年营收数据。
  2. 识别数据有变化,再检索原因分析文档。
  3. 如果两个来源存在矛盾,再检索第三条资料交叉验证。
  4. 最后组织成回答。

这种模式适合复杂问答、多步推理、需要工具调用的场景。但它对模型能力要求更高,同时需要考虑规划失败时的兜底策略、工具调用的异常处理、成本控制等问题。

对于大多数刚开始接触 RAG 的开发者,我的建议是:先把手动流程跑熟,再用 LangGraph 等框架逐步引入 Agent 能力。不要跳过基础阶段直接上 Agentic RAG,否则你会被调试复杂度淹没。

10. 最后一个建议:从最小项目开始

如果你看完文章准备动手,我给的建议非常简单:不要一开始就追求企业级完美架构,而是先用 30 分钟跑通最小 RAG,再逐步添加混合检索、Rerank、评测、权限、缓存。

RAG 的学习曲线不算陡峭,但坑位很多。先把主链路跑通,你就能在后续每个优化点上做对比实验,真正理解每一步改动带来的效果变化。这和所有工程实践的规律一致:先把地基夯实,再盖高楼。带着你手头的文档,从安装依赖开始,跑通第一条链路,你就能感受到 RAG 从概念变成工具的过程。

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

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

立即咨询