loading

Loading

探索与发现

首页 AI 开发实战

RAG 的下一站:Agentic Retrieval

字数: (2774)
阅读: (6)
0
摘要:用户问“我们去年买的套餐现在还能退吗”,经典 RAG 检索出一段通用退款政策就结束了。可这个问题至少要拆成订单时间、地区、套餐版本三件事。Agentic Retrieval 要解决的,就是这种“一次检索不够用”的场景。

前段时间看一个客服知识库的 bad case。用户问:“我们去年买的套餐现在还能退吗?”

经典 RAG 的做法是拿这句话去向量库检索,返回一段退款政策,然后让模型生成答案。问题是,这段政策是通用条款,真正决定答案的至少有三件事:订单是什么时候买的、用户在哪个地区、买的是哪个版本的套餐。

一次检索把这三件事全漏了。模型只能根据通用条款给一个模糊的回答,听起来很合理,但没法执行。

这就是 Agentic Retrieval 想解决的问题。

一次性检索,差在哪

经典 RAG 的假设是:问题所需的知识,能在一轮检索里找齐。这个假设在很多场景成立,比如“这个函数的参数是什么”“公司的报销标准是多少”。

但遇到下面这些情况,它就开始吃力:

问题需要多个文档拼起来;条件藏在上下文里,需要先追问;知识有时效性,旧版本和新版本混在一起;答案需要计算或比较;用户的问题本身就很模糊,需要先澄清。

单次检索没有机会修正。第一次没找对,后面只能在错误的证据上生成。

把检索当成工具

Agentic Retrieval 的核心变化,是把检索从“预处理步骤”变成 Agent 可以规划和调用的工具。

一个典型的循环是:先理解问题,拆成几个子问题;针对每个子问题选择数据源和查询方式;拿到结果后判断证据够不够;不够就改写查询或者换一个数据源;够了再生成答案。

还是前面那个退款问题,拆开之后大概是:

订单是什么时候买的?查订单库。用户在哪个地区?查用户资料。适用哪版退款政策?查政策库,并确认版本有效期。三者合起来,才能回答“能不能退”。

这听起来像人处理问题的方式,因为它本来就是。难点不在于让模型多调几次工具,而在于让它知道什么时候该继续、什么时候该停。

Planner 不一定非要用大模型。固定业务场景里,用规则或者小模型做子问题拆分,成本更低,行为也更稳定。大模型适合处理开放的、边界不清的问题,不适合每次都重新发明一套固定的查询流程。

多轮检索要有预算

Agentic Retrieval 最容易被滥用的地方,是把“多轮”变成“无限轮”。

如果没有预算,Agent 很容易陷入循环:查不到就换个关键词,再查不到就再换,最后烧掉一堆 token,还是没答案。

我现在会给它设几道闸:

最大轮次,按任务复杂度定,通常 2 到 5 轮;时间预算,超过就返回当前最佳结果并标注不确定性;早停条件,所有子问题都有高置信证据,或者连续两轮没有新增有效证据,就停;并行化,互不依赖的子问题同时查,降低延迟。

还有缓存。常见查询、文档切片和重排结果都可以缓存,但缓存键要带上权限和版本,不能只按内容哈希。

证据够不够,要让系统自己说

多轮检索最关键的组件不是 Planner,而是 Verifier。

Planner 决定去哪找,Verifier 决定找够了没有。后者如果只是让模型“感觉一下”,整个循环就没有可靠的停止条件。

我一般要求 Verifier 输出结构化结果,比如:

{
  "sufficient": false,
  "missing": ["退款到账时间"],
  "conflicts": ["新旧政策对退款期限说法不一致"],
  "next_action": "search_faq"
}

这样系统才能根据 sufficient 决定继续还是结束,根据 missing 决定下一轮查什么,根据 conflicts 决定是否要人工介入。

把“够不够”变成可判断的信号,比让模型自由发挥稳定得多。

评测要看过程

Agentic RAG 的评测,不能只看最终答案像不像。

要看的至少有几件事:关键证据有没有被找到;引用的证据是否真的支持结论;多轮之后有没有跑偏;成本和时间是否可接受;遇到无答案或越权问题时,能不能正确地说“不知道”或“没权限”。

我一般会准备一组黄金问题,覆盖单跳、多跳、时间条件、证据冲突、无答案和越权场景。其中“无答案”和“越权”最容易暴露问题,因为很多系统会强行编一个答案。

另外,引用准确率要单独看。答案对了但引用错了,在知识库场景里是严重问题,因为用户会顺着引用去核对。

引用生成还有一个细节:不要等答案写完再让模型补引用。正确顺序是先生成带证据编号的草稿,再按编号替换成真实文档位置。反过来做,模型很容易把引用“分配”给看起来最相关的段落,而不是真正支撑结论的那一段。

什么时候别用

Agentic Retrieval 不适合所有场景。

如果问题简单、答案就在单篇文档里,经典 RAG 更快也更便宜。如果延迟要求很高,多轮检索很难满足。如果数据源单一且质量稳定,没有必要引入复杂的规划器。

我见过一些团队,把原本一个向量检索就能解决的问题,改成了三四个 Agent 协作,结果延迟翻倍,准确率没涨。复杂度应该由问题决定,不是由技术潮流决定。

把问题拆开之后

还是那个退款问题。系统第一次检索只拿到了通用政策,Verifier 判断缺少订单时间和地区,于是进入第二轮。

第二轮并行查了两个地方:订单库返回购买日期和套餐版本,用户资料返回所在地区。拿到之后,Verifier 发现政策库里还有一份旧版条款,和新版在退款期限上冲突,于是要求确认政策生效时间。

第三轮只查了一件事:这份订单购买时适用哪版政策。拿到明确版本后,证据齐了,系统停止检索,生成答案,并把订单号、政策版本和条款位置一起写进引用。

整个过程三轮,耗时不到两秒,比一次性检索慢,但答案能落地。

这里有几个工程细节值得注意。

查询改写不要只做同义词替换。多跳问题需要把“去年买的套餐”拆成“订单时间 + 套餐版本”,这更像信息抽取,而不是改写。

引用要跟着证据走。最终答案里的每个关键结论,都应该能对应到具体文档和段落。生成之后再让模型补引用,很容易编。

缓存要带权限。同一个问题,不同租户的答案可能不同,缓存键里必须有租户和权限范围,否则会把别人的数据捞出来。

冲突证据怎么处理

多轮检索很容易撞上互相矛盾的证据:新旧政策、不同地区的条款、两个部门各自维护的文档。

遇到冲突,我现在不让模型自己选。先按版本和生效时间过滤,过期的直接丢掉;如果都有效,就按来源权威性和适用范围排序;还是无法判断,就把冲突明确写进上下文,让答案标注“此处存在不一致”,必要时转人工。

最怕的是把冲突藏起来。模型看不到矛盾,就会随机挑一个,而且答得很自信。

回到那个退款问题

Agentic Retrieval 的价值,不是让 RAG 更复杂,而是让系统在证据不足时有机会补救,在证据充分时知道停止。

我现在判断一个 RAG 系统是否成熟,会看它能不能说清楚:这次答案用了哪些证据,为什么这些证据够了,哪些地方其实还不确定。

说不清楚的,大概率还停留在“检索一段、生成一段”的阶段。

转载请注明出处: 皮哈皮阿

本文的链接地址: https://blog.phpat.com/ai-dev/agentic-retrieval.html

手机扫码阅读

微信或手机浏览器扫一扫,随时随地随心阅读与分享

1 / 1
预览图