很多人做 RAG Agent 时卡在同一个地方:资料是检索出来了,但模型要么不会主动去查,要么一查就停不下来。这篇不聊概念定义,只给一条能落地的思路——把检索当成 Agent 的一个普通工具,塞进它的调用循环里,然后回答三个问题:工具怎么拆、循环怎么收尾、钱和步数怎么刹住。读完你能画出一张自己的流程图,知道哪些环节该自己写代码,哪些交给模型判断。
很多人做 RAG Agent 时卡在同一个地方:资料是检索出来了,但模型要么不会主动去查,要么一查就停不下来。这里不聊概念定义,只给一条能落地的思路——把检索当成 Agent 的一个普通工具,塞进它的调用循环里。然后回答三个问题:工具怎么拆、循环怎么收尾、钱和步数怎么刹住。
读完你应该能画出一张自己的流程图,知道哪些环节该自己写代码,哪些交给模型判断。判断标准很简单:如果模型需要在第二跳才知道该查什么,就适合嵌进循环;如果一开始就知道要查什么,预取更省事。
先想清楚:为什么要把检索塞进循环,而不是先查完再问
预取式 RAG 的前提是你提前知道该查什么。Agent 场景里问题往往是多跳的:先查到一个名词,才知道下一步该拿这个名词去查什么。把检索做成工具,模型可以按需决定查不查、查几次、换什么词再查,这是它和固定流水线最大的区别。
- 判断一:任务是否需要根据上一步结果决定下一步查什么。是,则嵌循环;否,则预取。
- 判断二:语料是否稳定、问题是否单一。是,预取更便宜也更快,不必上 Agent。
- 判断三:调用次数能否接受波动。嵌循环的调用次数不可预测,延迟和费用都会上去。
- 判断四:有没有兜底答案。检索不可用时如果只能说「没查到」,体验会变差,预取至少保证有东西可讲。
检索拆成几个工具:一个全能工具还是多个小工具
一个全能工具的好处是简单,坏处是模型必须在一次调用里同时决定「查什么词、走哪条路、要不要过滤」。拆成多个小工具,模型每次只做一个决定,成功率反而更高。常见拆法是:向量检索、关键词或精确匹配、按元数据过滤、读整篇文档,各自独立成一个工具。
| 工具 | 什么时候用 | 返回什么 |
|---|---|---|
| 向量检索 | 问题偏语义、说法和原文不一致时 | 带来源标识的片段,不含整篇 |
| 关键词匹配 | 要找精确名词、编号、报错文本时 | 命中的原文行或段落 |
| 元数据过滤 | 需要限定时间、来源、类型时 | 符合过滤条件的候选清单 |
| 读整篇文档 | 片段不够、要看上下文时 | 按文档标识取出全文或指定区间 |
工具描述比工具本身更重要。写清「什么时候用它、参数怎么填、返回什么」,模型才知道该调哪个。参数设计上宁少勿多,必填项越少越不容易出现参数报错。返回结果别塞整篇原文,先回片段加来源标识,需要全文再让模型调第二个工具去取。
{"name":"search_by_vector","description":"语义检索,适合问题说法和原文不一致时。参数 query 为自然语言问题,top_k 默认取较小值。返回片段加来源 id,不含全文。"}循环怎么收尾:步数、终止条件和结果拼装
嵌进循环后,最容易出问题的不是检索质量,而是收不住。模型会出于「保险」再多查一轮,或者卡在同义词上反复查。给一个明确的步数上限,并且把「已达上限」当成正常返回而不是报错,让模型基于已有片段作答。
- 设步数上限在循环外面写一个计数器,达到上限就跳出,把已收集的片段一起交给模型,要求它基于现有信息作答并说明信息可能不完整。
- 写终止条件在提示词里明确:信息够了就直接回答,不要为了保险再多查一轮。终止条件要具体,比如「已有片段能覆盖问题里的每个子问句」。
- 结果去重拼装多轮检索的结果按顺序拼进上下文,重复片段先做去重,否则上下文里全是同一段话,既费 token 又干扰判断。
- 记录每轮动作把「查了什么词、拿到什么、下一步打算查什么」记进日志。出问题时才看得出是检索没召回,还是模型没用好。
循环的上限不是模型决定的,是你在外面写的那行计数器决定的。
成本和体验怎么刹住:缓存、并发与降级
同一批文档反复被检索是常态。把片段做成短期缓存,能省掉相当一部分重复调用。缓存键建议用「查询词加过滤条件」的组合,别只按查询词,否则过滤一变就串了。检索工具和模型调用分别看延迟,先量出自己这边的基线,再判断慢在哪一段。
- 缓存:按查询词加过滤条件做键,命中直接返回片段,不走检索服务。
- 延迟:分别量检索和模型两段的耗时,别混在一起看总时长。
- 降级:检索服务不可用时,让 Agent 明确说「没查到」,而不是编一段话出来。
- 预算:把每轮循环的 token 消耗按任务维度记下来,做单任务预算,而不是只看总账单。
- 并发:同一用户的多轮请求串行处理,避免同一批文档被并发重复拉取。
上面这几条没有绝对优先级,要看你们线上表现。如果延迟高但费用正常,先查检索工具本身;如果费用高但延迟正常,先查是不是在反复拉同一批文档。两类问题排查顺序不一样,别一上来就调模型参数。
下一步把你现在的检索调用点标出来,看看哪些适合做成工具、哪些留着预取。然后在站内的工具目录里找现成的调试或测速工具,先量出自己这边的基线再改。→常见问题
RAG 和 Agent 一定要结合吗?
不一定。单轮问答、语料固定、问题类型稳定的场景,普通 RAG 就够用,加 Agent 只会让延迟和费用变高。只有当问题需要分几步、第二步依赖第一步的结果时,把检索放进循环里才划算。
检索工具该给模型几个?
起步给两到三个即可:一个语义检索、一个关键词或精确匹配,必要时加一个读全文。工具越多,模型选错的概率越高。等实测发现某类问题总是召回不到,再加专门工具。
怎么判断是检索没查到还是模型没用上?
把每轮的工具调用参数和返回片段记进日志。如果返回里明明有答案而模型没引用,通常是提示词没说清要怎么用;如果返回片段里根本没有相关内容,那是切分或检索策略的问题,换模型没用。