【干货收藏】RL增强型RAG实战:让大模型回答更精准的强化学习方案

本文的重点集中在强化学习三个核心模块的构建与优化:

  • 状态与动作设计:定义智能体状态,包括查询、上下文和历史回答,并设计改写查询、扩展上下文、过滤上下文等动作。
  • 奖励机制:通过语义相似度评估回答质量,为智能体提供反馈,提升回答的准确性与可靠性。
  • 策略网络与训练循环:结合启发式规则与epsilon-greedy策略,通过多轮迭代优化动作选择,使系统在复杂查询下更稳定可靠。

通过引入强化学习,RAG流程可以根据模型反馈动态调整查询策略,包含改写查询、扩展或过滤上下文块,并在多轮迭代中逐步逼近最优解。

一、RL增强型RAG方法概览

在智能问答和知识增强生成(RAG)中,我们通常先从海量文档中检索相关内容,再由模型生成答案。为了让大家更直观地理解,我们先用图示来对比两种方法——基础RAGRL增强型RAG

(一)基础RAG方法

在这里插入图片描述

基础RAG方法工作流程图

基础RAG方法流程非常简洁:

  1. 文档分块:将原始文档切分成多个内容块(Chunk);
  2. 向量检索:利用**向量嵌入模型,**根据用户查询找到最相关的内容块;
  3. 生成回答:将Top K相关块 作为上下文传递给大语言模型,生成最终响应。

(二)强化学习RL增强型RAG方法

在这里插入图片描述

RL增强型RAG工作流程图

为了让RAG更智能,我们引入了强化学习智能体,构建了RL驱动的RAG流程:

  1. 动态策略调整:智能体根据LLM回答不断优化检索策略,使每次查询更精准。
  2. 灵活检索:支持重写查询、扩充相关内容块,剔除无关信息,提升上下文质量。
  3. 多轮迭代优化:通过多轮迭代,智能体逐步让生成结果趋近最优,提高答案的准确性和相关性。

相比基础RAG,这种方法更强调策略的智能化生成质量的持续优化,让问答效果更可靠、更智能。
在这里插入图片描述

二、基础RAG流程构建

(一)系统环境配置

在构建RAG流程前,首先需要搭建系统环境,并加载必要的库和模型。本方案使用Qwen生成回答,并选用bge-large-zh-v1.5作为向量嵌入模型。


import os
import sys
import json
import math
import random
import hashlib
import time
import numpy as np
from typing import List, Dict, Tuple, Optional, Any
from dotenv import find_dotenv, load_dotenv

from langchain_chroma import Chroma
from langchain_community.chat_models.tongyi import ChatTongyi
from langchain_community.document_loaders import DirectoryLoader
from langchain_community.embeddings import HuggingFaceBgeEmbeddings
from langchain.vectorstores.base import VectorStoreRetriever
from chinese_recursive_text_splitter import ChineseRecursiveTextSplitter
from sklearn.metrics.pairwise import cosine_similarity

# 加载环境变量
load_dotenv(find_dotenv())

# 加载大语言模型
llm_model = ChatTongyi(model_name="qwen-max", streaming=True, temperature=0)

# 加载嵌入模型
embed_model = HuggingFaceBgeEmbeddings(
                model_name="../bge-large-zh-v1.5",
                model_kwargs={'device': 'cuda'},
                encode_kwargs={'normalize_embeddings': True}
                )

(二)文档向量生成

构建知识库前,需要先把本地文档转化为可检索的向量。整体流程为:文档加载 → 文本分块 → 向量生成与存储

# 文档加载
SAMPLE_DIR = "data"

# 向量检索(Chroma)创建/加载
def create_vectorstore(data_path: str):
    """创建或加载向量存储,用于文档检索"""
    chroma_path = "./chroma_langchain_db"
    if os.path.exists(chroma_path):
        print("正在加载本地向量存储...")
        vectorstore = Chroma(persist_directory=chroma_path,embedding_function=embed_model,collection_name="rag-chroma")
        return vectorstore.as_retriever()
    
    print("正在加载文档...")
    loader = DirectoryLoader(data_path, glob="**/*.*", show_progress=True)
    documents = loader.load()
    
    print("正在分块...")
    text_splitter = ChineseRecursiveTextSplitter(
        keep_separator=True,
        is_separator_regex=True,
        chunk_size=250,
        chunk_overlap=50
    )
    doc_splits = text_splitter.split_documents(documents)
    print(len(doc_splits))
    
    print("正在创建新的向量存储...")
    vectorstore = Chroma.from_documents(documents=doc_splits,collection_name="rag-chroma",embedding=embed_model,persist_directory=chroma_path)
    print("向量存储创建完成!")
    
    return vectorstore.as_retriever()

