ealeng
Menu

Episode 20 of 25 · Multi-agent systems

One agent or a team?

Splitting a support agent into a team: triage and three specialists. What a handoff passes on (a note, the whole conversation, or a log of who did what), why the whole conversation made the orders agent hand a case to itself, why no team beat one agent, and how much each handoff loses.

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

0:00Cold open

0:01

A customer wrote in. Her trekking poles never arrived.

0:05

Our AI support agent is now a team, like a call center. A front-desk agent found her account, and transferred her to the orders agent.

0:15

The orders agent replied: I’ve handed your case to our orders team.

0:21

But it is the orders team. It looked nothing up, and refunded nothing, in all three runs. In two of them, it said she’d been handed on.

0:31

Why would an agent hand a case to itself?

0:35Intro

0:36

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

0:41

Today: one agent, or a team of agents? And what gets lost when one agent hands a case to another.

0:49Sofia again

0:50

I’m Sofia, a support engineer at a made-up outdoor shop. Same shop as the AI agents series.

0:58

Until now, one AI agent answered every message. An agent is a model that can call tools: look up an order, or send a refund.

1:08

I test it on thirty support tasks. Each task runs three times, so ninety runs. Every run is a real, recorded run of a small model, nano.

1:19

One agent, with every tool, passed seventy-eight of the ninety. Passed means it did the right thing in the shop, and told the customer.

1:29

So why try a team? Because a team sounds tidier: each agent gets just one job.

1:3701 · The team

1:38

So I built a team, like a call center. First, a front desk. We call it triage. It finds the customer, and decides who should help.

1:48

Behind it, three specialists: orders, refunds, and the product catalog. Each one only gets its own tools.

1:56

Passing a case to another agent is called a handoff. The agent calls a transfer tool, and writes a short note.

2:04

Cases rarely bounced. In two hundred and seventy team runs, only one went back and forth.

2:1202 · One handoff

2:14

First, here’s the poles case going well, one agent at a time.

2:19

Triage looked up her account. Then it handed her to orders, with a note: who she is, and what she wants.

2:26

Orders found her order, and checked the tracking. It said: lost. So orders handed her to refunds.

2:34

Refunds sent back sixty-eight dollars. That’s the right answer. One agent alone got the same, in all three runs.

2:4403 · What gets passed

2:45

But what exactly does the next agent get when the case arrives? I tried three ways.

2:51

One: the customer’s message, and the note. Like a sticky note on the file.

2:57

Two: the whole conversation so far. Every message, and every tool call triage made. Like a call recording where every earlier voice sounds like your own.

3:08

Three: the same facts, written as a log. And every line says who did it.

3:1504 · Who am I?

3:16

The whole conversation is where the poles case broke. Here’s why.

3:21

To a model, a chat is a list of messages. Each one is marked with a role: the customer, a tool’s result, or the assistant.

3:30

The assistant’s messages are what the model itself said and did earlier.

3:36

In this conversation, triage’s lookups and its transfer are marked: assistant. So, most likely, the orders agent read them as its own.

3:46

As if it read: I already looked her up, and I already transferred her to orders. So it acted like triage, and said she had been handed on.

3:56

This happened in six of the eighty-seven runs with a handoff, not just here. Each time, the next agent replied without checking anything, and all six failed.

4:08

With the note, or with the log of who did what, that never happened. Not once. Here, the orders agent looked up the order, and the refund went out.

4:1905 · The scoreboard

4:20

So, across all thirty tasks, did any team beat one agent? One agent passed seventy-eight. Take a guess.

4:30

None did. With a note, or with the log, the team passed seventy-four. With the whole conversation, sixty-nine.

4:38

With ninety runs, gaps this small could be luck. But no team did better, and every team cost more: up to thirty-eight percent more per task.

4:4906 · A task cut in half

4:50

Splitting can also cut a task in half.

4:54

Another customer asks: when will my backpack ship? The answer is the restock date. Only the catalog agent has the stock tool.

5:04

Triage sent every one of these cases to orders. Orders has no stock tool, and it never passed the case on.

5:12

Three team setups, three runs each: zero of nine gave the date. One agent, with every tool: two of three.

5:2207 · What I do now

5:23

So here’s what I do now. Before splitting an agent, I compare the team with one agent that has the same tools.

5:31

If I do split, I pass a note, or a log that says who did what. Never the whole conversation.

5:39

I give each specialist every tool its tasks need.

5:43

And I split only when it buys something one agent can’t have: different tools, permissions, or owners.

5:50

