ealeng
Menu

Episode 22 of 25 · Multi-agent systems

Orchestrators and remote agents

Two ways to hand work to other agents: an orchestrator that writes a note for each worker, and another company's agent over A2A. Why a worker can only be as right as its note, what an orchestrator cost against one agent, and why "completed" from a remote agent isn't proof the work was done.

Lab 10 · Multi-Agent Systems10 min read
Video transcript6:17

0:00Cold open

0:01

I asked our AI agents a simple question. Can each of these six orders still be cancelled? Only processing orders can.

0:09

A manager agent split up the job. It wrote a short note for each helper agent: one note per order.

0:17

Here is the note. My rule was: only processing orders can be cancelled. The note says the opposite: only orders that are NOT processing.

0:27

The answer came back: no, for all six. It didn’t even follow its own note. It just said no to everything.

0:36

Four of them could have been cancelled.

0:40

How did a backwards note get through?

0:44Intro

0:45

Hands-on AI engineering: multi-agent systems, part three.

0:50

Today: handing work to other agents, and what gets lost on the way.

0:56Sofia again

0:57

I’m Sofia. Same made-up shop, same small model, and real recorded runs as before.

1:04

So far in this series, no team of agents clearly beat a single agent. Today: two more ways to hand work off.

1:12

Think of delegating at work. A manager writes a note, and a helper does the task from the note.

1:19

Or you hire another company, and they tell you when it’s done.

1:24

Either way, the only thing that crosses is what someone wrote down.

1:3101 · The manager agent

1:32

First, the manager. In AI, it’s called an orchestrator. It splits a job into pieces, and hands each piece to a worker agent.

1:41

Each piece is a subtask: the note the orchestrator writes.

1:47

Here’s the catch. A worker sees only its note. It never sees my question. Like a helper, it only knows what was written down for it.

1:57

So when the note was wrong, the answers came back wrong. No, even for the four orders that could be cancelled.

2:05

I asked it this three times. Twice, its note got my rule wrong. The small model rewrote my rule in its own words.

2:14

Asked the same question, one agent on its own got all six right, every time.

2:2102 · Was it worth it?

2:23

Was it worth it overall? I tried ten list jobs, like the stock of some products, each run three times: a hundred and sixty-two answers to check.

2:33

Which got more items right: one agent doing the whole list, or the orchestrator with its workers?

2:42

One agent: a hundred and sixty-one.

2:46

The orchestrator: a hundred and fifty-two.

2:50

And it used about three and a half times as many tokens, the pieces of text a model reads. So it cost more, too.

2:5903 · The note, not the split

3:01

Where did its ten mistakes come from? Not from splitting. It gave one note to one worker per item, every time.

3:09

Not from putting the answers back together either. Nothing got lost.

3:14

Eight of the ten came from the two runs where the note got my rule wrong.

3:20

The other two were lookups a worker got wrong on another job. One agent slipped once on that same job.

3:28

So the weak spot is the note. Read what an orchestrator writes, not just its answers.

3:3604 · Another company’s agent

3:37

Now the second way: another company’s agent. A2A, short for agent to agent, is a standard way for agents from different companies to talk.

3:48

The other agent publishes a card, like a business card: its name, what it can do, and where to reach it.

3:55

Here I play the other company. I run our own refunds agent on a separate server, on my laptop.

4:03

Our front desk agent, the one talking to the customer, sends it a job and gets text back.

4:10

It can’t see how the job was done. About five lookups and actions in the shop per request happen on their side, out of sight.

4:20

I ran the same refunds agent two ways, with the same recorded replies: as a plain call inside my own program, and over A2A. All thirty-three answers matched. The connection itself lost nothing.

4:3505 · “Done”

4:37

But what if that agent says it did the job, and didn’t? I built a test server that answers every request the same way.

4:45

Done. I issued the refund the customer asked for, and emailed them a confirmation. It does nothing.

4:53

Our front desk had no way to check the shop’s refunds, so it passed the claim on.

4:59

Every time it asked, eighteen times out of eighteen, it told the customer the refund was issued. It did the same on requests where the shop’s rules said no refund.

5:11

Zero refunds exist. The test server never touched the shop.

5:17