流程解析:

  • 检查本地数据库:已有向量存储则直接加载,提高效率;
  • 加载并分块文档:通过ChineseRecursiveTextSplitter将文档拆分成合理长度的文本块;
  • 向量生成并持久化:利用嵌入模型将文本转为向量,并存储至Chroma数据库,供检索使用。

(三)文档向量检索

向量化文档后,可以根据查询快速找到最相关的文本块。

def retrieve_relevant_chunks(retriever: VectorStoreRetriever, query_text: str, top_k: int = 5) -> List[str]:
    """
    根据查询文本检索最相关的文档块
    """
    chunks = retriever.get_relevant_documents(query_text, k=top_k)
    docs = [doc.page_content for doc in chunks]
    return docs

流程解析:

  • 输出查询文本query_text,通过向量检索器获取最相关的文档块;
  • 提取文本内容,返回前top_k个最相关块,供后续LLM生成答案使用。

(四)LLM响应生成

有了查询和相关文档块后,即可调用大语言模型生成最终答案。


def construct_prompt(query: str, context_chunks: List[str]) -> str:
    """
    构造提示词,将系统消息、上下文和问题组合成完整的输入提示。
    """
    system_message = (
        "你是一名有用的智能助手。请仅根据提供的上下文回答问题。"
        "如果上下文中没有相关信息,请回答:'我没有足够的信息来回答这个问题。'"
    )

    context = "\n".join(context_chunks)
    prompt = f"系统提示: {system_message}\n\n上下文:\n{context}\n\n问题:\n{query}\n\n回答:"
    return prompt

def generate_response_with_llm(prompt: str, context_chunks: List[str], query: str) -> str:
    """调用 Qwen LLM 生成答案"""
    answer = llm_model.invoke(prompt).content
    return answer

def basic_rag_pipeline(retriever: VectorStoreRetriever, query: str) -> str:
    """封装完整的基础 RAG 流程"""
    chunks = retrieve_relevant_chunks(retriever, query, top_k=5)
    prompt = construct_prompt(query, chunks)
    return generate_response_with_llm(prompt, chunks, query)

我们来测试一下完整的RAG流程:


query = "什么是Agentic RAG?"
answer = basic_rag_pipeline(query)
print(answer)

输出示例:

Agentic RAG是一种先进的检索增强生成(RAG)策略,结合了动态查询分析和自我纠错机制,能够根据查询复杂性和上下文环境智能调整检索与生成策略,适合快速反应、任务复杂且环境变化快的应用场景。

至此,我们实现了一个简洁清晰的RAG流程

查询文本 → 检索相关文档块 → 构建Prompt → 调用LLM → 生成答案

该流程逻辑清晰、易于扩展,可作为小型原型项目的基础框架。下一步,我们将在此基础上引入强化学习RL增强逻辑,进一步提升回答的准确性和智能化水平。

三、RL增强型RAG流程构建

在基础RAG流程中,我们发现生成的回答有时存在准确性不足或信息不完整的问题。引入强化学习(Reinforcement Learning, RL),可以使RAG流程在检索与生成的各个环节实现自我优化,从而显著提升回答质量。

(一)强化学习简介

强化学习是一类机器学习方法,通过引入智能体(Agent),在环境中不断进行动作(Action)探索,并依据反馈奖励(Reward)不断调整策略,实现最佳决策。

与监督学习不同,强化学习并不会直接告知智能体应采取的最佳动作,而是通过试错探索逐步发现能够获得更高奖励的行为模式。

强化学习的核心要素包括:

  • 智能体(Agent):负责学习与决策的主体;
  • 环境(Environment):智能体交互的外部世界;
  • 状态(State, S):在当前环境中智能体所处的状态;
  • 动作(Action, A):智能体可执行的动作集合;
  • 奖励(Reward, R):执行动作后从环境获得的反馈信号;
  • 策略(Policy, π):智能体依据当前状态选择动作的规则或方法。

强化学习的目标是学习一个策略π,以最大化期望累积奖励

在强化学习公式中:

  • π: 表示最优策略;
  • γ:折扣因子(0 ≤ γ ≤ 1),用于平衡即时奖励与未来奖励的重要性;
  • Rₜ: 时间步t的奖励;
  • T: 最终时间步。

(二)状态、动作与奖励设计

在构建强化学习算法时,第一步是明确三要素:状态(State)动作(Action)奖励(Reward)

  • 状态(State):在RAG场景中,初始状态通常包括用户查询文本、检索到的上下文以及基于初始检索生成的回答。
  • 动作(Action):指智能体根据当前状态可以采取的操作。在RAG中,动作可以包括更换模型、调整上下文或改写查询等。
  • 奖励(Reward):智能体执行动作后获得的反馈信号。在RAG中,奖励通常定义为生成回答与标准答案的相似度。