Next time: a second agent as a check. A reviewer, a vote, a debate. Which one is worth paying for?

5:58Summary

6:00

One agent with the right tools is the baseline to beat.

6:04

If you split it, say who did what.Sofia: Say who did what.

Key takeaways

  • ✓The baseline for any team is one agent with the same tools. On the shop's 30 tasks × 3 runs, one agent passed 78 of 90. The team passed 74 with a note, 69 with the whole conversation, and 74 with a log of who did what. No team was better, and every team cost more: up to 38% more per task.
  • ✓A handoff passes only what someone wrote down. With a note, the next agent knows what the note says, and looks up again what triage already found (0.88 repeated lookups per task, against 0.02 for one agent).
  • ✓With the whole conversation, triage's tool calls arrive marked "assistant", the role a model reads as its own earlier words. On the lost-poles case, the orders agent looked nothing up and refunded nothing in 3 of 3 runs, and in 2 it said it had handed her to the orders team. Across all tasks, in 6 of 87 runs with a handoff the next agent answered at once without a tool, and all 6 failed.
  • ✓The same facts as a log where every line says who did it never caused that (0 of 87), and neither did the note. In three-turn conversations, the log tied one agent (18 of 24); the whole conversation was worst (10 and 8 of 24).
  • ✓Splitting tools can cut a task in half. The backpack's ship date needs the catalog's stock tool, but every team run went to orders and stopped: 0 of 9, against 2 of 3 for one agent. Split only for something one agent can't have: different tools, permissions or owners.

So far one AI agent has answered every message in the made-up outdoor shop from the agent chapters. This chapter splits it into a team, like a call center, and asks two questions: does the team do better, and what gets lost when one agent hands a case to another?

The code is Lab 10's 01_one_vs_many.py and 02_handoffs.py. The video covers script 01 only (Exercises 1 and 2). This chapter also covers that script's three-turn conversations (Exercise 4) and script 02, from the lab's recorded results; script 01's outage test (Exercise 3) isn't covered. Every agent is gpt-5.4-nano, on Lab 09's 30 support tasks, three runs each: 90 runs per setup. The lost-poles runs shown were replayed from the lab's cache (no new model calls), and each replay matched the recorded result.

The team

  • Triage is the front desk. It can find the customer and hand a case to a person, and it sends everything else to a specialist.
  • Orders handles order status, tracking, cancellations and address changes.
  • Refunds has the refund policy and the refund tools.
  • Catalog has products and stock.

Each specialist gets only its own tools and its own part of the policy. Passing a case to another agent is a handoff: the agent calls a transfer tool (transfer_to_orders) with a short note, and the next agent takes over and talks to the customer. Nothing comes back to triage.

Cases rarely bounced: in 270 team runs, one went orders → refunds → orders. The rest went one way (133 triage → orders, 90 triage → refunds, 19 triage → orders → refunds, 18 to catalog, 9 never left triage).

What gets passed

The next agent only knows what it's given. The lab tries three formats:

Format The next agent gets
A note the customer's message, and the sender's note
The whole conversation every earlier message: the customer's, and the earlier agents' tool calls and results
A log of who did what the same facts as the whole conversation, as lines like [triage] called find_customer(...), plus the note

The case to follow: "Hi, grace.kim@example.com. My trekking poles never arrived and it's been weeks." The tracking says the parcel is lost, so the right outcome is a $68 refund. One agent with every tool got it in 3 of 3 runs. Pick a format and step through it:

Try it · Pass the lost-poles caseRecorded gpt-5.4-nano runs · task T06, run 1 of 3 per format

How does the next agent get the case?

The next agent gets every earlier message: the customer's, and triage's tool calls and their results.

CustomerGraceTriagefind customer · transferOrdersorders · trackingRefundsrefund toolsCatalogproducts · stocknot needed here
step 1 of 4

The customer writes

“Hi, grace.kim@example.com. My trekking poles never arrived and it's been weeks.”

The right outcome: tracking says the parcel is lost, so refund the $68 poles. One agent with every tool did that in 3 of 3 runs. Press Next to follow the case through the team.

With a note, triage finds Grace and hands her to orders. Orders finds her order, sees the tracking say "lost", and hands her to refunds. Refunds sends back $68. The log works the same way.

Who am I?

