开场:为什么需要 RAG
大型语言模型擅长生成,但它们的知识来自训练数据,存在时效性与覆盖面边界。RAG(Retrieval-Augmented Generation)把“检索”与“生成”结合起来:先检索外部知识,再让模型在可控的上下文内回答,从而把模型从“记忆”转向“检索+推理”。这也是 LangChain 文档中问答用例的核心思想。
一、RAG 的双引擎:检索与生成
RAG 的核心可以理解为两条主线:
- 检索主线:把问题转成向量或关键词,在外部知识库里找相关证据。
- 生成主线:把检索结果组织成上下文,让模型基于证据作答。
只有这两条主线都工作正常,RAG 才能提升可靠性。检索错了,生成再强也只是“基于错误证据的流畅回答”。
二、入库阶段:让知识可被检索
RAG 的第一步是“可检索化”,它通常包括:
- 资料收集与清洗:去重、去噪、统一编码;
- 切分与分块:将长文档切成可检索的片段,必要时保留重叠;
- 向量化:把每个片段转成 embedding;
- 索引与元数据:写入向量库并记录来源、时间、权限等元数据。
分块是高频设计点:片段太长会导致召回“笼统”,太短又容易丢上下文。实际工程中通常需要针对业务语料做反复实验。
三、查询阶段:从问题到答案的路径
查询阶段可以拆成“检索 -> 组织 -> 生成”三步:
- 检索:把用户问题转成向量,通过 top-k 召回相关片段;
- 组织:根据长度预算与重要性选择片段,生成上下文;
- 生成:将上下文与问题拼接成提示词,让模型回答。
LangChain 的问答用例正是围绕这一流程构建:通过 retriever 取回相关文档,再把文档与问题一起交给 LLM 生成答案。它强调“把检索结果显式提供给模型”,以降低幻觉。
四、LangChain QA 的落地思路
LangChain 文档给出的路径是:
- 构建一个 retriever(比如向量库的检索器);
- 定义一个 prompt,把检索到的文档作为上下文;
- 用 LLM 生成最终回答。
伪代码可以简化为:
# 1) 创建检索器
retriever = vectorstore.as_retriever(search_kwargs={"k": 4})
# 2) 取回相关文档
docs = retriever.get_relevant_documents(question)
# 3) 组织上下文并生成
context = "\n\n".join([d.page_content for d in docs])
answer = llm.invoke(prompt_template.format(context=context, question=question))
这个流程看似简单,但“检索质量”和“上下文组织”往往决定最终质量。
五、关键设计点:从参数到策略
- top-k 选择:k 太小会漏掉关键证据,太大则浪费上下文窗口。
- 分块大小与重叠:大块保留语义,小块提高精度;重叠可减少切分断裂。
- 重排序与过滤:仅靠向量检索容易带入噪音,必要时加入 reranker 或元数据过滤。
- 混合检索:在某些场景,关键词检索与向量检索结合效果更稳定。
这些都是“需要业务数据验证”的参数,而非一次性固定。
六、提示词与上下文组织
RAG 的生成效果很大程度上取决于提示策略:
- 明确告诉模型“只基于上下文作答”;
- 把上下文结构化(标题、来源、时间);
- 对引用做标注,便于溯源。
如果上下文组织不好,即使检索到了正确证据,也可能被模型忽略。
七、评估与监控:让 RAG 可持续优化
有效的 RAG 需要持续评估:
- 检索层指标:召回率、命中率、top-k 覆盖;
- 生成层指标:答案正确性、可追溯性;
- 线上指标:点击率、人工反馈、纠错率。
评估结果反过来指导分块策略、检索参数与 prompt 设计,这是一个长期迭代过程。
八、常见风险与治理思路
- 数据过期:知识库内容过旧,答案“看似合理但过时”。
- 上下文污染:检索结果包含错误或不相关片段,导致生成偏离。
- 信息泄露:元数据权限控制不严,容易把敏感内容带入上下文。
治理方法是“检索前过滤、生成中约束、输出后审计”,而不是仅依赖模型自觉。
九、知识更新与版本治理
RAG 系统最大的敌人之一是“知识漂移”。当文档更新或 embedding 模型升级时,索引必须同步更新,否则检索结果会落后或错位。实践中常见策略:
- 增量更新:新内容先入库,旧内容定期重算;
- 双索引切换:新索引构建完成后灰度切换;
- 版本标记:每条文档附带版本或时间戳,便于回溯。
这些工程化措施并不“性感”,却决定了 RAG 的长期稳定性。
十、上下文压缩与引用管理
上下文窗口有限,检索回来的内容经常需要再压缩或裁剪。常见策略包括:
- 摘要压缩:对候选文档先做摘要,再进入最终上下文;
- 证据抽取:只保留与问题相关的句子;
- 结构化引用:在上下文中保留来源标识,便于模型引用与后续审计。
引用管理是很多系统的“隐形需求”:当用户质疑答案时,能够回溯到原文比“模型自信的解释”更有价值。
十一、RAG 与工具调用的结合
RAG 本质上是一种“知识检索”机制,但很多问题还需要实时计算或外部操作,这时可以把 RAG 与工具调用结合:
- RAG 提供静态知识与背景;
- 工具调用提供实时数据与确定性计算;
- LLM 负责融合与解释。
这种组合能显著拓展系统能力,也更适合复杂业务场景。
十二、落地检查清单(实战导向)
- 检索与生成是否分别有指标?
- 文档更新后是否能快速同步?
- 是否可追溯到“答案来源”?
- 是否有针对长上下文的裁剪策略?
- 是否对敏感数据做了检索过滤?
这些问题比“模型大小”更容易决定一个 RAG 系统是否可用。
十三、检索失败的诊断与回溯
RAG 出错时,常见现象是“模型答非所问”。为了定位问题,需要把流程拆开检查:
- 检索是否命中:top-k 是否包含正确证据;
- 证据是否可读:文本是否被切分得过碎或上下文不完整;
- 提示是否偏离:prompt 是否把问题与证据绑定得足够强;
- 模型是否忽略:上下文是否过长或被噪音掩盖。
把问题定位清楚后,才知道该调检索参数、调整切分策略,还是改 prompt。
十四、长文档与多跳问题
RAG 在长文档场景常遇到两个难点:
- 长文档无法一次塞入上下文;
- 多跳问题需要跨多个片段推理。
常见解决方案是“分层检索”:先检索到章节级片段,再在章节内细查;或者用二阶段策略先召回候选,再针对候选做局部摘要。这类策略能在上下文受限时保持可用的覆盖率。
十五、缓存与成本控制
RAG 的成本不仅来自模型调用,还来自检索与向量化的持续维护。常见做法包括:
- 检索缓存:对高频问题缓存检索结果,减少重复检索;
- 上下文缓存:对稳定文档的摘要或证据片段做缓存;
- 请求合并:在高并发场景对相似查询做合并处理。
这些策略可以在不牺牲准确性的前提下降低整体成本,并提升响应稳定性。
十六、结论:RAG 的边界与价值
RAG 并不能“消灭幻觉”,它只是把答案约束在可检索的证据之内。只要证据不可靠,输出仍会不可靠。因此,RAG 的核心价值不是替代模型,而是让模型在可审计、可追溯的范围内工作。把检索质量、上下文组织与评估体系做好,RAG 才能真正成为生产系统的一部分。
十七、提示词中的小技巧
在提示词中明确“只能使用上下文回答”,并要求模型引用证据来源,通常能显著降低胡编。另一种实用做法是把问题与证据分段标记,如“问题/证据/答案”,减少模型忽略证据的概率。这些小技巧虽然简单,却能在不改模型的情况下提升稳定性。
十八、轻量复盘
RAG 的效果往往是“系统性结果”,而不是某个参数的单点优化。只要检索质量、上下文组织与评估机制形成闭环,模型就能在可控范围内输出稳定答案。
十九、补充一句
不要把 RAG 当成一次性交付,它更像一个持续运营的系统:知识在变、用户在变,检索与提示也需要持续更新。把迭代节奏纳入产品流程,才能长期保持效果。一个实用的方法是固定“回归问题集”,每次更新都跑一遍,避免效果悄然退化。最好把检索日志和答案结果一起回放,才能看清错在检索还是生成。上线后每周抽检一批问题,也能快速发现漂移。固定评估集加上定期人工复核,是成本最低的稳定策略之一。只要坚持这个节奏,效果会更可控。小步快跑、快速验证是长期维护的关键,持续记录误答案例才能推动检索改进。