此外,由于状态会随着训练过程不断更新,需要在每轮迭代后保存当前状态,以便智能体能够基于历史经验进行策略优化,避免重复犯错。

(1) 定义状态表示

以下函数用于定义 RAG 场景下的强化学习状态表示:

def define_state(
    query: str, 
    context_chunks: List[str], 
    rewritten_query: Optional[str] = None, 
    previous_responses: Optional[List[str]] = None, 
    previous_rewards: Optional[List[float]] = None,
    last_action: Optional[str] = None,
    action_rewards: Optional[Dict[str, float]] = None
) -> dict:
    """
    定义强化学习智能体的状态表示
    """
    state = {
        "original_query": query,  # 初始用户查询
        "current_query": rewritten_query if rewritten_query else query,  # 当前查询(可能已改写)
        "context": context_chunks,  # 检索到的上下文块
        "previous_responses": previous_responses if previous_responses else [],  # 历史生成回答
        "previous_rewards": previous_rewards if previous_rewards else [],  # 历史奖励
        "last_action": last_action, # 上次动作
        "action_rewards": action_rewards if action_rewards else {} # 动作奖励
    }
    return state

通过这种状态表示,智能体可以完整记录查询历史、检索上下文、生成记录及奖励反馈,从而为策略优化提供充分信息,实现对 RAG 流程的持续迭代改进。

(2)定义动作空间

在完成状态表示后,下一步是为强化学习智能体定义动作空间,动作空间指的是智能体在每个时间步可以采取的所有可能操作,它决定了策略优化的灵活性和范围。

在RAG场景中,常见的四类基础动作包括:

  • rewrite_query:改写原始查询,以优化检索效果;
  • expand_context:检索更多上下文块,丰富参考信息;
  • filter_context:移除无关上下文块,提升回答相关性;
  • generate_response:基于当前查询和上下文生成最终回答。

以下是一个定义动作空间的示例函数:


def define_action_space() -> List[str]:
    """
    定义强化学习智能体可以采取的动作集合。
    """
    actions = ["rewrite_query", "expand_context", "filter_context", "generate_response"]
    return actions

通过这种动作空间设计,智能体能够在每一步中自主选择最优动作,动态调整检索与生成策略,实现回答更准确、更完整、更高效的目标。

(3) 奖励函数设计

在强化学习中,智能体在每一步采取动作后,需要根据当前状态与动作获得奖励(Reward),以此指导策略的更新与优化。

RAG场景中,奖励的核心是衡量生成回答的质量。我们引入大语言模型(LLM) 作为评估器,利用其语义理解能力,对生成结果与标准答案进行评分,范围设为[0, 1]:分数越高,表示回答与标准答案的语义一致性、逻辑性和内容匹配度越高。

以下为奖励函数实现逻辑:


# 奖励函数:(response vs ground_truth)
def calculate_reward(response: str, ground_truth: str) -> float:
    """
    使用大模型对 response 和 ground_truth 进行语义评分
    返回 [0, 1] 范围的分数
    """
    prompt = f"""
你是一个专业的评估助手。
请比较下面两段文本的语义相似度,考虑准确性、完整性和逻辑性。
请只返回一个 0 到 1 的小数分数,0 表示完全不相关,1 表示完全一致。
标准答案:
{ground_truth}
模型回答:
{response}
请给出分数即可,不要输出其他内容:
"""
    try:
        result = llm_model.invoke(prompt).content.strip()
        score = float(result)
        if 0 <= score <= 1:
            return score
        else:
            # 如果解析失败或分数异常,则返回默认分数
            return 0.0
    except Exception as e:
        print(f"Reward calculation error: {e}")
        return 0.0

通过这种奖励设计,智能体能够在训练过程中持续获得高质量反馈信号,从而动态调整检索策略和生成策略,推动RAG流程在迭代中不断提升回答的准确性与一致性

在没有标准答案的情况下,可以借助大语言模型或专用评估模型对生成结果进行打分,将准确性、相关性与完整性等指标作为奖励信号。

(三)Action函数设计

在定义好动作空间后,需要为每个动作实现具体逻辑,以指导RL智能体在训练过程中动态调整RAG流程****。回顾前文提到的四个核心动作**:**

  • rewrite_query:改写原始查询,提升检索效果;
  • expand_context:获取更多上下文块;
  • filter_context:移除无关上下文块;
  • generate_response:基于当前查询和上下文生成回答。

(1)rewrite_query——改写查询

改写查询是优化检索相关性、提升生成质量的关键步骤。通过调用LLM将原始查询改写得更精准、更具体,可以显著提高检索结果的相关性和覆盖度。

