许多复杂问题需要多轮才能解决。 LLM 智能体与环境交互以从系统中其他模型或工具中获得有用的反馈。
多轮 MAGRPO#
多轮 MAGRPO 构建一个 rollout 树,其分支代表不同的联合响应 (TreeRPO)。
每个 episode 从数据集中采样一个任务,从而提供所有智能体的初始观察和历史记录 \( \mathbf{o}_0=\{o_{1, 0}, \cdots, o_{n, 0}\} \) 和 \( \mathbf{h}_0=\{h_{1, 0}, \cdots, h_{n, 0}\} \)。 在每个回合中,智能体根据当前观察-动作历史 \( \mathbf{h}_t \) 生成一组联合响应 \( \mathbf{a}^{\mathcal{G}}_t\gets\boldsymbol{\pi}^{\mathcal{G}}(\cdot|\mathbf{h}_t) \)。 每个响应开始一个不同的 rollout。 智能体根据累积的历史和当前联合动作 \( \mathbf{a}^{(g)}_{t} \in \mathbf{a}^{\mathcal{G}}_{t} \),为每个响应获得联合奖励 \( r^{(g)}_{t} \)。 每个 rollout 独立进化,随着环境的变化产生新的联合观察 \( \mathbf{o}^{\mathcal{G}}_{t+1} \),并在下一个回合中分支到进一步的 rollouts \( t+1 \)。 这个过程持续到终端回合 \( H \)。
联合模式#
MAGRPO 支持在每个回合中形成联合响应的两种模式:
- 对齐 (
joint_mode="aligned"):具有相同生成索引的响应在智能体之间组合。 每个智能体在每个节点上采样 \( G \) 响应 (固定的num_generations值)。 在具有 \( T \) 个回合和无提前终止的情况下,树具有 \( G^T \) 个叶子。
- 交叉 (
joint_mode="cross"):智能体采样的联合行动的笛卡尔积产生 \( G^N \) 联合行动。 在无提前终止的情况下,树具有 \( G^{N \cdot T} \) 个叶子。 响应在组合中被重用,因此联合样本不是独立的。 这增加了奖励评估的数量和 rollout 的大小,而无需保证更准确的值估计。
只能组合来自相同 rollout 的响应,因为 rollouts 独立进化。 当前的 MAGRPO 实现累积未折扣的回报:
discount不会改变其树递归。 MAREINFORCE 描述回报聚合和优势归一化。
多轮 MAAC/IAC#
MAGRPO rollout 树在每个 episode 中生成大量样本。 在多轮设置中,MAAC/IAC 仅为每个智能体在每个回合中生成一个样本,并且 episode 持续到回合结束。
MAAC/IAC 使用一步时序差目标,discount 应用于下一个 rollout 值,并在最终或提前终止的回合后不进行 bootstrapping。 当前实现在收集完整的 episode 之前。 策略更新发生在达到 rollout_buffer_size 时,并且在 epoch 的结束时,任何剩余的缓冲区都会被清除。 策略不会在相同 episode 的回合之间进行更新。
IAC/MAAC 多轮训练需要将
num_generations设置为 1。
环境转换#
外部反馈机制控制如何将环境观察纳入后续回合的提示。 这些机制通常在 CoMLRL 的下游环境中实现。
自定义外部反馈#
用户可以通过定义具有以下接口的函数来实现自定义外部反馈:
prompt: 原始任务提示或问题描述 (必需)agent_completions: 列表或先前回合的完成,每个智能体一个 (必需)num_agents: 系统中智能体的数量(必填)prompt_history_per_agent: 包含每个智能体先前提示的列表(可选)response_history_per_agent: 包含每个智能体先前响应的列表(可选)
该函数必须返回下一回合的提示列表,每个智能体一个。
trainer 仅传递上述参数,不包含任何其他关键字参数。可以通过闭包或 functools.partial 配置特定模式的参数。
默认情况下,每个返回的提示将成为新的 prompt 字段,并通过相应智能体的格式器传递。
如果使用 external_prompt_passthrough=True,则直接使用返回的提示,无需重新格式化。
在 MAGRPO 中,外部过渡被调用,针对每个 rollout 分支,并传递该分支的历史。
以下示例构造下一回合的提示:
from typing import List, Optional
def custom_external(
prompt: str,
agent_completions: List[str],
num_agents: int,
prompt_history_per_agent: Optional[List[List[str]]] = None,
response_history_per_agent: Optional[List[List[str]]] = None,
) -> List[str]:
# Custom logic to format next-turn prompts
# Access environment feedback, tool outputs, etc.
next_turn_prompts = []
for i in range(num_agents):
# Format prompt for agent i based on history and feedback
next_prompt = f"{prompt}\nPrevious attempt: {agent_completions[i]}\nPlease revise."
next_turn_prompts.append(next_prompt)
return next_turn_prompts示例模式#
一个 代码生成环境 包含三个示例外部过渡模式:
external.mode=expert_edits: 外部 LLM (默认: DeepSeek-Coder) 提出代码编辑建议。后续提示包括编辑建议和先前回合的上下文。通过所需的 API 键,用户可以通过expert_model选择不同的专家(例如,Claude, GPT)
external.mode=level_feedback: 静态 AST 检查和动态代码执行提供诊断。 默认情况下,沙箱仅包含第一个测试。sandbox_slice参数选择所有测试 (0、None 或 ‘all’) 或特定数量的测试 (支持负值)。
external.mode=plain: 此自改进模式仅包含先前回合的提示和响应以及修订指令。