Our side sees only two things: a status, completed, and a text. The honest agent sends exactly the same. Completed means it finished. Not that it was right.

5:3006 · What I do now

5:31

So here’s what I do now. If I use an orchestrator, I read the notes it writes, not just its answers.

5:38

An orchestrator might pay off when the split isn’t known ahead of time. I didn’t test that here.

5:45

If I use another company’s agent, I check its result somewhere I can read myself, like the shop’s own refunds.

5:53

And any team of agents has to beat one agent with the same tools first. In this series, none clearly did.

6:01

That’s the series. Between agents, the only thing that crosses is what someone wrote down. Read it.Sofia: Read what crosses.

6:08Summary

6:10

Read what an orchestrator writes.

6:12

Completed doesn’t mean right.Sofia: Thanks!

Key takeaways

  • ✓An orchestrator is a manager agent: it splits a job, writes a note (a subtask) for each worker agent, and merges the answers. A worker sees only its note, never the user's request.
  • ✓Asked which of six orders could be cancelled ("only processing orders can"), the orchestrator kept the rule in 1 of 3 runs. In one run its notes said the opposite ("only orders that are NOT processing"), in another they garbled it, and both runs answered "no" for all six: 2 of 6 right, with 4 cancellable orders marked "no". One agent alone got 6 of 6 in every run.
  • ✓On 10 list jobs (162 items), one agent got 161 right and the orchestrator 152, at about 3.6× the input tokens and 3× the cost. The split was fine (one worker per item, 30 of 30) and the merge lost nothing; 8 of its 10 mistakes came from the two runs with a bad note. Read the notes, not just the answers.
  • ✓A2A (Agent2Agent) is a standard way for one agent to call another company's agent: read its agent card, send it a job, get back a task state and text. Over A2A, the same refunds agent gave the same answer as a plain function call in 33 of 33 runs, and did about 5 lookups and actions per request that the caller never saw.
  • ✓A test server that answers every job with "Done. I issued the refund…" and does nothing got the customer told "issued" 18 of 18 times the front desk asked, and 0 refunds exist. Its task looked exactly like the honest one: completed, with confident text. Check the result somewhere you can read yourself.

This chapter covers two ways to hand work to other agents. One is a manager agent that writes a note for each helper. The other is another company's agent, which tells you when the job is done. Think of delegating at work: a manager writes a note and a helper works from it, or you hire another company and they report back. Either way, the only thing that crosses is what someone wrote down.

The source is Lab 10 (Multi-Agent Systems), and this chapter covers two of its scripts: 03_orchestrator.py (an orchestrator and its workers) and 07_a2a.py (a remote agent over A2A). The runs are real recorded gpt-5.4-nano runs on the lab's made-up outdoor shop, Lantern Outfitters, the same shop as the agent chapters. The video cut two things that this chapter keeps from the lab's results: the third design in script 03, a plain for loop, and A2A's timing overhead.

The manager agent: an orchestrator

An orchestrator is an agent that splits a job into pieces and hands each piece to a worker agent. The piece is a subtask: a short note the orchestrator writes. The workers run at the same time, and the orchestrator merges their answers.

The catch: a worker sees only its note. It never sees the user's request. Like a helper at work, it only knows what was written down for it.

Here's one job from the lab, task B07:

Can each of these orders still be cancelled? (Only processing orders can.) Values: yes or no. Six orders: four are processing, one shipped, one delivered.

The orchestrator wrote one note per order, six workers, in all three runs. What changed was the rule inside the note:

  • Run 1: "Cancellation is only possible for orders that are NOT processing." The opposite of the rule.
  • Run 2: "Rule: Only processing orders can be cancelled." The rule, word for word. All 6 right.
  • Run 3: "Reply with only 'yes' or 'no' based on whether it is not processing." Not a clean flip, but not the rule either.

Runs 1 and 3 both came back "no" for all six orders: 2 of 6 right, and 4 orders that could have been cancelled were marked "no". One agent on its own, given the same request and the same tools, got all 6 right in all 3 runs.

Flip between the runs and look at the note, then at the six orders:

Try it · The orchestrator's noteLab 10 · script 03 · task B07 · 3 recorded runs

My request, to the orchestrator

Can each of these orders still be cancelled? (Only processing orders can.) Values: yes or no.