def rewrite_query(state: Dict[str, Any]) -> str:
    """
    根据当前对话状态中的 query 和 context_chunks 调用 LLM 改写查询。
    """
    query = state.get("current_query", "")
    context_chunks = state.get("context", [])

    # 构建提示词(中文版本)
    rewrite_prompt = f"""
    你是一名查询优化助手。你的任务是根据给定的查询,结合已有上下文,将其改写得更精准,
    以便检索到更相关的信息。该查询将用于文档检索。

    原始查询:
    {query}

    当前已检索到的上下文:
    {' '.join(context_chunks[:2]) if context_chunks else '暂无可用上下文'}

    请输出优化后的查询,仅返回改写后的内容:
    """

    rewritten_query = llm_model.invoke(rewrite_prompt).content
    return rewritten_query

(2)expand_context——扩展上下文

扩展上下文用于检索更多相关上下文块,拓宽知识覆盖范围。在扩展过程中,需注意去除重复信息限制新增上下文的数量,以避免噪声干扰。

def expand_context(retriever: VectorStoreRetriever, current_query: str, current_chunks: List[str], top_k: int = 3) -> List[str]:
    # 检索更多上下文片段
    candidates = retrieve_relevant_chunks(retriever, current_query, top_k=top_k + len(current_chunks))
    # 去重并合并
    new_chunks = [c for c in candidates if c not in current_chunks]
    expanded = current_chunks + new_chunks[:top_k]
    return expanded

(3)filter_context——优化上下文

优化上下文用于从已有的上下文块中筛选出最相关的部分,确保信息更加集中与精准,从而提高回答质量。

def filter_context(retriever: VectorStoreRetriever, current_query: str, context_chunks: List[str]) -> List[str]:
    """
    使用 LLM 对上下文相关性打分,并返回最相关的上下文块。
    """
    if not context_chunks:
        return []
    
    filtered_chunks = []
    for chunk in context_chunks:
        # 构建中文提示,要求模型给出相关性分数
        prompt = f"""
        你是一名专业的信息检索助手。
        请根据以下查询内容,评估给定文档片段的相关性。
        评分范围为 0 到 10:
        0 表示完全无关,10 表示高度相关。
        查询内容:
        {current_query}
        文档片段:
        {chunk}
        请只返回一个数字(0-10),不要输出其他内容。
        """
        
        try:
            score_text = llm_model.invoke(prompt).content.strip()
            score = float(score_text) if score_text.replace(".", "", 1).isdigit() else 0.0
        except Exception as e:
            print(f"Error scoring chunk: {e}")
            score = 0.0
        
        # 直接按阈值过滤
        if score >= 5.0:
            filtered_chunks.append(chunk)
    
    return filtered_chunks

这两个步骤(扩展上下文优化上下文)让智能体能够在信息广度信息精度之间动态平衡,从而生成覆盖度高且针对性强的回答。

(4)generate_response——生成回答

有了用户查询和相关上下文,就可以生成最终回答:

def generate_response(state: Dict[str, Any]) -> str:
    """
    结合当前查询与上下文生成回答。
    """
    prompt = construct_prompt(state["current_query"], state["context"])
    response = generate_response_with_llm(prompt, state["context"], state["current_query"])
    return response

通过这一系列动作函数,RL智能体能够动态调整检索与生成策略,实现从查询优化到上下文管理再到答案生成的完整策略闭环。

(四)策略网络

在定义好状态、动作奖励逻辑之后,下一步是实现一个策略网络(Policy Network),用于根据当前状态动态选择最优动作。

策略网络本质上是一个决策函数:输入当前状态和动作空间,输出智能体在当前情境下应采取的动作。

这里我们采用epsilon-greedy策略,并结合简单的启发式规则来平衡探索与利用:

  • 如果没有生成过任何回答 → 优先改写查询(rewrite_query)
  • 如果已有回答但奖励低 → 尝试扩展上下文(expand_context)
  • 如果上下文块太多 → 优先过滤上下文(filter_context)
  • 其他情况 → 直接生成回答(generate_response)

其中,epsilon参数用于探索与利用与平衡:以一定概率选择随机动作,保证智能体能尝试不同策略,避免陷入局部最优。


# 策略网络:epsilon-greedy + 简单启发式优先级
def policy_network(state: Dict[str, Any], action_space: List[str], epsilon: float = 0.2) -> str:
    last_action = state.get("last_action", None)
    available_actions = [a for a in action_space if a != last_action]
    context_len = len(state.get("context", []))
    
    # 随机探索
    if random.random() < epsilon:
        return random.choice(available_actions)

    # 使用动作奖励选择高概率动作
    # rewards = np.array([state["action_rewards"].get(a, 0.5) for a in available_actions])
    # probs = np.exp(rewards) / np.sum(np.exp(rewards))
    # return np.random.choice(available_actions, p=probs)
    
    # 利用启发式规则
    if len(state["previous_responses"]) == 0 and "rewrite_query" in available_actions:
        return "rewrite_query"
    
    # 如果已有奖励但最大奖励低 -> expand
    if state["previous_rewards"] and max(state["previous_rewards"]) < 0.6 and context_len < 10 and "expand_context" in available_actions:
        return "expand_context"
    
    # 如果上下文太多 -> filter
    if len(state["context"]) > 8 and "filter_context" in available_actions:
        return "filter_context"
    
    return "generate_response"

