米其林后厨来了位新主厨,名叫阿聪。他基本功炉火纯青——刀工利落、火候精准、调味老到,这些本事都刻在他的肌肉记忆里。但新餐厅的菜单有四十道菜,他只做过其中五道。当客人点了一道他从未做过的「杏仁鳟鱼配芦笋」时,阿聪面临一个选择:是硬着头皮凭基本功自由发挥,还是翻一翻后厨那本厚厚的菜谱? 你可能会说:这还用选?当然是查菜谱啊!但仔细想想,阿聪并不是每道菜都会去翻菜谱——「番茄炒蛋」他闭着眼睛都会做,翻了反而浪费时间。他真正需要的,是自己判断:这道菜我有把握吗?没把握就去查菜谱;查到的步骤够不够细?不够就再打电话问法国师傅;最后还要把菜谱、电话心得和自己的手艺融合成一道完整的菜端上桌。 这正是 RAG Agent 的秘密。大模型不再是「只会背诵课本」的考生,而变成了像阿聪这样知道自己不知道什么的厨师。它会按需触发检索、调用知识库与工具、判断信息够不够、多轮迭代查证,最后把外部知识和自己的推理能力融为一体。这篇文章,我们就用阿聪做菜的故事,把 RAG Agent 的完整决策循环拆给你看。

岗位关联

对 AI 从业者来说,RAG Agent 是从「调 API 的工程师」升级为「设计 Agent 决策循环的架构师」的分水岭——掌握它,你就能为企业知识助手、智能客服这类真实场景搭建会主动查证、能自我校验的智能体。

目录
  1. 可视化演示
  2. 1. Agent概念概览:一个会「查菜谱」的主厨
  3. 2. 检索触发决策:翻菜谱还是直接下锅
  4. 3. 检索工具设计:菜谱要整理得方便查
  5. 4. 信息充分判断:试吃一口才知道够不够
  6. 5. 多轮迭代检索:不够就再打电话追问
  7. 6. 结果整合推理:把菜谱变成自己的菜
  8. 7. 评估与调优:用顾客点评精进手艺
  9. AI 应用场景
  10. Python 演示
  11. 常见误区
  12. 面试题

可视化演示

\u53ef\u89c6\u5316\u5c55\u793aRAG Agent\u7684\u81ea\u4e3b\u68c0\u7d22\u51b3\u7b56\u5faa\u73af\u3001\u591a\u8f6e\u8fed\u4ee3\u68c0\u7d22\u4e0e\u67e5\u8be2\u6539\u5199\u3001\u4ee5\u53ca\u591a\u6e90\u77e5\u8bc6\u6574\u5408\u4e0e\u51b2\u7a81\u68c0\u6d4b\uff0c\u4ea4\u4e92\u5207\u6362\u89c2\u5bdfAgent\u52a8\u6001\u83b7\u53d6\u5916\u90e8\u77e5\u8bc6\u7684\u6838\u5fc3\u73af\u8282\u3002

本节配有交互动效(进入视口后自动加载,约 3KB)。

Agent\u81ea\u4e3b\u68c0\u7d22\u51b3\u7b56\u5faa\u73af \u601d\u8003\u2192\u68c0\u7d22\u2192\u5904\u7406\u2192\u56de\u7b54\u56db\u9636\u6bb5\u5faa\u73af \u7f6e\u4fe1\u5ea6\u4f4e\u4e8e\u9608\u503c\u65f6\u81ea\u52a8\u89e6\u53d1\u68c0\u7d22 Think \u2192 Retrieve \u2192 Process \u2192 Answer \u70b9\u51fb\u5207\u6362\u67e5\u770b\u8fed\u4ee3\u68c0\u7d22

1. Agent概念概览:一个会「查菜谱」的主厨

阿聪的基本功,是长年累月练出来的,刀工火候全在肌肉记忆里。可新餐厅的菜单有四十道菜,他只做过其中五道。遇到「杏仁鳟鱼配芦笋」,他面临一个抉择:硬做,还是翻菜谱?聪明的厨师知道,有些菜靠基本功就能搞定,有些菜必须借助外部资料。这个「先判断、再行动」的意识,就是 RAG Agent 的灵魂。

大模型同样如此。它的「基本功」是训练时学到的参数知识——常识、语法、热门话题都在里面;而公司政策、最新产品文档、私有数据库这些「新菜单上的菜」,它从未见过。传统 RAG 的做法是:不管三七二十一,先把文档查一遍再说。但 RAG Agent 更进一步,它让模型自己决定:这道菜我有把握吗?没有才去查。

