一文读懂什么是RAG
如果你在用大模型做问答、知识库、客服、代码助手,你一定会遇到同一个问题:
模型“很会说”,但它并不总是“知道最新、最对、最贴合你业务”的内容。
RAG(Retrieval-Augmented Generation,检索增强生成)就是为这个问题而生的。
这篇文章会用实战视角讲清楚:
- RAG 的基本概念和核心工作机制
- RAG 在项目中的常见用法
- RAG 与 Skill、Prompt、MCP 的联系和区别
- 如何用向量数据库、Dify、n8n 构建可落地的 RAG
- 大模型在什么时机、按什么规则触发 RAG 调用
先说结论:RAG 是什么?
RAG 是“先检索外部知识,再让模型生成答案”的技术范式。
你可以把它理解成两段式流程:
- Retrieval(检索):从知识库里找出和问题最相关的内容片段
- Generation(生成):把这些片段作为上下文喂给大模型,生成答案
这和“直接问模型”最大的区别是:
RAG 的答案不仅来自模型参数记忆,还来自你可控、可更新的外部知识源。
为什么 RAG 这么重要?
因为它正好补上了纯大模型的三大短板:
1) 最新知识不足
大模型训练数据有时间截断。
你昨天更新的产品文档、今天发布的政策公告,模型参数里并不一定有。
2) 业务私有知识缺失
企业内部 SOP、合同条款、项目经验、运维手册通常不在公开互联网中。
RAG 可以把这些私域内容变成模型可用上下文。
3) 可追溯性弱
纯生成容易“讲得像真的”,却难以给出来源。
RAG 可以把引用片段和来源 URL 一起返回,提升可信度和审计性。
RAG 的核心架构(最小理解版)
一个典型 RAG 系统通常由 6 部分组成:
- 文档加载器(Loader):读取 PDF、Markdown、网页、数据库记录
- 文本切分器(Chunker):把长文拆成适合检索的小片段
- 向量化模型(Embedding):把文本转成向量
- 向量数据库(Vector Store):存储向量并支持相似度检索
- 检索器(Retriever):根据问题召回 top-k 相关片段
- 生成器(LLM):基于“问题 + 检索上下文”生成最终回答
常见链路是:
Query -> Embedding -> Similarity Search -> Context Assembly -> LLM Answer
RAG 的典型用法(从 0 到 1)
用法 1:企业内部知识问答
最常见落地方式是把文档中心接成知识库,例如:
- 产品文档
- 实施手册
- 售后 FAQ
- 安全规范
用户提问时先检索相关片段,再让模型回答并附引用来源。
用法 2:客服和工单辅助
在客服场景里,RAG 可把“回答一致性”从“靠人记忆”升级为“靠知识检索”。
这样新客服也能快速给出接近资深同事的答案质量。
用法 3:代码与运维助手
把 README、架构文档、历史事故复盘、部署手册接入 RAG。
当工程师问“某服务为什么这样配”“这个告警怎么处理”时,能得到贴近团队上下文的回答。
RAG 与 Prompt、Skill、MCP 的联系与区别
这四个概念经常一起出现,但关注层次不同。
Prompt:定义表达与行为风格
Prompt 解决“模型怎么回答”:
- 输出语言与格式
- 角色语气
- 禁止事项(例如不要编造)
它本身不提供知识检索能力。
Skill:定义任务流程方法
Skill 解决“任务怎么做更稳”:
- 先检索还是先澄清
- 命中阈值不够时是否拒答
- 回答时是否必须附引用
它是可复用 SOP,不是底层连接协议。
MCP:定义工具连接协议
MCP 解决“模型如何调用外部能力”。
在 RAG 场景下,MCP 可以连接:
- 向量检索工具
- 文档读取工具
- 重排序(rerank)工具
- 权限和审计系统
RAG:定义“检索 + 生成”的能力范式
RAG 关注的是知识增强本身。
它可以在没有 MCP 的情况下实现,也可以通过 MCP 让这套能力更标准化、更可治理。
一张表看清四者差异
| 维度 | Prompt | Skill | MCP | RAG |
|---|---|---|---|---|
| 核心作用 | 约束模型表达 | 固化任务流程 | 连接外部工具 | 用检索增强生成 |
| 解决问题 | 怎么说 | 怎么做 | 怎么接 | 知识从哪来 |
| 所在层次 | 推理层 | 编排层 | 集成层 | 能力层 |
| 是否直接引入外部知识 | 否 | 间接 | 间接 | 是 |
| 常见产物 | 提示词模板 | SKILL/SOP | Server/Tool API | 检索链路与知识库 |
RAG 实战示例一:向量数据库方案(可直接上手)
下面给一个最小可运行思路:
使用LangChain + Chroma搭一个本地 RAG 原型。
第一步:准备数据
将你的知识文档放入docs/,格式可以是:
.md.txt.pdf(需对应 loader)
第二步:构建索引(离线阶段)
fromlangchain_community.document_loadersimportDirectoryLoader,TextLoaderfromlangchain_text_splittersimportRecursiveCharacterTextSplitterfromlangchain_openaiimportOpenAIEmbeddingsfromlangchain_community.vectorstoresimportChroma loader=DirectoryLoader("docs",glob="**/*.md",loader_cls=TextLoader)docs=loader.load()splitter=RecursiveCharacterTextSplitter(chunk_size=800,chunk_overlap=120)chunks=splitter.split_documents(docs)emb=OpenAIEmbeddings(model="text-embedding-3-large")db=Chroma.from_documents(chunks,emb,persist_directory="./chroma_db")db.persist()第三步:在线问答(检索 + 生成)
fromlangchain_openaiimportChatOpenAI,OpenAIEmbeddingsfromlangchain_community.vectorstoresimportChromafromlangchain.promptsimportChatPromptTemplate db=Chroma(persist_directory="./chroma_db",embedding_function=OpenAIEmbeddings(model="text-embedding-3-large"))retriever=db.as_retriever(search_kwargs={"k":4})llm=ChatOpenAI(model="gpt-4o-mini",temperature=0)prompt=ChatPromptTemplate.from_template("你是企业知识助手。请仅基于上下文回答;若上下文不足,请明确说明。\n\n""问题:{question}\n\n""上下文:\n{context}\n\n""请给出要点式回答,并附上引用片段编号。")defask(question:str):hits=retriever.invoke(question)context="\n\n".join([f"[{i+1}]{d.page_content}"fori,dinenumerate(hits)])answer=llm.invoke(prompt.format(question=question,context=context))returnanswer.content第四步:上线前加三件事
- 重排序(Rerank):提升 top-k 相关性
- 引用回传:答案附 source、文档名、段落位置
- 阈值拒答:相似度太低时不回答,避免幻觉
RAG 实战示例二:借助 Dify 快速搭建
Dify 的优势是低代码、可视化快。
常见做法是“先验证业务价值,再决定是否自研”。
一套实操流程
- 在 Dify 创建知识库,导入企业文档
- 配置切分策略(chunk size / overlap)
- 选择 embedding 模型和召回参数(top-k)
- 在工作流中加入“知识检索节点 + LLM 节点”
- 配置未命中策略(追问、转人工、拒答)
- 打开日志评估命中率和回答质量
适合 Dify 的场景
- 业务要快速 PoC
- 团队工程资源有限
- 需要产品、运营一起调试 Prompt 与知识库
RAG 实战示例三:借助 n8n 编排自动化流程
n8n 更像自动化编排平台,适合把 RAG 接入业务流程。
一个典型工作流
Webhook -> Query Normalize -> Vector Search -> LLM Answer -> Slack/CRM 回写
你可以在 n8n 里做什么
- 把用户提问先做意图分类(FAQ/工单/销售咨询)
- 仅对“知识问答类”触发 RAG
- 对“交易类操作”走审批流,不直接由模型执行
- 把问答日志写回数据库,做后续质量评估
大模型在什么时机触发 RAG?
这是 RAG 成败最关键的工程问题之一。
不是每个问题都要走检索,触发策略应该可配置、可观测。
常见触发时机(建议组合使用)
1) 关键词/意图触发
当问题包含“最新版本、公司政策、价格、SLA、内部流程”等词时,强制触发 RAG。
因为这些问题最依赖实时和私域知识。
2) 置信度触发
先让模型做一次“是否需要外部知识”判断:
如果模型对答案置信度低,自动进入检索链路。
3) 任务类型触发
对 FAQ、客服、合规问答默认走 RAG;
对创意写作、头脑风暴可不走 RAG,降低延迟和成本。
4) 用户显式触发
允许用户通过指令触发,例如:
- “请基于知识库回答”
- “请给出处”
- “只用公司文档回答”
如何设计 RAG 触发策略(实战版)
建议采用“三段式决策”:
- Router 判断:分类问题类型(知识密集/通用对话/操作执行)
- Gate 判门槛:看是否满足检索阈值(相似度、时效性、领域敏感度)
- Fallback 策略:未命中时追问或拒答,而不是硬编
可参考下面伪代码:
defshould_use_rag(query,intent,user_preference):ifuser_preference=="force_rag":returnTrueifintentin{"policy","pricing","internal_sop","faq"}:returnTrueif"最新"inqueryor"版本"inqueryor"公司"inquery:returnTruereturnFalsedefanswer(query):intent=classify_intent(query)ifshould_use_rag(query,intent,user_preference="auto"):docs=retrieve(query,top_k=5)ifnotdocsormax_score(docs)<0.72:return"当前知识库未检索到足够可信的信息,请补充上下文或转人工。"returnllm_with_context(query,docs)returnllm_direct(query)RAG 常见坑与优化建议
坑 1:只换了向量库,没做数据治理
RAG 的瓶颈往往不在模型,而在文档质量。
脏数据、重复文档、过期内容会直接拉低答案可信度。
坑 2:切分策略不合理
chunk 太大,召回不准;chunk 太小,上下文断裂。
建议按文档类型分策略,比如 FAQ、技术文档、合同文本分别配置。
坑 3:只看“能回答”,不看“答得对”
需要建立评估集,至少跟踪:
- 命中率(retrieval hit rate)
- 引用准确率(citation precision)
- 拒答准确率(该拒时是否拒)
坑 4:忽略成本与延迟
RAG 是“检索 + 生成”双成本路径。
要通过缓存、路由、分层索引来控制延迟与 token 消耗。
RAG 的优势与劣势
优势
- 可以补足大模型的最新知识和私域知识
- 回答更可追溯,适合企业审计场景
- 知识更新不需要重新训练大模型
- 可按业务域做精细化治理
劣势
- 系统复杂度明显高于纯 Prompt 方案
- 需要持续维护知识库与索引
- 检索链路增加延迟和成本
- 召回不准时会把错误上下文“放大”
RAG + Skill + Prompt + MCP 的推荐组合
在真实项目里,建议这样分层:
- Prompt:定义回答边界(只基于证据、必须附来源)
- Skill:定义流程(何时检索、何时拒答、何时追问)
- MCP:接入检索工具、权限策略、审计能力
- RAG:提供外部知识增强能力
这个组合能同时兼顾:可用性、准确性、可治理性。
总结
RAG 的本质不是“让模型更聪明”,而是“让答案更有依据”。
当你需要最新信息、私域知识、可追溯输出时,RAG 几乎是必选项。
你可以记住这句:
- Prompt 决定怎么说
- Skill 决定怎么做
- MCP 决定怎么接工具
- RAG 决定知识从哪来
如果你正在做企业级 AI 应用,建议从一个高价值场景开始:
先用 Dify/n8n 快速验证,再逐步升级到向量库 + 自定义触发策略 + 全链路评估。
这样你不仅能“做出一个能答的机器人”,还能做出“答得准、可持续迭代”的生产级系统。