《实用笔记:RAG系统——从零到精通的完整指南(2026版)》
《实用笔记:RAG系统——从零到精通的完整指南(2026版)》的操作流程详解:适用于采用该架构的团队的合同、检查项及可直接插入的代码模块。
本指南将逐步演示如何从原始材料构建出《RAG系统:完整的零到精通指南(2026版)》中的可用系统。重点在于可操作的步骤、明确的检查点,以及可直接放入代码库的代码,无需猜测其用途。 在概览阶段,应在修改代码之前明确输入参数、各步骤的负责人以及完成标准。操作人员应能够从已知的检查点重新运行相应步骤,而无需推测隐藏状态。 除了功能结果外,还需记录执行时间以及令牌或查询成本。提前了解成本情况,可避免在系统从演示环境过渡到共享环境时出现意外费用。
引发变革的问题
在处理“问题起源”阶段时,首先写下相关契约:所需的输入参数、成功标志以及部分失败时的处理方式。这样的检查清单能确保后续的代码修改保持一致性。 将配置信息与应用程序代码分开存放。环境文件、密钥存储以及功能开关应集中于一个位置,这样操作人员无需查看整个系统结构即可进行审计。 在调整提示词之前,先使用固定的问题集来测试召回率。仅仅更换提示词往往无法解决检索效果不佳的问题。
什么是RAG?(先了解直观概念)
在完成“什么是RAG”这一阶段时,首先需列出相关规范:所需输入、成功标志以及部分失败时的处理方式。这样的检查清单能确保后续的代码修改保持一致性。 同时记录正常流程与异常恢复流程。重试机制、人工审核环节以及错误消息处理都是产品本身的组成部分,而非后续需要补充的功能。 在调整提示词之前,先使用固定的问题集来衡量召回率。仅仅更换提示词很难解决检索效果不佳的问题。
为何仅靠大语言模型行不通
在完成“为何仅靠大语言模型会失败”这一阶段时,首先需明确规范:所需的输入、成功标志以及部分失败时的处理方式。这样的清单能确保后续的代码修改保持一致性。 建议使用小型、可测试的单元,而非庞大的脚本。当某个步骤失败时,故障应指向单一责任点,而非复杂的流程链。 缓存稳定的系统指令和工具结构。重复发送相同的开头信息是导致资源浪费的常见原因。 在完成“为何仅靠大语言模型会失败”这一阶段时,首先需明确规范:所需的输入、成功标志以及部分失败时的处理方式。这样的清单能确保后续的代码修改保持一致性。 在功能结果旁记录执行时间以及token或查询成本。提前了解成本情况,可避免从演示环境过渡到共享环境时出现意外账单。
RAG流程概览
将该阶段的RAG流程视为可度量的对象时,其效果最佳。在扩大范围之前,先记录一份理想的转录文本、一个失败案例以及回滚说明。 将配置与应用程序代码分开。环境文件、密钥存储和功能标志应集中存放于一处,以便操作人员无需查看整个系统结构即可进行审计。 将分块策略与检索策略分开。当质量指标发生变化时,修改其中一项不应强制要求重新编写另一项。
User Query
│
▼
┌──────────────────┐
│ Retriever │ ← Hybrid search (vector + BM25) + reranking
│ (Vector DB) │
└────────┬─────────┘
│ Top-K relevant chunks (reranked)
▼
┌──────────────────┐
│ Augmenter │ ← Inject chunks into the LLM prompt
│ (Prompt Builder)│
└────────┬─────────┘
│ Augmented prompt
▼
┌──────────────────┐
│ Generator │ ← LLM reads context, generates answer
│ (LLM) │
└────────┬─────────┘
│
▼
Final Answer (with citations)
工作原理:技术深度解析
工作原理:将该阶段视为可测量的表面时,其效果最佳。在扩大范围之前,先记录一个成功的处理案例、一个失败案例以及回滚说明。同时记录正常流程和恢复流程。重试机制、人工审核环节以及死信处理都是产品本身的一部分,而非后续需要补充的内容。应将分块策略与检索策略分开,当质量指标发生变化时,修改其中一项不应迫使重新编写另一项。
第一阶段:记录数据摄取与分块
将第一阶段文档摄取过程视为可度量的工作面,效果最佳。在扩大范围之前,先记录一份理想的处理结果、一个故障案例以及回滚说明。 相较于庞大的脚本,应优先选择小型且可测试的单元。当某一步骤出现故障时,故障原因应能明确指向某个特定责任方,而非复杂的流程链。 应将分块策略与检索策略分开。当质量指标发生变化时,修改其中一项不应迫使重新编写另一项。 将第一阶段文档摄取过程视为可度量的工作面,效果最佳。在扩大范围之前,先记录一份理想的处理结果、一个故障案例以及回滚说明。 除了功能结果外,还需记录处理时间以及令牌或查询成本。提前了解成本情况,可避免在从演示环境过渡到共享环境时出现意外费用。
第二阶段:模型嵌入与向量数据库
在第二阶段嵌入模型阶段,应在修改代码之前明确输入参数、该步骤的负责人以及终止标准。操作人员应能够从已知的检查点重新运行该步骤,而无需猜测隐藏状态。 配置信息应置于应用程序代码之外。环境文件、密钥存储以及功能标志应集中存放于一个位置,以便操作人员无需查看整个流程即可进行审计。 当下一步为代码执行或工具调用时,优先使用具有架构验证的结构化输出,而非自由形式的文本。
第三阶段:混合搜索——2026年的标准
在第三阶段的混合搜索环节中,修改代码之前需明确输入参数、该步骤的负责人以及终止标准。操作人员应能够从已知的检查点重新运行该步骤,而无需猜测隐藏状态。 需同时记录正常流程与异常恢复流程。重试机制、人工审核环节以及错误处理都是产品本身的组成部分,而非后续需要补充的功能。 必须引用那些真正作为答案依据的段落。如果没有引用,操作人员就无法区分是幻觉内容还是索引缺失导致的错误。
Hybrid Score = RRF(vector_rank, BM25_rank)
def reciprocal_rank_fusion(vector_results, bm25_results, k=60):
scores = {}
for rank, doc in enumerate(vector_results):
scores[doc.id] = scores.get(doc.id, 0) + 1/(rank + k)
for rank, doc in enumerate(bm25_results):
scores[doc.id] = scores.get(doc.id, 0) + 1/(rank + k)
return sorted(scores.items(), key=lambda x: x[1], reverse=True)
第四阶段:重排序——至关重要的缺失环节
在第四阶段的重排序环节中,修改代码之前需明确输入参数、该步骤的负责人以及终止标准。操作人员应能够从已知的检查点重新运行该步骤,而无需猜测隐藏状态。 相较于冗长的脚本,更应采用小型且可测试的单元。当某一步骤失败时,故障原因应能指向单一责任主体,而非复杂的流程链。 需引用实际作为答案依据的段落。没有引用的话,操作人员就无法区分是幻觉内容还是索引缺失导致的错误。 在第四阶段的重排序环节中,修改代码之前需明确输入参数、该步骤的负责人以及终止标准。操作人员应能够从已知的检查点重新运行该步骤,而无需猜测隐藏状态。 除了功能结果外,还需记录执行时间以及令牌或查询成本。提前了解成本情况,可避免在从演示环境过渡到共享环境时出现意外费用。
/p>from sentence_transformers import CrossEncoder
reranker = CrossEncoder("cross-encoder/ms-marco-MiniLM-L-6-v2")def rerank(query, retrieved_chunks, top_n=5):
pairs = [(query, chunk.text) for chunk in retrieved_chunks]
scores = reranker.predict(pairs)
ranked = sorted(zip(retrieved_chunks, scores),
key=lambda x: x[1], reverse=True)
return [chunk for chunk, _ in ranked[:top_n]]
第5阶段:提示词增强与生成
在处理第5阶段的提示词增强任务时,首先需明确相关约定:所需输入、成功标志以及部分失败时的处理方式。这样的检查清单能确保后续的代码修改保持一致性。 应将配置信息置于应用程序代码之外。环境文件、密钥存储以及功能开关应集中存放于一个位置,以便操作人员无需查看整个系统结构即可进行审计。 需缓存稳定的系统指令和工具架构。重复发送相同的开头信息是导致资源浪费的常见原因。
from langchain_openai import ChatOpenAI
from langchain.chains import RetrievalQA
from langchain.prompts import PromptTemplate
PROMPT = PromptTemplate(
input_variables=["context", "question"],
template="""You are a precise assistant. Answer using ONLY the context below.
If the answer isn't present, respond: "I don't have enough information."CONTEXT:
{context}QUESTION: {question}ANSWER:"""
)llm = ChatOpenAI(model="gpt-4o", temperature=0)
qa_chain = RetrievalQA.from_chain_type(
llm=llm,
retriever=hybrid_retriever, # your hybrid + rerank retriever
chain_type_kwargs={"prompt": PROMPT},
return_source_documents=True
)result = qa_chain.invoke({"query": "What are the refund policy terms?"})
print(result["result"])
print("Sources:", [d.metadata["source"] for d in result["source_documents"]])
从零构建生产级RAG系统
在完成“构建生产级 RAG 系统”这一阶段时,首先需明确相关约定:所需的输入参数、成功标志,以及部分失败时的处理方式。这样的检查清单能确保后续的代码修改始终符合初始设计。
步骤 1:安装依赖项
在执行“步骤1:安装依赖项”阶段时,首先需明确相关约定:所需的输入参数、成功标志,以及部分失败时的处理方式。这样的检查清单能确保后续的代码修改保持一致性。 建议使用小型、可测试的单元,而非冗长的脚本。当某个步骤失败时,故障应指向单一责任模块,而非复杂的流程链。 在调整提示词之前,先使用固定的问题集来测试召回率。仅仅更换提示词往往无法解决检索效果不佳的问题。
pip install langchain langchain-openai langchain-chroma \
chromadb pypdf sentence-transformers rank-bm25
步骤2:数据摄取、分块与索引构建
在处理第二步“数据摄取分块”阶段时,首先需明确相关约定:所需的输入参数、成功标志,以及部分失败时的处理方式。这样的清单能确保后续的代码修改始终符合约定。 将此阶段视为输入与验证后输出之间的契约。为相关成果命名,定义成功判定标准,杜绝无声的半完成状态。 在调整提示词之前,需先用固定的问题集来衡量检索覆盖率。仅仅更换提示词往往无法改善较差的检索效果。
from langchain_community.document_loaders import PyPDFDirectoryLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_openai import OpenAIEmbeddings
from langchain_chroma import Chroma
loader = PyPDFDirectoryLoader("./docs/")
raw_docs = loader.load()splitter = RecursiveCharacterTextSplitter(
chunk_size=512, chunk_overlap=64
)
chunks = splitter.split_documents(raw_docs)embeddings = OpenAIEmbeddings(model="text-embedding-3-large")
vectorstore = Chroma.from_documents(
documents=chunks,
embedding=embeddings,
persist_directory="./chroma_db"
)
print(f"✅ Indexed {len(chunks)} chunks.")
第三步:带有重新排序功能的混合检索器
在处理第三步的混合检索阶段时,首先写下相关约定:所需的输入参数、成功信号以及部分失败时的处理方式。这样的清单能确保后续的代码修改保持一致性。 在功能结果旁记录执行时间以及令牌或查询成本。提前了解成本情况,可避免在从演示环境过渡到共享环境时出现意外费用。 在调整提示词之前,先使用固定的问题集来测试召回率。仅仅更换提示词很难改善较差的检索效果。
from langchain_community.retrievers import BM25Retriever
from langchain.retrievers import EnsembleRetriever
from sentence_transformers import CrossEncoder
# Vector retriever
vector_retriever = vectorstore.as_retriever(search_kwargs={"k": 20})# BM25 sparse retriever
bm25_retriever = BM25Retriever.from_documents(chunks)
bm25_retriever.k = 20# Hybrid: RRF fusion
hybrid_retriever = EnsembleRetriever(
retrievers=[bm25_retriever, vector_retriever],
weights=[0.5, 0.5]
)# Reranker
reranker = CrossEncoder("cross-encoder/ms-marco-MiniLM-L-6-v2")def retrieve_and_rerank(query, top_n=5):
candidates = hybrid_retriever.invoke(query)
pairs = [(query, doc.page_content) for doc in candidates]
scores = reranker.predict(pairs)
ranked = sorted(zip(candidates, scores),
key=lambda x: x[1], reverse=True)
return [doc for doc, _ in ranked[:top_n]]
高级RAG:2026年的前沿技术
在处理“高级 RAG 2026 版”阶段时,首先列出相关约定:所需输入、成功标志以及部分失败时的处理方式。这样的检查清单能确保后续的代码修改保持一致性。 将配置信息置于应用程序代码之外。环境文件、密钥存储和功能开关应集中存放,以便操作人员无需查看整个系统结构即可进行审计。 在调整提示词之前,先使用固定的问题集来测试召回率。仅仅更换提示词很难解决检索效果不佳的问题。
代理型 RAG —— 2026 年的主流模式
在处理 Agentic RAG 的 The Dominant 阶段时,首先写下相关契约:所需输入、成功标志以及部分失败时的处理方式。这样的清单能确保后续的代码修改保持一致性。 同时记录正常流程和异常恢复流程。重试机制、人工审核环节以及死信处理都是产品本身的组成部分,而非后续的优化工作。 在调整提示词之前,先使用固定的问题集来衡量召回率。仅仅更换提示词很难解决检索效果不佳的问题。
# LangGraph agentic RAG loop (simplified)
from langgraph.graph import StateGraph
def should_retrieve(state):
# Model decides: do I need more context?
return "retrieve" if state["confidence"] < 0.8 else "generate"def retrieve_node(state):
results = retrieve_and_rerank(state["query"])
return {**state, "context": results, "iterations": state["iterations"]+1}def generate_node(state):
answer = llm.invoke(build_prompt(state["context"], state["query"]))
return {**state, "answer": answer}graph = StateGraph(AgentState)
graph.add_node("retrieve", retrieve_node)
graph.add_node("generate", generate_node)
graph.add_conditional_edges("retrieve", should_retrieve)
RAFT — 基于检索的微调技术
在进行RAFT检索增强微调阶段时,首先需明确相关规范:所需输入、成功标志以及部分失败时的处理方式。这样的清单能确保后续的代码修改保持一致性。 优先选择小型、可测试的单元,而非庞大的脚本。当某个步骤出现故障时,故障应指向单一责任点,而非复杂的流程链。 在调整提示词之前,先使用固定的问题集来衡量召回率。仅仅更换提示词很难改善较差的检索效果。 在进行RAFT检索增强微调阶段时,首先需明确相关规范:所需输入、成功标志以及部分失败时的处理方式。这样的清单能确保后续的代码修改保持一致性。 在功能结果之外,还需记录执行时间以及token或查询成本。提前了解成本情况,可避免在从演示环境过渡到共享环境时出现意外费用。
GraphRAG——现已可投入生产使用
当将 GraphRAG 的“现已可投入生产使用”阶段视为一个可度量的系统时,其效果最佳。在扩大应用范围之前,需记录一份最佳处理方案、一个故障案例以及回滚说明。 配置应与应用程序代码分开存放。环境文件、密钥存储和功能开关应集中管理,以便操作人员无需查看整个系统结构即可进行审计。 分块策略与检索策略应相互独立。当质量指标发生变化时,修改其中一项不应强制要求重新编写另一项。
pip install graphrag
graphrag init --root ./my_project
graphrag index --root ./my_project
graphrag query --root ./my_project --method global \
"What are the relationships between our key clients and regulatory changes?"
具备访问权限感知功能的 RAG——企业级应用的必备条件
在“企业级”阶段的访问感知型RAG系统中,将其视为可度量的对象才能发挥最佳效果。在扩大应用范围之前,先记录一份理想的处理流程、一个失败案例以及回滚说明。同时文档化正常流程与恢复流程,重试机制、人工审核环节以及死信处理都属于产品本身的功能,而非后续需要补充的内容。应将分块策略与检索策略分开,当质量指标发生变化时,修改其中一项不应强制要求重新编写另一项。
大规模应用下的混合检索与神经网络重排序
将混合检索神经重排阶段视为可度量的对象时,其效果最佳。在扩大范围之前,先记录一个理想案例、一个失败案例以及回滚说明。 优先选择小型且可测试的单元,而非庞大的脚本。当某一步骤失败时,故障应指向单一责任主体,而非复杂的流程链。 将分块策略与检索策略分开。当质量指标发生变化时,修改其中一项不应迫使重新编写另一项。 将混合检索神经重排阶段视为可度量的对象时,其效果最佳。在扩大范围之前,先记录一个理想案例、一个失败案例以及回滚说明。 除了功能结果外,还需记录处理时间以及令牌或查询成本。提前了解成本情况,可避免在从演示环境过渡到共享环境时出现意外费用。
Query → Metadata filter (narrow the space)
→ Parallel hybrid search (BM25 + dense ANN, top-50–500 each)
→ RRF fusion
→ Cross-encoder reranker (top-5 to top-10)
→ LLM generation with citations
经过强化学习优化的检索(R3)
对于经过强化学习优化的检索R3阶段,在修改代码之前需明确输入参数、该步骤的负责人以及终止标准。操作人员应能够从已知的检查点重新运行该步骤,而无需猜测隐藏状态。 配置信息应置于应用程序代码之外。环境文件、密钥存储以及功能标志应集中存放于一个位置,以便操作人员无需查看整个系统结构即可进行审核。 需注明实际作为答案依据的段落。若没有引用,操作人员就无法区分幻觉内容与索引缺失导致的错误。
多模态RAG——图像、表格、视频
在多模态RAG图像表格处理阶段,修改代码之前需明确输入内容、该步骤的负责人以及终止标准。操作人员应能够从已知的检查点重新运行该步骤,而无需猜测隐藏状态。 需同时记录正常流程与异常恢复流程。重试机制、人工审核环节以及错误处理都是产品本身的组成部分,而非后续需要补充的功能。 必须注明实际用于支撑答案的原文段落。若没有引用依据,操作人员就无法区分幻觉内容与索引缺失问题。
RAG即服务与LLMOps集成
在 RAG as a Service 阶段,修改代码之前需明确输入参数、该步骤的负责人以及终止标准。操作人员应能够从已知的检查点重新运行该步骤,而无需猜测其中的隐藏状态。 相较于冗长的脚本,更应采用小型、可测试的单元。当某个步骤失败时,故障原因应能明确指向单一责任方,而非复杂的流程问题。 如果后续步骤是代码调用或工具调用,应优先使用具有结构化格式且经过模式验证的输出,而非自由形式的文字描述。 在 RAG as a Service 阶段,修改代码之前需明确输入参数、该步骤的负责人以及终止标准。操作人员应能够从已知的检查点重新运行该步骤,而无需猜测其中的隐藏状态。 除了功能结果外,还需记录执行时间以及令牌或查询成本。提前了解成本情况,可避免在从演示环境过渡到共享环境时出现意外账单。
RAG的优势
在分析RAG的优势时,首先列出相关规范:所需输入、成功标志以及部分失败时的处理方式。这样的清单能确保后续的代码修改保持一致性。 将配置信息与应用程序代码分开存放。环境文件、密钥存储以及功能开关应集中管理,这样操作人员无需查看整个系统结构即可进行审计。 在调整提示词之前,先使用固定的问题集来测试召回率。仅仅更换提示词往往无法解决检索效果不佳的问题。
劣势与局限性(需如实说明)
在处理“缺点、限制与诚实面对”这一阶段时,首先写下合同条款:所需的输入参数、成功标志以及部分失败时的处理方式。这样的清单能确保后续的代码修改保持透明可溯。 同时记录正常流程与故障恢复路径。重试机制、人工审核环节以及死信处理都是产品本身的组成部分,而非后续的优化工作。 在调整提示词之前,先使用固定的问题集来衡量检索效果。仅仅更换提示词很难解决检索能力薄弱的问题。
当前RAG的应用场景
在处理“RAG的适用场景”这一阶段时,首先需明确相关规范:所需的输入参数、成功标志以及部分失败时的处理方式。这样的清单能确保后续的代码修改始终符合预期。 相比冗长的脚本,应优先选择小型且可测试的单元。当某个步骤出现故障时,故障点应指向单一责任模块,而非复杂的流程链。 在调整提示词之前,需先使用固定的问题集来测试召回率。仅仅更换提示词往往无法解决检索效果不佳的问题。 在处理“RAG的适用场景”这一阶段时,首先需明确相关规范:所需的输入参数、成功标志以及部分失败时的处理方式。这样的清单能确保后续的代码修改始终符合预期。 除了功能结果外,还需记录执行时间以及token或查询成本。提前了解成本情况,可避免在从演示环境过渡到共享环境时出现意外费用。
RAG与微调、RAFT及提示工程对比
将RAG、微调与RAFT等技术视为可度量的指标体系时,效果最佳。在扩大应用范围之前,需记录一份理想的运行案例、一个失败案例以及回滚说明。 配置信息应置于应用代码之外。环境文件、密钥存储和功能开关应集中管理,以便操作人员无需查看整个系统结构即可进行审核。 为每轮对话和每次会话设定Token预算。智能工具往往会大量消耗上下文资源,设置上限可避免演示过程出现意外的费用支出。
RAG的未来
RAG阶段的未来发展在被视为可度量的对象时效果最佳。在扩大范围之前,先记录一个成功的案例、一个失败案例以及回滚说明。同时将正常流程与恢复流程都记录下来。重试机制、人工审核环节以及错误处理都属于产品本身的组成部分,而非后续需要补充的内容。应将分块策略与检索策略分开处理;当质量指标发生变化时,修改其中一项不应迫使另一项也必须重新编写。
结论
将“结论阶段”视为可度量的对象来处理效果最佳。在扩大范围之前,需记录一份理想的输出样本、一个故障案例以及回滚说明。 优先选择小型且可测试的单元,而非庞大的脚本。当某一步骤出现故障时,故障应指向单一责任模块,而非复杂的流程链。 将分块策略与检索策略分开。当质量指标发生变化时,修改其中一项不应迫使重新编写另一项。 将“结论阶段”视为可度量的对象来处理效果最佳。在扩大范围之前,需记录一份理想的输出样本、一个故障案例以及回滚说明。 除了功能结果外,还需记录执行时间以及令牌或查询成本。提前了解成本情况,可避免在从演示环境过渡到共享环境时出现意外费用。
操作检查清单
将操作检查清单阶段视为可衡量的工作面,效果最佳。在扩大范围之前,先记录一份完美的测试用例、一个故障案例以及回滚说明。
把这一阶段视为输入与已验证输出之间的契约。为相关文档命名,明确成功标准,绝不允许出现悄无声息的半完成状态。
将分块策略与检索策略分开。当质量指标发生变化时,修改其中一项不应强制要求重新编写另一项。
在预算允许的情况下,使用测试环境而非真实的付费 API,在持续集成过程中添加能够检测关键路径的冒烟测试。
在功能结果旁记录执行时间以及令牌或查询成本。提前了解成本情况,可避免在从演示环境过渡到共享环境时出现意外账单。
应将分块策略与检索策略分开。当质量指标发生变化时,修改其中一项不应强制重新编写另一项。
在升级该技术栈之前,先冻结版本,为关键流程保存标准转录文本,并明确回滚步骤。共享环境需要设置速率限制、租户验证机制,以及明确的密钥轮换负责人。与其追求花哨的一次性演示,不如注重扎实的可靠性。
a92d0a529925的批注:不要将提供商密钥放入代码仓库,为每个会话设置令牌上限,并将转录文本与评估用文件存放在同一位置,以便后续模型更换时保持可比性。