doc: MULTI_AGENT.md — coordination patterns enabled by agent-as-filesystem
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
b0514ea34f
commit
524cbde6d3
|
|
@ -0,0 +1,148 @@
|
|||
# Multi-Agent Coordination
|
||||
|
||||
ollie exposes agents as filesystem objects via the 9P protocol. This means
|
||||
multi-agent coordination requires no framework, SDK, or message bus — it is
|
||||
ordinary shell scripting against a mounted filesystem.
|
||||
|
||||
## The Namespace
|
||||
|
||||
Every session lives under `/s/{id}/`:
|
||||
|
||||
| Path | Purpose |
|
||||
|------|---------|
|
||||
| `/s/new` | Create a session (write `name`, `backend`, `model`, `agent`, `cwd`) |
|
||||
| `/s/{id}/prompt` | Submit a prompt (dispatched async on close) |
|
||||
| `/s/{id}/chat` | Cumulative conversation history (append-only read) |
|
||||
| `/s/{id}/state` | Current state: `idle`, `thinking`, `calling:<tool>` |
|
||||
| `/s/{id}/statewait` | **Blocking read** — returns when state changes |
|
||||
| `/s/{id}/ctl` | Control commands: `stop`, `kill`, `compact`, model/backend switches |
|
||||
| `/s/{id}/cfg` | Mutable session config (KV pairs) |
|
||||
|
||||
Utility files at the session root (`/s/`) provide higher-level operations:
|
||||
|
||||
| File | Purpose |
|
||||
|------|---------|
|
||||
| `/s/b` | One-shot: create, submit, wait, print result, kill |
|
||||
| `/s/bfg` | Batch foreground: submit to existing session, wait, print |
|
||||
| `/s/bbg` | Batch background: submit, return session path immediately |
|
||||
| `/s/sh` | Interactive shell session |
|
||||
|
||||
Global namespaces are shared across all sessions:
|
||||
|
||||
| Path | Purpose |
|
||||
|------|---------|
|
||||
| `/t/{name}` | Tool scripts (read/write) |
|
||||
| `/t/idx` | Synthesized tool index (descriptions + args) |
|
||||
| `/a/{name}.json` | Agent configs (supports `mv`, `cp`, `rm`) |
|
||||
| `/sk/{name}` | Skill files |
|
||||
| `/p/{name}` | Prompt templates |
|
||||
|
||||
## Spawning Agents
|
||||
|
||||
From within an agent session, use `subagent_spawn`:
|
||||
|
||||
```sh
|
||||
subagent_spawn [-name NAME] [-agent AGENT] [-backend BACKEND] [-model MODEL] [-cwd DIR] <prompt>
|
||||
```
|
||||
|
||||
This creates a child session, writes the prompt, and returns the session path
|
||||
(e.g. `s/my-session`). Child sessions carry the parent session ID in their name,
|
||||
so the spawning tree is recoverable from session IDs alone.
|
||||
|
||||
## Coordination Patterns
|
||||
|
||||
### Hub-and-Spoke (Conductor)
|
||||
|
||||
A root agent reasons about a task and delegates subtasks to workers. Workers
|
||||
report back via their chat history; the conductor reads `/s/{id}/chat` after
|
||||
`statewait` unblocks.
|
||||
|
||||
```sh
|
||||
# Conductor spawns two workers
|
||||
worker_a=$(subagent_spawn -model haiku "analyse /src/a.go")
|
||||
worker_b=$(subagent_spawn -model haiku "analyse /src/b.go")
|
||||
|
||||
# Wait for both
|
||||
until [ "$(cat $worker_a/state)" = "idle" ]; do cat $worker_a/statewait; done
|
||||
until [ "$(cat $worker_b/state)" = "idle" ]; do cat $worker_b/statewait; done
|
||||
|
||||
# Collect results
|
||||
cat $worker_a/chat $worker_b/chat
|
||||
```
|
||||
|
||||
The conductor and workers can run on different models. Mechanical analysis goes
|
||||
to cheaper models; reasoning stays on the expensive one.
|
||||
|
||||
### Pipeline
|
||||
|
||||
Agent A produces output; agent B consumes it. Composition via `/tmp/` or direct
|
||||
path passing.
|
||||
|
||||
```sh
|
||||
step1=$(subagent_spawn "extract all TODOs from /src/ and write to /tmp/todos.txt")
|
||||
until [ "$(cat $step1/state)" = "idle" ]; do cat $step1/statewait; done
|
||||
subagent_spawn "prioritise the TODOs in /tmp/todos.txt and produce a plan"
|
||||
```
|
||||
|
||||
### Scatter-Gather (Swarm)
|
||||
|
||||
Spawn N workers in parallel, collect when all reach `idle`. Because `statewait`
|
||||
blocks until state changes, no polling loop is needed.
|
||||
|
||||
```sh
|
||||
# Scatter
|
||||
for f in /src/*.go; do
|
||||
subagent_spawn "review $f for security issues" &
|
||||
done
|
||||
wait # wait for all subagent_spawn calls to return session paths
|
||||
```
|
||||
|
||||
Or from within `execute_code` using parallel steps:
|
||||
|
||||
```json
|
||||
{
|
||||
"steps": [
|
||||
{ "parallel": [
|
||||
{ "code": "subagent_spawn 'task A'" },
|
||||
{ "code": "subagent_spawn 'task B'" },
|
||||
{ "code": "subagent_spawn 'task C'" }
|
||||
]}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Peer-to-Peer
|
||||
|
||||
Any agent can read any other agent's session directory. There is no privileged
|
||||
orchestrator role — agents coordinate by reading each other's `chat` and `state`
|
||||
files directly. A peer can wait on another peer's `statewait`, then act on what
|
||||
it reads in `chat`.
|
||||
|
||||
### Reactive / Event-Driven
|
||||
|
||||
`statewait` is a proper synchronization primitive. A shell script (or another
|
||||
agent) blocks on it and wakes exactly when the target agent transitions state.
|
||||
This enables event-driven pipelines without polling:
|
||||
|
||||
```sh
|
||||
# Block until agent finishes, then trigger downstream work
|
||||
cat /s/worker-123/statewait
|
||||
# agent is now idle — proceed
|
||||
```
|
||||
|
||||
### Self-Directed Spawning
|
||||
|
||||
Agents can spawn sub-agents mid-task without human direction. If an agent
|
||||
determines that parallelism or specialization would help, it calls
|
||||
`subagent_spawn` on its own. No human prompt is required to initiate a
|
||||
multi-agent workflow — the model decides.
|
||||
|
||||
## Design Principle
|
||||
|
||||
ollie imposes no coordination model. There is no built-in conductor, swarm
|
||||
layer, or workflow engine. Orchestration is handled by the surrounding
|
||||
environment — shell scripts, cron, systemd, containers, or another agent.
|
||||
|
||||
This is intentional. The filesystem namespace is the API. Any tool that can
|
||||
read and write files can participate in a multi-agent workflow, which means the
|
||||
full Unix toolchain is available as an orchestration layer.
|
||||
Loading…
Reference in New Issue