A flexible multi-agent simulation framework built on Concordia v2 with Hydra-based configuration management and multi-model support.
- Hydra Configuration: Composable YAML configurations for experiments, models, scenarios
- Multi-Model Support: GPT-4o, GPT-4o-mini, Claude, Ollama with per-agent model assignment
- Dynamic Scenarios: Switch scenarios via config (marketplace, election, misinformation, ai_conference, debate)
- Social Media Environment: In-memory social media platform with posts, replies, likes, boosts, follows
- Evaluation Probes: Query agents at checkpoints without affecting their memory (categorical, numeric, boolean, judged_numeric)
- ValueFlow Scenario: Replication of arxiv 2602.08567 β measures how value perturbations propagate through multi-agent networks via Schwartz Value Survey probes and System Susceptibility metrics
- Style Diversity Evaluation: Reference-free metrics (self-BLEU, lexical diversity, content evolution, etc.) for diagnosing repetitive agent behavior
- Experiment Organization: Structured study/hypothesis/condition tree for reproducible experiments (see
experiments/study_schema.md) - Modular Architecture: Engines, simulators, and components can be mixed and matched
- Extensible Design: Easy to add new scenarios, agents, game masters, and components
- Full Dev Infrastructure: Pre-commit hooks, CI/CD, type checking, ~320 tests
# Clone and install
git clone git@github.com:mptouzel/scensim.git
cd scensim/simulator
# Using uv (recommended)
uv sync
# Or using pip
pip install -e ".[dev]"
# Setup pre-commit hooks
pre-commit install- Copy the environment template:
cp .env.example .env- Add your API keys to
.env:
OPENAI_API_KEY=your-key-here
ANTHROPIC_API_KEY=your-key-here
# Run with default configuration (marketplace)
uv run python run_experiment.py
# Social media scenarios
uv run python run_experiment.py scenario=misinformation
uv run python run_experiment.py scenario=ai_conference
# Traditional scenarios
uv run python run_experiment.py scenario=election
uv run python run_experiment.py scenario=debate
# Override parameters
uv run python run_experiment.py simulation.execution.max_steps=50 model=claude
# Switch model
uv run python run_experiment.py scenario=ai_conference model=gpt4o
# Multi-model simulation
uv run python run_experiment.py model=multi_model
# Quick test with mock models (no API calls)
uv run python run_experiment.py --quick-test
# View configuration without running
uv run python run_experiment.py --cfg job| Scenario | Engine | Description |
|---|---|---|
marketplace |
sequential | Buyers, sellers, and an auctioneer negotiate trades |
election |
sequential | Voters, candidates, and media interact during a campaign |
misinformation |
social_media | Information spread and manipulation on a social media platform |
ai_conference |
social_media | Two echo chambers (conference attendees vs. protesters) collide on social media; studies groupthink dynamics |
debate |
sequential | Formal debate with debaters, moderator, and judges |
valueflow |
valueflow | Value perturbation propagation across agent networks (arxiv 2602.08567); measures Ξ²-susceptibility and System Susceptibility via Schwartz Value Survey probes |
Social media scenarios auto-select the social_media environment config via a Hydra defaults override, which activates the SocialMediaEngine for parallel agent execution with feed-based interaction.
simulator/
βββ run_experiment.py # Main entry point (Hydra-decorated)
βββ config/ # Hydra configuration
β βββ experiment.yaml # Main config with defaults
β βββ simulation/ # Simulation mode configs
β β βββ sequential.yaml
β β βββ parallel.yaml
β βββ model/ # Model configurations
β β βββ gpt4.yaml # GPT-4o-mini (default)
β β βββ gpt4o.yaml # GPT-4o
β β βββ claude.yaml
β β βββ mock.yaml
β β βββ multi_model.yaml
β βββ environment/ # Environment settings
β β βββ generic_world.yaml
β β βββ game_theoretic.yaml
β β βββ social_media.yaml
β β βββ valueflow.yaml # ValueFlowEngine settings
β βββ scenario/ # Scenario definitions
β β βββ marketplace.yaml
β β βββ election.yaml
β β βββ misinformation.yaml
β β βββ ai_conference.yaml
β β βββ debate.yaml
β β βββ valueflow.yaml # Topology, perturbation, interaction config
β βββ evaluation/ # Evaluation metrics
β βββ basic_metrics.yaml
β βββ election.yaml
β βββ marketplace.yaml
β βββ valueflow.yaml # 56 Schwartz value probes (JudgedNumericProbe)
βββ scenarios/ # Scenario implementations
β βββ marketplace/ # Marketplace scenario
β β βββ agents.py # BuyerAgent, SellerAgent, AuctioneerAgent
β β βββ game_masters.py # MarketGameMaster
β β βββ knowledge.py # Knowledge builders
β β βββ events.py # Event generators
β β βββ data/knowledge.yaml
β βββ election/ # Election scenario
β β βββ agents.py, game_masters.py, knowledge.py, events.py
β β βββ data/knowledge.yaml
β βββ misinformation/ # Misinformation scenario (social media)
β β βββ agents.py # SocialMediaUserAgent prefab
β β βββ game_masters.py # MisinformationGameMaster
β βββ ai_conference/ # AI Conference groupthink scenario (social media)
β β βββ agents.py # AIConferenceAgent prefab
β β βββ game_masters.py # AIConferenceGameMaster
β βββ valueflow/ # ValueFlow scenario (arxiv 2602.08567)
β βββ README.md # Modification guide and experiment status
β βββ agents.py # ValueFlowAgent prefab (neutral persona)
β βββ game_masters.py # ValueFlowGameMaster + build_topology_graph()
β βββ engine.py # ValueFlowEngine (DAG-filtered, 3 rounds)
β βββ simulator.py # ValueFlowSimulator (perturbation + judge wiring)
β βββ metrics.py # Ξ²-susceptibility, SS, JSON export
β βββ plotting.py # All visualization functions
β βββ data/schwartz_values.yaml # 56-value Schwartz dataset
βββ src/ # Core library
β βββ simulation/ # Simulation infrastructure
β β βββ simulation.py # Core Simulation class
β β βββ simulators/
β β β βββ base.py # BaseSimulator (abstract)
β β β βββ multi_model.py # MultiModelSimulator
β β βββ engines/
β β βββ base.py # BaseEngine (abstract)
β β βββ sequential.py # SequentialEngine
β β βββ engine_utils.py # Action spec parser fix
β βββ entities/ # Generic entity prefabs
β β βββ agents/
β β β βββ basic_entity.py # BasicEntity prefab
β β β βββ planning_agent.py # PlanningAgent prefab
β β βββ game_masters/
β β β βββ basic_gm.py # BasicGameMaster prefab
β β βββ components/
β β βββ base.py # BaseComponent (abstract)
β βββ environments/ # Environment implementations
β β βββ social_media/
β β βββ app.py # Post dataclass + SocialMediaApp
β β βββ engine.py # SocialMediaEngine
β β βββ game_master.py # SocialMediaGameMaster prefab
β β βββ analysis.py # Transmission chain analysis
β βββ evaluation/ # Evaluation system
β β βββ probes.py # CategoricalProbe, NumericProbe, BooleanProbe
β β βββ probe_runner.py # ProbeRunner (orchestrates probe execution)
β βββ models/ # Model implementations
β β βββ openai_model.py # OpenAI GPT models
β β βββ anthropic_model.py # Anthropic Claude models
β β βββ local_model.py # LocalModel for Ollama/local LLMs
β βββ utils/ # Utilities
β βββ config_helpers.py # Config helper functions
β βββ validation.py # Config validation
β βββ event_logger.py # Simulation event logging
β βββ logging_setup.py # Logging configuration
β βββ testing.py # Test utilities and mocks
βββ scripts/ # Utility scripts
β βββ run_social_media_sim.py # Standalone social media runner
β βββ analyze_social_media.py # CLI analysis tool
β βββ explore_dashboard.py # Interactive Dash explorer
β βββ run_valueflow.py # ValueFlow sweep runner (baseline + perturbed + metrics)
β βββ judge_probe_results.py # Backfill null probe values via LLM judge
βββ experiments/ # Study definitions, tooling, and organized results
β βββ study_schema.md # Canonical study structure and pipeline
β βββ scripts/
β β βββ study_io.py # Shared I/O: load/validate study.yaml, extract run metadata
β β βββ organize_experiments.py # Organizer β builds studies/ tree from study.yaml
β βββ studies/
β βββ {study_name}/ # Per-study: study.yaml + eval.py + notebook.ipynb + generated results tree
βββ notebooks/ # Empty β notebooks live in experiments/studies/{study_name}/notebook.ipynb
βββ tests/ # Test suite (241 tests)
βββ conftest.py # Shared fixtures
βββ environments/ # Social media environment tests
βββ test_agents/
βββ test_simulators/
βββ test_evaluation/
βββ test_utils/
βββ test_scenarios/
βββ test_integration/
Configs are composed using Hydra's defaults list:
# config/experiment.yaml
defaults:
- simulation: sequential
- model: gpt4
- environment: generic_world
- scenario: marketplace
- evaluation: basic_metrics# Use Claude instead of GPT-4
uv run python run_experiment.py model=claude
# Use GPT-4o for higher quality
uv run python run_experiment.py model=gpt4o
# Parallel simulation with multi-model
uv run python run_experiment.py simulation=parallel model=multi_model
# Custom parameters
uv run python run_experiment.py \
scenario.agents.buyer.budget=1000 \
scenario.agents.seller.pricing_strategy=competitiveAssign different models to different agents:
# config/model/multi_model.yaml
model_registry:
gpt4:
provider: openai
model_name: gpt-4-turbo
claude:
provider: anthropic
model_name: claude-3-5-sonnet
entity_model_mapping:
Alice: gpt4
Bob: claude
narrator: gpt4The social media environment provides an in-memory platform for simulating information spread:
- Actions: post, reply, like, unlike, boost, follow, unfollow
- Feed: Chronological feed from followed users
- Engine:
SocialMediaEngineruns parallel agent actions each step - Analysis: Transmission chain extraction, keyword overlap, network analysis
Activated by the social_media environment config (config/environment/social_media.yaml). Social media scenarios auto-select this environment via a Hydra defaults override.
# Run social media scenarios
uv run python run_experiment.py scenario=misinformation
uv run python run_experiment.py scenario=ai_conference
# Standalone runner (mock mode)
uv run python scripts/run_social_media_sim.py
# Analyze results
uv run python scripts/analyze_social_media.py path/to/checkpoint.json
# Interactive dashboard
uv run python scripts/explore_dashboard.py path/to/checkpoint.jsonReplication of arxiv 2602.08567. Measures how injecting an amplified value into one agent propagates through a multi-agent network, using the Schwartz Value Survey as probes.
# Run a single experiment (chain topology, social_power perturbed at agent 0)
uv run python run_experiment.py scenario=valueflow evaluation=valueflow environment=valueflow
# Sweep topologies (H1), value types (H3), and perturbation locations (H4)
uv run python scripts/run_valueflow.py \
--topologies chain ring star fully_connected \
--values social_power helpful equality \
--locations 0 2 4
# Compare models β reuse existing baseline, write to separate results dir
uv run python scripts/run_valueflow.py \
--model gpt4 \
--topologies chain ring star fully_connected \
--baseline-dir outputs/valueflow_experiment/<timestamp> \
--output-dir experiments/valueflow/results_gpt4mini
# Analyze results
# Open notebooks/study_valueflow.ipynbKey metrics saved to experiments/valueflow/results/{condition}/valueflow_metrics.json:
target_value_ssβ System Susceptibility (headline scalar)beta_susceptibilityβ per-agent, per-value shift (perturbed minus baseline)beta_timeseriesβ Ξ² at each interaction round
See scenarios/valueflow/README.md for the full modification guide (add values, topologies, models, re-run from scratch).
Query agents at checkpoints without affecting their memory:
# config/evaluation/election.yaml
metrics:
vote_preference:
type: categorical
categories: [conservative, progressive, undecided]
prompt_template: |
Based on {agent_name}'s views, which candidate do they prefer?
applies_to: [voter]Probe types: categorical, numeric (min/max range), boolean (yes/no), judged_numeric (free-form agent response scored by a judge LLM).
Reference-free evaluation of agent linguistic diversity:
# Evaluate a single run
uv run python experiments/studies/style_diversity/eval.py path/to/checkpoint.json
# Compare two runs
uv run python experiments/studies/style_diversity/eval.py ckpt1.json ckpt2.json --compare
# Export to file
uv run python experiments/studies/style_diversity/eval.py checkpoint.json -o results/Computes 10 metrics per agent: self-BLEU, lexical diversity, content evolution, opener variety, action entropy, near-duplicate rate, target fixation, action diversity, new post rate, and inter-agent distinctiveness.
Organize simulation runs into a browsable study/hypothesis/condition hierarchy:
uv run python experiments/scripts/organize_experiments.py experiments/studies/style_diversity/study.yamlSee experiments/study_schema.md for the full schema covering directory layout, file formats, and the standard results notebook structure.
- Create config file
config/scenario/my_scenario.yaml:
name: my_scenario
premise: |
Description of your scenario...
roles:
- name: player
description: "A player in the game"
agents:
entities:
- name: Alice
role: player
prefab: basic_entity
params:
goal: "Win the game"
game_master:
prefab: basic_game_master
name: narrator
prefabs:
basic_entity: src.entities.agents.basic_entity.BasicEntity
basic_game_master: src.entities.game_masters.basic_gm.BasicGameMaster- (Optional) Create custom prefabs in
scenarios/my_scenario/agents.py - Run:
uv run python run_experiment.py scenario=my_scenario
For social media scenarios, add - override /environment: social_media to defaults and include initial_graph and seed_posts sections (see config/scenario/ai_conference.yaml for a complete example).
# All tests
uv run pytest
# With coverage
uv run pytest --cov=src --cov=scenarios
# Specific test directory
uv run pytest tests/test_evaluation/ -v
# Skip integration tests
uv run pytest -m "not integration"# Run all pre-commit hooks
uv run pre-commit run --all-files
# Type checking
uv run mypy src/ scenarios/
# Linting
uv run ruff check src/ scenarios/We use Conventional Commits:
# Using commitizen
uv run cz c
# Manual format
git commit -m "feat(scenario): add new auction mechanism"
git commit -m "fix(agent): resolve memory retrieval bug"Apache License 2.0 - See LICENSE for details.