llamaindex self-rag

接入与开发

讲清 LlamaIndex 里 Self-RAG 的自我反思检索流程:什么时候该补检索、什么时候该收手,以及工程上怎么落地。

用 LlamaIndex 搭 RAG,最烦的是检索命中一堆不相关片段,模型照样照着编。Self-RAG 的思路是让模型在生成过程中自己判断:这里要不要再查一次、查回来的东西靠不靠谱、答案有没有依据。这篇给的是判断标准和落地步骤,配合站内目录页一起看效果更好。

用 LlamaIndex 搭 RAG,最烦的场景不是检索不到东西,而是明明召回一堆不相关片段,模型照样照着编。Self-RAG 的思路是让模型在生成过程中自己判断:这里要不要再查一次、查回来的东西靠不靠谱、写出来的答案有没有片段撑着。这篇只讲这一个角度,给的是判断标准和能落地的步骤。

一个常见误区是把 Self-RAG 当成换一个更聪明的检索器。其实检索器该召回什么还是召回什么,多出来的是一层生成中的反思:它决定要不要继续查、要不要收手,以及当前输出站不站得住脚。下面按流程拆开说,配合站内目录页对照着看更清楚。

Self-RAG 到底多做了什么

普通 RAG 是「一次检索、一次生成」,检索结果好坏在生成前就定死了,模型只能硬着头皮往下写。Self-RAG 把「要不要检索」和「检索得怎么样」变成生成过程中的判断点,检索不再是前置步骤,而是可以被触发的动作。

  • 这段需不需要外部资料:问题本身就能答的,不必强行去查;
  • 召回片段是否相关:不相关的片段要能被识别出来并丢弃,而不是硬塞进上下文;
  • 生成内容有没有被片段支撑:写出的每个关键结论,要能在召回内容里找到依据;
  • 整体有没有用:答非所问或者信息量太低,也要能被标出来而不是直接返回。

关键区别在于,它愿意因为一次不满意的召回而再查一轮。比如第一轮只捞到边角信息,它会改写或拆细问题重查,而不是把不够用的片段凑合进上下文。反过来说,如果文档量很小、问题范围固定、答案本来就该来自模型常识,加这层反思只会拉长链路和成本,这时候反而该关掉。

对比项普通 RAGSelf-RAG
检索时机生成前一次性完成生成过程中按需触发
召回不相关时硬塞进上下文丢弃并可能改写查询重查
输出约束提示词里要求别乱编逐段判断有没有依据
适合场景文档少、问题固定文档杂、问题开放

在 LlamaIndex 里对应哪些部件

在 LlamaIndex 里,检索器只负责召回,反思环节更多是靠提示模板和输出结构实现的。重点是让判断结果变成可解析的字段,而不是让模型自由发挥写一段话,否则后面的逻辑根本没发接。

检索器
照旧负责召回,反思层不改变它召回什么,只影响要不要再召回一次
查询改写
召回不相关时把原问题拆细或换措辞再查,不是原样重试
结构化输出
把「要不要查」「够不够」做成明确字段,让代码能读到并分支
出口判断
判断为已有依据就收手生成,判断为还缺信息才继续查

顺序上建议先确认召回本身稳不稳,再考虑加反思层。如果检索器捞回来的内容本来就偏,反思层再聪明也补不回来。挑向量库和嵌入模型的时候,到 /stacks/vector-dbs 和 /embeddings 把候选翻一遍,重点看召回质量和过滤能力,别一上来就堆反思逻辑。

多轮反思的成本与时延怎么控

每多一轮「判断 + 检索 + 重写」就是一次额外调用,很容易一不留神把一次问答变成五六次模型请求。先给自己定上限:最多补查几轮、单次请求的总时延上限是多少,超了就返回当前最好的结果,别让它一路空转。

  1. 定轮数上限把补查轮数写死在配置里,比如最多两轮;超出直接收手生成,并记录触发上限的次数。
  2. 分档用模型判断环节用小模型或更短提示词,只有真正需要生成最终答案时再升级,避免全程大模型。
  3. 记录每轮指标把每轮检索条数、命中分数、是否触发补查记进日志,没有这些数据就调不动阈值。
  4. 量延迟基线到 /tools/speed-test 把接口延迟基线量一遍,判断是链路慢还是上游慢,别凭感觉归因。

如果业务本来就要求快,就只保留「要不要检索」这一个判断点,把多轮反思砍掉,别硬上全套。省钱的具体数字随模型和时间在变,到 /price-watch 核对当时的报价再算账更靠谱。

怎么验证这层反思真的有用

别只看单次问答顺不顺眼,要准备一小批评测问题,覆盖三类:答不上来的、需要两跳检索的、本来就该直接答的。看这三类里反思层会不会做出不同反应,如果都一样,说明判断点等于没起作用。

问题类型期望的反思行为不达标的样子
答不上来的触发补查或明确说不知道硬编一个答案
需要两跳的拆问题、多轮召回只答对一半
该直接答的不触发检索直接生成无谓地查一轮拖时间
  • 对照跑两组:关掉反思的普通 RAG 和开启反思的版本,比较答案里有没有出处、有没有把不相关片段当依据;
  • 判断阈值别拍脑袋,先看日志里命中分数的分布,再定低于多少就补查,跑几天再调;
  • 换模型或换嵌入模型之后整套阈值都要重测,参考 /benchmarks 的口径变化再决定要不要重跑;
  • 模型和方案的整体对比可以到 /rankings 看当前排序,但要明白那是通用口径,你的业务未必照着排。

常见跑偏与排查顺序

跑偏了别急着改提示词,按顺序排更省时间。很多所谓「Self-RAG 不好用」,其实问题根本不在反思层本身。

  1. 先查检索质量翻几轮日志,看召回是不是全是不相关片段;召回本身不行,反思层补不回来。
  2. 再查判断字段确认结构化输出有没有被正确解析,字段解析不稳会让整个反思逻辑直接失效。
  3. 最后查上限和超时确认轮数上限和超时设置写了没有;很多「很慢」其实是没设上限,一路查到超时。
  4. 兜底方案业务要快要稳就只留「要不要检索」一个判断点,把多轮反思砍掉,别为了概念硬撑。
Self-RAG 的价值不在于多查几轮,而在于知道什么时候不该查、什么时候该收手。
下一步想比较不同中转和官方渠道的实际表现与价格,再去目录页把候选筛一遍,比直接猜哪个划算更快。

常见问题

Self-RAG 和普通 RAG 最本质的区别是什么?

普通 RAG 的检索次数和时机是固定的,生成阶段没有回头路;Self-RAG 把检索变成一个可以多次触发、也可以被否决的动作,模型会判断召回内容够不够用,不够就再查一轮。代价是调用次数和时延都上去了,所以要先确认你的召回本身没问题,再考虑加这层。

在 LlamaIndex 里做 Self-RAG,工作量主要花在哪?

主要不在检索器,而在判断环节的可控性:提示模板要稳定输出可解析的判断字段,轮数上限、超时、失败兜底都要自己定。其次是日志,得能看出每轮查了什么、为什么补查,不然调优全靠猜。先做一个只判断「要不要查」的最小版本,跑通再加多轮。

什么情况下不建议上 Self-RAG?

文档规模小、问题范围固定、对响应速度要求高的场景,多轮反思带来的收益往往抵不过时延和成本。另外如果检索质量本身就差、召回经常偏题,先修分块和嵌入模型更划算,反思层救不了坏召回。判断标准可以先在站内量一遍延迟基线,再决定值不值得加。

本文依据各平台公开文档与官方公告整理,只做中文归纳;具体做法、参数与限制以官方文档为准。