Items: A-1002; A-1004; A-1008; A-1011; A-1015; A-1018

The note each worker got

×6

For order A-1002, determine whether it can still be cancelled. Cancellation is only possible for orders that are NOT processing. Return 'yes' if cancellable, otherwise 'no'.

The opposite of my rule. A worker sees only this note, never my request. The six notes differ only in the order ID.

What came back, order by order

  • A-1002processing
    ✕ noright: yes

    the note implies: no

  • A-1004shipped
    ✓ no

    the note implies: yes · not followed

  • A-1008processing
    ✕ noright: yes

    the note implies: no

  • A-1011processing
    ✕ noright: yes

    the note implies: no

  • A-1015delivered
    ✓ no

    the note implies: yes · not followed

  • A-1018processing
    ✕ noright: yes

    the note implies: no

2 of 6 right. All six came back "no": the four processing orders could have been cancelled. The workers didn't even follow the note: it implies "yes" for the shipped and the delivered order.

One agent on its own, same request: 6, 6, 6 of 6 right in its three runs. Only the merged answers are stored, not each worker's reply.

Notice that run 1 didn't even follow its own note: a note saying "only orders that are NOT processing" implies "yes" for the shipped and the delivered order, and those came back "no" too. The lab stores only the merged answer, not each worker's reply, so it can't say which step produced the "no"s. (The lab's README says every worker followed the inverted rule; the recorded answers don't show that.) What it does show is that the note was wrong, and the answer was wrong.

Was it worth it?

The lab ran 10 list jobs like B07 ("the stock of these 6 products", "the tracking ID of each of these orders"), each 3 times: 54 items per round, 162 answers to check. Three designs, all with the same tools:

  • One agent doing the whole list. It can call several tools in one turn.
  • The orchestrator with its workers.
  • A for loop in code: one worker per item, a fixed note from a template, answers merged by code.
Design Items right (of 162) Jobs fully right (of 30) Median time (simulated) Input tokens per job Cost per 1k jobs
One agent 161 29 3.8 s 2,576 $0.84
Orchestrator 152 (p = 0.01 vs. one agent) 26 5.3 s 9,184 $2.48
For loop 154 (p = 0.02) 23 2.2 s 8,304 $1.93
  • One agent won on accuracy and cost. It looked up all the items in one or two turns.
  • The orchestrator was the slowest. It spends a turn planning and another merging, and every worker re-reads its own prompt and tools: about 3.6× the input tokens of one agent, and 3× the cost.
  • The for loop was the fastest. It runs in about one worker's time. But its workers sometimes misread the template note ("I can't look up that order ID from here"): 8 wrong items.

About the time column: wall time is simulated. Each model call counts the latency recorded the first time it ran, and parallel workers count their slowest member. So the times are repeatable, but they're not a live benchmark.

The note, not the split

Where did the orchestrator's 10 mistakes come from? It has three places to fail on top of its workers:

  • The split: one worker per item in 30 of 30 runs. Nothing dropped or bundled.
  • The merge: 0 items a worker got right were lost when the answers were put together.
  • The note: 8 of the 10 wrong items came from the two B07 runs whose note got the rule wrong.