通过策略网络,RL智能体能够在不同状态下动态做出合理决策,既可以依靠规则快速收敛,又能通过随机探索避免陷入局部最优,从而推动RAG流程在检索与生成的迭代过程中不断优化效果。

(五)RL单步训练逻辑

在强化学习训练循环中,每一次迭代可以看作一次单步操作:智能体根据当前状态选择动作 → 执行动作 → 更新状态 → 计算奖励。

下面是一个实现该流程的示例函数:


def rl_step(retriever: VectorStoreRetriever, state: Dict[str, Any], action_space: List[str], ground_truth: str) -> Tuple[Dict[str, Any], str, float, Optional[str]]:
    # 选择动作
    action = policy_network(state, action_space)
    print('Choose:', action)
    response: Optional[str] = None
    reward = 0.0
    
    # 执行动作:改写查询
    if action == "rewrite_query":
        new_q = rewrite_query(state)
        state["current_query"] = new_q
        new_chunks = retrieve_relevant_chunks(retriever, new_q)
        state["context"] = list({*state["context"], *new_chunks})
        print("rewritten_query:", new_q)
        print("Context Num:", len(state["context"]))
    
    # 执行动作:扩展上下文
    elif action == "expand_context":
        state["context"] = expand_context(retriever, state["current_query"], state["context"], top_k=3)
        print("Context Num:", len(state["context"]))
    
    # 执行动作:优化上下文
    elif action == "filter_context":
        state["context"] = filter_context(retriever, state["current_query"], state["context"])
        print("Context Num:", len(state["context"]))
    
    # 执行动作:生成回答
    elif action == "generate_response":
        response = generate_response(state)
        reward = calculate_reward(response, ground_truth)
        state["previous_responses"].append(response)
        state["previous_rewards"].append(reward)
        # 更新动作的奖励估计
        update_action_rewards(state, action, reward)
    
    else:
        pass
    
    # 更新上一个动作
    state["last_action"] = action
    return state, action, reward, response

单步RL流程说明:

  • 动作选择
    使用policy_network根据当前状态选择动作,利用epsilon-greedy策略平衡探索和利用。
  • 动作执行
  • rewrite_query → 改写查询,更新上下文,提升检索相关性。
  • expand_context → 扩展上下文,检索更多相关信息,增加知识覆盖面。
  • filter_context → 优化上下文,筛选相关信息,确保上下文精简且有针对性。
  • generate_response → 生成回答并计算奖励。
  • 状态更新
    更新state中的查询、上下文、生成的回答和对应的奖励,为下一轮决策提供最新信息;更新last_action,记录本次动作,以供下一次决策参考。

(六)Policy更新逻辑

在强化学习中,智能体需要根据环境反馈的奖励信号不断优化策略,使得后续的动作选择更加精准。常见的更新方法包括奖励加权更新或更复杂的策略梯度方法

以下函数基于奖励加权平均的方式更新策略,适用于快速原型验证:


# 更新 action_rewards(简单的指数滑动平均)
def update_action_rewards(state: Dict[str, Any], action: str, reward: float, lr: float = 0.05):
    ar = state.get("action_rewards", {})
    prev = ar.get(action, None)
    if prev is None:
        ar[action] = reward
    else:
        ar[action] = prev * (1 - lr) + reward * lr
    state["action_rewards"] = ar

更新逻辑解析:

  • 动作-奖励映射
    state中维护一个action_rewards字典,记录每个动作的平均奖励。
  • 奖励加权更新
    每次执行动作后,使用新奖励更新旧的奖励估计,即通过指数滑动平均的方式调整每个动作的奖励值。高奖励的动作会得到逐步强化,提高选择的概率。
  • 与策略网络结合
    在下一轮决策中,policy_network可以基于action_rewards优先选择高收益动作,同时结合epsilon-greedy策略保留探索性。

(七)训练循环

在强化学习增强型RAG流程中,训练循环是整个模型优化过程的核心。通过反复的训练过程,让智能体在执行检索与生成任务时,不断优化策略,提升回答的质量。

def initialize_training_params() -> Dict[str, Any]:
    # 初始化训练参数,包括训练轮数、每轮最大步数以及学习率
    return {
        "num_episodes": 10,
        "max_steps_per_episode": 25,
        "learning_rate": 0.05
    }

