Coordinate an Agent Team
You have several agents, each good at one thing. You also have a
task that needs more than one of them. A single autonomous agent
would have to be a generalist. You want a lead that delegates and a
set of specialists that each answer in their own voice.
gemba-harness gives you that. One lead LLM session
coordinates N participant sessions over an in-memory message bus.
Every message and tool call lands in one trace. The exchange runs
asynchronously, so nothing blocks while a participant works.
This guide covers coordination as a capability in its own right. The same machinery powers Prove Agent Changes. Start there if your goal is to grade an agent change against pass/fail criteria.
Prerequisites
- Node.js 22+
ANTHROPIC_API_KEYset in the shell-
Agent profiles under
.claude/agents/for the lead and each participant (see Agent Teams to learn how to author them) - Install the command family, or invoke one command ephemerally:
npm install -g @forwardimpact/gemba
npx gemba-harness --help
Pick a coordination shape
Three subcommands of gemba-harness share one
orchestration loop and one tool surface. They differ in who leads,
how many participants there are, and how the session ends.
| Shape | Lead | Participants | Ends with | Reach for it when |
|---|---|---|---|---|
supervise |
supervisor | one agent | Conclude |
A second model should watch one agent and step in mid-run |
facilitate |
facilitator | N named | Conclude |
The work needs several specialists to coordinate in one sitting |
discuss |
lead | N named | Adjourn or Recess |
The session spans a human channel and may suspend and resume |
supervise is a one-lead, one-participant relay.
facilitate fans the lead out to many named specialists.
discuss is the suspendable sibling of
facilitate. It carries a stable thread id. It can pause
for an external reply, which makes it the shape a chat-channel
bridge drives. run is a single agent with no lead. It
is the autonomous building block under all three shapes. It does no
coordination.
How the lead and participants take turns
Every coordinated session runs the same loop. The lead receives the task on its first turn. Each participant waits until a message lands on its inbox. From then on, both sides repeat the same cycle: drain the inbox, run or resume the LLM with the drained messages, then settle any questions they still owe an answer to.
The loop fans messages out over an in-memory bus. It writes one
{ source, seq, event } NDJSON line for every tool call,
bus message, and orchestrator event. seq is monotonic
across the whole session, so the trace is a single ordered record of
who did what and when.
The lead delegates the work. It does not do the work itself. In
facilitate and discuss runs the lead gets Read,
Glob, and Grep only. It does not get
Edit, Write, or sub-agent tools. A
supervise lead also gets Bash so it can inspect the
working tree between rounds. Participants carry whatever tool
allowlist you grant them.
Pass messages with Ask, Answer, and Announce
Coordination happens through three tools. It does not happen through free-form chat. The trace records each call, so you can later read exactly how the team converged.
Ask({ question, to? }) → { askIds: [N, …] }
Answer({ message, askId? }) → routed back to the asker
Announce({ message }) → broadcast to everyone, no reply expected
Ask is asynchronous. It returns
immediately with one askId per addressee. It registers
a pending question. The lead can issue several Asks in
one turn, end that turn, and plan in the gap while participants work
in parallel. Each reply arrives later on the asker's next turn
as a tagged inbox line:
[ask#42] facilitator: What is your current status?
[answer#41] agent-1: I finished 7 of the 10 checks.
[shared] agent-2: FYI I am editing the shared config file.
[system] @orchestrator: You have an unanswered ask from facilitator (askId=42)…
Answer routes by askId.
Quote the N from the [ask#N] tag so the
reply reaches the right asker. The askId is optional.
The handler is forgiving. If you owe exactly one answer, the handler
picks it automatically. If you owe none or many and you omit the
askId, the message broadcasts as an Announce instead.
Addressees. On a multi-participant lead, omit
to to broadcast an Ask to everyone. The
supervise pair has only one possible target. The
harness rejects to there.
Every participant also has RollCall to list who is
currently in the session.
Prevent a session deadlock
If a participant ends its turn and still owes an answer, the loop
injects one synthetic reminder. The loop then resumes the
participant once. If the question is still unanswered after the
reminder, the loop emits a protocol_violation event. It
also unblocks the asker with a synthetic null answer. A silent
participant can never deadlock the team. You will see both the
reminder and any violation in the trace.
End the session
A session ends explicitly. The end tool depends on the mode:
-
Concludeends asuperviseorfacilitatesession with averdict(successorfailure) and a summary. Only the lead can use it. -
Adjournends adiscusssession with a verdict (adjournedorfailed), a summary, and an optional outcome. -
Recesssuspends adiscusssession with a resumption trigger. It does not end the session, so a bridge can re-enter later.
Each of these tools cancels in-flight Asks. Askers then
see why their question will go unanswered, and they do not hang. The
loop writes a terminal summary event with the verdict
and the turn count. The process exit code reflects the verdict. It
is 0 when the lead concluded with success, and
1 otherwise.
Tool surface by role
| Role | Ask | Answer | Announce | RollCall | Conclude | Also |
|---|---|---|---|---|---|---|
| Supervisor | ✓ | ✓ | ✓ | ✓ | ✓ | |
| Supervised agent | ✓ | ✓ | ✓ | ✓ | ||
| Facilitator | ✓ | ✓ | ✓ | ✓ | ✓ | |
| Facilitated agent | ✓ | ✓ | ✓ | ✓ | RequestForComment |
|
| Discuss lead | ✓ | ✓ | ✓ | ✓ |
Recess, Adjourn,
Acknowledge
|
|
| Discuss agent | ✓ | ✓ | ✓ | ✓ |
RequestForComment, Acknowledge
|
RequestForComment lets a participant queue an intent to
open a new discussion thread for a question that outlives the
current session. In discuss mode,
Acknowledge posts a brief message straight to the
thread (a status update or a reply to a human follow-up). It does
not discharge an owed Answer.
Consult an advisor
An advisor is a bounded, read-only, one-shot consult on a stronger
model. An agent participant sometimes hits a hard decision. Examples
are an architectural fork, an unclear root cause, and a trade-off it
cannot rank. The agent then calls the Advisor tool with
one focused question. The harness forwards the question to a fresh
session on the advisor model. It also forwards the agent's full
session context (its system prompt, delivered prompts, and
transcript so far). That session can read files. It cannot write,
execute, or spawn agents. Its final text returns as the tool result.
The caller stays in control of its own loop.
Two flags enable it on run, supervise,
facilitate, and discuss:
npx gemba-harness facilitate \
--task-file=sessions/release-review/task.md \
--lead-profile=facilitator \
--agent-profiles=security-reviewer,release-reviewer \
--advisor-model="claude-opus-4-8[1m]" \
--advisor-max-uses=3 \
--output=trace.ndjson
Omit --advisor-model to disable the tool entirely. You
then get no advisor prompt text, no tool, and no cost.
--advisor-max-uses (default 3) is a session-wide
budget. All participants share it, and the code enforces it. After
participants spend the budget, further consults return "proceed
with your best judgment". They do not start an advisor session.
Consults are fail-open. A consult that times out, errors, or is
aborted resolves the same way. The caller's session continues
normally. Lead roles never get the tool. Only agent participants get
it.
Every consult is evident in the trace. An
advisor_consult orchestrator event records the caller,
question, model, duration, and remaining budget. The advisor
session's own lines appear under a distinct
advisor source. Those lines include its result event
with token usage and cost.
Run a facilitated session
Write a facilitator profile and one profile per participant. Each participant profile only needs to describe its specialism. The runtime appends the coordination tools automatically. Then run:
npx gemba-harness facilitate \
--task-file=sessions/release-review/task.md \
--lead-profile=facilitator \
--facilitator-cwd=. \
--agent-profiles=security-reviewer,release-reviewer,doc-reviewer \
--agent-cwd=. \
--max-turns=200 \
--output=trace--review.ndjson
The --task-file content is the opening prompt every
participant sees. The facilitator profile steers how the team
pursues the goal. Each participant applies its own specialism. Pass
the task as exactly one of --task-file=<path>,
--task-text="<inline>", or
--task-event=<path> (a native GitHub event
payload).
The profile names above are examples. You choose your own. The Kata agent team is the reference tenant for this platform, and its profiles run through these same shapes.
Participants share --agent-cwd by default. If two might
edit the same file, give each one its own working directory. You can
instead restrict tool allowlists so only one can write.
--max-turns applies uniformly to the lead and every
participant. Always set a budget so a stuck participant cannot run
the session forever. The CLI default is 20. Raise it
for sessions that do real implementation work.
Run a supervised relay
When one lead watches one agent, use supervise. The
supervisor sees the agent at each Ask boundary, plans
the next step, and eventually calls Conclude:
npx gemba-harness supervise \
--task-file=task.md \
--lead-profile=reviewer \
--agent-profile=coder \
--supervisor-cwd=. \
--agent-cwd=/tmp/sandbox \
--allowed-tools=Read,Edit,Write,Bash,Grep,Glob \
--max-turns=200 \
--output=trace--relay.ndjson
For a tighter feedback loop, size the agent's per-turn budget
down so each Ask returns sooner.
Run a suspendable discussion
discuss adds two flags. --discussion-id is
the stable thread identifier carried through the trace.
--resume-context holds JSON-serialized prior state for
a resumed run. A bridge service relays the workflow callback when
the conversation suspends on a Recess and re-enters
later. Each participant's Answer to the lead
streams to the thread as a separate reply as the participant
produces it. The harness does not batch the replies at the end.
npx gemba-harness discuss \
--task-file=task.md \
--lead-profile=discussion-lead \
--agent-profiles=architect,security-reviewer \
--discussion-id=GD_kwExample \
--output=trace--discuss.ndjson
See Bridge a Threaded Channel to the Agent Team to wire a human channel into a discussion. That guide covers webhook intake, callback tokens, and the suspend/resume lifecycle.
Inspect the trace
Every coordinated run produces one NDJSON file. Read it as text for
a quick sanity check. Then hand it to gemba-trace for
structured analysis:
npx gemba-harness output --format=text < trace--review.ndjson
npx gemba-trace overview --file trace--review.ndjson
npx gemba-trace tool trace--review.ndjson Ask
npx gemba-trace tool trace--review.ndjson Announce
Ask/Answer show the targeted exchanges and
Announce shows the broadcasts, so you can trace where
participants converged or diverged. See
Analyze Traces for
the full method to read a trace.
Redaction
Redaction is on by default across supervise,
facilitate, and discuss. It replaces
allowlisted environment-variable values
(ANTHROPIC_API_KEY, GH_TOKEN,
GITHUB_TOKEN, and more) and credential-shaped strings
in the trace. Leave it on for any run whose trace might be shared.
Workflow artifacts stay downloadable through retention.
Verify
You have reached the outcome of this guide when:
-
You can run a
facilitatesession with a lead profile and two or more named participant profiles, and it produces a single NDJSON trace. -
You can read the trace and see
Ask/Answerexchanges routed byaskId,Announcebroadcasts, and a terminalsummaryevent with the verdict. -
A
superviserun exits0when the lead concludes with success and1otherwise. -
A
discussrun carries your--discussion-idthrough the trace and ends onAdjourn, or suspends onRecessfor a bridge to resume.
What's next
To wire a human channel into a discuss session, see
Bridge a Threaded Channel to the Agent Team
on the Forward Impact site.
Prove Agent Changes
Reproducible evidence that agent changes improved outcomes, from the eval session through the trace analysis.
Analyze Traces
See exactly what an agent did and why. Download traces, query turns, filter by tool or error, and measure token cost.
Set Up Persistent Memory and Metrics
Give your agent team persistent memory and real signal detection with wiki-backed state and XmR control charts. Get evidence that agents act on changes. They do not act on noise.