A cross-provider multi-model AI orchestration engine (Python): a supervisor plans a task DAG, routes each sub-task to the best-quality model capable of it (by strengths and tool support) across Anthropic, OpenAI-compatible APIs, and Ollama, then synthesizes a final answer. No LangChain/CrewAI/LiteLLM.
git clone https://github.com/ribato22/baton && cp baton/*.md ~/.claude/agents/Subagents overview
# Baton
[](https://github.com/ribato22/baton/actions/workflows/ci.yml)
[](https://github.com/ribato22/baton/blob/main/LICENSE)
[](pyproject.toml)
[](https://github.com/astral-sh/ruff)
**A cross-provider multi-model AI orchestration engine.** A *supervisor* model decomposes a goal
into a task DAG, *routes* each sub-task to the best-quality model capable of it — by required
strengths and tool support — across providers (Anthropic, any OpenAI-compatible endpoint, Ollama),
runs them one-shot or in an agentic tool loop, and *synthesizes* a final answer. Built without an
orchestration framework (no LangChain / CrewAI / LiteLLM).
> One conductor, many players — pass the *baton* from the leader model to the workers and back.
---
## Highlights
- **Supervisor + routing.** An LLM plans a validated, acyclic task DAG; a router sends each task
to the strongest model capable of it (by required strengths + tool support). `--prefer
cash_protect_quota` right-sizes instead, to protect subscription quota.
- **Cross-provider.** `AnthropicProvider` and a generic `OpenAICompatProvider` speak to Anthropic,
Google AI Studio (Gemini), Groq, OpenRouter, DeepSeek, Moonshot (Kimi), local Ollama, and any
other OpenAI-compatible endpoint — no code changes, just env vars.
- **Hybrid one-shot / agentic.** Tasks run as a single call *or* as a model↔tool loop (`run_python`
in a subprocess sandbox — container-isolated under `BATON_SANDBOX=docker` — plus host-mediated
`fetch_url` / `read_file`).
- **Shared context.** An append-only *blackboard* carries provenance; each task gets a scoped,
budget-capped projection of only the dependency artifacts it needs.
- **Streaming everywhere.** Live token streaming through the supervisor, workers, and synthesizer,
with per-task labels for parallel workers and cooperative early-stop.
- **Optional Web UI.** A small FastAPI + SSE app streams a run live in the browser (plan → per-task
worker output → synthesis → result); runs with real providers or a no-key demo.
- **Cost & honesty.** A `CostMeter` tallies per-model usage and cost, and propagates an *estimated*
flag when a provider returns no usage.
- **Forgery-resistant evaluation.** A 3-arm eval (baseline vs. orchestration vs. single-agent) with
a scorer that runs untrusted solution code under **process + filesystem separation** so a model
cannot fake a passing score.
- **Tested.** 560+ tests, zero-network by default (`FakeProvider` + local subprocesses), `ruff`-clean.
## Architecture
```mermaid
flowchart TD
goal(["goal"]) --> S["Supervisor<br/>plan → validated task DAG<br/>(acyclic · typed · one_shot | agentic)"]
S --> R["Router<br/>strongest capable model per task<br/>(by strengths + tool support)"]
R --> P
subgraph wave["wave execution · asyncio fan-out · fail-fast"]
direction TB
P["Projector<br/>scoped, budget-capped request<br/>(system + task + deps)"]
P --> W["Worker<br/>one-shot"]
P --> AW["AgenticWorker<br/>model ↔ tool loop<br/>(run_python · fetch_url · read_file)"]
end
W --> BB[("Blackboard<br/>append-only · provenance · latest-wins")]
AW --> BB
BB --> SY["Synthesizer<br/>combine artifacts → final answer"]
SY --> result(["result<br/>+ CostMeter totals · usage · duration"])
classDef io stroke:#8b5cf6,stroke-width:2px;
classDef store stroke:#f59e0b,stroke-width:2px;
class goal,result io;
class BB store;
```
<details>
<summary>Text version (renders anywhere, e.g. PyPI or a terminal)</summary>
```text
┌──────────────┐
goal ──────────► │ Supervisor │ plan → validated task DAG (acyclic, typed, one_shot|agentic)
└──────┬───────┘
▼
┌──────────────┐ per task: pick the strongest model whose strengths +
│ Router │ tool support fit the task (quality-first)
└──────┬───────┘
▼
┌───────────── wave execution (asyncio, fan-out cap, fail-fast) ─────────────┐
│ ┌───────────┐ scoped, budget-capped request (system + task + deps) │
│ │ Projector │──────────────────────────────────────────────────────────► │
│ └───────────┘ │
│ ▼ ▼ │
│ ┌─────────┐ one-shot ┌───────────────┐ model↔tool loop │
│ │ Worker │ │ AgenticWorker │ (run_python sandbox, │
│ └────┬────┘ └───────┬───────┘ fetch_url, read_file) │
│ └──────────────┬──────────────────┘ │
└───────────────────────┼───────────────────────────────────────────────────┘
▼
┌──────────────────────┐ append-only, provenance, latest-wins
│ Blackboard │◄──────────────────────────────────────
└──────────┬───────────┘
▼
┌──────────────┐
│ Synthesizer │ combine artifacts → final answer
└──────┬───────┘
▼
result (+ CostMeter totals, usage, duration)
```
</details>
| Component | File | Responsibility |
|---|---|---|
| Supervisor | `src/baton/supervisor.py` | Decompose goal → validated task DAG |
| Router | `src/baton/router.py` | Task → strongest capable model (by strengths + tool support) |
| Projector | `src/baton/projector.py` | Scoped, budget-capped request from blackboard artifacts |
| Worker | `src/baton/worker.py` | One-shot model call |
| AgenticWorker | `src/baton/agent.py` | Model↔tool loop with per-turn records |
| Blackboard | `src/baton/blackboard.py` | Append-only shared state with provenance |
| Synthesizer | `src/baton/synthesizer.py` | Artifacts → final answer |
| Runtime | `src/baton/runtime.py` | Orchestrate: plan → waves → synthesize (streaming, fail-fast) |
| Providers | `src/baton/providers/` | Anthropic + OpenAI-compatible adapters (complete/stream/tools) |
| Tools | `src/baton/tools/` | Sandbox / DockerSandbox, run_python, fetch_url, read_file |
| Eval | `eval/` | 5 composite goals, 3-arm comparison, forgery-resistant scorer |
## Quickstart
Requires **Python 3.11+** and [`uv`](https://docs.astral.sh/uv/).
```bash
git clone https://github.com/ribato22/baton
cd baton
uv sync --dev # install deps + dev tools
uv run pytest # 580+ tests, no network
uv run ruff check . # lint
# See it orchestrate end-to-end with ZERO API keys (FakeProvider demo):
uv run python examples/fake_provider.py
```
Then configure at least one real provider (see [Providers](#providers)) and run a demo:
```bash
cp .env.example .env # fill in one provider, then `set -a; . .env; set +a`
uv run python demo.py # show detected providers
uv run python demo.py orchestrate # full supervisor → workers → synth, streamed live
uv run python demo.py agentic # one cross-provider agentic coding task (run_python loop)
uv run python demo.py eval # 3-arm eval suite
```
### Example output
`demo.py orchestrate` streams every phase live, then prints the result (illustrative):
```text
Orchestrate demo — planner/synth model=openai/gpt-4o-mini
(planning + workers + synthesis stream live)
[haiku] Threads run as one— / tasks bloom in parallel time, / the join gathers all.
STATUS: success
FINAL:
Threads run as one—
tasks bloom in parallel time,
the join gathers all.
cost: $0.001834
```
`demo.py eval` prints the 3-arm table (`format_report`); read the `VERDICT` with the warnings
(illustrative numbers):
```text
GOAL WINNER BASE ORCH AGEN
-------------------------------------------------
slugify orchestration 0.70 1.00 0.85
roman baseline 1.00 0.85 0.55
calc orchestration 0.55 0.85 0.70
csv_stats agentic 0.40 0.55 0.85
json_flatten orchestration 0.70 1.00 0.85
-------------------------------------------------
wins: baseline=1 orchestration=3 agentic=1 ties=0
totals: baseline $0.0210 orchestration $0.0480 agentic $0.0350
VERDICT: ORCHESTRATION
```
## Usage
Baton ships three surfaces: a one-command **CLI** (the primary entrypoint), an optional **Web UI**,
and an importable **library**. All three need at least one configured provider — see
[Providers](#providers) — or (Web UI only) fall back to a no-key demo.
### CLI (primary)
```bash
uv run baton "write a haiku about concurrency, then explain the metaphor"
```
`baton` streams the plan, each parallel worker's output (labelled per task), and the synthesis live,
then prints a summary. Flags (`baton --help`):
| Flag | Description |
|---|---|
| `--prefer {quality,cash_protect_quota,local,cheap}` | routing objective (default `quality` — the strongest model capable of each task). `cash_protect_quota` right-sizes to protect subscription quota; `local`/`cheap` are accepted but currently behave as `quality` |
| `--provider NAME` / `-P NAME` | restrict the planner/synth baseline to this provider |
| `--model ID` | override the planner/synth `model_id` |
| `--json` | print the run summary as one parseable JSON line; disables streaming |
| `--no-stream` | disable live streaming of plan/worker/synth text |
| `--version` | print the installed version and exit |
Exit codes: `0` success, `1` run failure, `2` config error (e.g. no provider configured), `130`
Ctrl-C (prints whatever partial output had streamed so far — never a raWhat people ask about baton
What is ribato22/baton?
+
ribato22/baton is subagents for the Claude AI ecosystem. A cross-provider multi-model AI orchestration engine (Python): a supervisor plans a task DAG, routes each sub-task to the best-quality model capable of it (by strengths and tool support) across Anthropic, OpenAI-compatible APIs, and Ollama, then synthesizes a final answer. No LangChain/CrewAI/LiteLLM. It has 0 GitHub stars and was last updated today.
How do I install baton?
+
You can install baton by cloning the repository (https://github.com/ribato22/baton) or following the README instructions on GitHub. ClaudeWave also provides quick install blocks on this page.
Is ribato22/baton safe to use?
+
ribato22/baton has not been audited yet by our security agent. Review the original repository on GitHub before using it in production.
Who maintains ribato22/baton?
+
ribato22/baton is maintained by ribato22. The last recorded GitHub activity is from today, with 0 open issues.
Are there alternatives to baton?
+
Yes. On ClaudeWave you can browse similar subagents at /categories/agents, sorted by popularity or recent activity.
Deploy baton to your cloud
Ship this repo to production in minutes. Each platform spins up its own environment with editable env vars.
Maintain this repo? Add a badge to your README
Drop the badge into your GitHub README to show it's tracked on ClaudeWave. Each badge links back to this page and reflects the live Trust Score.
[](https://claudewave.com/repo/ribato22-baton)<a href="https://claudewave.com/repo/ribato22-baton"><img src="https://claudewave.com/api/badge/ribato22-baton" alt="Featured on ClaudeWave: ribato22/baton" width="320" height="64" /></a>More Subagents
The agent harness performance optimization system. Skills, instincts, memory, security, and research-first development for Claude Code, Codex, Opencode, Cursor and beyond.
The agent that grows with you
Java 面试 & 后端通用面试指南,覆盖计算机基础、数据库、分布式、高并发、系统设计与 AI 应用开发
Build Agentic workflows, RAG pipelines, with rich AI model and tool support on one collaborative workspace. Deploy on cloud, VPC, or self-hosted, so teams move from prototype to production without rebuilding the stack.
The agent engineering platform.
Turn any codebase, with its docs, SQL schemas, configs, and PDFs, into a queryable knowledge graph. A /graphify skill for Claude Code, Cursor, Codex, and Gemini CLI: local deterministic AST parsing, every edge explained, no vector store.