1 前言
HGPO(Hierarchy-of-Groups Policy Optimization)通过step-wise GRPO进行Agentic RL,其将处于相同状态的rollout step聚集,对它们进行Group-wise优势计算,实现了更加细粒度的奖励分配,缓解只在rollout结束时获得奖励的稀疏问题。
论文在ALFWorld 和 WebShop 上验证了方法的有效性。因此,这里会学习一下ALFWorld的环境构建,以及如何在verl里实现HGPO。
2 ALFWorld
2.1 ALFWorld 简介
ALFWorld模拟了一个家庭场景(厨房、浴室、卧室、客厅等),Agent 需要通过文本指令与环境交互,完成类似"把洗干净的苹果放进冰箱"这样的任务。Agent 每步接收自然语言描述的当前状态,并从候选动作列表中选择一个执行,直到任务完成或超过最大步数。
ALFWorld包括六类环境,Pick & Place (拾取与放置)、Examine in Light (在光源下检查)、Clean & Place (清洁与放置)、Heat & Place (加热与放置)、Cool & Place (冷却与放置)、Pick Two & Place(拾取两个物体并放置)。
在LLM Agentic RL中,一般使用纯文本模式,每个 step 的输入输出均为字符串。
2.2 ALFWorld 数据集格式
在HGPO项目的Readme里提供了ALFWorld的下载方案,完成后得到以下格式文件。
bash
$ALFWORLD_DATA/json_2.1.1/
├── train/ # 2435 个任务场景(训练集)
├── valid_seen/ # 242 个(验证集,in-distribution,房间布局在训练集中出现过)
├── valid_unseen/ # 85 个(验证集,out-of-distribution,房间布局未见过)
└── valid_train/ # 训练集的子集验证用
$ALFWORLD_DATA/verl_data/
├── train.parquet # 16 条 verl 格式训练数据(仅用于声明模态,实际任务由环境动态加载)
└── test.parquet # 128 条 verl 格式测试数据
verl_data/中的 parquet 文件只是占位符,prompt字段为空字符串,真正的任务由 ALFWorld 环境在reset()时随机加载。
同一个任务目录下通常有 2--3 个 trial_T... 子目录,代表同一任务、同一房间、不同人类标注员的演示轨迹,区别在于:
- 物体摆放位置不同(同一类物体放在不同家具上)
- Agent 初始站位不同
- 任务描述语言不同(语义相同,措辞各异)
TextWorld 训练时从这些 trial 中随机选一个作为实际游戏场景。
每个 trial 目录包含:
bash
trial_T.../
├── game.tw-pddl # TextWorld 游戏文件(环境实际加载此文件)
├── initial_state.pddl # PDDL 格式初始状态
└── traj_data.json # 任务元数据(任务类型、物体位置、人类标注描述等)
3 HGPO in VeRL
项目路径:github.com/langfengq/v...
这里记录一下如何在VeRL里使用ALFWorld环境。
3.1 交互逻辑
首先看一下multi-turn交互怎么实现的。
交互循环(单 Episode):
bash
reset()
→ 随机加载一个 game.tw-pddl 文件
→ 返回初始场景描述:
"You are in the middle of a room. Looking quickly around you, you see ..."
"Your task is to: put a hot apple in countertop."
for step in range(max_steps=50):
1. build_text_obs() 构造完整 Prompt(含历史 + 任务 + 可用动作列表)
2. LLM 生成响应: <think>...推理过程...</think><action>go to fridge 1</action>
3. alfworld_projection() 解析 <action> 标签内的动作文本
4. TextWorld.step(action) 执行动作,返回新观测 + reward + done
5. memory.store(obs, action) 写入历史记录
if done: break
reward: 0(中间步)或 10.0(任务完成,won=True)
以上逻辑通过VeRL多轮交互Loop实现。
3.2 奖励设计
任务完成奖励:只在完成任务时给予奖励,完成+10分,否则为0分。为了将奖励传递到历史的step中,引入折扣因子0.95,越靠近最后step奖励越高。
无效惩罚 :如果智能体生成了在当前环境中无效的动作 (invalid action),则施加一个小的负奖励:-0.1。invalid action包括如下几个:
| 条件 | 说明 |
|---|---|
输出中无 <action>...</action> 标签 |
格式错误 |
输出中无 <think>...</think> 标签 |
缺少推理过程 |
输出中含中文字符(\u4e00-\u9fff) |
语言错误 |
3.3 环境构造
在Agentic RL任务,最重要的就是环境如何构建,这里的环境包括文本解析与处理、环境交互与反馈、奖励打分等。env包括以下几个部分:
动作解析
首先,模型被要求以先进行推理,再以输出动作。token在多轮交互loop被解码后传入env里。一条典型的 LLM 输出格式:
vbnet
<think>
I need to heat the apple. I'm currently holding it and standing near the microwave.
The admissible actions include 'heat apple 1 with microwave 1', which is exactly what I need.
</think>
<action>heat apple 1 with microwave 1</action>
这条输出将会被送入env进行解析,解析出和的内容。
环境与奖励反馈
env会判断是否有无效动作,如果是无效动作,奖励会给予惩罚,参考以上的奖励系统部分。env也会判断llm是否完成了任务,如果llm最终完成了任务,环境会判断并给予+10分的分数。
如果是无效动作,observation会返回""Nothing happens."。如果是有效的动作,env会根据动作,生成下一步的observation,包括环境状态和可执行的动作。
游戏世界的状态是一组 PDDL 命题集合 (纯符号),Fast Downward C++ 引擎负责执行动作(增删命题)并枚举新的可行动作 ,而观测文本则完全由
game.tw-pddl中内嵌的 CSG Grammar 根据当前命题集合实时拼装生成------本质上是一个符号逻辑系统外套了一层自然语言生成器。
并行环境
框架会为每一个rollout创建一个env,并分配num_cpus=0.1的资源。