pettingzoo

Par mkurman · zorai

npx skills add https://github.com/mkurman/zorai --skill pettingzoo

name: pettingzoo description: API d'environnement multi-agent pour l'apprentissage par renforcement (PettingZoo). API standard pour RL multi-agent étendant Gymnasium avec Agent Environment Cycle (AEC) et APIs Parallel. Inclut les environnements Atari, Butterfly, Classic, MPE et SISL. Pour le RL monoagent, utilisez Gymnasium. Pour les implémentations d'algorithmes, utilisez stable-baselines3 ou CleanRL. license: MIT license tags: [multi-agent-rl, marl-environments, turn-based-games, parallel-envs, pettingzoo] metadata: skill-author: K-Dense Inc. --------|-----|----------| | Jeux au tour par tour (cartes, jeux de plateau) | ✅ Meilleur choix | ❌ Non approprié | | Actions simultanées (robotique, MPE) | ⚠️ Fonctionne mais maladroit | ✅ Meilleur choix | | Compatible avec CleanRL | ✅ Via wrappers | ❌ Nécessite conversion | | Compatible avec SB3 | ❌ Pas directement | ❌ Nécessite conversion |

3. Méthodes clés d'AEC

# Itérer sur les agents dans l'ordre du tour
for agent in env.agent_iter():
    # Obtenir l'observation/récompense de l'agent ACTUEL
    observation, reward, termination, truncation, info = env.last()

    # Vérifier si l'agent est terminé
    if termination or truncation:
        action = None
    else:
        action = policy(observation, agent)

    # Soumettre l'action — cela fait progresser l'environnement ET passe à l'agent suivant
    env.step(action)

# Après la boucle : vérifier quels agents sont encore actifs
print(env.agents)  # Liste des agents actifs

4. Environnements disponibles

Catégorie Environnements Style API Description
MPE simple_spread, simple_adversary, simple_tag, simple_world_comm Parallel Environnements multi-agent de particules, coopératifs/compétitifs
Atari pong, space_invaders, surround, tennis, warlords Parallel Versions multi-agent des jeux Atari classiques
Butterfly pistonball, cooperative_pong, knights_archers_zombies Parallel Jeux multi-agent coopératifs
Classic chess, go, rps, backgammon, texas_holdem, tictactoe AEC Jeux de plateau et de cartes classiques
SISL waterworld, pursuit Parallel Tâches de contrôle multi-agent

Lister tous les disponibles :

from pettingzoo.utils import all_modules
print(all_modules)

5. Wrappers utilitaires

from pettingzoo.utils import wrappers

# Conversion AEC → Parallel
from pettingzoo.utils.conversions import aec_to_parallel
parallel_env = aec_to_parallel(aec_env)

# Conversion Parallel → AEC
from pettingzoo.utils.conversions import parallel_to_aec
aec_env = parallel_to_aec(parallel_env)

# Remplir les observations pour des agents de tailles différentes
env = wrappers.PadObservations(env)

# Aplatir les observations dict
env = wrappers.FlattenObservations(env)

6. Exemple MPE — Navigation coopérative

from pettingzoo.mpe import simple_spread_v3

env = simple_spread_v3.parallel_env(
    N=3,            # Nombre d'agents
    local_ratio=0.5, # Combien les agents voient
    max_cycles=100,
    render_mode="human",
)

observations, infos = env.reset(seed=42)

for cycle in range(100):
    actions = {}
    for agent in env.agents:
        # observations[agent] est l'observation locale pour cet agent
        actions[agent] = env.action_space(agent).sample()

    observations, rewards, terminations, truncations, infos = env.step(actions)

    if all(terminations.values()) or all(truncations.values()):
        break

env.close()

7. Espaces d'observation et d'action

from pettingzoo.mpe import simple_spread_v3

env = simple_spread_v3.env(N=3)

# Espaces par agent
for agent in env.possible_agents:
    print(f"{agent} obs: {env.observation_space(agent)}")
    print(f"{agent} act: {env.action_space(agent)}")

