swarmagentkit
A tick-based / real-time multi-agent swarm runtime with a hierarchical memory model (per-agent memory and emergent collective memory), a hybrid LLM/rule-based orchestrator with automatic transparent fallback, and pluggable domain physics — so the same runtime drives a market simulation, a particle system, a geopolitics model, a fleet of warehouse robots, or a real drone swarm, by swapping one small piece instead of rewriting the engine.
pip install swarmagentkit
No required third-party dependency beyond Pydantic. No API key needed to get started — the offline rule-based mode runs with zero network access or credentials.
Why this exists
Most "multi-agent" libraries fall into one of two buckets:
- Workflow orchestrators (LangGraph, and similar) are excellent at
planner → tool → criticpipelines with a handful of agents and explicit control flow, but they don't give you a swarm's emergent social dynamics — a social graph that evolves, a collective mood the population senses and reacts to, hundreds/thousands of agents where only a bounded subset act per step. - Social-simulation frameworks give you the swarm dynamics, but are simulation-only by design — there's no path from "10,000 agents in a sandbox" to "12 drones in the sky" without rewriting your entire stack.
swarmagentkit is the middle layer: a swarm engine general enough to sit
under a workflow orchestrator (drive it from a LangGraph node — see
examples/langgraph_bridge/) and general enough to sit on top of real
hardware (drive real sensors/actuators — see examples/drone_swarm/ and
docs/realtime.md) without changing your agent logic
either way.
Quickstart
import random
from swarmagentkit import Agent, Event, SwarmRunner, build_world, spawn_agents
# 1. Population: how many agents, of what role — one call.
agents = spawn_agents("node", 20, allowed_actions=["maintain", "ping"])
world = build_world(agents)
# 2. Policy: decide what one agent does. This can be a plain function...
def policy(observation: dict, rng: random.Random) -> dict:
return {"action": "ping", "params": {}, "rationale": "demo heartbeat"}
# 3. Physics: decide what an action actually DOES to the world. This is the
# one domain-specific piece — everything else in swarmagentkit is generic.
class DemoPhysics:
def apply(self, world, agent_id, action, params, rng):
world.metrics["pings"] = world.metrics.get("pings", 0) + 1
return Event(tick=world.tick, type=action, actor_id=agent_id, public=True)
runner = SwarmRunner(world, DemoPhysics(), policy, max_active=20, seed=42)
result = runner.run(ticks=10)
print(result.ticks_run, result.event_count, result.final_metrics)
That's it — no LLM, no API key, fully deterministic given the seed. Bring an
LLM in whenever you want one (see below); swap DemoPhysics for your own
domain (see examples/).
Bring any LLM — or none at all — with full control over which one does what
from swarmagentkit.brains import make_brain, RoleRouterBrain, OfflineBrain
# One line per provider, hosted or local:
gpt = make_brain("openai", "gpt-4o-mini") # reads OPENAI_API_KEY
claude = make_brain("anthropic", "claude-sonnet-4-5") # reads ANTHROPIC_API_KEY
router_m = make_brain("openrouter", "meta-llama/llama-3.1-70b") # reads OPENROUTER_API_KEY
local = make_brain("ollama", "llama3.1:8b") # fully local, no key needed
custom = make_brain("custom", "my-model", base_url="https://llm.internal/v1", api_key="...")
# Mix them freely per role / per specific agent / for the orchestrator /
# for the end-of-run analysis — one router object, full control:
brain = RoleRouterBrain(
default=OfflineBrain(policy), # cheap fallback for most agents
by_role={"buyer": local, "seller": gpt},
by_agent={"vip_007": claude}, # override one specific agent
orchestrator_brain=router_m,
analyze_brain=gpt,
)
runner = SwarmRunner(world, DemoPhysics(), policy, brain=brain, use_llm=True, ...)
Every live brain call automatically, transparently falls back to your
offline policy function on any failure (bad key, timeout, malformed JSON,
rate limit) — a run never stalls or crashes because of one flaky API call,
and the report tells you exactly when a fallback happened
(result.orchestrator_mode).
Full control over population size and per-tick attention
These are two separate knobs, on purpose:
from swarmagentkit import spawn_agents, build_world
from swarmagentkit.builders import resize_role, add_agents, remove_agents
agents = spawn_agents("buyer", 5000) # total population: one number
world = build_world(agents)
resize_role(world, "buyer", 200) # shrink live, mid-run, to 200
add_agents(world, spawn_agents("seller", 50, start_index=0))
runner = SwarmRunner(world, physics, policy, max_active=30) # only 30 act per tick
max_active bounds cost/latency regardless of how large the population is —
a world can hold thousands of agents while only a small, orchestrator-chosen
subset actually thinks and acts on any given tick.
Simulation AND real-world actuation, same code
from swarmagentkit.realtime import RealtimeSwarmRunner
# Same policy_fn / brain / orchestrator you validated in simulation.
# Only the sensor/actuator adapters are new — see docs/realtime.md.
runner = RealtimeSwarmRunner(agents, MySensorAdapter(), MyActuatorAdapter(), policy, loop_hz=5.0)
runner.run_forever() # a real wall-clock loop; leave it running for months if you want to
See docs/realtime.md for drone (MAVSDK/PX4), warehouse
robot (ROS2), and IoT (MQTT) adapter sketches.
Use it with LangGraph (fully optional)
pip install "swarmagentkit[langgraph]"
from swarmagentkit.adapters.langgraph_node import make_swarm_node
swarm_node = make_swarm_node(runner, ticks_per_call=5)
graph.add_node("run_swarm", swarm_node) # then wire it into your StateGraph as usual
swarmagentkit has zero import-time dependency on LangGraph — the bridge module only matters if and when you import it.
What's in the box
| Module | What it gives you |
|---|---|
swarmagentkit.models |
Agent, Persona, Memory, CollectiveMemory, World, Edge, Event |
swarmagentkit.builders |
spawn_agents, build_world, resize_role — population control |
swarmagentkit.engine |
observe, social graph ops (upsert_edge/weaken_edge), event publishing |
swarmagentkit.collective |
aggregate_collective_memory — swarm-wide emergent state |
swarmagentkit.metrics |
MetricGovernor — decay/cap/floor governance so no metric runs away |
swarmagentkit.orchestrator |
Orchestrator — hybrid LLM/rule-based per-tick staging, transparent fallback |
swarmagentkit.physics |
Physics protocol — the one domain-specific seam |
swarmagentkit.runner |
SwarmRunner — the simulation-mode tick loop |
swarmagentkit.realtime |
RealtimeSwarmRunner — the same logic on a real wall-clock loop |
swarmagentkit.brains |
OfflineBrain, OpenAICompatibleBrain, RoleRouterBrain, make_brain |
swarmagentkit.adapters.langgraph_node |
Optional LangGraph bridge |
swarmagentkit.io.snapshot |
Save/load a full World or RunResult as JSON |
Full architecture write-up: docs/concepts.md.
Non-goals
To be upfront about scope:
- Not a workflow orchestrator. If you need explicit
planner → tool → criticcontrol flow for a handful of agents, use LangGraph (and optionally drive a swarm from one of its nodes — see above). - Not a physics/rigid-body engine.
Physics.apply()is where you decide what an action means; swarmagentkit doesn't simulate collisions, forces, or continuous dynamics for you. - Not a flight-control or motor-control stack. For real hardware, swarmagentkit sits above your flight controller / ROS2 stack, deciding swarm-level behavior — it does not replace PX4, ArduPilot, or a robot's low-level control loop.
- Not (yet) a distributed/multi-process runtime.
SwarmRunnerandRealtimeSwarmRunnerrun in a single process. Sharding across machines is on the roadmap, not in v0.1.
Comparison
| swarmagentkit | LangGraph | Typical social-sim frameworks | |
|---|---|---|---|
| Explicit workflow control flow | – | ✅ | – |
| Emergent swarm / collective memory | ✅ | – | ✅ |
| Hybrid LLM + rule-based fallback, built in | ✅ | manual | varies |
| Real-hardware actuation (drones/robots) | ✅ | – | usually – |
| Bring any LLM provider / mix providers per role | ✅ | ✅ | varies |
| Zero-dependency offline mode | ✅ | – | varies |
This table is meant descriptively, not as a ranking — these tools solve different problems and compose well together (see the LangGraph bridge above).
Contributing
See CONTRIBUTING.md. Issues and PRs welcome — especially
new domain examples under examples/.
License
Metadata
Release files for swarmagentkit-core 0.1.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 |
|---|---|---|---|---|
| swarmagentkit_core-0.1.0.tar.gz | 48.4 kB | Without provenance | Details for swarmagentkit_core-0.1.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| swarmagentkit_core-0.1.0-py3-none-any.whl | Python 3 | none | any | Details for swarmagentkit_core-0.1.0-py3-none-any.whl |
Total release size: 90.4 kB
Release files / swarmagentkit_core-0.1.0.tar.gz
| Download URL | swarmagentkit_core-0.1.0.tar.gz |
|---|---|
| Size | 48.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
71429aaeae00960b47ab301f71957bbc69864423f54a06eacd29253892d6a959
|
|
BLAKE2b-256 checksum How to use checksums |
41c303b37698b26f6a71ac0824886aa67d999e3d76f03f255aaa974fba0deb51
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.7
|
Release files / swarmagentkit_core-0.1.0-py3-none-any.whl
| Download URL | swarmagentkit_core-0.1.0-py3-none-any.whl |
|---|---|
| Size | 42.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
f6ac5d5bec4a3eb8ce66e5470d9c2ad9dbecd003903c5c3090ba0460fe6f190c
|
|
BLAKE2b-256 checksum How to use checksums |
e222289071986fcde7d12296d69359fb8b4ef178e91e5d29f764e957c8e6dd3b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.7
|
Security for swarmagentkit-core 0.1.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.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A 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.