Distributed multi-agent AI orchestration on Docker. Run isolated AI agents. Coordinate via NATS. Define workflows in YAML.
LangChain agents fall over at 5 concurrent tasks. CrewAI has no isolation. Autogen runs in a single Python process.
agent-mesh runs each agent in its own Docker container, talking over NATS, with a control plane that handles:
- π‘οΈ Process isolation (one OOM doesn't kill the swarm)
- π Retries + circuit breakers per agent
- π YAML-defined workflows (no Python required)
- π Distributed tracing of agent decisions
- βοΈ Per-agent rate limits + cost ceilings
- π§© Pluggable models (OpenAI, Anthropic, Ollama)
This is what production multi-agent looks like.
βββββββββββββββββββββββββββββββββββββββββββββββ
β CONTROL PLANE (Go) β
β βββββββββββββββ¬βββββββββββββ¬βββββββββββββ β
β β Orchestratorβ Registry β Workflow β β
β βββββββββββββββ΄βββββββββββββ΄βββββββββββββ β
β REST + gRPC API β
βββββββββββββββββββ¬ββββββββββββββββββββββββββββ
β
βββββββββββββ΄βββββββββββββ
β NATS (Bus) β
β subject: agent.* β
βββββββββββββ¬βββββββββββββ
β
ββββββββββββ¬βββββββββββ¬βββββ΄βββββ¬βββββββββββ¬βββββββββββ
βΌ βΌ βΌ βΌ βΌ βΌ
βββββββββ βββββββββ βββββββββ βββββββββ βββββββββ βββββββββ
βResearcherβ Coder β βReviewerβ β Writer β β Custom β β Custom β
β agent β β agent β β agent β β agent β β agent β β agent β
βββββββββ βββββββββ βββββββββ βββββββββ βββββββββ βββββββββ
(each in its own Docker container, isolated, replaceable)
git clone https://github.com/kasimmj/agent-mesh
cd agent-mesh
cp .env.example .env # add your model API keys
docker compose up -dThen submit a workflow:
curl -X POST http://localhost:8080/workflows \
-H "Content-Type: application/yaml" \
--data-binary @examples/workflows/research-and-write.yamlWatch agents collaborate in real-time:
docker compose logs -f
# Or: open http://localhost:8080/uiA workflow is YAML. Each step calls an agent and feeds its output forward.
name: research-and-write
description: Research a topic and produce a polished article.
steps:
- id: research
agent: researcher
input:
topic: "{{ .input.topic }}"
depth: 3
timeout: 60s
- id: draft
agent: writer
depends_on: [research]
input:
facts: "{{ .steps.research.output }}"
style: "technical-blog"
- id: review
agent: reviewer
depends_on: [draft]
input:
text: "{{ .steps.draft.output }}"
criteria: ["clarity", "accuracy", "tone"]
- id: refine
agent: writer
depends_on: [review]
input:
draft: "{{ .steps.draft.output }}"
feedback: "{{ .steps.review.output }}"
- id: finalize
agent: writer
depends_on: [refine]
input:
text: "{{ .steps.refine.output }}"
mode: "polish"
output: "{{ .steps.finalize.output }}"| Agent | Image | Role |
|---|---|---|
researcher |
ghcr.io/kasimmj/agent-mesh-researcher |
Web search + summarization + source citation |
coder |
ghcr.io/kasimmj/agent-mesh-coder |
Code generation, edits, test writing |
reviewer |
ghcr.io/kasimmj/agent-mesh-reviewer |
Critique, scoring, structured feedback |
writer |
ghcr.io/kasimmj/agent-mesh-writer |
Long-form text, refinement, style transfer |
executor |
ghcr.io/kasimmj/agent-mesh-executor |
Run code in a sandbox and return results |
vision |
ghcr.io/kasimmj/agent-mesh-vision |
Image understanding, OCR, captioning |
Every agent implements one Go interface:
type Agent interface {
Capabilities() Capabilities
Handle(ctx context.Context, task Task) (Result, error)
}Minimal example:
package main
import "github.com/kasimmj/agent-mesh/agents/base"
type Translator struct{ base.Agent }
func (t *Translator) Handle(ctx context.Context, task base.Task) (base.Result, error) {
text := task.Input["text"].(string)
target := task.Input["lang"].(string)
// ... call your model
return base.Result{Output: translated}, nil
}
func main() {
base.Run(&Translator{
Agent: base.Agent{
Name: "translator",
Version: "0.1.0",
},
})
}Build β Push β Mesh discovers it automatically via NATS.
Every agent message goes through NATS, so you can replay:
nats sub "agent.>" --server localhost:4222Distributed tracing (OpenTelemetry) is wired by default. Open Jaeger at localhost:16686.
Per-agent metrics in Prometheus (localhost:9090) with a pre-built Grafana dashboard at localhost:3000.
In config.yaml:
limits:
global:
max_cost_per_workflow: 1.00 # USD
max_agent_invocations: 50
timeout: 10m
per_agent:
researcher:
rate_limit: 30/min
max_tokens: 4000
models: [claude-haiku-4, gpt-4o-mini]If a workflow exceeds the budget, the orchestrator stops it cleanly and returns partial output.
- Core orchestrator + NATS bus
- YAML workflow DSL
- 6 built-in agents (researcher, coder, reviewer, writer, executor, vision)
- Web UI for workflow design (drag-and-drop)
- Multi-host deployment via Docker Swarm
- State persistence (resume from crash)
- Marketplace of community agents
Apache-2.0. See LICENSE.
Star β to follow production multi-agent AI.