The Coordination Cycle

A multi-agent system is not a one-way assembly line.

The coordinator splits the goal, specialists work, results come back, and the coordinator decides whether to finish, retry, or send more work.

That repeating path is the coordination cycle.

Intuition

One agent thinks, acts, observes, and remembers.

A team needs an extra layer around that:

flowchart LR D[Decompose] --> E[Execute] E --> A[Attribute] A --> R[Reconcile] R --> Q{Goal met?} Q -->|No| D Q -->|Yes| F[Final decision]
Step What happens
1. Decompose The coordinator splits the goal into bounded tasks.
2. Execute Specialists run, in parallel where possible.
3. Attribute Each result is tagged with its agent and task id.
4. Reconcile The coordinator combines, checks, and decides.

If something still conflicts, the cycle repeats.

Iterate until done

The loop in code is small. The design lives in the stop conditions, not in extra frameworks.

while not goal_satisfied(state):
    tasks = coordinator.delegate(state)
    results = await run_agents(tasks)
    state.merge(results)
    if conflict(state):
        state = coordinator.replan(state)

return coordinator.final_decision(state)

Three facts make this a loop rather than a script:

Bounding the loop

Without limits, two agents can undo each other forever: the flight agent picks a late arrival, the hotel agent rejects it, the flight agent picks it again.

MAX_ROUNDS, MAX_TOKENS = 3, 10_000
rounds = 0

while not goal_satisfied(state):
    if rounds >= MAX_ROUNDS:
        return escalate(state, "round limit")
    if state.tokens > MAX_TOKENS:
        return escalate(state, "over budget")
    if repeats_conflict(state):
        return escalate(state, "deadlock")

    tasks = coordinator.delegate(state)
    state.merge(await run_agents(tasks))
    rounds += 1

return coordinator.final_decision(state)
Limit What it means here
Round limit At most three delegation rounds
Cost budget Stop before 10,000 tokens
Deadlock check The same conflict twice means agents are undoing each other
Escalate Hand the partial plan and the conflict to a person

Escalation is a success of sorts. The system stopped honestly instead of booking a broken trip.

Parallel versus sequential

Parallel

Use it when tasks do not need each other's output.

flight, hotel, policy = await gather(
    flight_agent.run(f_task),
    hotel_agent.run(h_task),
    policy_agent.run(p_task),
)

Risk: wasted work if a later check fails. The hotel search may finish, then policy says the dates are invalid.

Sequential

Use it when one agent needs another agent's result.

flight = await flight_agent.run(f_task)
hotel = await hotel_agent.run(h_task)
budget = await budget_agent.run(combine(flight, hotel))

Risk: waiting time adds up. Each agent sits idle until the previous one finishes.

flowchart TB subgraph P["Parallel"] F1[flight_agent] H1[hotel_agent] P1[policy_agent] end subgraph S["Sequential"] F2[flight_agent] --> H2[hotel_agent] --> B2[budget_agent] end

A practical Paris design often mixes both: search flights and hotels together, then run budget and policy checks on the combined pair.

What goes wrong

One-line summary

The coordinator decomposes, delegates, attributes, and reconciles in a bounded loop; parallelise independent searches and escalate when rounds, cost, or a repeated conflict say stop.

Key terms