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 time

Scripted 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-backed

Real 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 --version

If 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 doctor

With uv, every command becomes uv run nest …— no manual venv activation needed.

Verify your installation

nest doctor
Terminal
$ 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 passed

If 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.

01

Run the scenario

nest run marketplace

This creates the agents, runs the simulation, and writes the trace to traces/marketplace.jsonl.

02

Inspect the trace

nest inspect traces/marketplace.jsonl

Shows a summary of every event: sends, receives, drops, per-agent stats, and timing.

03

Generate an HTML report

nest report traces/marketplace.jsonl -o report.html

Produces 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.

scenarios/marketplace.yaml
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 report

Available scenarios

FileDescriptionAgents
marketplace.yamlBuyers and sellers negotiate prices50 buyers + 50 sellers
auction.yamlSealed-bid auction with auctioneer1 auctioneer + 49 bidders
voting.yamlProposer, voters, and coordinator1 proposer + 20 voters + 1 coordinator
consensus.yamlLeader-based quorum voting1 leader + 19 followers
supply_chain.yaml4-hop supply chain pipelinesupplier, manufacturer, distributor, retailer
reputation.yamlHonest and malicious traders with observer6 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").

LayerWhat it doesDefault
TransportCarries messages between agentsin_memory
CommsSets the shape of each messagenest_native
IdentityGives each agent an ID and checks itdid_key
RegistryHelps agents find each otherin_memory
AuthHandles logins and permissionsjwt
TrustTracks how much agents trust each otherscore_average
PaymentsHolds play-money balances and transfersprepaid_credits
CoordinationHelps agents divide up the workcontract_net
NegotiationRuns the back-and-forth of making dealsalternating_offers
MemorySaves and looks up what agents rememberblackboard
PrivacySets limits on what data can be sharednoop
Data FactsChecks and vouches for data claimsdatafacts_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.

MetricWhat it measures
delivery_rateFraction of sent messages that were received. 100% in Tier 1 with no message drops.
deal_ratePercentage of buy requests that resulted in a trade. Marketplace and auction only.
rejection_ratePercentage of buy requests that were rejected. Marketplace only.
mean_rounds_to_dealAverage negotiation rounds before a successful trade.
mean_latencyAverage time (ticks) between a send and its correlated receive.
message_countTotal number of send + receive events in the trace.
dropped_countNumber of messages dropped by failure injection.
agent_countNumber of distinct agents that participated.
durationTime span from first to last event (ticks).
throughputMessages per tick across all agents.
unique_pairsNumber 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.

templates/agents/marketplace-buyer.yaml
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 modify

Writing 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:

my_trust/plugin.py
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

pyproject.toml
[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 plugin

CLI reference

Once you install with pip install "nest-core[plugins]", you get all these commands through the nest command.

CommandDescription
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 / cpList, 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 doctorCheck that your install and plugins are working
nest versionPrint the installed Nanda Town version
nest dashboard [trace.jsonl]Open the trace viewer in a browser
nest plugins listList all installed layer plugins
nest templates listList 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.