def training_loop(retriever: VectorStoreRetriever, query_text: str, ground_truth: str, params: Optional[Dict[str, Any]] = None):
    # 如果没有传入参数,则使用默认参数
    if params is None:
        params = initialize_training_params()
    
    # 获取训练参数
    num_episodes = params["num_episodes"]
    max_steps = params["max_steps_per_episode"]
    
    # 使用基础RAG模型生成响应,计算其奖励作为性能基线
    simple_response = basic_rag_pipeline(retriever, query_text)
    simple_reward = calculate_reward(simple_response, ground_truth)
    print(f"Baseline simple RAG response:\n{simple_response}\nReward: {simple_reward:.4f}\n")
    
    # 初始化最佳奖励和最佳响应
    best_reward = simple_reward
    best_response = simple_response
    rewards_history = [] # 存储每轮的奖励
    actions_history = [] # 存储每轮的动作
    best_state_across_episodes = None # 存储最佳状态
    
    for episode in range(num_episodes):
        print('-'*30)
        # 初始化 state:使用上轮最佳状态
        if best_state_across_episodes:
            state = best_state_across_episodes
        else:
            context_chunks = retrieve_relevant_chunks(retriever, query_text, top_k=5)
            state = define_state(query_text, context_chunks)
        print('Episode:', state)
        
        # 存储本轮执行的动作和奖励
        episode_actions = []
        episode_reward = 0.0
        
        # 每轮的训练步骤
        for step in range(max_steps):
            # 执行单步RL操作
            state, action, reward, response = rl_step(retriever, state, define_action_space(), ground_truth)
            episode_actions.append(action)
            
            # 如果生成了响应,更新奖励
            if response is not None:
                episode_reward = reward
                # 更新该动作的奖励信息
                update_action_rewards(state, action, reward, lr=params["learning_rate"])
                # 如果当前奖励超过最佳奖励,更新最佳奖励和最佳响应
                if reward > best_reward:
                    best_reward = reward
                    best_response = response
                    # best_state_across_episodes = state  # 保存最佳状态跨轮使用
                # 如果有生成响应,提前结束本轮
                break
        
        # 保存奖励和动作历史
        rewards_history.append(episode_reward)
        actions_history.append(episode_actions)
        print(f"Episode {episode}: Reward = {episode_reward:.4f}, Actions = {episode_actions}")
    
    # 计算性能提升
    improvement = best_reward - simple_reward
    print("\n=== 训练结束 ===")
    print(f"基线奖励: {simple_reward:.4f}")
    print(f"最佳RL增强奖励: {best_reward:.4f}")
    print(f"性能提升: {improvement:.4f} ({improvement * 100:.2f}%)")
    print(f"最佳响应:\n{best_response}")
    
    # 返回训练结果
    return {
        "baseline_reward": simple_reward, # 基线奖励
        "best_reward": best_reward, # 最佳奖励
        "improvement": improvement, # 性能提升
        "rewards_history": rewards_history, # 奖励历史
        "actions_history": actions_history, # 动作历史
        "best_response": best_response # 最佳响应
    }

训练循环核心逻辑解析:

  1. 初始化训练参数:如果没有传入参数,函数会使用默认的学习率、训练轮数等。
  2. 基础RAG基线性能:训练开始前,先运行一次基础的RAG流水线作为基线,并计算奖励,作为后续优化的对比。
  3. 每****轮训练:训练过程通过多轮(num_episodes)和每轮的多步来进行。每步都执行一次RL决策(选择动作、计算奖励等)。
  4. 动作与奖励记录:每轮训练结束后,保存该轮的奖励和动作,便于后续分析。
  5. 最佳结果记录:保存训练过程中生成的最佳回答及对应奖励,并与基础RAG对比计算提升幅度。

(八)完整RAG运行流程

