Multi-agent coordination through stigmergy - agents coordinate via environmental traces, not explicit messaging
Project description
Anthills ๐
Stigmergy-based AI agent orchestration. Agents coordinate through a shared environment โ not a central planner.
What is Anthills?
Most agent frameworks orchestrate through a central controller โ a graph, a DAG, a router that decides who does what next.
Anthills is different. It borrows from nature.
In an ant colony, no single ant knows the plan. Instead, ants deposit pheromones โ signals in the environment โ and other ants respond to those signals. Complex, adaptive behavior emerges from simple local rules. No orchestrator required.
Anthills brings this model to AI agents:
- Agents read from and write to a shared Pheromone Board โ a persistent, observable environment
- Coordination is emergent, not prescribed
- Any agent can react to any signal โ enabling flexible, parallel, self-organizing workflows
- The full history of signals is captured as a ledger โ making agent behavior auditable and replayable
Core Concepts
| Concept | Description |
|---|---|
| Pheromone Board | The shared environment all agents read from and write to |
| Pheromone | A signal deposited by an agent โ carries type, intensity, payload, and TTL |
| Worker | An agent that reacts to pheromones and may deposit new ones |
| Trail | A sequence of pheromone deposits that form an emergent task path |
| Colony | A named group of workers sharing a pheromone board |
| Ledger | Append-only log of all pheromone events โ the source of truth for tracing |
Installation
pip install anthills
For Claude integration:
pip install anthills[claude]
Quick Start
from anthills import Colony, Pheromone
# Define a colony (shared environment)
colony = Colony(name="research-pipeline")
# Define workers that react to signals
@colony.worker(reacts_to="task.created")
async def researcher(pheromone, board):
# Process the pheromone
result = f"Researched: {pheromone.payload['topic']}"
# Deposit a new signal for other workers
board.deposit(Pheromone(
type="research.complete",
payload={"findings": result},
deposited_by="researcher",
))
@colony.worker(reacts_to="research.complete")
async def summarizer(pheromone, board):
summary = f"Summary of: {pheromone.payload['findings']}"
board.deposit(Pheromone(
type="summary.ready",
payload={"summary": summary},
deposited_by="summarizer",
))
# Kick off the colony with an initial signal
colony.deposit(type="task.created", payload={"topic": "quantum computing"})
colony.run()
No graph definition. No router. Workers emerge into action as signals appear.
With Claude (LLM Integration)
from anthills import Colony
from anthills.integrations.claude import ClaudeWorker
colony = Colony(name="research")
@colony.worker(reacts_to="topic.queued")
class Researcher(ClaudeWorker):
system_prompt = "You are a research assistant."
output_pheromone_type = "research.complete"
async def build_messages(self, pheromone):
return [{"role": "user", "content": f"Summarize: {pheromone.payload['topic']}"}]
colony.deposit(type="topic.queued", payload={"topic": "stigmergy"})
colony.run()
Why Stigmergy?
Traditional agent orchestration is choreography โ someone writes the script.
Stigmergy is emergence โ the environment carries the coordination logic.
This makes Anthills particularly well-suited for:
- Long-running, async workflows where tasks arrive unpredictably
- Parallel multi-agent pipelines where bottlenecks are hard to predict upfront
- Adaptive systems that need to self-organize around failures or new inputs
- Observable AI workflows where you need to understand why agents did what they did
Examples
See the examples/ directory:
research_agents.pyโ Multi-agent research pipelinet1d_simulation.pyโ Type 1 Diabetes pathophysiology model (stigmergy in biology!)
Development
git clone https://github.com/t1dm-ai/anthills
cd anthills
pip install -e ".[dev,claude]"
pytest
Connectors
Connectors provide external tool integrations for your workers:
from anthills import Colony
from anthills.connectors import ConnectorRegistry, requires
from anthills.connectors.gmail import GmailConnector
from anthills.connectors.slack import SlackConnector
# Create registry with configured connectors
registry = ConnectorRegistry()
registry.register(GmailConnector(credentials_path="/path/to/creds.json"))
registry.register(SlackConnector(bot_token="xoxb-..."))
# Create colony with connectors
colony = Colony(name="notifications", connectors=registry)
# Workers declare their connector requirements
@colony.worker(reacts_to="alert.triggered", requires=["gmail", "slack"])
async def notify(ctx):
gmail = ctx.connectors["gmail"]
slack = ctx.connectors["slack"]
await gmail.send_email(to="team@example.com", subject="Alert", body="...")
await slack.send_message(channel="#alerts", text="...")
Built-in Connectors
| Connector | Install | Description |
|---|---|---|
GmailConnector |
pip install anthills[gmail] |
Send emails via Gmail API |
SlackConnector |
pip install anthills[slack] |
Post messages to Slack |
Custom Connectors
from anthills.connectors import Connector, ConnectorConfig
class MyConnector(Connector):
name = "my_service"
async def connect(self) -> None:
# Initialize connection
pass
async def disconnect(self) -> None:
# Cleanup
pass
Colony Templates
Templates provide declarative, reusable colony configurations:
from anthills.templates import TemplateCatalog, TemplateInstantiator
# Discover built-in templates
catalog = TemplateCatalog()
catalog.register_builtins()
# List available templates
for template in catalog.list():
print(f"{template.name}: {template.description}")
# Instantiate a template with parameters
instantiator = TemplateInstantiator(catalog)
colony = instantiator.instantiate(
"research_assistant",
parameters={
"research_depth": "comprehensive",
"output_format": "markdown"
}
)
colony.run()
Built-in Templates
| Template | Description |
|---|---|
customer_inquiry_responder |
Auto-respond to customer questions |
weekly_sales_summary |
Aggregate and report weekly sales data |
research_assistant |
Multi-step research with Claude |
Custom Templates
from anthills.templates import ColonyTemplate, WorkerSpec, TriggerSpec
template = ColonyTemplate(
name="my_pipeline",
description="Custom processing pipeline",
workers=[
WorkerSpec(
name="processor",
reacts_to="input.received",
handler="my_module:process_handler",
emits=["output.ready"]
)
],
triggers=[
TriggerSpec(type="input.received", payload={"source": "api"})
]
)
Project Structure
anthills/
โโโ board.py # Event-sourced PheromoneBoard with wildcard patterns
โโโ worker.py # Worker base class with retry & concurrency control
โโโ colony.py # Colony runner (async event loop, auto-halt)
โโโ connectors/ # External tool integrations
โ โโโ base.py # Connector, ConnectorConfig, ConnectorRegistry
โ โโโ registry.py # Registry and requires() helper
โ โโโ gmail/ # Gmail connector (optional)
โ โโโ slack/ # Slack connector (optional)
โโโ templates/ # Declarative colony configurations
โ โโโ base.py # ColonyTemplate, WorkerSpec, TriggerSpec
โ โโโ catalog.py # TemplateCatalog for discovery
โ โโโ instantiator.py # Convert templates to runnable colonies
โ โโโ builtins.py # Built-in template definitions
โโโ integrations/
โโโ claude.py # ClaudeWorker, LLMWorker, ClaudeToolWorker
Philosophy
This is not a general-purpose agent framework. It's a specific take: agents coordinating through environmental traces, not explicit messaging.
Use it when you want:
- Multiple agents collaborating on complex tasks
- Self-organization without central orchestration
- Transparent, auditable agent behavior
- Resilience to individual agent failures
Roadmap
- Event-sourced pheromone board with ledger
- Wildcard pattern matching for pheromone types
- Parallel agent execution with concurrency control
- Connector abstraction for external tools
- Colony templates for reusable configurations
- Claude/LLM integration
- Real-time dashboard (visualize pheromone board)
- Agent profiler (performance metrics)
- Trace debugger (replay decisions step-by-step)
- Redis-backed board for distributed colonies
- More connectors (GitHub, Jira, databases)
- Webhooks / external event triggers
Building This in Public
This project is being built on Twitter: @braz_builds
Daily updates on architecture, insights, and use cases.
Built with Claude + Python. Inspired by ant colonies. ๐
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file anthills-0.1.1.tar.gz.
File metadata
- Download URL: anthills-0.1.1.tar.gz
- Upload date:
- Size: 64.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ee6028be495e28e758cf9a0266367d0ae007167692aa506bcd5a0507a2c73af1
|
|
| MD5 |
858c36bedf59b8f3a3834fa515661972
|
|
| BLAKE2b-256 |
85d748b80dd1a1f975677fe98298456d46ae1c85a2d7951efd33ffdba512ee2b
|
Provenance
The following attestation bundles were made for anthills-0.1.1.tar.gz:
Publisher:
publish.yml on t1dm-ai/anthills
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
anthills-0.1.1.tar.gz -
Subject digest:
ee6028be495e28e758cf9a0266367d0ae007167692aa506bcd5a0507a2c73af1 - Sigstore transparency entry: 1063493323
- Sigstore integration time:
-
Permalink:
t1dm-ai/anthills@7a693e94e0c5084b0fa6c79cfea5aac544956f84 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/t1dm-ai
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@7a693e94e0c5084b0fa6c79cfea5aac544956f84 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file anthills-0.1.1-py3-none-any.whl.
File metadata
- Download URL: anthills-0.1.1-py3-none-any.whl
- Upload date:
- Size: 37.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f5b4502111b850b83c9bfad5539ce1abca1eb5e928dc7ea7380ea624f0ce1fa4
|
|
| MD5 |
9d7ec76f5e78b8dd0c572e8ff7f45bbe
|
|
| BLAKE2b-256 |
f5bf656bb7bf1181b77b70bc5acdcf824abad52bf903381ab7f0304c538cf55b
|
Provenance
The following attestation bundles were made for anthills-0.1.1-py3-none-any.whl:
Publisher:
publish.yml on t1dm-ai/anthills
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
anthills-0.1.1-py3-none-any.whl -
Subject digest:
f5b4502111b850b83c9bfad5539ce1abca1eb5e928dc7ea7380ea624f0ce1fa4 - Sigstore transparency entry: 1063493383
- Sigstore integration time:
-
Permalink:
t1dm-ai/anthills@7a693e94e0c5084b0fa6c79cfea5aac544956f84 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/t1dm-ai
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@7a693e94e0c5084b0fa6c79cfea5aac544956f84 -
Trigger Event:
workflow_dispatch
-
Statement type: