A pure-Python, zero-dependency framework for testing how communication topology affects multi-agent communication systems — Erdős–Rényi graph generation, deterministic agent policies, and reproducible density sweeps in one pipeline.
Most multi-agent tutorials pick a communication topology by instinct — a fully connected mesh because it "feels safer," or a chain because it's easy to trace. This library isolates relationship density as a single, controlled variable, so you can measure whether adding communication pathways actually changes what a network can do, instead of assuming it does.
Read the full write-up on Towards Data Science → Graph Engineering Isn't About More Connections — It's About Which Ones Get Used
Topology Generator → Router → Agent Policy → Shared State → Telemetry → Diagnostic Metrics
(Erdos-Renyi, (picks (PureAgent:
density-locked) next novelty-seeking,
speaker) then repeat)
Five components, one Engine.run() call:
| Component | Job |
|---|---|
| Topology Generator | Connected Erdős–Rényi random graphs at a locked target density, rejecting disconnected samples |
| Router | Picks the next speaker from the current node's open outbound edges |
| Agent Policy | Deterministic greedy-novelty-then-repeat policy (PureAgent), or a trivial DummyAgent for infrastructure validation |
| Telemetry | Per-message logging feeding six diagnostic metrics |
| Diagnostic Metrics | Relationship Efficiency, TF-IDF Redundancy, Information Gain, Edge Utilization, Communication Depth, and outcome metrics (Task Success, Information Recovery) |
git clone https://github.com/Emmimal/graph-density-engine.git
cd graph-density-engine
pip install -r requirements.txt # pytest only — for running the test suiteNo other dependencies, at any stage. The graph engine, agent policy, and every metric (including a from-scratch TF-IDF implementation) run on the Python standard library alone. There is no API key, no network call, and no model of any kind anywhere in the pipeline.
from agents.policy import PureAgent
from datasets.loader import DatasetLoader
from graph.engine import Engine
loader = DatasetLoader()
scenario = loader.load("incident_01")
agent = PureAgent(scenario=scenario)
engine = Engine(communication_budget=35)
record = engine.run(agent, density_level=0.6, seed=42, scenario_id=scenario.scenario_id)
print(record.diagnostic_metrics["edge_utilization"])
print(record.diagnostic_metrics["tfidf_redundancy"])
print(record.final_facts)Run this from the repository root — the package layout puts agents/, graph/, datasets/, and metrics/ directly at the top level, with no wrapping package directory.
Four phases, run in order, each validating the one before it:
| Phase | Command | What It Shows |
|---|---|---|
| 0 | python -m pytest tests/ -v |
16 unit tests validating every metric against synthetic examples, plus same-seed/different-seed reproducibility checks |
| 1 | python run_phase1.py |
Graph engine sanity check across the full density sweep, using a trivial DummyAgent — infrastructure only, no behavioral claim |
| 2 | python run_phase2.py --trials 10 --out results.json |
The real experiment: 50 runs (5 density levels × 10 trials) with the deterministic PureAgent |
Note: Phase 2b requires
run_experiment2.py, which isn't yet present in the repository's root file listing as of this writing. Push it before publishing this table, or remove the row until it is.
Engine(
num_agents=8, # Fixed agent count
communication_budget=35, # Max messages per trial before a forced timeout
router=None, # Defaults to uniform-random edge selection
)
engine.run(
agent, # DummyAgent or PureAgent — same interface, either works
density_level=0.6, # 0.0-1.0, fraction of the 56 possible directed edges (at 8 agents)
seed=42, # Full reproducibility: same seed -> identical topology and trace
scenario_id="incident_01", # Which frozen dataset scenario to load
synthesis_check=..., # Optional early-exit predicate (default: run to full budget)
)Density sweep used throughout the published results: [0.2, 0.4, 0.6, 0.8, 1.0], 10 trials each, seeds locked before execution.
graph-density-engine/
├── state.py, context.py, agent_output.py # Core dataclasses
├── agents/
│ ├── __init__.py
│ ├── base.py # Agent interface/base class
│ ├── dummy.py # Trivial agent for infrastructure validation
│ └── policy.py # PureAgent — deterministic novelty-seeking policy
├── graph/
│ ├── __init__.py
│ ├── budget.py # Message-budget tracking
│ ├── topology.py # Connected Erdos-Renyi generator
│ ├── router.py # Edge selection
│ ├── telemetry.py # Per-trial recording
│ └── engine.py # Orchestrates one trial end to end
├── metrics/
│ ├── __init__.py
│ ├── base.py # Shared metric interface
│ ├── tfidf.py # From-scratch TF-IDF vectorizer + cosine similarity
│ ├── tfidf_redundancy.py
│ ├── relationship_efficiency.py
│ ├── information_gain.py
│ ├── edge_utilization.py
│ ├── communication_depth.py
│ ├── state_size.py
│ └── outcome/
│ ├── __init__.py
│ ├── information_recovery.py
│ ├── task_success.py
│ ├── latency.py
│ └── token_cost.py
├── datasets/
│ ├── __init__.py
│ ├── generate_datasets.py # Builds the frozen incident_01..10.json corpus
│ ├── loader.py
│ └── incident_01.json … incident_10.json
├── tests/ # 6 files, 16 tests — Phase 0 + reproducibility suite
│ ├── __init__.py
│ ├── test_topology.py
│ ├── test_edge_utilization.py
│ ├── test_information_gain.py
│ ├── test_relationship_efficiency.py
│ ├── test_tfidf_redundancy.py
│ └── test_reproducibility.py
├── run_phase1.py, run_phase2.py
├── phase2_results.json
├── experiment.md # Frozen pre-registration protocol
├── interfaces.md # Frozen interface contracts
├── README.md
└── requirements.txt
| Operation | Measured Time |
|---|---|
| Phase 0 — 16 unit tests | under 0.25s |
| Phase 1 — 50 runs, DummyAgent | under 1s |
| Phase 2 — 50 runs, PureAgent | near-instant (not separately benchmarked) |
| API cost, any phase | $0 |
Phase 0 and Phase 1 timings above are measured on this machine; Phase 2 has not been separately benchmarked, and multi-machine/multi-OS reproducibility has not been independently verified. What's confirmed: the graph engine and agent policy are fully deterministic given a fixed seed (see tests/test_reproducibility.py), and every trial in the published sweep completed without a timeout.
Worth adapting if you:
- Are choosing a multi-agent communication topology by instinct rather than measurement
- Want a template for running controlled, reproducible agent-architecture experiments without spending API budget on every iteration
Skip it if you:
- Want a specific density value to copy into production — these numbers are scoped to one task, one topology family, one agent count
- Have a bottleneck in individual agent reasoning quality rather than communication structure
- Need true model stochasticity — this framework deliberately trades that away for exact reproducibility
- The agent policy is deterministic and rule-based, not an LLM. Results describe how a fixed, rational communication strategy behaves under different topologies, not how a stochastic model population would.
- Information Recovery uses keyword-overlap matching, not semantic similarity — a documented, deliberate trade-off for staying dependency-free.
- The included dataset corpus rotates 3 incident templates across 10 scenario files.
- The default 35-message communication budget is generous relative to the included 17-fact scenarios, producing a ceiling effect — see
experiment.md§12 for the full amendment history, including a bug that was found and fixed in the Information Recovery threshold and in an earlier circular stopping condition.
A pure-Python, zero-dependency framework for testing how communication topology affects multi-agent communication systems — Erdős–Rényi graph generation, deterministic agent policies, and reproducible density sweeps in one pipeline.