Self-RAG实战:自我反思提升内容生成质量
Self-RAG让大模型在生成文本时自主判断是否需要检索,并评估检索结果的相关性与支持度,同时对其实用性打分。内置“内部质检员”机制,可有效过滤不相关信息,提升内容生成的准确性和完整性。
在之前关于RAG系统的系列文章中,我们系统梳理了从索引、查询转换、路由、查询构建到检索召回各个环节的优化路径。有了这些基础,搭建一个“能跑”的Naive RAG已经不成问题。但真正把RAG推向生产环境,大家往往会发现,最终生成环节才是真正的“试金石”。
输出格式乱掉,比如让生成表格却输出了纯文本;回答不完整,甚至在对比类问题上答非所问;更头疼的是,偶尔还会冒出一些“整治不正确”或不符合社会偏好的内容——这些问题,几乎是每个RAG实践者都会遇到的“坎”。
这篇文章,我们就聚焦在生成环节(下图右下角的紫色区域),介绍一种非常高效、且经得起推敲的优化方案:Self-RAG。

Self-RAG的概念
想象一下你正在写一篇论文,写到一半突然对某个事实不太确定,你大概率会停下来,上网查证,再继续写。写完后,你可能还会回头审视某个段落,觉得逻辑不顺或证据不足,于是删掉重写。Self-RAG干的事,本质上就是把这个“写论文”的过程,内化到语言模型的生成逻辑里。
它的核心思想其实很朴素:让大模型在生成文本时,自己就能“停下来”问自己——我需要更多信息吗?我生成的内容足够好吗?相当于给模型配了一个随时盯场的“内部质检员”,一边写一边自我审核。
实现这个机制的关键,在于几组被称为“反思标记”的控制信号。它们为LLM指明了思考方向,具体包括下面四个标记:
- 检索需求标记(Retrieve):决定当前是否需要从外部数据源拉信息。选项包括“是”、“否”,还有一个“继续使用证据”——意思是之前查到的信息还能接着用,先不用动。
- 相关性标记(ISREL):判断检索到的信息跟当前输入是否相关。二分法,“相关”或“不相关”。
- 支持度标记(ISSUP):评估检索到的信息是否支撑了模型的生成内容。分三个等级:完全支持、部分支持、无支持或矛盾。
- 实用性标记(ISUSE):用1到5分(最常用五级标准)打分,评价生成内容的整体效用。
上面的流程图可以直观展示整个流程。为了更清晰,我们来看一段伪代码,它把执行过程讲得明明白白:
输入:接收输入提示(x)和之前生成的文本(y
从这段伪代码可以很清晰地看到,四大类标记是如何一关一关地介入检索与生成的。它不改变模型本身,而是在模型输出前后加了一道“自我检查”的工序。
Self-RAG的代码实现
下面进入工程环节。在参考Self-RAG原始思路的基础上,我们做了一个“轻量级”的实现——并没有完全照搬论文里的全部设计。比如,我们默认所有情况下都需要检索,因此没有实现检索需求评分器;实用性评分也没有输出1~5的分数,而是简单输出了yes/no。大家如果感兴趣,完全可以自行扩展,写出更复杂的评分器。
检索相关性评分器
第一个评分器的作用是:判断检索回来的文档跟用户问题是否相关。目标是“抓大放小”,不用太严格,关键在于过滤掉那些明显检索错误的垃圾信息。
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.pydantic_v1 import BaseModel, Field
from langchain_openai import ChatOpenAI
# Data model
class GradeDocuments(BaseModel):
"""Binary score for relevance check on retrieved documents."""
binary_score: str = Field(
description="Documents are relevant to the question, 'yes' or 'no'"
)
# LLM with function call
llm = ChatOpenAI(model="gpt-3.5-turbo-0125", temperature=0)
structured_llm_grader = llm.with_structured_output(GradeDocuments)
# Prompt
system = """You are a grader assessing relevance of a retrieved document to a user question. \n
It does not need to be a stringent test. The goal is to filter out erroneous retrievals. \n
If the document contains keyword(s) or semantic meaning related to the user question, grade it as relevant. \n
Give a binary score 'yes' or 'no' score to indicate whether the document is relevant to the question."""
grade_prompt = ChatPromptTemplate.from_messages(
[
("system", system),
("human", "Retrieved document: \n\n {document} \n\n User question: {question}"),
]
)
retrieval_grader = grade_prompt | structured_llm_grader
question = "agent memory"
docs = retriever.get_relevant_documents(question)
doc_txt = docs[1].page_content
print(retrieval_grader.invoke({"question": question, "document": doc_txt}))
生成相关性评分器
第二个评分器主要负责“查幻觉”——看模型生成的内容,是不是真的有被检索到的事实做支撑。如果生成的内容跟检索回来的事实对不上,那就需要标记出来,不能让它蒙混过关。
### Hallucination Grader
# Data model
class GradeHallucinations(BaseModel):
"""Binary score for hallucination present in generation answer."""
binary_score: str = Field(
description="Answer is grounded in the facts, 'yes' or 'no'"
)
# LLM with function call
llm = ChatOpenAI(model="gpt-3.5-turbo-0125", temperature=0)
structured_llm_grader = llm.with_structured_output(GradeHallucinations)
# Prompt
system = """You are a grader assessing whether an LLM generation is grounded in / supported by a set of retrieved facts. \n
Give a binary score 'yes' or 'no'. 'Yes' means that the answer is grounded in / supported by the set of facts."""
hallucination_prompt = ChatPromptTemplate.from_messages(
[
("system", system),
("human", "Set of facts: \n\n {documents} \n\n LLM generation: {generation}"),
]
)
hallucination_grader = hallucination_prompt | structured_llm_grader
hallucination_grader.invoke({"documents": docs, "generation": generation})
回答质量评分器
最后一个评分器负责“终审”——看最终的回答到底有没有解决用户的问题。这个评分器输出的结果,直接决定了这个答案是否可以对外输出。
### Answer Grader
# Data model
class GradeAnswer(BaseModel):
"""Binary score to assess answer addresses question."""
binary_score: str = Field(
description="Answer addresses the question, 'yes' or 'no'"
)
# LLM with function call
llm = ChatOpenAI(model="gpt-3.5-turbo-0125", temperature=0)
structured_llm_grader = llm.with_structured_output(GradeAnswer)
# Prompt
system = """You are a grader assessing whether an answer addresses / resolves a question \n
Give a binary score 'yes' or 'no'. Yes' means that the answer resolves the question."""
answer_prompt = ChatPromptTemplate.from_messages(
[
("system", system),
("human", "User question: \n\n {question} \n\n LLM generation: {generation}"),
]
)
answer_grader = answer_prompt | structured_llm_grader
answer_grader.invoke({"question": question, "generation": generation})
篇幅有限,这里只展示了最关键的三个评分器的核心代码。其余的实现逻辑,比如如何串联这些评分器、如何处理排序和重试,这里就不一一贴出了。
总结
通过这篇文章,我们完整走通了一个Self-RAG的轻量级Demo。核心就是四个评分器——检索需求评分器(本文中未实现)、检索相关性评分器、生成相关性评分器和回答质量评分器。它们共同构成了一个“生成-反思-再生成”的闭环,让RAG的输出不再是“黑盒”式的单次结果,而是经过自我审视的可靠内容。
到这一步,一个相对完整的RAG系统其实已经搭建完毕。但放眼整个RAG生态,还有两座大山注定绕不过去:一是将RAG与知识图谱结合,系统性提升推理和总结能力;二是让RAG与Agent融合,真正嵌入到实际业务流程里去。这些,也都是下一阶段值得深耕的方向。
你是一名 AI 行业编辑,请围绕下面这条热点输出一份资讯解读:
热点:Self-RAG实战:自我反思提升内容生成质量要求:
1. 先用一句话解释这条热点在讲什么
2. 再总结它为什么重要
3. 说明会影响哪些 AI 产品或内容方向
4. 最后给出 3 个适合资讯站使用的标题
游乐网为非赢利性网站,所展示的游戏/软件/文章内容均来自于互联网或第三方用户上传分享,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系youleyoucom@outlook.com。
相关热点佑驾创新与乐动机器人达成战略合作,围绕技术、产品、场景、数据四维度展开深度协同,旨在加速物理AI规模化落地,拓展无人车与机器人场景边界,推动具身智能商业化进程。
Meta开放AI算力租赁业务,市场反应从算力过剩转向算力商业运营。GPU从自用转向对外出租,算力从成本中心转为利润中心。AI云竞争核心从拥有GPU数量转向稳定跑满GPU的能力,依赖同步与参考时钟等底层基础设施的长期稳定运行。
针对大型多仓库工程(30+微服务、10+前端微应用),搭建包含规则、技能、子代理、13阶段工作流与门禁脚本的Harness系统,解决PRD不可信、方案与代码脱节、改完无人验证、交付环节琐碎等痛点,使AI在真实业务中稳定跑完需求。
部署MCP Toolbox前,先看清它的适用场景与安全边界,避免在权限管理不完善时接入敏感数据。 核心内容: 1 MCP Toolbox的核心功能与两种使用路线 2 项目适合与不适合的团队场景分析 3 实际验证的安全检查与关键限制 先说结论 MCP Toolbox 很适合小团队研究“让 AI
- 日榜
- 周榜
- 月榜
热点快看
