- 第一部分:理解 OpenAI Universe 的核心理念,这部分解释了 Universe 试图解决什么问题,它的基本构成和工作原理,这对于理解现代强化学习环境至关重要。
- 第二部分:使用现代工具实践,我们将使用 Gymnasium(OpenAI Gym 的继承者)和 PettingZoo(多智能体环境库)来实践 Universe 的核心理念,并提供一个完整的代码示例。
第一部分:理解 OpenAI Universe 的核心理念
什么是 OpenAI Universe?
OpenAI Universe 是一个在 2025 年发布的大规模基准测试平台,旨在衡量和训练智能体在现实世界任务上的能力,它的宏伟目标是:创建一个“智能体操作系统”,让 AI 智能体能够像人类一样,通过操作电脑(使用鼠标、键盘)来与成千上万个网站和应用程序进行交互。

在 Universe 出现之前,强化学习大多局限于简单的、模拟的环境(如 Atari 游戏、控制机器人),Universe 试图打破这个限制,将 RL 应用于更复杂、更真实的场景。
Universe 的核心组件
Universe 构建在几个关键概念之上:
-
环境:这是智能体与之交互的任何东西,在 Universe 中,环境可以是:
- 一个网站(如购物网站、游戏网站)
- 一个移动 App
- 一个桌面应用程序(如 Photoshop)
- 一个模拟器(如飞行模拟器)
- 一个机器人(通过远程桌面连接)
-
动作:智能体可以执行的操作,Universe 使用 VNC (Virtual Network Computing) 协议作为桥梁,将智能体的动作转换为屏幕上的交互。
(图片来源网络,侵删)- 基本动作:移动鼠标、点击、按下键盘按键、输入文本等。
- 动作空间:Universe 定义了标准化的动作空间,如
gym.spaces.Tuple,包含(x, y, left_click, middle_click, right_click, key_press)等。
-
观察:智能体从环境中接收到的信息,通常就是屏幕截图。
- 观察空间:通常是
gym.spaces.Box,表示一个图像(84x84x3的 RGB 图像)。
- 观察空间:通常是
-
奖励:环境根据智能体的行为给出的反馈,这部分是最关键也最需要人工设计的,Universe 本身不提供奖励,奖励必须由环境提供。
- 在购物网站上,成功完成购买并收到确认邮件,可以给予一个大的正奖励。
- 在游戏中,得分增加就是奖励。
- 在登录页面上,成功输入用户名和密码后给予奖励。
Universe 的工作流程
- 启动环境:通过 Universe API 启动一个环境(打开一个特定的 Chrome 浏览器标签页)。
- 初始化智能体:创建一个 RL 智能体(一个 PPO 或 A2C 算法的 Agent)。
- 交互循环:
- 观察:智能体从环境中获取当前的屏幕截图。
- 思考:智能体根据观察(图像)和内部策略,决定下一步的动作(移动鼠标到某个坐标并点击)。
- 行动:智能体将动作发送给 Universe 环境。
- 反馈:环境执行动作,返回新的观察(下一帧图像)、奖励和是否结束的标志。
- 学习:智能体收集
(观察, 动作, 奖励, 新观察)的数据,用于训练其策略模型,使其学会如何获得更高的累计奖励。
Universe 的现状与遗产
Universe 项目已于 2025 年停止维护,官方的 universe Python 包已不再更新,并且很多环境链接也已失效。
Universe 的思想遗产是巨大的:

