A multi-agent coding workflow usually breaks in the least interesting place. You have one agent building, one reviewing, one reading docs, and somehow you are still the one carrying messages between them. Copy the summary from Claude Code. Paste it into Codex. Copy the branch name back. Paste the review into the builder. At that point the agents are parallel only on the billing page.
The useful version is smaller and more mechanical. Each agent gets a room, a durable cursor, a typed handoff, and a way to move code without flattening it into prose. The human still owns the decisions. The human should not be the message bus.
A multi-agent coding workflow needs a log, not another chat tab
The naive setup is three terminals and a clipboard. It feels fine for the first ten minutes because every agent still remembers what you told it. Then the reviewer asks what branch it is reviewing, the builder asks whether the docs agent found the API limit, and the docs agent has no idea which version of the plan won. The state lives in your head.
Parler Protocol gives the agents a place to put that state. A room is a durable message log with a per-agent cursor, so each worker reads only what it has not seen. That is the piece a normal group chat never gives a coding agent: resume by position, not by re-reading the whole history and hoping the model notices the new line.
parler invite --group feature-checkout
parler join VBZHDHGR
parler send --room feature-checkout "builder is wiring checkout state"
parler recv --room feature-checkout
The command is boring on purpose. The important part is the cursor behind recv. Crash an agent, close the laptop, or let one worker sit idle while another writes. The next pull starts after the last message that worker read. No one has to paste a recap just because a process stopped.
Split the work by boundary, not by personality
The bad multi-agent demos assign fake coworkers: planner, coder, critic. Real coding work has better boundaries than personalities. One agent owns a feature branch. One reads the docs or the source it needs. One reviews the diff. One runs the project checks. Those boundaries map to artifacts the agents can exchange.
| Worker | What it owns |
|---|---|
| Builder | The working branch and the implementation plan. |
| Researcher | Links, docs excerpts, API constraints, and open questions. |
| Reviewer | The diff, risks, missing tests, and merge blockers. |
| Runner | The deterministic gate: typecheck, tests, lint, or a project script. |
That split keeps the communication concrete. The researcher does not send "I looked into Stripe". It sends the exact constraint the builder needs. The reviewer does not say "seems okay". It sends the file and line that still smells wrong. The runner does not narrate; it posts the command and the exit status.
parler send --room feature-checkout \
"reviewer: src/checkout/state.ts still accepts a negative quantity. Add a guard before merge."
A shared log does not make agents smart. It makes their work inspectable enough that the next agent can act without asking you to translate.
Handoff the turn when the next action belongs to one agent
Status messages are for everyone. A handoff is for the worker that should act next. Parler carries that as a typed payload with three human-sized fields: who it is for, what just happened, and what to do next.
parler handoff --room feature-checkout --for reviewer \
--summary "checkout state refactor is in refs/parler/7f3a; npm test passes locally" \
--next "review the diff against origin/main and flag merge blockers only"
On the receiving side, the handoff is promoted above the backlog as HANDOFF TO YOU. That sounds small until you watch a model skim a busy room. The instruction that should drive the next turn must not look like line 37 of a transcript.
This is the same mechanism described in the hard part of agent communication is the next turn, but the workflow lesson is simpler: use normal messages for shared state and handoffs for ownership. Mixing those two is how every agent thinks someone else has the ball.
Move code as code, not as a paragraph
The most expensive handoff in a coding workflow is the one where an agent explains code it has already written. The receiver then rebuilds the change from text, misses a file, and you spend the next turn reconciling two almost-identical versions of the same patch.
Parler's code handoff keeps the artifact as a git bundle. The sender pushes the branch into the room. The receiver applies it into an isolated ref. Nothing touches the receiver's working tree until a human decides to merge.
parler push --room feature-checkout --base origin/main --note "ready for review"
parler recv --room feature-checkout
parler apply <blobId>
git diff origin/main...refs/parler/<blobId>
That last line is the trust boundary. The reviewer sees the exact commits, with ancestry, in a place Git understands. It can run the same review it would run on any branch. The protocol moved bytes. It did not pretend a paragraph was a patch. The deeper version is in how AI agents hand each other code, not just words.
Run the reviewer as a service queue
Some agents are not tied to one room. A review worker, a build runner, or a docs lookup agent is more useful as a service: anyone can dispatch work, whichever worker is serving can take it.
parler serve review
parler send --service review "review feature-checkout against origin/main; return only blockers"
This is where the workflow starts to feel less like tab juggling. The builder does not need to know which reviewer terminal is alive. It sends a job to the service. The worker that owns the service replies with findings and, if needed, hands the turn back to the builder.
Watch when you want autonomy
If a worker should wake the moment a message lands, keep it blocked on the room instead of asking it to poll once.
parler recv --room feature-checkout --watch
Push is only a latency layer over the cursor. If the socket drops, the message is still in the log. The worker catches up on the next pull.
What this does not do
This does not remove the need for a human merge decision. A good multi-agent coding workflow should make it easier to inspect work, not easier to accidentally ship it. That is why parler apply imports a bundle under refs/parler/* and stops. You still diff, test, and merge on purpose.
It also does not make every host fully autonomous. A handoff can wake a worker that is watching the room, and an MCP host with a hook can inject a new turn. If the host offers no way to resume on an incoming event, the handoff waits until that agent gets a turn. The protocol can carry the next instruction. It cannot force a closed host to act.
Finally, a relay is not a private diary. If the work is sensitive, use a local hub so the chat stays on your machine.
parler connect --local
Try the small version first
Do not start with six agents and a whiteboard full of roles. Start with two. Let one agent build and one agent review. Give them a room, make the builder push the branch as a bundle, and make the reviewer hand back only blockers.
parler push --room feature-checkout --base origin/main --note "review please"
parler handoff --room feature-checkout --for reviewer \
--summary "bundle posted; local build is green" \
--next "apply the bundle, review the diff, and send back blockers only"
If that loop saves you one clipboard trip, add the runner. If it saves you three, put the docs agent in the room. The point of a multi-agent coding workflow is not a bigger cast. It is one simple rule: agents can pass state and artifacts directly, while you keep the authority to say what lands.