Overview
Nanda Town is a sandbox for testing how AI agents talk to each other. Think of it like a flight simulator, but for agents. You write a scenario in a YAML file — who the agents are, what roles they play, which rules they follow, and what can go wrong. Nanda Town runs it and saves every message to a JSONL file you can read back or replay later.
Nanda Town is an open initiative by Project NANDA. It is free, open-source research software (Apache 2.0).
How Nanda Town runs
Nanda Town is a Python tool you install on your own computer. It runs on your machine and saves a JSONL file to disk. This website only shows the docs, some ready-made example runs in the Visualizer, and the Experiments gallery. It does not run scenarios in your browser. Follow the Installation steps below to get the nest command.
Researchers
Watch how agents behave, where they get stuck or disagree, and how trust builds up. You can see everything that happens.
Protocol designers
Test your agent rules hard. Turn on failures on purpose, and replay any run to get the same result every time.
Developers
Build and fix multi-agent systems using JSONL files, metrics, and HTML reports.
Students
Learn by doing: how agents work together, simple game theory, and how agents interact.
Tier 1 vs Tier 2
Nanda Town has two ways to run. Both use the same scenario file, the same twelve layers, and the same trace file. The only difference is how the agents make their choices.
Tier 01
Same every timeScripted agents.
Agents follow fixed rules you set in advance. Use the same seed number and you get the exact same run, every time.
- ·Repeatable. Same seed gives the exact same result, every time.
- ·Fast. 10,000+ agents on a laptop, runs in under a second.
- ·Free. No API keys, no internet, no cost per run.
- ·Tests the rules, not the AI. If something breaks, you know it is the rules, not the AI model.
- ·Agents only follow the rules you set. They can not think or adapt.
Use Tier 1 to
- — Check that your rules work before adding AI models
- — Run big simulations (1000+ agents) fast
- — Reproduce a bug the same way every time
- — Try things going wrong on purpose (dropped messages, split networks)
Tier 02
LLM-backedReal AI agents.
Agents are run by real AI models like GPT-4, Claude, or any OpenAI-compatible service. Each agent gets the scenario details as a prompt and chooses what to do on every turn.
- ·Realistic. Agents decide like real AI systems do.
- ·Can surprise you. Agents may do things you did not plan for.
- ·Custom prompts. YAML templates set each agent’s personality.
- ·Not repeatable. Each run can come out different.
- ·Costs money. Every agent turn is an API call.
- ·Slow. Held back by API speed and limits (10–100 agents).
Use Tier 2 to
- — See how AI models act when many agents work together
- — Compare different models on the same scenario
- — Watch how agents team up and plan ahead
- — Check how well your prompts work for each agent role
A good way to work. Start with Tier 1 to make sure your scenario and rules work. Then move to Tier 2 by changing brain: state-machine to brain: llmin your YAML. Nothing else changes — same layers, same metrics, same trace file.
Installation
Prerequisites
Nanda Town needs Python 3.12 or newer. Check your version before you install:
python3 --versionIf you see 3.11 or older, install Python 3.12 first (brew install python@3.12 on macOS, sudo apt install python3.12 on Ubuntu, or use pyenv). Installing nest-core on an older Python will fail with a requires-python error.
Quick install (from PyPI)
python3.12 -m venv .venv
source .venv/bin/activate
pip install "nest-core[plugins]"This installs the Nanda Town engine, the nest command, the plugins for all 12 layers, and the seven built-in scenarios. The venv keeps it separate from your other Python projects so nothing clashes.
Prefer to skip the venv? Use pipx instead: pipx install "nest-core[plugins]" — this gives you the nest command everywhere without touching your system Python.
Or: install from source (development)
To work on Nanda Town itself, clone the repo and use uv for the workspace install:
git clone https://github.com/mariagorskikh/nest.git
cd nest
uv sync
uv run nest doctorWith uv, every command becomes uv run nest …— no manual venv activation needed.
Verify your installation
nest doctor$ nest doctor
Nanda Town doctor
========================================
[OK] Python 3.12.9
[OK] nest-core
[OK] scenario loader
[OK] plugin registry
[OK] scenario runner
[OK] simulator
[OK] all 12 default plugins resolve
========================================
7/7 checks passedIf you get command not found: nest, the venv isn't active or your shell's PATH doesn't include the install location. See Troubleshooting.
For Tier 2 (LLM agents)
If you want to run LLM-backed agents, set your API key:
# OpenAI
export OPENAI_API_KEY="sk-..."
# or Anthropic
export ANTHROPIC_API_KEY="sk-ant-..."Tier 1 scenarios (like marketplace) run entirely offline and never call an API.
Your first experiment
Run a full marketplace simulation in three steps. Fifty buyers and fifty sellers haggle over prices across ten rounds.
Before you start: open a terminal, cd into the directory where you want output to land, and make sure your venv is active (or prefix each command with uv run if you installed from source). The simulator writes its trace to a traces/ folder relative to your current working directory.
Run the scenario
nest run marketplaceThis creates the agents, runs the simulation, and writes the trace to traces/marketplace.jsonl.
Inspect the trace
nest inspect traces/marketplace.jsonlShows a summary of every event: sends, receives, drops, per-agent stats, and timing.
Generate an HTML report
nest report traces/marketplace.jsonl -o report.htmlProduces an HTML page with delivery rate, deal rate, latency, throughput, per-agent breakdown, and event summary.
Scenario YAML reference
A scenario YAML file sets up everything about a run. Here is a full example with notes on each part. It matches the real format.
name: marketplace
description: "50 buyers and 50 sellers trading products."
tier: 1 # 1 = scripted, 2 = AI model
seed: 42 # seed number (same run every time)
agents:
count: 100 # how many agents in total
brain: state-machine # "state-machine" or "llm"
# llm_provider: openai # For Tier 2: openai or anthropic
# llm_model: gpt-4o-mini # For Tier 2: model name
roles:
- name: buyer
count: 50
- name: seller
count: 50
layers: # which plugin to use for each layer
transport: in_memory
comms: nest_native
identity: did_key
registry: in_memory
auth: jwt
trust: score_average
payments: prepaid_credits
coordination: contract_net
negotiation: alternating_offers
memory: blackboard
privacy: noop
datafacts: datafacts_v1
task:
type: marketplace # which scenario to run
config:
rounds: 10 # settings for this scenario
failures: # things that can go wrong
message_drop: 0.0 # 0.0 = no drops, 0.1 = drop 1 in 10
byzantine_agents: 0.0 # share of agents that send junk messages
# network_partition: # split agents into groups that can't reach each other
# groups: [["buyer-0"], ["seller-0"]]
duration: "ticks: 10000" # most ticks the run can take
metrics: # which numbers to measure
- delivery_rate
- deal_rate
- mean_latency
- message_count
- agent_count
output:
trace: ./traces/marketplace.jsonl
# report: ./reports/marketplace.html # Optional HTML reportAvailable scenarios
| File | Description | Agents |
|---|---|---|
| marketplace.yaml | Buyers and sellers negotiate prices | 50 buyers + 50 sellers |
| auction.yaml | Sealed-bid auction with auctioneer | 1 auctioneer + 49 bidders |
| voting.yaml | Proposer, voters, and coordinator | 1 proposer + 20 voters + 1 coordinator |
| consensus.yaml | Leader-based quorum voting | 1 leader + 19 followers |
| supply_chain.yaml | 4-hop supply chain pipeline | supplier, manufacturer, distributor, retailer |
| reputation.yaml | Honest and malicious traders with observer | 6 honest + 2 malicious + 1 observer |
The twelve layers
Nanda Town splits what an agent can do into twelve layers. Think of them like floors in a building, each handling one job. Every layer comes with a default version you can swap for your own. Agents reach a layer with ctx.plugins.get("layer_name").
| Layer | What it does | Default |
|---|---|---|
| Transport | Carries messages between agents | in_memory |
| Comms | Sets the shape of each message | nest_native |
| Identity | Gives each agent an ID and checks it | did_key |
| Registry | Helps agents find each other | in_memory |
| Auth | Handles logins and permissions | jwt |
| Trust | Tracks how much agents trust each other | score_average |
| Payments | Holds play-money balances and transfers | prepaid_credits |
| Coordination | Helps agents divide up the work | contract_net |
| Negotiation | Runs the back-and-forth of making deals | alternating_offers |
| Memory | Saves and looks up what agents remember | blackboard |
| Privacy | Sets limits on what data can be shared | noop |
| Data Facts | Checks and vouches for data claims | datafacts_v1 |
Right now, the marketplace scenario uses the registry, identity, trust, and payments layers. Other scenarios load the layers but do not call them yet. Connecting more scenarios to the layers is still in progress.
Metrics
After each run, Nanda Town reads the JSONL file and works out the numbers. Pick which ones you want in the scenario YAML. There is no single overall score — each number tells you one thing.
| Metric | What it measures |
|---|---|
| delivery_rate | Fraction of sent messages that were received. 100% in Tier 1 with no message drops. |
| deal_rate | Percentage of buy requests that resulted in a trade. Marketplace and auction only. |
| rejection_rate | Percentage of buy requests that were rejected. Marketplace only. |
| mean_rounds_to_deal | Average negotiation rounds before a successful trade. |
| mean_latency | Average time (ticks) between a send and its correlated receive. |
| message_count | Total number of send + receive events in the trace. |
| dropped_count | Number of messages dropped by failure injection. |
| agent_count | Number of distinct agents that participated. |
| duration | Time span from first to last event (ticks). |
| throughput | Messages per tick across all agents. |
| unique_pairs | Number of unique agent pairs that exchanged messages. |
Agent templates (Tier 2)
Templates are YAML files that set how an AI agent acts: its prompt, which provider and model to use, and a few settings. They only apply to Tier 2 scenarios.
name: marketplace-buyer
description: "Buyer agent for marketplace scenarios."
provider: openai
model: gpt-4o-mini
temperature: 0.7
max_tokens: 256
system_prompt: |
You are a buyer in a marketplace simulation.
ACTION: send
TO: <agent-id>
MESSAGE: <message-content>
Rules:
- Send buy:<product>:<price> to purchase.
- If rejected, increase your offer or try another seller.CLI commands
nest templates list # List all templates
nest templates show <name> # View a template
nest templates create <name> # Create from scratch
nest templates duplicate <src> <dest> # Copy and modifyWriting a plugin
You can swap any of the twelve layers for your own version. A plugin is a Python class that has the methods the layer expects. You hook it in with Python entry points.
Example: custom trust plugin
Look at the built-in versions in packages/nest-plugins-reference/ to see what each layer expects. Here is a trust plugin:
from nest_core.types import AgentId, Evidence, ReputationScore
class DecayTrust:
"""Custom trust layer with time decay."""
def __init__(self, identity=None):
self._scores: dict[AgentId, list[float]] = {}
async def score(self, agent: AgentId) -> ReputationScore:
entries = self._scores.get(agent, [])
if not entries:
return ReputationScore(
agent_id=agent, score=0.5,
confidence=0.0, sample_count=0,
)
avg = sum(entries) / len(entries)
return ReputationScore(
agent_id=agent, score=avg,
confidence=min(1.0, len(entries) / 50),
sample_count=len(entries),
)
async def report(self, agent: AgentId, evidence: Evidence):
val = 1.0 if evidence.kind == "positive" else 0.0
self._scores.setdefault(agent, []).append(val)Register via entry point
[project]
name = "my-trust-plugin"
version = "0.1.0"
dependencies = ["nest-core"]
[project.entry-points."nest.plugins.trust"]
my_decay = "my_trust.plugin:DecayTrust"Then reference it in your scenario YAML:
layers:
trust: my_decay # Uses your custom pluginCLI reference
Once you install with pip install "nest-core[plugins]", you get all these commands through the nest command.
| Command | Description |
|---|---|
| nest run <name | path.yaml> | Run a built-in scenario by name, or your own YAML file, and save the trace |
| nest scenarios list / show / cp | List, print, or copy the seven built-in scenarios |
| nest inspect <trace.jsonl> | Print a summary of events and per-agent stats |
| nest report <trace.jsonl> | Make an HTML report of the numbers |
| nest init <name> | Start a new scenario YAML for you to fill in |
| nest doctor | Check that your install and plugins are working |
| nest version | Print the installed Nanda Town version |
| nest dashboard [trace.jsonl] | Open the trace viewer in a browser |
| nest plugins list | List all installed layer plugins |
| nest templates list | List the agent templates you have |
| nest templates show <name> | Show one template |
| nest templates create <name> | Make a new agent template |
| nest templates duplicate <src> <dest> | Copy a template |
Troubleshooting
Most install problems come down to four things: the wrong Python, no venv turned on, an out-of-date shell PATH, or running nest from the wrong folder. Find your problem in the list below.
ERROR: Package 'nest-core' requires a different Python
What it means: Your Python is older than 3.12. pip won't install because nest-core needs requires-python >=3.12.
Fix: Install Python 3.12 (brew install python@3.12, sudo apt install python3.12, or pyenv) and create a venv with it explicitly: python3.12 -m venv .venv, then source .venv/bin/activate before pip-installing.
zsh: command not found: nest
What it means: Either your venv isn't turned on in this shell, or you used pip install --user and ~/.local/binisn't on your PATH.
Fix: Run source .venv/bin/activate in the folder where you made the venv, then try again. Or install with pipx (pipx install "nest-core[plugins]") to get a global nest binary.
nest run marketplace: Scenario 'marketplace' not found
What it means: You installed without the [plugins] part, so the built-in scenarios are missing.
Fix: Install it again with the extra part: pip install "nest-core[plugins]" (the quotes matter on zsh — without them the shell reads [plugins] as a file pattern). Then run nest scenarios list to check the seven built-in scenarios show up.
Trace file isn't where I expected
What it means: nest run saves to ./traces/<scenario>.jsonl inside whatever folder you are in. If you ran it from your home folder, that is where traces/ ended up.
Fix: cd into a project folder first, or add --out /path/to/trace.jsonl to choose where it goes. nest run --help shows all the options.
I can't find a 'Run' button on this website
What it means: That is right — this website only shows ready-made JSONL traces in the Visualizer and links to the docs. It does not run the simulator. The simulator is the nest command you installed above.
Fix: Run a scenario on your computer (nest run marketplace), then drop the new traces/marketplace.jsonl file into the Visualizer to play it back.
FAQ
Ready to start?
Clone the repo and run your first simulation in under two minutes.