想象你是一家高档餐厅的老板。你的主厨厨艺惊人、能记住海量菜谱,可一旦顾客问起新菜或小众菜,他就开始“自由发挥”——“这道斐济名菜要加半斤盐、猛火三小时”,吓得客人夺门而出。你急需一个“外挂记忆”:让他随时查菜谱,而不是背菜谱。这正是检索增强生成(RAG)的诞生场景。 RAG 这套思路,相当于给大模型配了一座随时可查的菜谱库。顾客提问时,系统先去几万份文档里翻出最相关的几页,摆上“操作台”,大模型照着资料开口回答。这样一来,“冰箱坏了怎么办”“退款多久到账”这类问题,客服 AI 就不再凭空编造,而是有据可依。本文以 RAG 客服系统为例,带你走完这条路线的每个环节:如何把知识库变成计算机能查的样子、如何精准检索、如何注入 Prompt 并生成回答、如何评估效果,以及真实运维中会踩的坑。
掌握 RAG 是 AI 从业者进入企业级大模型应用开发的敲门砖——它让模型告别“自由发挥”、学会“有据可依”,是客服、医疗、法律等知识密集型场景落地 AI 的核心技术栈。
目录
可视化演示
演示文档分块嵌入、向量检索Top-K与上下文增强生成,理解RAG结合外部知识提升LLM回答准确性的流程。
本节配有交互动效(进入视口后自动加载,约 3KB)。
分块嵌入:文档向量化 文档切块 Embedding d→emb→v 建向量索引
RAG 基本概念:为什么大厨需要菜谱库
你餐厅那位天才主厨,背过上万个菜谱,可一旦顾客问起新菜、小众菜,他要么面红耳赤地沉默,要么一本正经地胡诌——“斐济名菜?加半斤盐,猛火三小时!”把顾客吓得不轻。作为老板,你需要的不是让他背更多菜谱,而是给他一个随时能翻的菜谱库。这正是 RAG(Retrieval-Augmented Generation,检索增强生成)的设计初衷:不改变模型本身,而是给模型接一个“外部记忆”。
客服场景的痛点也是如此。用户问“你们的退款什么时候到账”,模型大概率没背过你们公司的财务政策,但知识库里躺着标准答案。RAG 先把问题拿去检索,捞出最相关的政策条文,再让模型基于条文组织回答。与“重新训练模型”相比,RAG 可以随时增删知识、不用花高昂的微调成本,是知识密集型场景最务实的方案。
标准 RAG 流程包含三个阶段:检索(Retrieval)、增强(Augmentation)、生成(Generation),可以浓缩为下面的过程:
1. 知识库 D:存放全部客服资料(退换货、物流、发票政策)的文档集合,相当于整座菜谱库。
2. 相似度函数 Sim:衡量问题 $q$ 与每篇文档 $d$ 语义接近程度的函数,分数越高越相关。
3. TopK 截断:从所有文档中只取分数最高的 $K$ 份,过滤无关噪声,控制输入长度。
4. 增强 Aug:把检索到的片段与原始问题拼装成标准 Prompt,相当于把菜谱摊开在操作台上。
5. 生成 LLM:大模型阅读增强后的输入,产出一条有据可依的回答。
整个过程就是给主厨装了一台“菜谱检索机”:先翻索引(检索)、把相关页摊开(增强)、照着菜谱开口(生成)。主厨还是那个主厨,但有了外挂菜谱,他再也不会上来就“加半斤盐”。
向量检索原理:给菜谱贴“口味坐标”
如果菜谱库只有五十本,靠人工分类完全可以——川菜、粤菜、甜点各放一柜。可库藏达到几万本时,人工整理就崩了:“水煮鱼”该放川菜还是热菜?顾客问“哪道菜又辣又下饭”,按柜子找根本答不上来。RAG 需要更聪明的办法:给每一份菜谱和每一个问题都贴上一组“口味坐标”,用坐标距离判断“像不像”。
这组“口味坐标”就是向量(Embedding)。Embedding 模型能把任意一段文本(一句话、一篇文档)转换成一串几百上千维的浮点数向量。语义相近的文本,向量在空间中的方向就接近;语义风马牛不相及,方向就相差很远。这些向量不会存在普通表格里,而是存入向量数据库——一种专门按“高维坐标就近查找”设计的索引柜。
如何度量两个向量“像不像”?最常用的是余弦相似度:
1. 点积:两个向量逐维度相乘再求和,量化方向一致性,方向越一致数值越大。
2. L2 范数:向量各维度平方和再开方,代表向量长度,写在分母用于消除文本长短的影响。
3. 归一化比值:用点积除以两个长度的乘积,只看方向、不看长度,得到稳定的相似度分数。
回到餐厅:每份菜谱被画成一个“口味坐标点”,顾客的问题也被画成一个坐标点。“水煮鱼”和“毛血旺”坐标挨得很近,系统一眼就能判断“这位客人要川味重口”。坐标怎么存、怎么快速找邻居,正是向量数据库的看家本领。
检索与重排:海选与决赛的配合
几万份菜谱,顾客问一句“适合小孩吃的清淡菜”,理论上可以跟所有菜谱逐一算相似度,但每次都全量计算实在太慢太贵。聪明的餐厅分两步:先“海选”,用快而粗的法子从几万份里捞出前 100 份候选;再“决赛”,用精而细的法子从 100 份里排出前 3 名。这就是召回(Recall)与重排(Rerank)的分工。
召回的常见策略有三种:纯向量检索(语义理解好)、BM25 关键词检索(订单号、型号等精确匹配好),以及两者结合的混合检索。多路召回得到几份不同的排名列表后,怎么合并成一份?常用 RRF(Reciprocal Rank Fusion,倒数排名融合):
1. 候选集合 R:向量检索、BM25 等多路召回各自返回的排名列表的集合。
2. 排名位置 r(d):文档 $d$ 在某一列表中的名次,从 1 开始。
3. 加权融合:对每路结果求 $\frac{1}{k + r(d)}$ 再相加,各路都靠前的文档获得最高融合分。
重排阶段通常用一个更强大、也更慢的 Reranker 模型,对海选出的 Top-100 精读后打精细分,最终只把 Top-K(一般取 3~5)作为上下文送进大模型。K 太小容易漏关键信息,太大则稀释注意力、抬高成本。对应餐厅:跑堂小二先抱来一百本“可能沾边”的菜谱(召回),主厨亲自快速翻一遍,只留三本真正对得上胃口的摊在操作台上(重排)。既快,又不失精准。
注入与生成:把菜谱摆上操作台,开火
检索到的三份菜谱如何变成一道成品菜?直接把文档和问题一股脑扔给模型说“回答吧”?当然不行——就像你不能把三本菜谱连盘子一起摔进锅里。这一步叫注入(Augmentation):把用户问题、检索到的上下文、系统指令按模板拼装成 Prompt。Prompt 的结构直接影响回答质量,客服场景通常包含三层:人设指令(“你是一位严谨的客服助手,请严格依据资料回答”)、检索上下文、用户问题。
注入了上下文之后,上下文管理也是门学问:内容过长会被截断,多份自相矛盾的文档会让模型左右为难。工程上通常会对检索片段做去重、按与问题的相关度重排,并在 Prompt 中明确“资料不足时请直接说不知道”。从数学角度看,RAG 的生成阶段可表示为:
1. 生成条件:预测第 $t$ 个词时,模型同时参考问题、检索文档和已生成词,保证回答不离谱。
2. 连乘:整句概率等于每个词条件概率的乘积,让模型整体权衡,而不是只看局部。
3. arg max 寻优:在所有可能的回答中找出概率最高的那条,作为最终输出。
对应餐厅:操作台上摆好三本菜谱、附带顾客备注“少辣、不要香菜”,主厨照着这些情报动火炒菜。菜是菜谱里的做法,但口味完全贴合眼前这位客人——这就是“增强”在生成阶段的价值。
客服系统实战:把流水线搬进生产环境
光有算法还不够,你要把它变成一天能服务一万个顾客的“智能咨询台”。生产级客服系统的典型链路是:用户提问 → 检索服务(向量库 ANN 搜索 + 重排)→ 生成服务(大模型推理)→ 返回答案。链路背后还有一条知识库流水线:把散落的政策文档、FAQ 表格清洗、去重、切分成合适的片段,再用 Embedding 模型向量化,写入向量数据库。
工程上要先算清成本账。大模型 API 按 token 计费,RAG 每个环节都在花钱,单次请求的成本模型可以这样拆:
1. 向量化成本:用 Embedding 模型把用户问题转成向量,按调用次数计费。
2. 检索成本:向量数据库的 ANN 近似近邻搜索和重排模型计算的机器开销。
3. 输入成本:注入的 Prompt 上下文越长,输入侧 token 费用越高,所以 Top-K 必须克制。
4. 输出成本:回答越长,生成侧费用越高,需要设置 max tokens 上限。
除了成本,还有三件事必须做:限流与缓存——高频常见问题直接走缓存,别每次都搜库调模型;隐私脱敏——用户姓名、手机号在入知识库前要清洗;引用溯源——回答必须附带“哪些文档片段支撑了这句话”,方便审计和排错。对应餐厅:咨询台从“厨师口述”升级为“标准流水线”——点菜(提问)、传菜员到档案柜取证(检索)、后厨统一炒制(生成)、上菜附上菜谱页码(溯源)。流程标准化,才能规模化。
效果评估:试菜员与顾客共同打分
菜好不好吃,不能只靠厨师自夸。客服 AI 也一样,上线前必须“试菜”:准备一批带标准答案的测试问题集,让 RAG 系统跑一遍,再从多个维度打分。评估要分开看:检索好不好是一回事,回答好不好是另一回事,两者可能互相拖后腿。
衡量“检索好不好”的核心指标之一是召回率 Recall@K——知识库里真正相关的文档,有多少被成功捞了出来:
1. 交集数量:检索返回的 TopK 文档与人工标注的相关文档重叠的个数。
2. 相关文档总数:标注集中与这个问题有关的全部文档数量。
3. 比值:分子除分母,满分 1.0,反映检索的“全不全”。
回答质量则常用 RAGAS 框架——一套专为 RAG 设计的自动评估指标,重点关注三维度:忠实度(回答是否严格基于检索文档、没有自行发挥)、答案相关性(是否正面回答问题)、上下文相关性(检索内容是否与问题相关)。落地时结合人工抽检,形成“评测 → 发现短板 → 调优(换 Embedding、调 chunk 大小、加 Reranker)→ 再评测”的闭环。对应餐厅:Recall@K 是试菜员核对“端上来的菜是否覆盖顾客真想要的菜”,RAGAS 是逐口检查色香味是否达标。有了打分表,厨师改进才有方向。
常见问题:餐厅的兜底预案
运营一年,咨询台难免遇到幺蛾子,最典型三类:幻觉(检索没捞到好东西,模型开始胡编)、检索失败(知识库明明有答案却搜不到)、知识更新慢(涨价政策改了三天,库还是旧的)。这些问题不是“可能遇到”,而是“一定会遇到”,需要提前设计防线。
要对“回答是否靠谱”做量化判断,工程上常用忠实度(Faithfulness)指标:
1. 支持句数:逐句比对,句子的关键信息能在检索文档中找到对应依据,才算“支持”。
2. 总句子数:大模型生成回答包含的全部句子数量。
3. 忠实度比值:结果越接近 1 说明回答越脚踏实地;明显低于 0.7 就要警惕幻觉风险。
对策是体系化的:检索端用混合检索 + 更细粒度切分提高命中率;生成端在 Prompt 中写明“资料不足时必须回答不知道”;知识端建立定期重建索引的更新流水线;系统层面再加一道兜底话术——当检索最高得分低于阈值时,直接转人工客服。对应餐厅:厨师偶尔还是会说错菜名(幻觉),那就加保险——没有十足把握的菜,直接说“这道菜我不确定,请让经理来”。正是这些兜底预案,才让 RAG 客服系统真正顶住真实世界的考验。
AI 应用场景
大模型电商客服
阶段:检索增强生成(RAG 全链路)
解决的问题:传统客服机器人依赖规则和关键词,答非所问率高;纯 LLM 客服知识陈旧、爱编造。RAG 让回答始终基于最新知识库,新活动政策上线只需更新文档,不用重训模型。
具体案例:某电商平台将商品手册、售后政策、物流说明切片向量化。用户问“冰箱冷藏室结冰怎么办”,系统检索到对应故障排查文档,再由大模型组织成步骤化回答,并附上“手册来源页码”,投诉率明显下降。
企业内部知识库问答助手
阶段:知识库构建 + 检索优化
解决的问题:员工在企微群里反复问 HR 和 IT 相同问题(调休安排、VPN 配置、报销流程),人工回复成本高。RAG 助手可 7×24 值班,检索不到时自动转人工,后台记录高频未命中问题反哺知识库建设。
具体案例:某公司把入职指南、报销制度、网络配置文档录入向量库,机器人回答时标注来源文档链接。三个月后,IT 工单量下降约 40%,新员工“找不到文件”的求助基本消失。
金融合规咨询助手
阶段:效果评估 + 幻觉抑制
解决的问题:金融领域的错误回答代价极高,必须可溯源、可审计。RAG 的引用机制和忠实度评估,正好满足“每一句回答都要有文件出处”的合规要求。
具体案例:一家投顾公司用 RAG 构建监管政策问答系统,客服回答必须标注依据文件编号;RAGAS 忠实度低于阈值时自动转人工并生成审计日志,顺利通过合规检查。
Python 演示
import mathimport refrom collections import Counter class SimpleRAG: """简化版 RAG 客服系统:TF-IDF 检索 + 模板生成""" def __init__(self): self.docs = {} self.doc_vectors = {} self.idf = {} self.k = 3 # 默认召回 Top-K def tokenize(self, text): """中文按字符 bigram 切分,兼顾鲁棒性""" text = re.sub(r'\s+', '', text) if len(text) <= 1: return [text] return [text[i:i + 2] for i in range(len(text) - 1)] def fit(self, knowledge_base): """构建知识库:doc_id -> 文本,并计算 TF-IDF 向量""" self.docs = knowledge_base doc_tf = {} df = Counter() for doc_id, text in knowledge_base.items(): tokens = self.tokenize(text) tf = Counter(tokens) doc_tf[doc_id] = tf df.update(set(tokens)) n_docs = len(knowledge_base) self.idf = { token: math.log((n_docs + 1) / (freq + 1)) + 1 for token, freq in df.items() } self.doc_vectors = {} for doc_id, tf in doc_tf.items(): vec = {} for token, count in tf.items(): vec[token] = count * self.idf.get(token, 0) norm = math.sqrt(sum(v * v for v in vec.values())) if norm > 0: vec = {t: v / norm for t, v in vec.items()} self.doc_vectors[doc_id] = vec def retrieve(self, query, k=None): """检索:返回 (doc_id, score) 列表,按余弦相似度降序""" k = k or self.k q_tf = Counter(self.tokenize(query)) q_vec = {} for token, count in q_tf.items(): q_vec[token] = count * self.idf.get(token, 0) q_norm = math.sqrt(sum(v * v for v in q_vec.values())) if q_norm > 0: q_vec = {t: v / q_norm for t, v in q_vec.items()} scores = [] for doc_id, doc_vec in self.doc_vectors.items(): score = sum(q_vec.get(t, 0) * w for t, w in doc_vec.items()) scores.append((doc_id, score)) scores.sort(key=lambda x: x[1], reverse=True) return scores[:k] def generate(self, query, top_docs): """生成:把检索结果拼成上下文,套模板输出回答""" context = '\n'.join(self.docs[did] for did, _ in top_docs) return '根据知识库,关于「{}」的回答:\n{}'.format(query, context[:120]) def ask(self, query): """完整 RAG 流程:检索 -> 增强 -> 生成""" top_docs = self.retrieve(query) return self.generate(query, top_docs) if __name__ == '__main__': kb = { "kb01": "退换货政策:自签收之日起7天内支持无理由退换货。", "kb02": "物流查询:标准快递预计3-5个工作日送达。", "kb03": "退款说明:退款将在1-3个工作日原路退回。", "kb04": "会员积分:每消费1元累计1积分,积分可兑换优惠券。", "kb05": "发票开具:支持电子发票,下单后可在线申请。", } bot = SimpleRAG() bot.fit(kb) top = bot.retrieve("怎么申请开发票") print("Top 命中:", [did for did, _ in top]) print(bot.ask("怎么申请开发票"))
def tokenize(self, text)按中文 bigram 切分文本,让“退款多久到”这类短句也能提取出可匹配的特征。df.update(set(tokens))统计每个词出现在多少篇文档中,这是计算 IDF(逆文档频率)的基础。self.idf = {...}词越罕见 IDF 越高,避免“的”“了”这类高频词主导相似度。vec[token] = count * self.idf.get(token, 0)用 TF 乘以 IDF 得到词的权重,构成文档向量。norm = math.sqrt(...)计算向量长度,后面用它做归一化,消除文档长短的影响。scores.sort(key=lambda x: x[1], reverse=True)按相似度从高到低排序,取出 Top-K 个文档。context = '\n'.join(self.docs[did] for did, _ in top_docs)把命中的文档拼成上下文,这就是“注入”增强。bot.ask("怎么申请开发票")一行调用走完“检索 → 增强 → 生成”全流程。
常见误区
误区“RAG 不就是在问答时把公司文档全贴给 ChatGPT 吗?我把所有资料塞进 Prompt,它就能回答所有问题了。”
正解这样做会很快撞上上下文窗口上限,费用暴涨,而且无关信息会严重干扰模型注意力。RAG 的核心是先检索、再注入——只把与当前问题最相关的几个片段找出来,就像厨师查菜谱只翻相关几页,而不是把整本菜谱背给顾客听。
为何常见:大模型强大的文本理解能力让人误以为“喂得越多答得越准”,忽略了上下文长度和注意力都是稀缺资源。
误区“RAG 让模型有据可依,所以它回答的每一句话都是真实的,可以完全信任。”
正解RAG 能显著降低幻觉,但无法根除。如果检索到的文档本身不相关、不完整或含错误信息,模型依然可能一本正经地编造。忠实度评估和人工抽检仍是上线前必须做的功课。
为何常见:产品宣传常说 RAG“让模型有据可依”,初学者容易把“有据”等同于“有正确可靠的据”,忽略了检索质量这个前提。
误区“语义搜索是新技术,向量检索全面碾压 BM25,以后只做向量检索就够了。”
正解向量检索擅长语义相近的模糊匹配(“冰箱结霜”和“冷藏室结冰”),但对精确匹配场景(订单号、型号、政策编号),关键词检索往往更准。生产系统普遍采用混合检索(向量 + BM25),再用 RRF 或 Reranker 融合,取长补短。
为何常见:语义搜索的“聪明”容易被高估,而精确匹配的“笨办法”价值只有在真实数据上对比评测时才会显现。
误区“知识库上线时已经整理好了,以后不需要再动,反正文档都在那里。”
正解商品价格、退换政策、物流时效随时在变。文档不更新,RAG 就会用旧知识一本正经地回答过时信息,比答不上来更危险。生产系统需要建立定期重建索引、清理过期文档、监控未命中问题的更新流水线。
为何常见:知识库构建成本高,团队往往把精力集中在“建库”,而忽略了“养库”;数据库的静态思维也被错误地搬到了知识库上。
面试题
Q1. RAG 中的字母 "R" 代表什么?
- A.Random 随机
- B.Retrieval 检索← 正确答案
- C.Recurrent 循环
- D.Recursive 递归
答案:B。RAG 全称 Retrieval-Augmented Generation,R 代表 Retrieval(检索)。A 的 Random 是随机,C 的 Recurrent 是 RNN 里的“循环”,D 的 Recursive 是“递归”,都是起名时容易混淆的干扰项。记住“先检索、再增强、后生成”这条主线就不会选错。
Q2. 向量检索中最常用来度量两个向量相似度的方法是?
- A.计算文本编辑距离
- B.计算向量余弦相似度← 正确答案
- C.计算欧拉公式数值
- D.计算贝叶斯后验概率
答案:B。余弦相似度通过计算两个向量的夹角余弦值度量语义接近程度,是 Embedding 检索的主流选择。编辑距离用于字符串匹配,欧拉公式是复变函数内容,贝叶斯后验概率属于概率推断,都与向量语义距离无关。
Q3. RAG 客服系统执行流程的正确顺序是?
- A.生成→检索→增强
- B.检索→增强→生成← 正确答案
- C.增强→生成→检索
- D.检索→生成→增强
答案:B。标准 RAG 流程是先确定“资料在哪”(检索),再把资料与问题拼装(增强),最后由大模型产出回答(生成)。其他顺序要么先凭空生成再补资料,要么把增强放在生成之后,逻辑上都说不通。
Q4. Embedding 向量化要解决的问题是?
- A.把图片缩小节省空间
- B.将文本转为稠密数值向量← 正确答案
- C.把音频转写成文字字幕
- D.将视频逐帧抽成图片
答案:B。Embedding 模型把文本映射成稠密向量,使语义相近的文本在向量空间中距离更近,这是 RAG 检索的前提。A 是图像压缩、C 是语音识别、D 是视频抽帧,都不是文本语义表示。
Q5. 为什么不能把整个知识库直接放进 Prompt 让模型回答?
- A.大模型无法理解长文本
- B.上下文窗口长度有限← 正确答案
- C.会导致模型严重过拟合
- D.会导致知识库被篡改
答案:B。大模型的上下文窗口有固定上限,塞入全部文档会超长、费用暴涨,无关信息还会干扰注意力。RAG 的“检索”正是为了只保留最相关的片段。A 说法不准确(模型能读长文但窗口有限),C 的过拟合与 Prompt 输入无关,D 更是无稽之谈。
Q6. RAG 检索结果不靠谱时,可以采取哪些优化手段?
- A.更换更强的向量模型← 正确答案
- B.引入 BM25 混合检索← 正确答案
- C.加入重排 Rerank 环节← 正确答案
- D.删除用户全部历史记录
答案:ABC。换更强的 Embedding 模型可提升语义表示质量;BM25 混合检索能补足精确匹配短板;Rerank 精排能挑出更相关的片段。这三招分别从“表示、召回、排序”三个环节优化检索。删除用户历史记录与检索效果无关,属于隐私操作。
Q7. 重排 RRF 融合排序的基本思想是?
- A.对多路结果取分平均值
- B.按排名倒数加权融合← 正确答案
- C.每次只保留最优一路
- D.随机选取一路结果返回
答案:B。RRF(Reciprocal Rank Fusion)的核心是 $\sum 1/(k + r(d))$:文档在某一路中排名越靠前,贡献的融合分越高,最终按融合分排序。A 的平均分忽视了排名价值,C 和 D 都丢弃了多路召回的信息优势。
Q8. 以下哪些属于 RAG 系统在真实运营中的常见风险?
- A.模型产生幻觉回答← 正确答案
- B.检索结果完全不相关← 正确答案
- C.知识库未及时更新← 正确答案
- D.温度系数自动归零
答案:ABC。检索质量差导致答案不相关、知识库过期导致答出旧政策、上下文不足时模型编造——这三大风险分别对应检索端、知识端、生成端的故障。温度系数是采样参数,由代码控制,不会“自动归零”,属于无厘头干扰项。
Q9. 用 RAGAS 评估客服系统时,以下哪一项不属于其核心评估维度?
- A.上下文相关性维度
- B.答案相关性判断
- C.忠实度校验评估
- D.模型训练速度指标← 正确答案
答案:D。RAGAS 三大核心维度是上下文相关性(检索的内容是否切题)、答案相关性(回答是否正面回应问题)和忠实度(回答是否严格基于检索文档)。模型训练速度属于工程性能指标,不属于 RAGAS 的评估范围。
Q10. 关于知识库文档切分(chunk)大小的影响,以下说法正确的是?
- A.chunk 过大会稀释语义← 正确答案
- B.chunk 过小截断上下文← 正确答案
- C.需结合评测灵活选择← 正确答案
- D.chunk 越大一定越好
答案:ABC。chunk 过大,一段文本里混入多个主题,向量表示被稀释,检索精度下降;chunk 过小,可能截断关键上下文,导致信息不完整。正确做法是通过检索和生成两个阶段的评测,寻找最佳切分粒度。D 的“越大越好”忽略了语义稀释的代价,是典型的想当然。