技术上看,RAG Agent 是一个「感知—决策—行动」循环。Agent 收到用户问题(Query)后,由一个策略函数(Policy)判断是否调用外部知识;如果需要,就执行检索(Retrieve)获取证据文档;最后将证据与自身推理结合,生成最终答案。整个过程由 Agent 自主编排,这是它与「固定先查后答」的传统 RAG 最本质的区别。

所以 RAG Agent 不是「会联网的聊天机器人」那么简单,它更像阿聪的身份定位:一个知道自己不知道什么的厨师——知道何时该翻菜谱,也知道如何把菜谱和手艺融为一体。

Answer=Policy(Query, Retrieve(Query))\text{Answer} = \text{Policy}\Big(\text{Query},\ \text{Retrieve}(\text{Query})\Big)
这个公式的意思是:最终答案 = 策略函数综合「用户问题」和「检索到的文档」得出的输出。策略决定查不查,检索负责查,答案是把两者融会贯通的结果。
  1. Query(用户问题)这就是客人点的那道菜,是整个流程的起点。
    Query\text{Query}
  2. Retrieve(Query)(检索函数)翻菜谱的动作,根据问题到知识库中取回候选文档。
    Retrieve(Query)\text{Retrieve}(\text{Query})
  3. Policy(·,·)(策略函数)阿聪的「临场决策」,决定这道菜要不要查、查到什么程度。
    Policy(Query, Retrieve(Query))\text{Policy}\big(\text{Query},\ \text{Retrieve}(\text{Query})\big)
  4. Answer(最终答案)融合菜谱与基本功后端上桌的成品菜。
    Answer\text{Answer}

2. 检索触发决策:翻菜谱还是直接下锅

阿聪看到「杏仁鳟鱼配芦笋」这道菜时,大脑飞速运转:鱼的煎法他有十足把握,但「芦笋泥配杏仁脆片」的装盘逻辑他没见过。粗略一估,七成把握,但七成在米其林餐厅意味着可能被退菜。于是他果断翻开菜谱,补上这块短板。而若是「番茄炒蛋」这种闭眼都会做的菜,他绝不会多翻一页。

这个「估算把握」的过程,在 RAG Agent 里叫置信度评估。模型在回答之前,先对自己「肚里的知识」做一个信心打分:信心高于阈值,就直接回答(Direct);低于阈值,就触发检索(Retrieve)。这个判断函数就是触发策略。常见的策略有三种:全量检索(每次都查,稳但慢)、按需检索(信心低才查,快但险)、混合式(先按需,推理中途发现不会就再补查)。

实际操作中,置信度可以由模型输出的概率分数、不确定性估计等指标衡量,而阈值 $\tau$ 是一个需要调参的关键超参数。$\tau$ 调得太低,模型过度自信,答错了还嘴硬;$\tau$ 调得太高,模型动不动就翻菜谱,延迟和成本双双上涨。

阈值 $\tau$ 像阿聪的「心理底线」:资深厨师自信阈值低,遇到七成把握的菜也敢硬做;新主厨阈值调高点,多翻几页菜谱,总比端出黑暗料理强。