- VNC 作为标准:Universe 证明了使用 VNC 协议来构建基于视觉的通用 RL 环境是可行的,这个思想被后来的项目继承。
- 推动了研究:Universe 促进了基于视觉的 RL、多任务学习和元学习等领域的研究。
- 催生了后继者:
- OpenAI Gym:Universe 严重依赖 Gym,Gym 现在是
gymnasium库,是 RL 环境的事实标准。 - PettingZoo:专注于多智能体环境的库,提供了大量标准化的多智能体游戏(如棋类、扑克等),是 Universe 多任务理念的延续。
- DeepMind Control Suite / Brax:提供了高质量的物理模拟环境。
- ViZDoom:一个专门为基于 3D 视觉的 RL 设计的 Doom 游戏环境。
- OpenAI Gym:Universe 严重依赖 Gym,Gym 现在是
第二部分:使用现代工具实践 (Gymnasium + PettingZoo)
虽然 Universe 本身不可用,但我们可以用现代工具复现其核心思想:让智能体通过视觉输入(图像)来学习玩游戏。
我们将使用 gymnasium 来创建一个标准化的 RL 流程,并用 PettingZoo 中的一个经典游戏——“捉迷藏” (Hide and Seek) 作为我们的环境,这个游戏有两个智能体(一个藏匿者,一个寻找者),它们需要在 2D 网格世界中移动,完美地体现了多智能体交互。
步骤 1:安装必要的库
pip install gymnasium pip install pettingzoo pip install "stable-baselines3[extra]" # 一个强大的 RL 算法库 pip install matplotlib
步骤 2:编写代码
我们将创建一个脚本来训练一个智能体(我们只训练寻找者)在“捉迷藏”游戏中获胜。
import gymnasium as gym
import pettingzoo
from pettingzoo.butterfly import hide_and_seek_v3
from stable_baselines3 import PPO
from stable_baselines3.common.env_checker import check_env
from stable_baselines3.common.vec_env import DummyVecEnv, VecMonitor
from stable_baselines3.common.env_util import make_vec_env
import matplotlib.pyplot as plt
# --- 1. 创建环境 ---
# PettingZoo 环境遵循 AEC (Agent-Environment Cycle) 格式,智能体轮流行动。
# Stable-Baselines3 (SB3) 默认处理的是 Parallel (并行) 环境。
# 为了使用 SB3,我们需要将 AEC 环境包装成一个 SB3 可以理解的单智能体环境。
# 我们将关注其中一个智能体('seeker')。
def create_seeker_env():
"""创建一个只关注 'seeker' 智能体的环境包装器"""
env = hide_and_seek_v3.env(render_mode="rgb_array") # 使用 rgb_array 模式以获取图像观察
# PettingZoo 环境的观察空间通常是字典,包含 'observation' 和 'action_mask'
# SB3 更习惯处理单一的 Box 空间,这里我们简化,只使用 'observation'。
# 对于更复杂的情况,可能需要自定义包装器来处理 'action_mask'。
# 创建一个自定义的 Gymnasium 环境包装器
class HideAndSeekWrapper(gym.Wrapper):
def __init__(self, env):
super().__init__(env)
# 我们只关心 seeker 的观察空间和动作空间
# 注意:这只是一个简化示例,完整的实现需要更精细地处理
# 比如如何处理回合结束,以及如何重置环境
# 假设我们只处理 seeker
self.agent_name = "seeker_0"
# 获取 seeker 的观察和动作空间
self.observation_space = env.observation_space(self.agent_name)
self.action_space = env.action_space(self.agent_name)
# 重置计数器,用于在 seeker 行动后自动重置
self.steps = 0
def reset(self, **kwargs):
# 重置底层环境
observations, infos = self.env.reset(**kwargs)
# 我们只返回 seeker 的观察
# 为了与 SB3 兼容,返回 (obs, info)
return observations[self.agent_name], infos[self.agent_name]
def step(self, action):
# 在 SB3 中,我们假设智能体一直在行动。
# 但 PettingZoo 是轮流的,所以我们需要让 seeker 执行一个动作,
# 然后自动执行其他智能体的动作,直到下一次轮到 seeker。
# 执行 seeker 的动作
next_observations, rewards, terminations, truncations, infos = self.env.step({self.agent_name: action})
# 检查是否终止
if terminations[self.agent_name] or truncations[self.agent_name]:
# 如果结束,返回最终的观察和奖励
return next_observations[self.agent_name], rewards[self.agent_name], terminations[self.agent_name], truncations[self.agent_name], infos[self.agent_name]
# 如果没有结束,让游戏继续进行,直到再次轮到 seeker
# 这是一个简化的循环,可能需要更复杂的逻辑来处理多步
current_agent = self.env.agent_selection
while current_agent != self.agent_name and not (terminations[current_agent] or truncations[current_agent]):
# 让其他智能体随机行动
random_action = self.env.action_space(current_agent).sample()
next_observations, rewards, terminations, truncations, infos = self.env.step({current_agent: random_action})
current_agent = self.env.agent_selection
# 返回再次轮到 seeker 时的观察
# 注意:这里的奖励可能需要累积,我们这里简化处理,只给最后一次的奖励
return next_observations[self.agent_name], rewards[self.agent_name], terminations[self.agent_name], truncations[self.agent_name], infos[self.agent_name]
return HideAndSeekWrapper(env)
# --- 2. 检查环境 ---
# 这是一个好习惯,可以确保你的环境符合 Gymnasium 的接口规范。
# print("Checking environment...")
# check_env(create_seeker_env())
# print("Environment is valid!")
# --- 3. 创建并行环境以加速训练 ---
# 使用 SB3 的 make_vec_env 来轻松创建一个并行环境
# 这会创建多个环境实例,智能体可以同时在它们中训练,大大提高数据效率
env = make_vec_env(create_seeker_env, n_envs=4) # 创建4个并行环境
# --- 4. 初始化并训练智能体 ---
# 我们使用 PPO (Proximal Policy Optimization) 算法
# "CnnLstmPolicy" 是一个专门用于处理图像输入的策略
model = PPO(
"CnnLstmPolicy",
env,
verbose=1,
tensorboard_log="./hide_and_seek_tensorboard/"
)
print("Starting training...")
# 训练 1,000,000 个时间步
model.learn(total_timesteps=1_000_000)
print("Training finished!")
# --- 5. 保存和加载模型 ---
model.save("ppo_hide_and_seek_seeker")
del model # 删除旧模型
model = PPO.load("ppo_hide_and_seek_seeker", env=env)
# --- 6. 评估训练好的智能体 ---
print("Evaluating the trained agent...")
# 创建一个新的、可渲染的环境用于评估
eval_env = hide_and_seek_v3.env(render_mode="human") # 使用 "human" 模式来观看游戏
obs, _ = eval_env.reset()
# 为了在评估时使用我们的包装器逻辑,我们可以手动包装
# 或者直接在循环中控制 seeker
done = False
while not done:
# 注意:评估时我们只控制 seeker
# 获取当前 agent
current_agent = eval_env.agent_selection
if current_agent == "seeker_0":
# 使用训练好的模型选择动作
# SB3 的 model.predict 返回 (action, None)
action, _ = model.predict(obs, deterministic=True)
obs, reward, terminated, truncated, info = eval_env.step({"seeker_0": action})
if terminated or truncated:
print(f"Episode finished. Reward: {reward}")
obs, _ = eval_env.reset()
else:
# 其他智能体随机行动
action = eval_env.action_space(current_agent).sample()
obs, reward, terminated, truncated, info = eval_env.step({current_agent: action})
if terminated or truncated:
obs, _ = eval_env.reset()
eval_env.close()
代码解释
-
create_seeker_env():- 这是整个示例的核心。
stable-baselines3(SB3) 是为单智能体、并行环境设计的,而PettingZoo的环境是多智能体的、轮流行动的。 - 我们创建了一个
HideAndSeekWrapper类来桥接这个差异,它将一个多智能体环境包装成一个 SB3 可以理解的“单智能体”环境。 reset(): 只返回seeker_0的初始观察。step(): 当 SB3 给出一个动作时,这个函数会:- 让
seeker_0执行该动作。 - 它会让环境中的其他智能体(
hider_0)随机行动,直到再次轮到seeker_0。 - 返回
seeker_0在下一次行动前的观察、奖励和终止状态。
- 让
- 这是整个示例的核心。
-
make_vec_env():- 这是 SB3 的一个强大功能,它会创建
n_envs个相同的环境实例,并将它们并行运行。 - 智能体可以在这些环境中同时收集经验,极大地加快了训练速度和数据吞吐量。
- 这是 SB3 的一个强大功能,它会创建
-
PPO(...):- 我们选择了 PPO 算法,它是当前最流行、最稳健的强化学习算法之一。
"CnnLstmPolicy"是一个预定义的策略,它使用卷积神经网络 来处理图像输入,并使用长短期记忆网络 来处理时序信息(即游戏的历史帧),这对于理解游戏状态至关重要。
-
model.learn():- 这是训练的入口。
total_timesteps指定了训练的总步数,你可以通过verbose=1来查看训练过程中的损失、奖励等信息。
- 这是训练的入口。
-
评估:
- 我们创建了一个新的、使用
render_mode="human"的环境,这样我们就可以用肉眼观看训练好的智能体是如何玩游戏的。 - 在评估循环中,我们只让
seeker_0使用训练好的模型 (model.predict) 来选择动作,而hider_0仍然随机行动,以测试seeker的能力。
- 我们创建了一个新的、使用
虽然 OpenAI Universe 这个具体项目已经过去,但它所倡导的“通过通用接口让 AI 在多样化的数字世界中学习和交互”的理念,已经成为现代 AI 研究的重要方向。
通过这份教程,你学会了:
- 理解 Universe 的核心思想:将 RL 应用于基于视觉的、复杂的、真实世界的任务。
- 掌握现代 RL 工具链:学会了如何使用
gymnasium、pettingzoo和stable-baselines3来构建、训练和评估一个智能体。 - 处理多智能体环境:了解了如何将多智能体环境适配到单智能体算法框架中进行训练。
未来的方向可以包括:
- 更复杂的视觉环境:尝试使用
ViZDoom或DeepMind Control Suite。 - 真正的多智能体学习:使用
PettingZoo配合专门的多智能体算法(如 MAPPO, QMIX)来训练多个智能体协同工作。 - 探索 Universe 的遗产:研究一些基于 Universe 思想的开源项目,如
ai2thor(一个用于 AI 研究的 3D 室内环境模拟器),它也允许智能体通过第一人称视角与物体交互。