最后,我们将前面实现的各个模块串联起来,构建一个完整的RAG主流程

    # 1. 创建向量存储并添加 chunks
    retriever = create_vectorstore(SAMPLE_DIR)
    print("向量存储已创建并填充。")
    
    # 2. 定义查询与 ground truth(用于奖励计算)
    query = "请简要讲解下构建Agentic RAG的步骤。"
    ground_truth = (
        "构建 Agentic RAG 包含 10 步:\n"
        "1. 定义状态与节点常量,管理工作流数据;\n"
        "2. 初始化 Qwen 模型与嵌入模型;\n"
        "3. 构建查询路由器,智能判断问题类型;\n"
        "4. 搭建本地向量检索节点;\n"
        "5. 集成网络搜索,获取实时信息;\n"
        "6. 评分文档相关性,过滤无效内容;\n"
        "7. 调用生成节点,结合上下文生成答案;\n"
        "8. 检测幻觉,确保内容真实;\n"
        "9. 评估答案质量,必要时重试;\n"
        "10. 用 LangGraph 构建动态工作流,实现自适应问答闭环。"
    )
    
    # 3. 先演示 basic RAG pipeline
    baseline = basic_rag_pipeline(retriever, query)
    print("\n--- Baseline RAG Output ---")
    print(baseline)
    print("---------------------------\n")
    
    # 4. 训练 RL-enhanced RAG
    params = initialize_training_params()
    params["num_episodes"] = 5
    params["max_steps_per_episode"] = 20
    params["learning_rate"] = 0.08
    random.seed(42)
    results = training_loop(retriever, query, ground_truth, params)
    
    # 6. 保存结果到文件
    out = {
        "query": query,
        "ground_truth": ground_truth,
        "results": results
    }
    with open("rl_rag_results.json", "w", encoding="utf-8") as f:
        json.dump(out, f, ensure_ascii=False, indent=2)
    print("\n结果已保存至 rl_rag_results.json")

if __name__ == "__main__":
    main()

完整RAG主流程解析:

  1. 初始化向量存储:加载或创建文档向量数据库;
  2. 定义查询与参考答案:用于基线测试及后续RL奖励计算;
  3. 执行基础RAG流程:演示检索增强生成的基础效果;
  4. 训练RL增强版RAG:通过多轮交互与奖励优化,不断改进生成效果;
  5. 结果持久化:将最终结果保存为JSON文件,方便后续分析与复现。

通过完整的主流程,我们将基础RAG流程与强化学习增强机制结合,形成一个端到端的查询处理系统。从向量存储的创建到基线测试,再到训练并优化生成策略,整个流程能够有效提升生成的回答质量。

四、RL增强型RAG测试效果对比

在本实验中,我们对比了Baseline RAG与**RL增强型RAG(RL-enhanced RAG)**的性能表现,同时展示了部分训练过程的日志信息。

1. 实验设置

  • Baseline RAG:标准的检索增强生成系统,未加入强化学习优化。
  • RL增强型RAG:在Baseline基础上,通过强化学习持续探索各种动作,并依据奖励信号优化策略,从而实现更优的决策效果。
  • 评价指标:奖励值(Reward),用于衡量生成回答的质量和相关性。

2. 实验结果

实验结果显示,Baseline RAG的平均奖励值为0.5000,而RL增强型RAG的平均奖励值达到0.7500,提升幅度为0.2500(约 25%)。这一结果表明,强化学习机制显著提高了系统在生成回答时的准确性和信息相关性。

  1. 部分运行日志

Episode 0: Reward = 0.7500, Actions = ['rewrite_query', 'filter_context', 'rewrite_query', 'expand_context', 'rewrite_query', 'filter_context', 'expand_context', 'rewrite_query', 'filter_context', 'rewrite_query', 'expand_context', 'rewrite_query', 'filter_context', 'rewrite_query', 'generate_response']
Episode 1: Reward = 0.5000, Actions = ['rewrite_query', 'generate_response']
Episode 2: Reward = 0.7500, Actions = ['rewrite_query', 'filter_context', 'rewrite_query', 'filter_context', 'expand_context', 'filter_context', 'rewrite_query', 'generate_response']
Episode 3: Reward = 0.5000, Actions = ['rewrite_query', 'generate_response']
Episode 4: Reward = 0.4000, Actions = ['rewrite_query', 'generate_response']

=== Training finished ===
Baseline reward: 0.5000
Best RL-enhanced reward: 0.7500
Improvement: 0.2500 (25.00%)
Best response:
基于LangGraph和Qwen构建Agentic RAG系统涉及...

从日志和奖励值可以看出,RL增强型RAG在测试用例的表现明显优于Baseline。高奖励的Episode通常对应多轮上下文优化和有效的上下文过滤操作,生成内容的准确性和相关性显著提升。

此外,RL增强型RAG展现了更强的自适应能力:系统能够根据奖励信号动态调整生成策略和信息源选择,从而在复杂查询场景下获得更优输出。

总体而言,RL增强型RAG通过强化学习有效优化了检索增强生成流程,为系统在多样化和复杂查询环境中的稳定表现提供了坚实保障。

五、总结与未来方向

本文从基础RAG流程出发,构建了基于强化学习(RL)增强型RAG方案。通过引入自定义奖励函数贪心策略(Greedy Algorithm),系统能够在多轮迭代中动态调整查询与检索策略,有效提升事实性查询的准确率与回答稳定性。

实验结果显示:

  • 基础RAG: 满足一般检索需求,面对复杂查询时,回答准确性仍存在不足。
  • RL增强型RAG:在短时间内的训练下,性能提升了15%~20%,生成的回答更加精确,且上下文更加一致。
  • 策略网络与奖励机制:通过优化检索范围与生成精度的平衡,使系统在两者之间实现了更优的协调。