Trigger(q)={Retrieve,Conf(q)<τDirect,otherwise\text{Trigger}(q) = \begin{cases} \text{Retrieve}, & \text{Conf}(q) < \tau \\ \text{Direct}, & \text{otherwise} \end{cases}
这是一个「条件决策」公式:对问题 $q$,如果模型信心 Conf 低于阈值 $\tau$,就去检索;否则直接回答。阈值就是阿聪心里的那道安全线。
  1. q(问题)客人的点菜,即当前待回答的 Query。
    qq
  2. Conf(q)(置信度)模型对「自己能否答好」的信心打分,0 到 1 之间。
    Conf(q)\text{Conf}(q)
  3. τ(阈值)阿聪的心理底线,低于这个信心就要查菜谱。
    τ\tau
  4. Trigger(触发决策)整个条件判断的结果,二选一:查,或不查。
    Trigger(q)∈{Retrieve,Direct}\text{Trigger}(q) \in \{\text{Retrieve}, \text{Direct}\}

3. 检索工具设计:菜谱要整理得方便查

菜谱书不是随便翻的。它有目录、有页码、有章节索引,阿聪查「酥皮做法」时绝不会从头翻到尾,而是先看目录锁定页码。知识库也一样——Agent 要能快速准确地查到东西,依赖一个设计良好的检索工具接口。

这个工具接口(Tool API)规定了「怎么问」和「给什么」:输入查询参数,输出候选文档(TopK)。为了让查询更精准,通常要先做 Query 改写:把口语「咋报销啊」改写成规范检索词「报销流程」;再把改写后的文本编码成向量,与知识库中的文档向量做相似度打分,分数最高的 K 篇返回给 Agent。

多源检索整合就像阿聪同时翻「法餐菜谱」和「面点菜谱」两本书——将多个知识库的检索结果按分数归一化后合并排序,让 Agent 一次拿到跨领域的综合证据。工具设计还包括异常处理:搜不到时返回空集,再由 Agent 决定下一步怎么走。

阿聪的案台上放的不只一本菜谱,还有师傅的电话和 iPad 教学视频。工具接口设计得越多、越标准,Agent 的「信息触手」就越长,能触达的知识也就越广。

q′=Rewrite(q),Score(d)=E⃗(d)⋅E⃗(q′)∥E⃗(d)∥ ∥E⃗(q′)∥q' = \text{Rewrite}(q), \qquad \text{Score}(d) = \frac{\vec{E}(d) \cdot \vec{E}(q')}{\|\vec{E}(d)\| \ \|\vec{E}(q')\|}
这是「把问题翻译成机器能比对的格式」的公式:先将用户问题改写成标准查询 $q'$,再用向量余弦相似度给每篇文档打分,分数代表「这篇文档和问题有多相关」。
  1. q'(改写后的查询)把口语、指代不清的问题,转成知识库能听懂的标准问法。
    q′=Rewrite(q)q' = \text{Rewrite}(q)
  2. E(·)(向量编码器)把文字变成一串数字向量,让机器能计算「像不像」。
    E⃗(d), E⃗(q′)\vec{E}(d),\ \vec{E}(q')
  3. Score(d)(文档相关性得分)计算文档与查询的余弦相似度,值越大越相关。
    Score(d)=cos⁡(E⃗(d), E⃗(q′))\text{Score}(d) = \cos\big(\vec{E}(d),\ \vec{E}(q')\big)
  4. TopK(取回前 K 篇)把所有文档按得分从高到低排序,只取前 K 篇返回。
    TopK(D)={d1,d2,…,dK}\text{TopK}(D) = \{d_1, d_2, \dots, d_K\}

4. 信息充分判断:试吃一口才知道够不够

阿聪照着菜谱做了第一版,夹起一块让副厨试吃。副厨皱起眉头:「鱼肉可以,但酥皮根本没起来——这页菜谱的信息不够!」这个「试吃」动作,在 RAG Agent 里就是信息充分性判断。

Agent 拿到检索回来的文档后,不会盲目相信「查到了就对了」。它要评估两件事:一是相关性——这些文档跟当前问题沾边吗?二是覆盖度——文档合起来,能否覆盖问题里的关键信息点(实体、条件、数字)?如果相关性得分低,或者关键信息缺了一大块,就判定为「信息不充分」。

实现时,通常给每篇文档算一个相关性得分,再按排名加权求和,与充分性阈值 $\tau_s$ 比较。评估粒度可以是文档级、句子级甚至 token 级:企业知识助手只需检查关键实体是否全部出现在文档中,复杂推理则让模型生成一个「还缺什么信息」的清单,逐项核对。

这个「试吃」机制,让 Agent 不至于端上一盘「看起来有菜谱、实际上缺步骤」的半成品。阿聪的餐厅能拿米其林三星,靠的就是这一口严谨。

Suff(D)=∑d∈TopKwd⋅Rel(d,q)≥τs\text{Suff}(D) = \sum_{d \in \text{TopK}} w_d \cdot \text{Rel}(d, q) \ge \tau_s
这个公式是说:把 TopK 篇文档的「相关度」按权重加起来,如果总分达到阈值 $\tau_s$,就认为信息够了;不够就说明还缺料。
  1. TopK(候选文档集合)检索器取回的 K 篇文档,就是阿聪翻到的几页菜谱。
    d∈TopKd \in \text{TopK}
  2. Rel(d, q)(相关度)每页菜谱和当前这道菜的相关程度。
    Rel(d,q)\text{Rel}(d, q)
  3. w_d(权重)排名越靠前的文档权重越高,防止「低分长文」淹没高价值信息。
    wdw_d
  4. τ_s(充分性阈值)判定「够不够」的门槛线,达到就算试吃合格。
    Suff(D)≥τs\text{Suff}(D) \ge \tau_s

5. 多轮迭代检索:不够就再打电话追问

阿聪翻完菜谱,发现「酥皮配方」在第 3 页,但做法里写着「需要低温醒面」——低温是多少度?菜谱没写。他掏出手机,又给法国师傅打了个电话。一次没查够,就再查一次;这次的电话比翻书更精准,直接问「4°C 低温醒面多久」。多轮迭代检索,就是把这个「查→评→再查→再评」的循环形式化。

第 $t$ 轮,Agent 用当前查询 $q^{(t)}$ 检索知识库,得到文档集 $D^{(t)}$,然后做充分性判断。如果判定不充分,就用一个 Refine(精化)函数,根据已查到的文档生成更精准的下一轮查询——比如从文档里提炼出「低温=4°C」这个缺失的关键信息,补充进查询词。之后进入第 $t+1$ 轮,直到满足终止条件。

循环不能无限跑下去,所以有两个终止条件:信息充分了(达到阈值 $\tau_s$),或者轮次超过上限 $T_{\max}$(常见 2 到 5 轮)。少了查不全,多了浪费时间和算力,这个「止损线」是多轮迭代的设计精髓。

多轮迭代不是无脑重复,而是「越问越精准」的追问——阿聪的电话越打越短,因为问题越来越聚焦。真正高效的 Agent,每一轮检索都比上一轮更接近答案。

Stop(t)=(S(t)≥τs)∨(t≥Tmax⁡)\text{Stop}(t) = \big(S^{(t)} \ge \tau_s\big) \lor \big(t \ge T_{\max}\big)
q(t+1)=Refine(q(t), D(t))q^{(t+1)} = \text{Refine}\big(q^{(t)},\ D^{(t)}\big)
第一个公式是「什么时候停」:充分了停,或者到最大轮次强制停。第二个公式是「下一轮怎么问」:用已查到的文档精炼出更准的问题,而不是原地重复。
  1. t(迭代轮次)这是第几次查菜谱,从 0 开始计数。
    tt
  2. S⁽ᵗ⁾(第 t 轮充分性得分)这轮查完后的信息充分度,越高越好。
    S(t)S^{(t)}
  3. T_max(最大轮次)最多允许查几轮,防止无限循环的超时上限。
    Tmax⁡T_{\max}
  4. Refine(查询精化)把「菜谱缺页」变成「具体问师傅哪一句」的追问生成器。
    q(t+1)=Refine(q(t), D(t))q^{(t+1)} = \text{Refine}\big(q^{(t)},\ D^{(t)}\big)
  5. ∨(逻辑或)两个停止条件满足任意一个就停。
    A∨BA \lor B

6. 结果整合推理:把菜谱变成自己的菜

菜谱、电话记录、阿聪自己的手艺——三样东西凑齐了。但他绝不会把菜谱纸直接铺在盘子上端给客人。他会动手做菜,把菜谱的步骤融进自己的火候与调味里。这个「融会贯通」的过程,在 RAG Agent 里就是结果整合推理。

Agent 同样不能把检索文档原文整段粘贴给用户。它要经历三步:去重过滤——三篇文档讲同一件事,只留最详细的那篇;上下文注入——把过滤后的证据按逻辑顺序组织进提示词上下文;推理生成——让大模型结合自身常识与检索证据,用通顺、简洁的语言生成答案。每一步都直接影响最终质量。

还有一个生产级细节:检索文档如果太多,会把模型的上下文窗口挤爆,所以要控制注入长度;如果两篇文档「打架」(一个说报销 3 天到账,一个说 7 天),还要按时效性和可信度做矛盾裁决。这些工艺,是 RAG Agent 与「简单拼接」的本质区别。

最终端上桌的是一道完整的菜——菜谱的影子还在(答案里可以追溯引用来源),但已经变成了自己的语言。客人吃到的,是阿聪的厨艺,而不是菜谱复印件。

a^=arg⁡max⁡a Pθ(a∣q, Merge(TopK(D)))\hat{a} = \mathop{\arg\max}_{a} \ P_{\theta}\big(a \mid q,\ \text{Merge}(\text{TopK}(D))\big)
这个公式的意思是:在给定问题 $q$ 和整合后的证据 Merge(TopK(D)) 的条件下,从所有可能的答案中选出模型认为概率最高的那一个——也就是「用证据推理出最靠谱的答案」。
  1. Merge(TopK(D))(证据整合)把取回的文档去重、排序、压缩成一段精炼证据。
    Merge(TopK(D))\text{Merge}(\text{TopK}(D))
  2. P_θ(a | ·)(条件概率)大模型在给定条件下,认为答案 $a$ 有多合理。
    Pθ(a∣q, Merge(TopK(D)))P_{\theta}\big(a \mid q,\ \text{Merge}(\text{TopK}(D))\big)
  3. argmax(取最优)在所有候选答案中,挑概率最高的那个作为输出。
    a^=arg⁡max⁡aPθ(⋅)\hat{a} = \mathop{\arg\max}_{a} P_{\theta}(\cdot)

7. 评估与调优:用顾客点评精进手艺

餐厅每季度看一次顾客点评:复购率、差评关键词「酥皮没起来」、「太咸」。阿聪复盘后发现,上次参考的菜谱出版社不靠谱,换成法国师傅的配方后进步明显。评估与调优,就是 RAG Agent 持续变强的闭环。

RAG Agent 的评估分两层。检索层看 Recall@K:真实相关的文档,有没有被召回?端到端层看答案准确率:模型最终输出的答案,对不对、忠不忠实于检索证据?调优则围绕几个旋钮展开:触发阈值 $\tau$、充分性阈值 $\tau_s$、每轮取回数 TopK、最大迭代轮次 $T_{\max}$,通过评测数据做网格搜索。

调优策略有规律可循:如果「答非所问」频繁,就提高 $\tau$ 让 Agent 更勤快检索;如果「幻觉」变多,就提高 $\tau_s$ 从严把关;如果「检索噪声」干扰大,就调小 TopK。每一步调整都用指标验证,而不是拍脑袋。

好厨师靠客人反馈精进手艺,好 Agent 靠评估指标持续迭代。阿聪的菜谱越用越薄,但他的菜越做越好——这正是 RAG Agent 能不断变强的根本原因。

Recall@K=∣{相关文档}∩TopK∣∣{相关文档}∣\text{Recall@K} = \frac{|\{\text{相关文档}\} \cap \text{TopK}|}{|\{\text{相关文档}\}|}
Acc=1N∑i=1NI(a^i=ai∗)\text{Acc} = \frac{1}{N} \sum_{i=1}^{N} \mathbb{I}\big(\hat{a}_i = a_i^*\big)
第一个公式衡量「该查的有没有查到」:被召回的相关文档占全部相关文档的比例。第二个公式衡量「最终答对的比例」:N 个问题里,预测答案与标准答案一致的占比。
  1. 相关文档(真实答案所在的文档集合)客人真正会点好评的那几道菜对应的菜谱页。
    {相关文档}\{\text{相关文档}\}
  2. TopK(检索返回集合)Agent 实际翻到的 K 页菜谱。
    TopK\text{TopK}
  3. ∩(交集)既相关又被查到的文档集合。
    {相关文档}∩TopK\{\text{相关文档}\} \cap \text{TopK}
  4. I(·)(指示函数)答对记 1,答错记 0,一个简单的计数器。
    I(a^i=ai∗)\mathbb{I}(\hat{a}_i = a_i^*)
  5. N(样本总数)测试集里一共有多少个问题。
    NN

AI 应用场景

企业知识助手

阶段:检索触发决策 + 多轮迭代检索

解决的问题:员工常问「新休假政策」「报销上限」等问题,这些内容频繁更新且不在大模型的训练数据里。传统做法是人工维护 FAQ 或全文检索,答非所问率高。RAG Agent 能先判断「这个问题我有把握吗」,没把握就实时检索企业知识库,信息不充分时继续追问补查。

具体案例:某制造企业的内部助手接到「研发岗年假怎么算」的提问。Agent 先凭参数知识觉得「年假和工龄有关」,但发现「研发岗」的补充条款不在记忆里,遂触发检索,查回最新制度文档;发现缺少「入职未满一年」的子条款,又进入第二轮检索补全,最后整合成一份带引用来源的完整答复。

智能客服

阶段:检索工具设计 + 结果整合推理

解决的问题:复杂售后问题(退换货 + 运费险 + 优惠券叠加)需同时查阅工单系统、商品库、优惠券规则等多个数据源。传统客服机器人只会匹配单条 FAQ,组合问题直接懵。RAG Agent 通过工具接口并行检索多个内部系统,再统一排序、去重、整合后生成答复。

具体案例:电商客服 Agent 收到「用了 20 元券买的衣服想退,运费险还生效吗」。它并行调用订单查询工具、优惠券规则库、运费险政策库三个接口,发现一篇文档说「退货运费险随订单生效」,另一篇说「已使用优惠券不退现金」,通过矛盾裁决后整合出「可退货、券不退现金、运费险可用」的准确答复。

科研文献研究助手

阶段:Query 改写 + 充分性判断 + 多轮迭代检索

解决的问题:研究人员提问「Transformer 的注意力机制在长文本上的变体」,表述口语化、概念宽泛。直接检索要么搜不到,要么返回一堆不相关论文。RAG Agent 先把问题改写为「long-context transformer attention variants」,检索后评估覆盖度,发现缺少「稀疏注意力」这一子方向,再补充检索第二轮。

具体案例:某药物研发团队使用研究助手调研「靶点抑制剂的 ADMET 预测方法」。Agent 第一轮检索到综述文献但缺乏最新数据,判定不充分后,从文献关键词中提炼出「graph neural network」等术语精化查询,最终整合了 6 篇高相关论文,输出带引用的调研摘要,节省了约 3 天人工调研时间。

Python 演示

python64 行
class RAGAgent:    """极简 RAG Agent 演示: 模拟"查菜谱"决策循环"""     def __init__(self, knowledge_base, threshold=0.8, top_k=2):        self.kb = knowledge_base          # 外部知识库(菜谱库)        self.threshold = threshold        # 触发检索的置信度阈值 tau        self.top_k = top_k                # 每轮取回 TopK 文档        self.retrieve_count = 0           # 检索次数计数器     def estimate_confidence(self, query):        """模拟模型对自身知识的信心评估(0~1)"""        hits = sum(1 for kw in self.kb if kw in query.lower())        return min(1.0, hits / 3.0)     def retrieve(self, query):        """检索器: 在知识库中找候选文档"""        self.retrieve_count += 1        docs = []        for kw, content in self.kb.items():            if kw in query.lower():                docs.append((kw, content, 1.0))        docs.sort(key=lambda x: x[2], reverse=True)        return docs[:self.top_k]     def judge_sufficient(self, docs, query):        """充分性判断: 问题里的关键实体都要被覆盖"""        words = [w for w in query.lower().split() if w.isalpha() and len(w) > 3]        covered = [w for w in words if any(w in d[1].lower() for d in docs)]        return len(covered) >= max(1, len(words))     def refine_query(self, query, docs):        """根据已查到的文档, 生成更精准的下一轮查询"""        extra = " ".join(            w for kw, content, _ in docs            for w in (kw + " " + content).lower().split()            if w.isalpha() and len(w) > 4 and w not in query.lower()        )        return (query + " " + extra).strip()[:60]     def answer(self, query, max_rounds=3):        """RAG Agent 主流程: 信心判断->检索->充分性判断->迭代"""        docs = []        for _ in range(max_rounds):            if self.estimate_confidence(query) >= self.threshold:                break                    # 信心足, 直接回答            docs = self.retrieve(query)  # 翻菜谱            if self.judge_sufficient(docs, query):                break                    # 试吃合格, 停止检索            query = self.refine_query(query, docs)        if not docs:            return "信息不足: 建议人工确认或补充知识库"        return "综合检索结果: " + " | ".join(content for _, content, _ in docs)  if __name__ == "__main__":    kb = {        "leave": "leave policy: 15 paid days per year",        "reimburse": "reimburse policy: submit via OA within 3 days",    }    agent = RAGAgent(kb)    print(agent.answer("leave policy for new employees"))    print("检索次数:", agent.retrieve_count)    print(agent.answer("insurance claim process"))    print("检索次数:", agent.retrieve_count)
目的:用不到 60 行代码实现一个极简 RAG Agent,演示「信心判断 → 触发检索 → 充分性判断 → 多轮迭代」的完整决策循环。运行后你会看到:熟悉的问题触发检索后快速给出答案,完全陌生的知识领域则要迭代无果后建议人工确认。
  1. hits = sum(1 for kw in self.kb if kw in query.lower())数问题里命中几个知识库关键词,用于估算「有没有把握」。
  2. self.retrieve_count += 1每检索一次计数器加一,对应阿聪翻菜谱的次数。
  3. docs.sort(key=lambda x: x[2], reverse=True)按相关性得分排序,取最高的 TopK 篇。
  4. return len(covered) >= max(1, len(words))「试吃」判断:关键实体全部被覆盖才算信息充分。
  5. query = self.refine_query(query, docs)信息不足时,从已查文档中提炼新词,生成更精准的追问。
  6. if self.estimate_confidence(query) >= self.threshold: break信心足够就直接回答,不浪费检索资源。

常见误区

误区很多初学者觉得 RAG Agent 不就是「让模型能上网搜资料」嘛,把知识库一接,模型就会自己查了,没什么复杂的。

正解搜索框只是工具箱里的一个零件。RAG Agent 的真正价值在于完整的决策循环:要不要检索(触发策略)、检索后够不够用(充分性判断)、不够怎么办(多轮迭代)、拿到手怎么用(结果整合)。就像阿聪不是「有本菜谱」就能当主厨,关键在于他什么时候翻、翻完怎么判断、判断完怎么用。

为何常见:因为日常使用的工具型 Agent 界面都极简,点一下就能搜索,背后的决策逻辑被封装得看不见,容易让人把表象当本质。

误区与其费劲判断「该不该查」,不如任何时候都先检索一遍,多查总不会错吧。

正解每次都检索有三大代价:延迟(查询耗时)、噪声(不相关内容混入)、成本(API 和算力开销)。大量问题模型本身就会,比如「1+1 等于几」或热门常识,检索纯属多余,还会把不相关内容当证据引入,反而诱发幻觉。正确做法是按需触发:信心不足才查,就像阿聪不会为「番茄炒蛋」去翻菜谱。

为何常见:把「查资料」和「答得不好」简单对立,直觉上觉得多查一步总比少查一步安全,忽略了噪声和成本的代价。

误区TopK 设得越大,拿到的知识点越多,答案一定越可靠吧?

正解文档过多会挤爆上下文窗口,多篇文档之间还可能互相矛盾,模型被噪声干扰后反而答非所问。工程实践通常把 K 控制在 3 到 8 篇,再配合重排序(把最相关的排到前面)和过滤来提升质量。阿聪也不会把整本菜谱扛到灶台边——他只翻需要的那几页。

为何常见:直觉上「信息量 = 质量」,忽略了语言模型注意力资源的有限性,以及冗余矛盾信息的干扰效应。

误区多轮检索不就是循环调用检索函数嘛,只要多跑几轮,答案自然会更好。

正解无脑重查和「第一次没查好、第二次也差不离」。真正的多轮迭代包含三个要素:Query 改写(每一轮的问法都比上一轮更精准)、充分性判断(知道什么时候可以停)、终止条件(防止无限循环)。阿聪第二次打电话之所以能解决问题,是因为他带着「4°C 醒面多久」这个具体问题去问,而不是把第一个问题原样再问一遍。

为何常见:把「循环次数」误当成「迭代」,忽略了迭代的本质是每轮都有信息增益,而不仅仅是重复执行。

误区很多人写完检索后,直接把文档段落往 prompt 里一贴,让模型照着输出,认为 RAG Agent 就大功告成了。

正解原样粘贴等于把菜谱纸端上桌。生产级的整合要经过去重(多篇讲同一件事只留精华)、矛盾处理(不同来源打架时按可信度裁决)、逻辑组织(先背景后细节地排布证据),最后让模型用自己的语言生成答案,并保留引用可追溯。这一步的质量直接影响答案的可读性和忠实度。

为何常见:Demo 阶段简单拼接就能跑通,导致很多人误以为生产环境也这么做,忽视了工程化与原型验证之间的巨大差距。

面试题

Q1. RAG Agent 与传统 RAG 最本质的区别是什么?

单选题 · easy

  • A.检索触发由策略自主决策← 正确答案
  • B.使用更大的预训练模型
  • C.不需要任何外部知识库
  • D.生成阶段不再使用解码器

答案:A。传统 RAG 是「固定先查后答」,而 RAG Agent 的核心是策略函数自主决定何时检索、是否多轮迭代。就像阿聪不是每道菜都翻菜谱,而是先判断有没有把握。B 是规模问题,C 和 D 与 RAG 的定义直接矛盾。

Q2. 触发策略中「Confidence(q) < τ」表示什么?

单选题 · easy

  • A.信心充足,直接作答
  • B.信心不足,触发检索← 正确答案
  • C.文档得分低,重写查询
  • D.答案太短,启动多轮

答案:B。Confidence(q) 是模型对问题的信心打分,τ 是阈值。信心低于阈值就说明「心里没底」,需要触发检索;高于阈值才直接回答。C 指的是检索之后的处理,D 与触发策略无关。

Q3. Query 改写(Rewrite)的主要作用是什么?

单选题 · hard

  • A.将口语转成规范检索词← 正确答案
  • B.把答案翻译成多语言
  • C.缩小检索结果范围
  • D.提升模型推理速度

答案:A。Query 改写把「咋报销啊」这类口语、指代不清的表达转换成知识库能精确匹配的规范查询词,是检索质量的第一道保障。它不负责翻译答案、也不直接改变检索数量和推理速度。

Q4. 信息充分性判断为「不充分」时,Agent 的正确做法是什么?

单选题 · mid

  • A.直接输出当前检索结果
  • B.迭代检索并精化查询← 正确答案
  • C.降低阈值直至通过
  • D.丢弃所有检索文档

答案:B。不充分说明现有证据不足,正确做法是进入下一轮迭代:根据已查文档精化查询词,再查一轮。A 会输出半成品,C 是作弊式自欺,D 等于前功尽弃。就像阿聪试吃发现酥皮没起来,应该去追问师傅而不是硬上菜。

Q5. 检索环节中的 TopK 表示什么?

单选题 · easy

  • A.返回得分最高K篇文档← 正确答案
  • B.检索 K 个知识库
  • C.生成 K 个候选答案
  • D.迭代 K 轮检索

答案:A。TopK 是「取相关性得分最高的 K 篇文档」返回给 Agent,是检索器的标准输出形式。它不限制知识库数量、不决定生成候选数、也不控制迭代轮数。

Q6. 多轮迭代检索的终止条件包含哪些?

多选题 · mid

  • A.充分性得分达到阈值← 正确答案
  • B.达到最大迭代轮次← 正确答案
  • C.用户主动更换问题
  • D.检索文档数为零

答案:AB。终止条件只有两个:信息充分(S(t) ≥ τs)或轮次耗尽(t ≥ T_max)。C 是用户行为而非 Agent 决策;D 文档数为零通常会触发换词重试而不是直接终止,否则「第一次搜不到就放弃」会大幅降低召回率。

Q7. 结果整合模块需要处理哪些问题?

多选题 · mid

  • A.多文档信息去重← 正确答案
  • B.文档间矛盾裁决← 正确答案
  • C.查询关键词扩展
  • D.证据上下文注入← 正确答案

答案:ABD。整合阶段负责去重(多篇讲同一件事)、矛盾裁决(不同来源结论冲突)和上下文注入(把证据组织进提示词)。C「查询关键词扩展」属于检索阶段的 Query 改写职责,不在整合模块。

Q8. Recall@K 评估的是什么能力?

单选题 · mid

  • A.相关文档被召回占比← 正确答案
  • B.生成答案与标签匹配
  • C.统计检索耗时长
  • D.计算文档去重比例

答案:A。Recall@K 衡量检索层「该查的有没有查到」——真实相关文档中被 TopK 召回的比例。B 是端到端准确率的指标,C 是性能指标,D 是整合模块的内部行为,都不属于召回率。

Q9. Agent 频繁「答非所问」,哪些调优方向是合理的?

多选题 · hard

  • A.提高触发阈值,更频繁检索← 正确答案
  • B.收紧充分性阈值,从严把关← 正确答案
  • C.扩大 TopK,塞入更多文档
  • D.禁用查询改写,用原问

答案:AB。答非所问往往源于「该查没查」或「证据不足仍硬答」。提高触发阈值 τ 让 Agent 更勤快检索,提高充分性阈值 τs 让不合格证据无法通过。C 扩大 TopK 会引入更多噪声,让问题更严重;D 禁用改写会降低检索精度。

Q10. 两篇检索文档对同一问题给出相反结论时,整合阶段最合理的处理方式是什么?

单选题 · extreme

  • A.按可信度时效性裁决← 正确答案
  • B.随机丢弃其中一篇
  • C.两篇都原样拼接
  • D.取字符数更多一篇

答案:A。矛盾裁决应依据可信度(来源权威性、相关性得分)和时效性(政策类文档新版优先),像阿聪发现出版社不靠谱后换法国师傅的配方。B 随机丢弃会丢掉可能正确的信息;C 原样拼接让模型无所适从;D 长度与正确性无关。