什么是 Self-RAG?它如何通过自我反思提升回答质量?

#RAG#Agent#面试八股

什么是 Self-RAG?它如何通过自我反思提升回答质量?

结论:Self-RAG(Self-Reflective Retrieval-Augmented Generation)把"要不要检索、检索到的有没有用、自己说的有没有依据" 交给模型在生成过程中自己判断。传统 RAG 是"固定检索一次,塞进去就生成",Self-RAG 则是"按需检索 + 逐段评估 + 不合格就重来", 用一个会打分的小模型(critic)产出反思标记(Reflection Token)来驱动控制流。

1. 四类反思标记

标记回答的问题取值用在哪
Retrieve这个问题需要检索吗yes / no / continue生成开头,决定是否发起检索
ISREL这段资料和问题相关吗relevant / irrelevant过滤候选段落
ISSUP这句话被资料支持吗fully / partially / no校验生成的每句话
ISUSE这个回答有用吗1~5多候选之间选优

原论文的做法是先用强模型标注一批"带标记"的数据,再微调出一个能自己输出这些标记的小模型。工程上也可以用提示词复现近似效果。

2. 控制流

query
  │
  ▼
[Retrieve?] ──no──▶ 直接生成 ──▶ 输出
  │yes
  ▼
检索 top-k
  │
  ▼
逐段 [ISREL] ──irrelevant──▶ 丢弃(k 太小就补检索)
  │relevant
  ▼
生成答案
  │
  ▼
逐句 [ISSUP] ──no/partial──▶ 标记该句 ──▶ 换查询重检索(最多 R 轮)
  │fully
  ▼
[ISUSE] 打分 ──▶ 多个候选取最高 ──▶ 输出

3. 与其它"会反思"的方案对比

方案检索时机评估粒度需要训练额外开销
朴素 RAG固定一次无否无
CRAG(Corrective RAG)先检索再判质量文档级否1 次判定
Self-RAG按需 + 循环段落级 + 句子级原论文需要2~4 倍
Agentic RAG由 Agent 决定步骤级否多轮工具调用

CRAG 的策略更简单:检索结果分"正确/错误/模糊"三档,错误就转网络搜索,模糊就做查询分解。Self-RAG 的粒度更细,代价也更大。

4. 工程近似实现:用提示词做反思循环

import json

# chat(system, user) 是对 chat.completions.create 的一层薄封装
JUDGE_RETRIEVE = '判断回答该问题是否需要查知识库。输出 JSON:{"retrieve": true|false, "reason": "..."}'
JUDGE_SUPPORT = ('判断<答案>中每句是否被<资料>支持。输出 JSON:'
                 '{"unsupported": ["原句"], "verdict": "pass|fail"}')

def self_rag(question: str, max_rounds: int = 2) -> str:
    need = json.loads(chat(JUDGE_RETRIEVE, question))["retrieve"]
    if not need:                                  # 闲聊、常识题:省掉检索
        return chat("直接回答,简洁。", question)

    best, best_score = None, -1.0
    query = question
    for _ in range(max_rounds):
        docs = retrieve(query, k=8)
        rel = [d for d in docs if judge_relevance(question, d) == "relevant"]
        if not rel:
            query = rewrite(question)             # 相关段落全被否,换查询再来
            continue
        ans = generate(question, rel)
        verdict = json.loads(chat(JUDGE_SUPPORT, f"<资料>{rel}</资料>\n<答案>{ans}"))
        score = 1.0 if verdict["verdict"] == "pass" else 0.5
        if score > best_score:
            best, best_score = ans, score
        if score == 1.0:
            break                                  # 全部有依据,提前退出
    return best or "知识库中未找到足够依据,建议转人工。"

三个要点:最大轮数必须设(否则死循环烧钱)、每轮换查询(重复相同检索没有意义)、兜底话术(所有轮次都失败时诚实拒答)。

5. 值不值得上

场景建议理由
高风险问答(法务、医疗、财务)值得忠实度提升比延迟更重要
离线报告生成值得延迟不敏感,可多轮自检
低延迟客服对话谨慎2~4 倍开销,用户等不了
简单 FAQ不值得一次检索就够,反思是浪费

6. 常见追问

Q:一定要微调吗? 论文需要,是为了让单模型在一次前向里输出标记、降低成本。工程上用提示词加小模型判定也能复现 80% 的效果,只是多几次调用。

Q:跟 Agent 有什么区别? Self-RAG 的反思是固定的几个判定点,控制流写死;Agent 是开放式规划,用工具做任意动作。前者可控,后者灵活。

Q:会不会一直重试? 必须用轮数上限 + token 预算双约束,并在日志里记录触发重试的比例。重试率长期高于 20%,说明检索或分块有问题,不是反思不够。

Q:怎么证明它比朴素 RAG 好? 固定检索与生成模型,只切换是否开启反思,对比忠实度、拒答准确率与 P95 延迟三个数。

小结

Self-RAG 的价值不在"多检索几次",而在把评估嵌进生成过程:先问该不该查,再问查得对不对,最后问说得有没有依据。这套思路比具体实现更值得带走。

笔记加载中…