ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

AGI Maze:构建世界模型智能体的基准框架与评估实践

2026/8/24 5:15:17 拓冰建站 浏览量
AGI Maze:构建世界模型智能体的基准框架与评估实践 1. 项目概述为什么我们需要一个“世界模型”的试炼场最近和几个做强化学习与具身智能的朋友聊天大家普遍有个痛点我们手头的智能体Agent在某个特定任务上可能表现得很“聪明”比如在Atari游戏里打砖块得分很高或者在某个模拟环境中能完美导航。但一旦环境规则发生微小的、未在训练中见过的变化或者任务目标需要一点点的组合与推理智能体就立刻“懵了”表现断崖式下跌。这背后反映的核心问题是我们训练的模型大多只是在拟合数据或优化某个单一奖励函数它并没有真正“理解”它所处的环境——它没有一个关于这个环境如何运作的、可预测的、可推理的“世界模型”。这就是“世界建模”智能体World-Modeling Agents要解决的问题。一个拥有世界模型的智能体不仅仅会对当前状态做出反应它会在内心构建一个关于环境动态、物体属性和因果关系的内部模拟。它能够进行“思想实验”如果我采取行动A环境可能会如何变化这个变化会导致什么后果这种基于模型的规划与推理能力被认为是迈向更通用人工智能的关键一步。然而评估一个智能体是否真的学会了世界模型而不是通过其他捷径比如记忆状态-动作对来完成任务是极其困难的。现有的基准测试如Atari、MuJoCo连续控制任务或是更复杂的Procgen、NetHack虽然各有侧重但往往更侧重于最终的性能分数而非对模型内部世界知识的结构化、可解释的检验。我们需要一个专门为“世界建模”能力量身定制的基准框架。于是“AGI Maze”这个概念进入了视野。它不是一个具体的迷宫游戏而是一个基准框架的设计理念。其核心思想是构建一个以迷宫为隐喻的、高度可控且可扩展的测试环境。迷宫本身象征着智能体需要探索和理解的未知结构化空间而“AGI”前缀则点明了其终极目标服务于通用人工智能智能体的核心能力评估。这个框架旨在系统性地评估智能体在不同维度上的世界建模能力比如物体持久性理解、物理常识推理、组合泛化以及反事实思考等。简单来说AGI Maze想做的就是为世界建模智能体搭建一个“高考考场”考题不是简单的分数计算而是设计一系列精心构造的“陷阱题”和“综合应用题”专门考察你对物理世界基本规律的理解深度和灵活运用能力。这对于推动下一代AI的发展至关重要。2. AGI Maze框架的核心设计哲学与评估维度2.1 从“性能评估”到“能力诊断”的范式转变传统的AI基准测试大多遵循“黑盒评估”范式给定输入评估输出如得分、准确率。我们只知道智能体“做得好不好”但很难知道它“为什么做得好”或“哪里没学好”。AGI Maze框架的设计哲学是推动评估从“性能评估”转向“能力诊断”。这意味着框架内的每一个任务、每一个环境变化都对应着对智能体某项特定世界建模能力的探针。框架设计者需要像出题老师一样心中明确每道题要考察的知识点。例如一道题迷宫中有一个开关和一个被锁住的门。智能体需要先找到开关并按下才能打开门通过。考察点智能体是否理解了“开关”和“门”之间的因果联系因果关系建模它是否能将“按下开关”这个动作与“门的状态改变”这个远期结果关联起来并进行规划多步规划能力框架会提供丰富的、结构化的评估指标不仅包括最终的任务完成率、步数效率更重要的是包括一系列“诊断性指标”如预测误差智能体内部世界模型对下一状态预测的准确度。规划深度智能体成功进行规划的任务的复杂度。泛化间隙在训练分布内任务和分布外OOD任务上表现的差距用以衡量其世界模型的鲁棒性和抽象程度。干预推理得分在反事实问题“如果当初没按开关门会开吗”上的回答准确率。通过这套组合指标我们可以绘制出一幅关于智能体世界建模能力的“能力雷达图”清晰看到其长处和短板。2.2 构建可分解、可组合的评估维度AGI Maze框架的强大之处在于其模块化和可组合性。它将复杂的世界建模能力分解为多个相对独立的维度每个维度都可以通过一系列逐渐增加难度的任务来评估。主要维度可能包括物体与属性持久性智能体是否理解物体即使不在视野内也依然存在是否理解物体的属性如颜色、形状、状态是稳定的除非有外部动作改变它任务可能涉及物体被遮挡后重新定位或根据物体固有属性进行推理。空间与几何关系对距离、方向、连通性、拓扑结构的基本理解。任务可能是在复杂迷宫中导航或理解“箱子在桌子左边”这种关系。物理常识与动态对重力、支撑性、连续性、碰撞等基本物理规律的理解。例如判断一个积木塔是否会倒塌或者一个球被推动后的运动轨迹。因果关系与工具使用理解动作因如何导致状态改变果以及如何利用一个物体工具去影响另一个物体。开锁、杠杆、连锁反应等谜题都归属此类。时间与序列推理理解事件的顺序性、持续时间以及延迟效应。例如“先浇水等待一段时间花才会开”。部分可观测性与主动感知在无法直接获取全局状态部分可观测时智能体是否会采取主动探索如移动到新位置来减少不确定性更新其内部世界模型组合泛化智能体能否将学到的简单概念和规则组合起来解决全新的、更复杂的问题这是衡量其世界模型是否真正“抽象”和“可推广”的关键。AGI Maze框架允许研究者像搭积木一样将这些维度进行组合创造出高度复杂的综合评估任务。例如一个任务可能同时测试“物理常识”避开不稳定的地面、“工具使用”找到钥匙和“组合泛化”在一个从未见过的迷宫布局中应用这些规则。2.3 环境设计在简约与丰富之间寻找平衡一个好的基准框架其环境本身也是精心设计的工具。AGI Maze类环境通常追求一种“简约的丰富性”。简约视觉上可能采用网格世界Grid World、简约的2D或3D几何图形以降低感知复杂度迫使智能体专注于逻辑和关系推理而不是复杂的图像识别。这减少了计算开销也便于大规模实验和可重复性研究。丰富在简约的视觉外壳下嵌入丰富的、可交互的实体、属性和物理规则。一个方块可以具有“可推动”、“易燃”、“导电”等多种属性一个简单的杠杆可以与多个远处的门耦合。这种设计使得环境的状态空间和交互可能性呈指数级增长为测试智能体的推理深度提供了广阔空间。环境的另一个关键特性是高度可配置性。研究者可以通过配置文件或程序化接口轻松地修改迷宫布局、物体属性、物理规则、任务目标从而生成海量的训练和测试变体。这对于系统性地研究泛化能力至关重要。3. 实现一个简易AGI Maze评估环境的实操指南理论说了很多我们动手搭建一个高度简化的AGI Maze风格评估环境来直观感受其设计。我们将使用Python和流行的强化学习库gym或更现代的gymnasium作为基础。3.1 环境定义与核心状态设计首先我们定义环境的核心元素。我们创建一个名为WorldModelMaze的网格世界环境。import numpy as np import gym from gym import spaces import matplotlib.pyplot as plt class WorldModelMaze(gym.Env): metadata {render.modes: [human]} def __init__(self, size10, seedNone): super(WorldModelMaze, self).__init__() self.size size # 迷宫大小 self.seed seed self.rng np.random.default_rng(seed) # 动作空间0:上1:右2:下3:左4:交互如推/按 self.action_space spaces.Discrete(5) # 观察空间一个字典包含局部网格视图和智能体携带状态 # 局部视图以智能体为中心的5x5网格每个格子编码物体类型 self.observation_space spaces.Dict({ local_grid: spaces.Box(low0, high255, shape(5, 5, 3), dtypenp.uint8), carrying: spaces.Discrete(2), # 0:未携带钥匙1:携带钥匙 door_open: spaces.Discrete(2), # 0:门关1:门开 }) # 物体类型编码 self.EMPTY 0 self.WALL 1 self.AGENT 2 self.KEY 3 self.DOOR 4 self.SWITCH 5 # 颜色映射 (RGB) self.COLOR_MAP { self.EMPTY: [255, 255, 255], # 白色 self.WALL: [100, 100, 100], # 灰色 self.AGENT: [0, 0, 255], # 蓝色 self.KEY: [255, 255, 0], # 黄色 self.DOOR: [139, 69, 19], # 棕色(关) self.SWITCH: [255, 0, 0], # 红色 } # 开门后的颜色 self.DOOR_OPEN_COLOR [200, 200, 200] # 浅灰色表示可通过 self.reset() def _generate_maze(self): 生成一个简单的迷宫布局包含墙、钥匙、门和开关。 grid np.full((self.size, self.size), self.EMPTY, dtypeint) # 添加边界墙 grid[0, :] self.WALL grid[-1, :] self.WALL grid[:, 0] self.WALL grid[:, -1] self.WALL # 随机添加一些内部墙 for _ in range(self.size * 2): x, y self.rng.integers(1, self.size-1, size2) grid[x, y] self.WALL # 固定位置放置关键物体为了可重复评估 self.key_pos (2, 2) self.door_pos (self.size-2, self.size-2) self.switch_pos (self.size-3, 2) grid[self.key_pos] self.KEY grid[self.door_pos] self.DOOR grid[self.switch_pos] self.SWITCH # 初始智能体位置 self.agent_pos np.array([1, 1], dtypeint) grid[tuple(self.agent_pos)] self.AGENT return grid这个环境定义了几个关键物体墙、钥匙、门、开关和智能体本身。观察空间是一个字典包含局部网格视图5x5 RGB图像和两个符号状态是否携带钥匙、门是否打开。这种设计模拟了部分可观测性——智能体不能直接看到全局地图。3.2 动态规则与奖励函数设计接下来我们实现环境动态这是注入“世界模型”测试逻辑的核心。def step(self, action): reward 0 done False info {success: False, reason: } old_pos self.agent_pos.copy() next_pos old_pos.copy() # 移动动作 if action 0: next_pos[0] - 1 # 上 elif action 1: next_pos[1] 1 # 右 elif action 2: next_pos[0] 1 # 下 elif action 3: next_pos[1] - 1 # 左 # 交互动作 elif action 4: # 检查面前一格假设面向方向这里简化为检查相邻四格 for d in [(-1,0),(0,1),(1,0),(0,-1)]: check_pos tuple(old_pos np.array(d)) if not (0 check_pos[0] self.size and 0 check_pos[1] self.size): continue target_cell self.grid[check_pos] # 与开关交互 if target_cell self.SWITCH: self.door_open True info[reason] switch_activated reward 0.5 # 稀疏奖励鼓励交互行为 break # 与钥匙交互 elif target_cell self.KEY: self.carrying_key True self.grid[check_pos] self.EMPTY # 钥匙被拾取后消失 info[reason] key_picked reward 0.5 break self._update_grid() obs self._get_obs() return obs, reward, done, info # 检查移动是否有效是否撞墙或关着的门 if not (0 next_pos[0] self.size and 0 next_pos[1] self.size): next_pos old_pos # 撞边界不动 else: target_cell self.grid[tuple(next_pos)] if target_cell self.WALL: next_pos old_pos reward - 0.01 # 轻微惩罚撞墙 elif target_cell self.DOOR: if self.door_open: # 门已开可以通过 pass else: # 门关着检查是否携带钥匙 if self.carrying_key: self.door_open True self.carrying_key False # 消耗钥匙 info[reason] door_unlocked_with_key reward 1.0 else: next_pos old_pos # 无法通过 reward - 0.01 else: # 移动到空地或其他可通行物体上 pass # 更新智能体位置 self.grid[tuple(old_pos)] self.EMPTY self.agent_pos next_pos self.grid[tuple(next_pos)] self.AGENT # 任务成功条件到达门的位置且门是开的 if np.array_equal(self.agent_pos, self.door_pos) and self.door_open: reward 10.0 done True info[success] True info[reason] reached_open_door # 步数惩罚鼓励效率 reward - 0.01 self._update_grid() obs self._get_obs() return obs, reward, done, info def _update_grid(self): 更新网格视觉表现例如门的状态改变颜色。 # 基础网格已由物体ID构成渲染时会根据ID映射颜色 # 这里我们确保门的位置ID正确开门后该位置变为可通过的空地但为了渲染我们保留ID但用不同颜色 pass # 具体颜色映射在渲染函数中处理 def _get_obs(self): 构建观察值字典。 # 生成局部5x5视图 local_view np.zeros((5, 5, 3), dtypenp.uint8) center_x, center_y self.agent_pos for i in range(-2, 3): for j in range(-2, 3): view_i, view_j i2, j2 world_x, world_y center_x i, center_y j if 0 world_x self.size and 0 world_y self.size: obj_id self.grid[world_x, world_y] # 特殊处理打开的门在观察中显示为特殊颜色 if obj_id self.DOOR and self.door_open: local_view[view_i, view_j] self.DOOR_OPEN_COLOR else: local_view[view_i, view_j] self.COLOR_MAP.get(obj_id, [0,0,0]) else: # 视野外显示为黑色墙 local_view[view_i, view_j] [0, 0, 0] obs { local_grid: local_view, carrying: 1 if self.carrying_key else 0, door_open: 1 if self.door_open else 0, } return obs这个动态规则包含了几个关键的世界建模测试点因果关系按开关动作4在开关旁会导致door_open状态变为True。智能体需要学会“开关控制门”这个因果链。工具使用与消耗钥匙是一个工具用于开门且使用后消失被消耗。智能体需要理解钥匙的“一次性使用”属性。部分可观测与记忆智能体只能看到5x5局部视野。要找到钥匙、开关和门它必须探索并记住它们的大致位置。组合任务最优策略是探索找到钥匙 - 探索找到开关并按下 - 前往门的位置此时门应已开。这需要组合“导航”、“工具获取”、“因果干预”等多个子技能。奖励函数设计为“稀疏奖励塑形奖励”的组合。到达开门状态有高额奖励10交互行为拿钥匙、按开关有中等奖励0.5撞墙和每一步有小惩罚-0.01。这种设计使得单纯通过随机探索很难获得正向反馈从而激励智能体学习有效的规划。3.3 训练一个基线智能体并观察其行为为了展示这个环境的评估作用我们可以用一个简单的深度Q网络DQN智能体进行训练并观察其学习过程。import torch import torch.nn as nn import torch.optim as optim import collections import random class DQN(nn.Module): 处理字典观察的Q网络。 def __init__(self, obs_space, action_space): super(DQN, self).__init__() # 处理局部图像假设展平后接入全连接层实际应用更应用CNN self.fc1 nn.Linear(5*5*3 2, 128) # 5x5x3的图像展平 2个符号状态 self.fc2 nn.Linear(128, 64) self.fc3 nn.Linear(64, action_space.n) def forward(self, obs): # obs 是一个字典需要手动拼接 local_grid obs[local_grid].flatten() carrying obs[carrying].unsqueeze(0) if obs[carrying].dim() 0 else obs[carrying] door_open obs[door_open].unsqueeze(0) if obs[door_open].dim() 0 else obs[door_open] # 确保都是浮点型并拼接 x torch.cat([ local_grid.float() / 255.0, # 归一化 carrying.float(), door_open.float() ], dim-1) x torch.relu(self.fc1(x)) x torch.relu(self.fc2(x)) return self.fc3(x) class ReplayBuffer: def __init__(self, capacity): self.buffer collections.deque(maxlencapacity) def push(self, state, action, reward, next_state, done): self.buffer.append((state, action, reward, next_state, done)) def sample(self, batch_size): return random.sample(self.buffer, batch_size) def __len__(self): return len(self.buffer) def train_agent(env, episodes2000, batch_size32, gamma0.99, eps_start1.0, eps_end0.01, eps_decay0.995): agent_pos env.agent_pos obs_space env.observation_space act_space env.action_space policy_net DQN(obs_space, act_space) target_net DQN(obs_space, act_space) target_net.load_state_dict(policy_net.state_dict()) target_net.eval() optimizer optim.Adam(policy_net.parameters(), lr1e-3) replay_buffer ReplayBuffer(10000) eps eps_start stats {episode_rewards: [], success_rate: []} success_count 0 for episode in range(episodes): obs env.reset() total_reward 0 done False # 将初始观察转换为适合网络的格式这里需要手动转换字典中的值为张量 state {k: torch.tensor(v).unsqueeze(0) if isinstance(v, np.ndarray) else torch.tensor([v]) for k, v in obs.items()} while not done: # epsilon-贪婪策略 if random.random() eps: action env.action_space.sample() else: with torch.no_grad(): q_values policy_net(state) action q_values.argmax().item() next_obs, reward, done, info env.step(action) total_reward reward # 转换next_obs next_state {k: torch.tensor(v).unsqueeze(0) if isinstance(v, np.ndarray) else torch.tensor([v]) for k, v in next_obs.items()} # 存储转换 replay_buffer.push(state, action, reward, next_state, done) state next_state # 经验回放与学习 if len(replay_buffer) batch_size: transitions replay_buffer.sample(batch_size) batch_state, batch_action, batch_reward, batch_next_state, batch_done zip(*transitions) # 注意这里需要小心地批处理字典状态。一个简单的方法是分别处理每个键。 # 为了简化演示我们假设已有一个能处理批字典的函数。实际实现会更复杂。 # 此处省略详细的DQN训练循环代码因为它较长且是标准实现。 # 核心是计算Q目标值reward gamma * max_a Q_target(next_state) 如果非终止状态。 # 然后计算损失MSE(Q_policy(state)[action], target) # 最后反向传播更新policy_net并定期更新target_net。 if done: if info[success]: success_count 1 break # 简化每100轮更新一次目标网络衰减epsilon if episode % 100 0: target_net.load_state_dict(policy_net.state_dict()) eps max(eps_end, eps * eps_decay) stats[episode_rewards].append(total_reward) if episode % 100 0: recent_success_rate success_count / 100 if episode 100 else 0 stats[success_rate].append(recent_success_rate) print(fEpisode {episode}, Reward: {total_reward:.2f}, Eps: {eps:.3f}, Recent Success Rate: {recent_success_rate:.2f}) success_count 0 return policy_net, stats注意上面的训练代码是一个高度简化的框架省略了将字典观察批处理的复杂细节和完整的DQN损失计算。在实际研究中通常会使用像stable-baselines3这样的库或者精心编写自己的训练循环。这里的目的是展示评估流程。通过训练我们可以观察success_rate的变化。一个成功的世界建模智能体应该能学会上述的组合策略。我们可以通过分析其决策轨迹、在关键节点如看到开关时的Q值分布来诊断其是否理解了环境中的因果关系。4. 基于AGI Maze框架的进阶评估与问题排查4.1 设计诊断性评估任务一个完整的AGI Maze基准框架不会只有一个固定迷宫。其威力在于一系列精心设计的诊断任务。以下是一些可以基于我们简易环境扩展的评估任务示例因果干预测试任务描述在智能体学会标准任务后在新的迷宫中开关和门之间的连接被“切断”即按下开关不再开门。评估智能体需要多少次探索才能发现这一规则变化并转而寻找钥匙如果存在或尝试其他方法。考察点世界模型更新速度、对因果失效的检测能力。实现在环境类中添加一个causal_link_active变量在特定评估阶段将其设为False。组合泛化测试任务描述训练智能体在多种小型迷宫有钥匙或开关上然后在一个全新的、更大的迷宫中进行测试该迷宫包含多个门、钥匙和开关且逻辑更复杂例如开关A控制门1钥匙B开锁门2且门1后藏着钥匙C用于开锁门3。考察点智能体能否将学到的“钥匙开门”、“开关开门”的基本规则组合并推广到更复杂的场景中。实现设计一个迷宫生成器可以程序化地创建符合特定逻辑约束的迷宫。反事实推理测试任务描述在智能体完成一次轨迹后向其提问“如果你在步骤t没有按下开关你最终能到达门吗” 这需要智能体利用其内部世界模型进行“回滚”和“模拟”。考察点评估智能体内部模型的保真度和用于推理的能力而不仅仅是用于行动选择。实现这通常需要智能体架构本身支持反事实查询或者在环境外部构建一个模拟器来运行智能体的“假设”策略。部分可观测性压力测试任务描述将局部视野从5x5缩小到3x3甚至1x1完全依赖记忆和触觉。或者增加“迷雾”机制使远处物体不可见。考察点智能体构建和维持内部空间地图的能力以及其主动探索策略的有效性。4.2 智能体常见失败模式与诊断在AGI Maze类环境中训练智能体常会观察到以下几种典型的失败模式它们对应着世界建模能力的不同缺陷失败模式可能表现对应的世界建模缺陷诊断与改进方向“撞墙专家”智能体在迷宫边缘或障碍物前反复徘徊无法有效探索内部。空间关系建模差。无法理解“墙”是不可通过的这一基本空间属性或无法将局部观察整合成有效的地图。检查观察表示是否足够如是否包含距离信息增加对无效移动的惩罚引入好奇心驱动探索奖励访问新状态。“钥匙收集者”智能体学会了拾取钥匙但拾取后要么原地不动要么无视门的存在。工具使用与目标关联断裂。理解了钥匙的“可拾取性”但未将其与“开门”这一最终目标联系起来。模型可能缺少对任务层级结构的表示。设计课程学习先在一个只有钥匙和门的简单环境中训练使用基于模型的规划算法如蒙特卡洛树搜索显式地模拟拾取钥匙后的未来状态。“开关无视者”智能体找到了钥匙并成功开门但完全忽略了开关的存在。在需要开关的任务中失败。因果关系建模缺失或奖励塑造误导。智能体找到了一个能获得高奖励的捷径用钥匙因此没有动机去探索开关的因果效应。调整环境使得仅用钥匙无法开门或开门奖励极低必须使用开关或者在训练初期随机化门的解锁机制有时用钥匙有时用开关迫使智能体学习两者。“健忘的探索者”智能体在探索中曾经过钥匙或开关但走开后似乎忘记了它们的位置导致无头苍蝇般乱转。记忆与状态估计能力不足。在部分可观测下无法有效维护一个内部状态估计如“钥匙大概在左上区域”。在智能体架构中引入显式记忆模块如LSTM、Transformer记忆池或可微分的神经图使用基于定位的SLAM同步定位与地图构建启发式方法。“组合无能”在训练分布内的任务上表现良好但在组合泛化测试如多钥匙多门中完全失败。过度拟合与缺乏抽象。模型记忆了具体的状态-动作序列而非抽象的关系规则如“任何钥匙对应其颜色的门”。在训练时使用大量程序化生成的、具有不同布局但相同逻辑规则的环境变体采用图神经网络GNN来显式地建模物体之间的关系使用元学习或课程学习来提升泛化能力。4.3 实操心得与避坑指南在实际构建和利用此类基准进行研究时我总结了几点关键心得奖励设计是双刃剑过于密集的塑形奖励如每靠近目标一步就给小奖励可能会让智能体学会“骗奖励”的局部策略而忽略了真正的因果理解。稀疏奖励只在达成关键子目标或最终目标时给奖励更能考验世界建模和规划能力但也会使训练变得极其困难。一个折中的方法是设计基于事件的奖励只在智能体执行了有意义的因果动作如按下开关、拾取钥匙时给予中等奖励。观察表示决定学习上限如果只给智能体提供原始的局部像素它可能需要花费大量计算资源学习“视觉感知”这掩盖了我们对“推理”能力的评估。提供适当的符号化或结构化观察如物体类别、相对位置、属性向量可以降低感知难度让评估更聚焦于推理本身。这类似于给人类玩家提供游戏的小地图和物品栏状态。环境随机化必须“有意义”为了测试泛化我们会在训练时随机化迷宫布局、物体位置。但随机化必须控制在不改变核心逻辑规则的范围内。例如墙的形状可以变但“墙不可通过”的规则不能变钥匙和门的位置可以变但“钥匙开门”的规则不能变。否则智能体学不到任何稳定知识。评估指标要多元化不要只看最终成功率。分析智能体的轨迹它是否走了最优路径它是否重复访问无效区域它在关键决策点如看到开关的犹豫时间有多长记录其内部世界模型的预测误差它对下一状态的预测准确吗这些过程性指标比单一的结果性指标更能揭示问题本质。基线智能体的选择对比不同架构的智能体时要确保训练计算量和参数规模大致相当。一个简单的反应式策略如DRQN和一个复杂的基于模型的规划器如MuZero在相同环境下的表现差异能清晰地说明世界建模带来的优势或劣势在简单任务中模型可能带来不必要的开销。构建和利用像AGI Maze这样的基准框架本身就是一个不断迭代和深化的过程。它迫使研究者不仅思考如何让智能体“得分更高”更要思考如何设计实验去“拷问”智能体内心的那个“世界模型”到底学到了什么、遗漏了什么。这个过程或许比单纯追求SOTA结果更能推动我们向真正理解世界的通用人工智能迈进。