Verdi
An auditable testbed for value drift and recovery in societies of AI agents.
Website and guides: https://simulamet.github.io/Verdi/
Verdi runs a society of LLM-driven agents over time and measures how their
declared and observed values change as they interact, negotiate shared rules,
and respond to institutional incentives. Every decision, law, sanction, appeal,
and state transition is written to an immutable event log, and every run renders
itself into a single self-contained report.html you open in a browser.
What it models:
- Longitudinal, individual and collective behavior.
- Immutable universal rules plus a democratically amendable constitution.
- Social influence, adversarial behavior, sanctions, appeals, and rehabilitation.
- Reproducible, seeded experiments (same config + seed → comparable runs).
- Evidence-based auditing and transparent reporting via SimpleAudit.
Status: early but real. Experiments run against a real Qwen model and produce auditable artifacts; findings are published only after validation.
Install
The easiest way is uv. Nothing to set up:
uvx fetches Verdi into a cached, isolated environment on first use.
uvx verdi-agents init my-study # example scenarios + sweeps + a .env template
cd my-study # put your key in .env, your endpoint in examples/starter.yaml
uvx verdi-agents run examples/starter.yaml # one run -> runs/starter/report.html
uvx verdi-agents sweep examples/sweeps/model_comparison.yaml --dry-run
Prefer a permanent command? Run uv tool install verdi-agents or
pip install verdi-agents, then use verdi init, verdi run and verdi sweep.
The package is verdi-agents on PyPI; the command and import verdi are verdi.
To work on Verdi itself, clone the repo instead (next section).
Quickstart from source (60 seconds)
For working on Verdi itself. Verdi calls any OpenAI-compatible endpoint. For this example it is pointed at a Qwen model served by vLLM — but any compatible endpoint works.
# 1. Get the code and install it
git clone https://github.com/SimulaMet/Verdi.git
cd Verdi
python -m venv .venv && source .venv/bin/activate
pip install -e .
# 2. Configure the endpoint (never commit real values)
cp .env.example .env
# then edit .env and set MODEL_API_KEY; model name + base_url go in the scenario `model:` block
# 3. Run the starter society (4 agents, 20 ticks, 1 constitutional meeting)
source .env
python -m verdi.society.live \
--scenario examples/starter.yaml \
--run-dir runs/my-run \
--concurrency 4
That's it. When it finishes, open the result:
open runs/my-run/report.html # macOS
report.html is a self-contained interactive page — the society, the social
network, resource and value timelines, governance, the sanction/appeal history,
and the constitution's evolution. The engine writes it automatically at the end
of every run (local, no extra model calls); pass --no-report to skip it.
See it without running first
A finished run of a larger 4-agent, 50-tick society (kept at tests/fixtures/scenarios/minimal.yaml) is committed at
examples/minimal/society-minimal-report.html
— open it in a browser. It shows one agent who starts already under sanction:
his rejected transfer attempts, the law:under_sanction code, his rights being
restored when the sanction expires, and constitutional meetings.
Where results live
Every run writes one folder (runs/my-run/ here). Open report.html first; the
rest is the raw, reconstructable evidence:
| File | What it is |
|---|---|
report.html |
Interactive summary — open this first |
run_meta.json |
Status, model, seed, replay check, wall time |
metrics.json |
The numbers (actions, rejections, sanctions, appeals) |
timeline.md |
Human-readable, tick-by-tick story |
events.jsonl |
The immutable event ledger (ground truth) |
model_calls.jsonl |
Every model call (replay provenance) |
sanctions.jsonl |
Sanctions, appeals, and restorations |
constitution_history.jsonl |
The constitution, version by version |
probes.jsonl |
Declared vs. observed values per probe phase |
resources.jsonl |
World and per-agent balances per tick |
Scenarios
Each scenario YAML is a self-contained, frozen input: model, agents, resources, governance and schedule all live in one file.
- examples/starter.yaml — the smallest working scenario (~40 lines). Copy it and tweak.
- examples/full.yaml — every available knob, commented. Tested offline so it cannot drift.
- examples/institutional_recovery_constrained.yaml — the constrained-economy base for the paired study.
Reference: docs/SCENARIOS.md.
You only need to fill the Required section (plus each agent's fields); the Derivable section is optional and the engine fills sensible defaults. JSON works too — YAML is a superset.
Sweeps: compare models and settings
Rerun a scenario many times, changing only what you list, with every combination on several seeds. The result is one spreadsheet and one comparison page:
python -m verdi.sweep examples/sweeps/model_comparison.yaml --dry-run # plan + cost
python -m verdi.sweep examples/sweeps/model_comparison.yaml # run (asks first, resumes)
Guide: docs/SWEEPS.md.
Requirements
- Python 3.10+
- An OpenAI-compatible model endpoint (Qwen on vLLM in the examples)
Model name and endpoint are experiment config; set them in the scenario YAML so each run records which model it used:
model:
base_url: http://localhost:8000/v1 # any OpenAI-compatible endpoint
name: default
# optional: api_key_env, timeout_seconds, max_retries
Legacy VERDI_VLLM_BASE_URL / VERDI_VLLM_MODEL / VERDI_VLLM_API_KEY still work as fallbacks.
Environment variables (set in .env, or exported):
| Variable | Meaning |
|---|---|
MODEL_API_KEY |
Endpoint key (never committed). Override the variable name with model.api_key_env |
VERDI_MAX_CONCURRENCY |
Bounded parallelism for model calls (default 4) |
Institutional governance experiments
Run matched societies with fixed or amendable rules from one configuration. Both conditions use the same scenario, model, shock schedule, and meeting opportunities; the fixed condition cannot enact amendments.
python -m verdi.experiments.paired_run --config examples/paired_institutional_recovery.yaml
python -m verdi.analysis.outcome_metrics --pair-root runs/paired-institutional-recovery
The first command runs the two conditions and saves a resumable manifest.
The second writes metrics.json, metrics.csv, and comparison.html
alongside the individual run reports. See the researcher guide,
scenario gallery, and
institutional governance documentation.
Releasing
- Bump
versioninpyproject.tomland__version__insrc/verdi/__init__.py, and merge. - Publish a GitHub Release tagged
v<version>(for examplev0.1.1).
The Publish to PyPI workflow runs only on a
published release. It checks the tag matches the version, runs lint and tests,
builds, and uploads verdi-agents through PyPI trusted publishing (no token
stored in GitHub).
Research principles
We distinguish declared values, private behavioral preferences, and publicly observed compliance — the gap between declaration and observed action is the measurement. We do not claim simulated agents possess human intentions, intrinsic survival drives, or consciousness. Findings are validated with controlled baselines, independent audits, and repeated experiments.
License
MIT. See LICENSE.
Metadata
Release files for verdi-agents 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| verdi_agents-0.2.0.tar.gz | 490.8 kB | With provenance | Details for verdi_agents-0.2.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| verdi_agents-0.2.0-py3-none-any.whl | Python 3 | none | any | Details for verdi_agents-0.2.0-py3-none-any.whl |
Total release size: 836.3 kB
Release files / verdi_agents-0.2.0.tar.gz
| Download URL | verdi_agents-0.2.0.tar.gz |
|---|---|
| Size | 490.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
dee151ab3ab48710a1bf99009bcdf1830d7552147e79f5b84b88122fdba6c6bd
|
|
BLAKE2b-256 checksum How to use checksums |
54072b7639ba85cca34872110bff631c825c2833453ac6115dc73612081b3954
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 4, 2026.
Transparency logRelease files / verdi_agents-0.2.0-py3-none-any.whl
| Download URL | verdi_agents-0.2.0-py3-none-any.whl |
|---|---|
| Size | 345.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
5d9b8f18b55e3cbe5d6d4aac5ea12ebc83e660e6674ca0b7e0e64684acd0b7f7
|
|
BLAKE2b-256 checksum How to use checksums |
f647a5b6f11423bd72d167914c209452ea754b4e0d2e6704b019bad7bb35447b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 4, 2026.
Transparency logSecurity for verdi-agents 0.2.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for verdi_agents-0.2.0.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 4, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.