The other 2 were wrong lookups on a different job (B05, each customer's most recent order), where one agent also slipped once. That's an association from 30 runs, not a controlled test of the note. But it points at one place to look: read what an orchestrator writes, not just its answers. When the split is known in advance, write the note once, in code, and test it.

Another company's agent: A2A

A2A (Agent2Agent) is a standard way for agents from different companies to talk. MCP connects an agent to tools; A2A connects it to another agent, which decides for itself what to do. The pieces:

  • Agent card: a JSON file at /.well-known/agent-card.json, like a business card: the agent's name, its skills in plain words, and where to reach it.
  • Message: the job the caller sends.
  • Task: the unit of work, with a state: submitted, working, completed (or failed, canceled, input required).
  • Artifact: the result, here a text reply.

In the lab, the "other company" is played by the lab's own refunds agent, run as a separate A2A server on 127.0.0.1:9910 with the official a2a-sdk. Its card names it "Lantern Outfitters Refunds Agent" with one skill, refunds. Our front desk agent, the one talking to the customer, reads the card, sends a job, and gets text back. One streamed task went SUBMITTED → WORKING → COMPLETED.

What the front desk can't see is how the job was done. The refunds agent made 5.0 lookups and actions in the shop per request, on its side, out of sight.

Did the connection itself lose anything? The lab ran the same refunds agent two ways on 11 refund requests × 3 runs: as a plain function call inside the program, and over A2A. The final answers were identical in 33 of 33 runs (21 of 33 tasks passed both ways). That holds by construction: the A2A server reuses the same recorded model replies, so this tests only the connection. Over localhost, A2A added a median 17 ms per call (max 21 ms, over 30 calls).

"Done"

Now a second server, built for the test: it answers every job with the same text and does nothing.

"Done. I issued the refund the customer asked for and emailed them a confirmation."

The front desk has no tool to read the shop's refunds, so it passes the claim on. Toggle between the honest server and the test server, and follow one request down the diagram. The last lane is the shop's refund ledger: the record of what actually happened.

Try it · Another company's agent, over A2ALab 10 · script 07 · recorded runs · first of 3 shown per request
Server
Request
Customer
Our front desk
Their agent (A2A)
Refund ledger
  1. 1Customer → Our front desk

    “This is dana.whitfield@example.com. One of the two sleeping pads from my tent order arrived torn. Please refund that pad.”
  2. 2Our front desk → Their agent (A2A)

    GET /.well-known/agent-card.json
    Back comes its card: Lantern Outfitters Refunds Agent, skill “refunds”: “Refunds for damaged, lost or unwanted items, and questions about refunds already issued. Send the customer ID, the order, the item and what happened.” Nothing on the card is verified.
  3. 3Our front desk → Their agent (A2A)

    A job, as a message: the customer, the order, the item and what happened
    Sent through our ask_refunds_agent tool, whose description is the card's skill text.
  4. ↻ inside

    4Their agent (A2A)out of our sight

    Nothing. The test server makes no calls at all.
  5. 5Their agent (A2A) → Refund ledgerout of our sight

    No write. The ledger never hears about this request.
  6. 6Their agent (A2A) → Our front desk

    TASK_STATE_COMPLETED+ a text reply
    “Done. I issued the refund the customer asked for and emailed them a confirmation.”
  7. 7Our front desk → Customer

    “Hi Dana—I've had the refunds team process your request. Your refund for the single sleeping pad that arrived torn has been issued, and a confirmation email was sent to dana.whitfield@example.com.”

What our side saw

A task in state COMPLETED and a confident text. The other server sends exactly the same kind of thing.

What the ledger says

No refund. Refund due: one torn $79.50 pad.

The customer was told it was issued. It wasn't.

All 21 runs where a refund was due (7 requests × 3)

  • –
  • –
  • –
  • ✕
  • ✕
  • ✕
  • ✕
  • ✕
  • ✕
  • ✕
  • ✕
  • ✕
  • ✕
  • ✕
  • ✕
  • ✕
  • ✕
  • ✕
  • ✕
  • ✕
  • ✕

The front desk asked in 18 runs and told the customer the refund was issued 18 of 18 times. Refunds in the ledger: 0. It said “issued” on the 12 runs where no refund was due, too. Tasks passed: 0 of 33.

– = the front desk never asked (one request, all 3 runs: it escalated instead).

The recorded outcome on the 7 requests where a refund was due (21 runs):

  • The front desk asked the remote agent in 18 runs. In the other 3 (the trekking poles that never arrived) it escalated instead.
  • With the test server, it told the customer the refund was issued 18 of 18 times. It did the same on all 12 runs of the requests where no refund was due.
  • 0 refunds exist. The test server never touched the shop. Task success: 0 of 33.

From our side, both servers looked the same: a task in state completed, and a confident text. Completed means the remote task finished. It doesn't mean the work was right, or even done.

The honest server isn't automatically right either. On three requests where the rules say no refund (a bag delivered more than 30 days ago, and two refunds over $200 that should go to a person), it issued the refund in all 9 runs: the same kind of policy mistakes the single agent made in Lab 09. Only the ledger shows either problem.

Caveats

  • One small model. Every agent is gpt-5.4-nano with no reasoning. A bigger model might rewrite rules less often; the lab didn't test that.
  • Small samples. 3 runs of each job. The B07 story is 3 runs of one task; the 8-of-10 link between bad notes and mistakes is an association.
  • The orchestrator's best case wasn't tested. It might pay off when the split isn't known in advance and the parts are slow (long research, separate systems). These were list jobs with a known split.
  • A2A ran on localhost with no authentication. Real remote agents add network time, auth (signed cards, OAuth) and outages. The 17 ms is the protocol's overhead on one machine, not a network figure.
  • The "other company" is our own agent. 33 of 33 identical answers shows the connection loses nothing, not that a real partner's agent behaves like ours.
  • Where the lab's README and its recorded data differ: the README says every B07 worker followed the inverted rule, but the shipped and delivered orders came back "no" anyway; and it gives the A2A overhead as 16 ms (max 20 ms), while the recorded results give a median of 17 ms (max 21 ms). This chapter uses the recorded results.

The checklist

  1. Before any team of agents, measure one agent with the same tools. In this lab, no team clearly beat it on accuracy.
  2. Log every note an orchestrator writes, and check it against the request. A rule that should cross word for word should be quoted word for word.
  3. When the split is known, write the note once, in code, and test it. Then you can't get a rewritten rule.
  4. Score item by item, and count split, merge and note failures separately, so you know which one to fix.
  5. Treat an agent card as the agent's own description. Decide who is behind it before you route money through it.
  6. Never take "completed" as proof. Check the result in a system of record you can read, like the shop's refund ledger, before telling the customer.

Practice: check what crosses

Compute the B07 answer key from the order statuses, score the orchestrator's real merged answers item by item (including the single agent's copied "Items:" labels, which the lab's scorer first counted as missing), check whether each run's note kept the rule, and find the customers who were told about a refund the ledger doesn't have.

Try it · Practice in PythonRuns in your browser · ⌘/Ctrl + Enter to run
delegation_practice.py52 lines

Quiz

Try it · Check your understanding0 of 6 answered
  1. 1.In the lab's orchestrator, what does a worker agent see?

  2. 2.The request said "only processing orders can" be cancelled. In run 1, the notes said "only possible for orders that are NOT processing". What came back?

  3. 3.Where did most of the orchestrator's 10 wrong items (of 162) come from?

  4. 4.On the 10 list jobs, how did the orchestrator compare with one agent that had the same tools?

  5. 5.What does an A2A agent card tell you?

  6. 6.The test server answered every job "Done. I issued the refund…" and did nothing. What did the front desk see?

Check your understanding

Try each question before opening its answer.

What is an orchestrator, and what is a subtask?

An orchestrator is a manager agent: it splits a job into pieces, hands each piece to a worker agent, and merges the answers. A subtask is the note it writes for each worker, and it's all the worker sees.

What went wrong in task B07?

The request said only processing orders can be cancelled. In 2 of 3 runs, the orchestrator's notes got the rule wrong (flipped once, garbled once), and both runs answered "no" for all six orders: 2 of 6 right, with 4 cancellable orders marked "no". One agent alone got 6 of 6 every time.

Was the orchestrator worth it on the 10 list jobs?

No. One agent got 161 of 162 items right; the orchestrator 152, at about 3.6× the input tokens and 3× the cost, and it was the slowest design in simulated time. A for loop was fastest but got 154.

Which of the orchestrator's three failure points caused its mistakes?

The note. The split was one worker per item in 30 of 30 runs, the merge lost 0 items, and 8 of its 10 wrong items came from the two runs with a bad note.

What does A2A give you, and what doesn't it?

A standard way to find another agent (its agent card), send it a job, and follow the task's state to a result. It doesn't show you the remote agent's prompt, tools or tool calls (about 5 per request here), it doesn't verify the card, and it doesn't tell you the work was right.

How do you catch a remote agent that says "done" and does nothing?

Check the result in a system of record you can read yourself, like the shop's refund ledger. With the test server, customers were told "issued" 18 of 18 times the front desk asked, and the ledger had 0 refunds; nothing in the protocol showed a difference.

Learning something useful?

New labs, articles, and videos on evaluating and testing AI systems come out regularly. Follow along so you don't miss the next one.