The whole conversation is where the case broke. To a model, a chat is a list of messages, each marked with a role: system (its instructions), user (the customer), tool (a tool's result), or assistant: what the model itself said and did earlier.

In this format, triage's lookup and its transfer arrive marked assistant. Only the system prompt changes: "You are the orders agent." So, most likely, the orders agent read triage's work as its own, as if it read "I already looked her up, and I already transferred her to orders." It replied:

Thanks, Grace—I've handed your case to our orders team to locate your purchase, check the shipping/tracking details, and confirm what happened with the delivery.

It is the orders team. It looked nothing up and refunded nothing, in all 3 runs; in 2 of them it said she'd been handed on, and in the third it promised a lookup and stopped.

This wasn't one case. Across all 30 tasks, in 6 of the 87 runs with a handoff, the next agent answered on its first call without using a tool, and all 6 failed. With the note, and with the log, it never happened: 0 of 87. A caveat on the reason: the roles are the likely cause, and the log (same facts, labelled) avoided it. But the note avoided it too, and the lab doesn't isolate the roles as the cause.

The note has its own cost. The next agent only knows what the note says, so it checks again: with notes, specialists repeated 0.88 lookups per task that an earlier agent had already done (one agent: 0.02; the log: 0.41).

Did any team beat one agent?

Try it · Did any team beat one agent?30 tasks × 3 runs per setup · tap a point
Across:
passed more than one agent: no team here60%70%80%90%100%$1.20$1.40$1.60$1.80cost per 1,000 tasks →tasks passed ↑One agent · 78Note · 74Whole conversation · 69Log · 74

Team · log of who did what: 74 of 90 passed (95% interval 73–89%), p = 0.41 against one agent. $1.77 per 1,000 tasks (+38%), 6.7 model calls and 6,967 input tokens per task, 1.04 handoffs, 0.41 repeated lookups.

Vertical lines are 95% intervals. No team passed more tasks than one agent, and every team cost more.

Setup Passed (of 90) p vs. one agent Cost per 1,000 tasks Model calls per task
One agent 78 (87%) – $1.29 5.0
Team, a note 74 (82%) 0.41 $1.71 7.2
Team, the whole conversation 69 (77%) 0.08 $1.49 5.9
Team, a log of who did what 74 (82%) 0.41 $1.77 6.7

None did. With 90 runs, gaps this small could be luck, so the team isn't shown to be worse either. But no team was better, and every team cost more: +33%, +16% and +38%. Every handoff is another model call that re-reads its prompt and tools, and often looks up what triage already found. "Not worse" isn't a reason to ship more moving parts.

Two more things from the same runs:

  • Hand-offs to a person failed for everyone. 1 of 9 for one agent, 0 of 9 for each team: the same "$200 rule ignored" failure as in the agent loop chapter. Splitting the policy across agents didn't help.
  • Two-part requests weren't dropped. Both two-part tasks mentioned both parts in every reply, 6 of 6 in every setup.

A task cut in half

"When will my 65L backpack ship?" The answer is the restock date, and only the catalog agent has the stock tool.

Triage sent every one of these runs to orders. Orders has no stock tool, and it never passed the case on: its replies said there was no ship date yet. Team: 0 of 9 (three formats, three runs each). One agent: 2 of 3. No note fixes this: the task needs two agents' tools, and only one agent got it.

Conversations: who gets the next message?

The lab's Exercise 4 (not in the video) runs 8 three-turn conversations, 3 times each. Turn 1 leaves out the email, turn 2 gives it, and turn 3 asks for something else, often another specialist's job. "Sticky" sends the next message to the agent that spoke last; "retriage" sends every message back to triage.

Setup Whole conversation right (of 24) Cost per 1,000 conversations
One agent 18 $2.74
Team, a note, sticky 16 $3.50
Team, a note, retriage 11 $4.65
Team, the whole conversation, sticky 10 $3.14
Team, the whole conversation, retriage 8 $2.97
Team, a log, sticky 18 $3.88

The log tied one agent, at 1.4 times the cost. The whole conversation was worst. Retriage did worse than sticky in both formats it was tried with. Two conversations failed in every setup, one agent included; they're policy mistakes, not handoff ones.

What survives a handoff?

Script 02 (not in the video) measures the loss directly, on 10 research questions with 4–5 known key facts each.

The telephone game. Start from a correct fact sheet, and have a fresh model call rewrite it "for the next person", 5 times, 3 runs per question.

Instruction Key facts after 1 hop After 5 hops Notes with every fact (of 30)
"Keep it short" (≤ 40 words) 98% 97% 27
"Keep every number, name and date" (≤ 80 words) 100% 100% 30

The loss was small, and it happened at the first rewrite. Once a fact is dropped, no later writer can put it back: a sleeping bag's 4.6 rating was gone in 3 of 3 short chains. Saying what must survive mattered more than the number of hops.

A pipeline. Researcher → Writer → Editor, against one agent, with the same 120-word limit on every final answer:

Setup Facts in notes In draft In final Every fact in the final (of 30) Cost per 1,000
One agent – – 88% 19 $0.67
One agent, notes first 92% – 88% 15 $0.91
Researcher → writer → editor 93% 92% 92% 21 $1.55
… editor also sees the notes 93% 92% 92% 21 $1.63

The handoffs lost almost nothing: 93% → 92% → 92%. The missing facts were never found in research. Three agents found a few more facts than one, at 2.3 times the cost, and the difference is inside the noise at 30 runs. Giving the editor the notes changed nothing, because there was nothing to put back. So measure each stage, and fix the one that loses information.

Caveats

  • Small numbers. 90 runs per setup (30 for script 02). The gaps between one agent and the teams have p = 0.08–0.41; "no team was better" is solid, "teams are worse" isn't shown.
  • One small model, one made-up shop. Every agent is gpt-5.4-nano, no thinking. The tasks were written for one agent first (Lab 09).
  • The "who am I" mechanism is likely, not proven. The labelled log avoided the failure, but so did the note.
  • Lab and video counts. The lab's README says "up to +37%" (from the rounded $1.77 / $1.29); from the unrounded costs it's +38%, as the video says. The README's "6 of 87 handoffs" is 6 of 87 runs with a handoff: one task (3 runs per format) never left triage.

The checklist

  1. Compare any team with one agent that has the same tools, on the same tasks, with intervals and cost.
  2. Pass a note or a log that says who did what. Never the whole conversation as if it were the next agent's own.
  3. Give each specialist every tool its tasks need, and test the tasks that cross two toolsets.
  4. Split only for something one agent can't have: different tools, permissions or owners.
  5. Measure what survives each stage, not just the final answer, and tell the writer what must survive.
  6. Test whole conversations, not single turns, and decide who gets the next message.

Practice: what crosses a handoff

Write the labelled log, the three handoff formats, and the counts this chapter uses. The tests use the real lost-poles messages: your note and log modes must match, exactly, what the orders agent was given; full mode must hand over triage's calls as assistant messages. Then the repeated lookups in each run, the 6 of 87 "answered at once" across all 270 team runs, and the one bounce.

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

Quiz

Try it · Check your understanding0 of 6 answered
  1. 1.Before you split one agent into a team, what do you compare the team with?

  2. 2.In "whole conversation" mode, how do triage's tool calls reach the orders agent?

  3. 3.After a handoff, how often did the next agent answer at once, without using a tool?

  4. 4.With a note, the team passed 74 of 90 and one agent 78 (p = 0.41). What can you say?

  5. 5."When will my 65L backpack ship?" needs the restock date. Why did every team run fail it?

  6. 6.In a Researcher → Writer → Editor pipeline, the share of key facts went 93% in the notes, 92% in the draft, 92% in the final answer. Where should you fix it?

Check your understanding

Try each question before opening its answer.

What is a handoff, and what crosses it?

One agent passes the case to another with a transfer tool, and the next agent talks to the customer. Only what was written down crosses: the note, and whatever earlier messages the format includes.

What does the next agent get in each of the three formats?

A note: the customer's message and the sender's note. The whole conversation: every earlier message, including the earlier agent's tool calls and results. A log: the same facts as labelled lines like "[triage] called find_customer(…)", plus the note.

Why did the orders agent say it had handed the case to the orders team?

In the whole conversation, triage's lookup and transfer arrived marked "assistant", the role the model reads as its own earlier words. So, most likely, it acted like triage: no lookup and no refund in 3 of 3 runs, and "handed on" in 2.

How often did that kind of failure happen, and in which formats?

With the whole conversation, in 6 of 87 runs with a handoff the next agent answered at once with no tool, and all 6 failed. With the note and with the log: 0 of 87.

Did any team beat one agent?

No. One agent passed 78 of 90; the teams 74 (note), 69 (whole conversation) and 74 (log). The gaps could be luck, but every team cost more, up to 38%.

Why did every team run fail the backpack ship date?

The answer needs the catalog's stock tool. Triage sent all 9 runs to orders, which has no stock tool and never passed the case on. One agent with every tool got 2 of 3.

Where did the facts go missing in the Researcher → Writer → Editor pipeline?

In research. The stages went 93% → 92% → 92%: the handoffs lost almost nothing. Another editor wouldn't help; a better search would.

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.