未来优化方向:

  1. 优化策略算法:尝试策略梯度或PPO等更高效的强化学习方法;
  2. 丰富奖励指标:加入一致性、覆盖率或用户满意度等多维度的奖励信号;
  3. 多模态扩展:融合图像、表格等多模态信息,拓展RAG的应用场景。

通过此次探索,RL增强型RAG方法已展现出显著的优化潜力,特别是在增强查询准确性、生成质量和上下文一致性等方面。基于强化学习的反馈机制,使得RAG系统能够在多轮迭代中不断优化,解决了传统RAG方法在复杂任务中存在的不足。随着未来技术的进一步发展,RL增强型RAG方法有望成为构建更智能、更稳定的知识增强系统的关键技术之一。

普通人如何抓住AI大模型的风口?

领取方式在文末

为什么要学习大模型?

目前AI大模型的技术岗位与能力培养随着人工智能技术的迅速发展和应用 , 大模型作为其中的重要组成部分 , 正逐渐成为推动人工智能发展的重要引擎 。大模型以其强大的数据处理和模式识别能力, 广泛应用于自然语言处理 、计算机视觉 、 智能推荐等领域 ,为各行各业带来了革命性的改变和机遇 。

目前,开源人工智能大模型已应用于医疗、政务、法律、汽车、娱乐、金融、互联网、教育、制造业、企业服务等多个场景,其中,应用于金融、企业服务、制造业和法律领域的大模型在本次调研中占比超过 30%。
在这里插入图片描述

随着AI大模型技术的迅速发展,相关岗位的需求也日益增加。大模型产业链催生了一批高薪新职业:
在这里插入图片描述

人工智能大潮已来,不加入就可能被淘汰。如果你是技术人,尤其是互联网从业者,现在就开始学习AI大模型技术,真的是给你的人生一个重要建议!

最后

只要你真心想学习AI大模型技术,这份精心整理的学习资料我愿意无偿分享给你,但是想学技术去乱搞的人别来找我!

在当前这个人工智能高速发展的时代,AI大模型正在深刻改变各行各业。我国对高水平AI人才的需求也日益增长,真正懂技术、能落地的人才依旧紧缺。我也希望通过这份资料,能够帮助更多有志于AI领域的朋友入门并深入学习。

真诚无偿分享!!!
vx扫描下方二维码即可
加上后会一个个给大家发

在这里插入图片描述

大模型全套学习资料展示

自我们与MoPaaS魔泊云合作以来,我们不断打磨课程体系与技术内容,在细节上精益求精,同时在技术层面也新增了许多前沿且实用的内容,力求为大家带来更系统、更实战、更落地的大模型学习体验。

图片

希望这份系统、实用的大模型学习路径,能够帮助你从零入门,进阶到实战,真正掌握AI时代的核心技能!

01 教学内容

图片

  • 从零到精通完整闭环:【基础理论 →RAG开发 → Agent设计 → 模型微调与私有化部署调→热门技术】5大模块,内容比传统教材更贴近企业实战!

  • 大量真实项目案例: 带你亲自上手搞数据清洗、模型调优这些硬核操作,把课本知识变成真本事‌!

02适学人群

应届毕业生‌: 无工作经验但想要系统学习AI大模型技术,期待通过实战项目掌握核心技术。

零基础转型‌: 非技术背景但关注AI应用场景,计划通过低代码工具实现“AI+行业”跨界‌。

业务赋能突破瓶颈: 传统开发者(Java/前端等)学习Transformer架构与LangChain框架,向AI全栈工程师转型‌。

image.png

vx扫描下方二维码即可
在这里插入图片描述

本教程比较珍贵,仅限大家自行学习,不要传播!更严禁商用!

03 入门到进阶学习路线图

大模型学习路线图,整体分为5个大的阶段:
图片

04 视频和书籍PDF合集

图片

从0到掌握主流大模型技术视频教程(涵盖模型训练、微调、RAG、LangChain、Agent开发等实战方向)

图片

新手必备的大模型学习PDF书单来了!全是硬核知识,帮你少走弯路(不吹牛,真有用)
图片

05 行业报告+白皮书合集

收集70+报告与白皮书,了解行业最新动态!
图片

06 90+份面试题/经验

AI大模型岗位面试经验总结(谁学技术不是为了赚$呢,找个好的岗位很重要)图片
在这里插入图片描述

07 deepseek部署包+技巧大全

在这里插入图片描述

由于篇幅有限

只展示部分资料

并且还在持续更新中…

真诚无偿分享!!!
vx扫描下方二维码即可
加上后会一个个给大家发

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值