Quick Start¶
Run from the CLI (Hydra)¶
The fastest way to run an experiment — no Python script needed:
pip install -e ".[langchain,hydra]"
python run.py # run default scenario from config.yaml
python run.py +scenario=ultimatum # run a specific scenario
python run.py +scenario=ultimatum game.total=200 # override game param
python run.py +scenario=bilateral_trade experiment=benchmark # 20 matches, parallel
Run multiple games in parallel¶
Run all games simultaneously with a single unified tabbed dashboard:
Each scenario runs in its own thread with isolated agents. The dashboard shows a tab per game with live match progress, summaries, and results.
You can also pick a subset:
Each scenario is a YAML file under conf/scenario/ that defines the game, agents, and experiment preset. You can create your own scenarios.
Baseline vs Redteam mode¶
Control agent_a's prompt strategy with the mode key:
python run.py game=ultimatum mode=redteam experiment=quick # adversarial agent_a
python run.py game=ultimatum mode=baseline experiment=quick # cooperative agent_a
Batch matrix runner¶
Run a full sweep of games, modes, and victim models in parallel:
python scripts/run_matrix.py --dry-run # preview commands
python scripts/run_matrix.py --games ultimatum --modes redteam baseline # run subset
python scripts/run_matrix.py -p 8 # 8 parallel runs
After runs complete, analyze results:
Override agents inline¶
python run.py 'agents=[{preset: ultimatum/rational, agent_id: a1}, {preset: ultimatum/selfish, agent_id: a2}]'
# Override agent params
python run.py 'agents=[{preset: ultimatum/rational, agent_id: a1, temperature: 1.5}, {preset: ultimatum/attacker, agent_id: a2}]'
See all available options with python run.py --help.
Run a batch of matches¶
from neg_env import RandomAgent, ExperimentRunner, ExperimentConfig
config = ExperimentConfig(game_id="ultimatum", num_matches=100)
agents = [RandomAgent(agent_id="alice", seed=42), RandomAgent(agent_id="bob", seed=43)]
result = ExperimentRunner(config).run(agents)
print(f"Deals: {result.num_matches - result.no_deal_count}/{result.num_matches}")
print(f"Mean shares (deal): {result.mean_shares}")
print(f"Mean utility: {result.mean_payoffs}")
Use LLM agents¶
from dotenv import load_dotenv
from neg_env import LangChainNegotiationAgent, ExperimentRunner, ExperimentConfig
from neg_env.prompts import SYSTEM_PROMPT_UNFAIR
load_dotenv() # loads OPENAI_API_KEY from .env
agents = [
LangChainNegotiationAgent(
agent_id="agent_a",
provider="openai",
model="gpt-4o-mini",
system_prompt=SYSTEM_PROMPT_UNFAIR,
),
LangChainNegotiationAgent(
agent_id="agent_b",
provider="openai",
model="gpt-4o-mini",
system_prompt=SYSTEM_PROMPT_UNFAIR,
),
]
config = ExperimentConfig(game_id="ultimatum", num_matches=5, open_dashboard=True)
result = ExperimentRunner(config).run(agents)
Custom game settings¶
from neg_env import UltimatumGame
game = UltimatumGame(total=200, max_rounds=20)
result = ExperimentRunner(config).run(agents, game=game)
# Pin reservation values for controlled experiments
game = UltimatumGame(total=100, reservation_values={"agent_a": 10, "agent_b": 30})
result = ExperimentRunner(config).run(agents, game=game)