# Politiques spécifiques aux agents
policies = {
    "agent_0": policy_0,
    "agent_1": policy_1,
    "agent_2": policy_2,
}

8. Atari multi-agent

from pettingzoo.atari import pong_v3

env = pong_v3.parallel_env(render_mode="human")
observations, infos = env.reset()

# Deux agents : "first_0" et "second_0"
# Chacun voit le jeu de sa perspective
for agent in env.agents:
    print(env.observation_space(agent))  # Box(210, 160, 3)
    print(env.action_space(agent))       # Discrete(6)

9. Intégration CleanRL

CleanRL a un support intégré pour Atari multi-agent PettingZoo :

# Voir : cleanrl/ppo_pettingzoo_ma_atari.py
from cleanrl.ppo_pettingzoo_ma_atari import make_env

envs = make_env("pong_v3", seed=1)

10. Environnement multi-agent personnalisé

from pettingzoo import ParallelEnv
import functools
import gymnasium as gym
from gymnasium import spaces
import numpy as np

class CustomMARLEnv(ParallelEnv):
    metadata = {"name": "custom_marl_v0"}

    def __init__(self, render_mode=None):
        super().__init__()
        self.possible_agents = ["agent_0", "agent_1"]
        self.observation_spaces = {
            a: spaces.Box(low=0, high=1, shape=(4,), dtype=np.float32)
            for a in self.possible_agents
        }
        self.action_spaces = {
            a: spaces.Discrete(3) for a in self.possible_agents
        }
        self.render_mode = render_mode

    def reset(self, seed=None, options=None):
        self.agents = self.possible_agents[:]
        self.state = np.zeros(4, dtype=np.float32)
        observations = {a: self.state.copy() for a in self.agents}
        infos = {a: {} for a in self.agents}
        return observations, infos

    def step(self, actions):
        # Appliquer les actions, mettre à jour l'état
        for agent, action in actions.items():
            self.state[0] += (action - 1) * 0.1
        self.state = np.clip(self.state, 0, 1)

        rewards = {a: float(self.state[0]) for a in self.agents}
        terminations = {a: False for a in self.agents}
        truncations = {a: False for a in self.agents}
        observations = {a: self.state.copy() for a in self.agents}
        infos = {a: {} for a in self.agents}

        # Supprimer les agents morts
        if self.state[0] > 0.9:
            self.agents = []

        return observations, rewards, terminations, truncations, infos

    def render(self):
        if self.render_mode == "human":
            print(f"State: {self.state}")

    def close(self):
        pass

11. Intégration Supersuit (prétraitement RL)

pip install supersuit
from pettingzoo.atari import space_invaders_v2
from supersuit import (
    resize_v1, frame_skip_v0, frame_stack_v1,
    color_reduction_v0, dtype_v0, pettingzoo_env_to_vec_env_v1,
)

env = space_invaders_v2.parallel_env()
env = resize_v1(env, (84, 84))
env = frame_skip_v0(env, 4)
env = frame_stack_v1(env, 4)
# Convertir en Gymnasium VecEnv pour la compat SB3/CleanRL
env = pettingzoo_env_to_vec_env_v1(env)

Motifs clés

  1. Utiliser l'API AEC pour les jeux au tour par tour (échecs, poker) — la logique séquentielle est naturelle
  2. Utiliser l'API Parallel pour les actions simultanées (MPE, Atari multi-agent)
  3. Toujours vérifier env.agents — il change à mesure que les agents sont ajoutés/supprimés
  4. Utiliser env.observation_space(agent) et env.action_space(agent) — ils peuvent différer par agent
  5. Supersuit fournit un prétraitement prêt pour RL — empilage de frames, redimensionnement, skip
  6. PettingZoo utilise Gymnasium sous le capot — les espaces d'observation/action viennent de gymnasium.spaces

Références

Skills similaires