Lab 2 · Domain 1 · 17%

Multi-Agent Systems & Orchestration

Multi-agent is the most over-prescribed architecture on this exam. It looks like sophistication and it reads like risk: coordination overhead, duplicated tokens, and an audit trail no one can reconstruct. This lab is about the two questions a senior architect asks before splitting a system into agents (is the work genuinely parallelizable, and does a subtask need context the parent must not carry) and about saying out loud why a single agent was the better answer.

Answer key Lab2_Complete.ipynb
Exam objectives covered
  • Design multi-agent systems and orchestration strategies
  • Apply decomposition techniques for complex problem solving
  • Select appropriate architectural patterns (workflow, agentic, augmented LLM)
The default is one agent, and the exam knows it. Every multi-agent item is really testing whether you can resist the impressive answer. A second agent is only justified when subtasks are genuinely parallelizable or when a subtask needs context isolation, and of those two, isolation is the stronger reason. If a scenario gives you neither, the extra agent is the distractor, and its cost is not just tokens: it is an execution trace that no one can replay when the regulator asks what happened.

1. When Multi-Agent Is the Wrong Answer

Start from the position that you are not building a multi-agent system, and make the scenario prove otherwise. The costs are concrete and they are paid on every run:

  • Coordination overhead. A manager that delegates must serialize a brief, wait, receive, and reconcile. That is latency and complexity that a single loop never pays.
  • Token duplication. Each agent carries its own instructions, its own copy of shared context, its own tool schemas. Five agents reading the same corpus can pay for that corpus five times.
  • An unreconstructable audit trail. One agent produces one linear transcript. Five agents produce five interleaved ones, and the reason a wrong output reached production may live in a subagent transcript the parent never saw.

Against those costs there is exactly one bar, and both halves are legitimate on their own:

JustificationThe testIf it fails
ParallelismAre the subtasks genuinely independent (no subtask needs another's output)?A serial pipeline in disguise. You paid coordination cost for work that still runs in sequence.
Context isolationDoes a subtask need to read a large or untrusted corpus the parent must never carry?You could have done it in one call. The split bought nothing but a serialization boundary.

If a scenario satisfies neither, the answer is a single agent, possibly a workflow around a single agent (Lab 1), but not a second reasoning loop.

2. Orchestration Topologies

When multi-agent is warranted, the shape matters more than the count. Five topologies cover the exam, arranged from cheapest to most elaborate. Choose the simplest one that satisfies the requirement, and be able to name each one's failure mode; that is what the items test.

TopologyUse whenSignature failure modeCost profile
Single agent
one loop
The default. One context, one transcript, sequential tools. Context window fills with tool results it no longer needs (see §4). Lowest. One set of instructions, one prefix to cache.
Orchestrator–worker
manager delegates
A manager decomposes, dispatches self-contained briefs, and synthesizes what workers report back. The manager under-specifies a brief; the worker lacks a constraint the manager knew (see §3). Manager tokens + N worker contexts. Cache the shared prefix or pay for it N times.
Sequential pipeline
A → B → C
Stages are genuinely dependent and each boundary is verifiable (Lab 1's decomposition rule). Unverified output compounds down the chain; errors localize nowhere. Sum of stages, serial. No parallel saving; latency adds up.
Parallel fan-out / fan-in
split, then merge
Independent subtasks run concurrently, then one call synthesizes. Two workers write the same resource; conflicting or lost writes. Wall-clock latency of the slowest branch, but N× tokens at once.
Hierarchical
subagents of subagents
Almost never on this exam. Genuine multi-level decomposition of a very large problem. Infinite or runaway delegation; cost blowup no one budgeted. Highest and hardest to predict. Depth multiplies every cost above.
Orchestrator–worker is the answer far more often than hierarchical. When a scenario needs delegation, one manager over a flat set of workers is almost always sufficient. Subagents-of-subagents earns its keep only when a single worker's subtask is itself large enough to decompose, and if you cannot point to that, the depth is architecture theatre. Prefer the flattest topology that expresses the work.

3. Context Isolation Is the Killer Feature

The strongest architectural reason to use a subagent is not speed. It is that a subagent can read forty files and return a two-hundred-token finding, and the parent never carries the forty files. The parent's context window stays clean; it holds the finding, not the evidence.

This is why isolation beats parallelism as a justification. Parallelism saves wall-clock time. Isolation changes what is possible: it lets a bounded parent reason over a corpus far larger than its own context window, one distilled finding at a time. A single agent that tried to read those forty files itself would blow its window and degrade long before it reached a conclusion.

Explicit context passing — the #1 multi-agent bug

Here is the failure that every orchestrator–worker design must design against: a subagent does not inherit the parent's conversation. It starts with an empty context. Everything it needs (the constraint, the schema, the definition of done, the thing the parent learned three turns ago) must be written into the delegation prompt. The most common multi-agent bug is a subagent that produces a confident, well-formed answer while missing the one constraint the parent knew and forgot to pass.

So the delegation brief is not a convenience; it is the interface contract. Make it self-contained on purpose.

python
import anthropic

client = anthropic.Anthropic()

def delegate(subtask: str, *, corpus: str, constraints: list[str],
             output_contract: str) -> str:
    """Dispatch a self-contained brief to a worker.

    The worker inherits NOTHING from the manager's conversation. Every
    constraint the manager knows must be written into this prompt, or the
    worker will confidently answer the wrong question.
    """
    brief = (
        f"TASK: {subtask}\n\n"
        f"CONSTRAINTS (all must hold):\n"
        + "\n".join(f"- {c}" for c in constraints)
        + f"\n\nRETURN EXACTLY: {output_contract}\n"
        "Return only the finding. Do not echo the corpus back."
    )

    response = client.messages.create(
        model="claude-haiku-4-5",          # a worker; cheaper than the manager
        max_tokens=1024,
        thinking={"type": "adaptive"},
        output_config={"effort": "low"},   # scoped subtask, terse output
        system=[
            # The 40-file corpus lives ONLY in the worker's context, never
            # the manager's. This is the isolation the split exists to buy.
            {"type": "text", "text": corpus,
             "cache_control": {"type": "ephemeral"}},
        ],
        messages=[{"role": "user", "content": brief}],
    )
    return next(b.text for b in response.content if b.type == "text")

Three things are load-bearing in that call. The corpus sits in the worker's system block, so it never enters the manager's window; that is the isolation. The brief names the constraints explicitly, because the worker cannot see the conversation that established them. And the worker runs a cheaper model at effort: "low", because a scoped subtask with a clear contract does not need the manager's horsepower (Lab 3 covers routing by difficulty).

"The subagent had all the information" is almost never true after the fact. When a multi-agent system produces a subtly wrong result, look first at the delegation prompt, not the worker's reasoning. The worker reasoned correctly over the context it was given; the context was incomplete. Treat every brief as if the worker has amnesia, because it does.

4. Managing Context Across a Long-Running Agent

Even a single long-running agent has a multi-agent problem in miniature: its context window fills with old tool results it no longer needs. Two server-side mechanisms manage this, and the exam wants you to know they are different tools for different jobs.

Context editingCompaction
Edit typeclear_tool_uses_20250919compact_20260112
Beta headercontext-management-2025-06-27compact-2026-01-12
What it doesDeletes old tool results outrightSummarizes earlier history into a compaction block
CostCheap — nothing is regeneratedA summarization pass runs server-side
What it losesSpecifics. Cleared results are gone; the gist is not preservedLittle. The gist survives; exact details may blur
Reach for it whenOld tool outputs are irrelevant and you want the transcript leanThe conversation itself is long and you must preserve its meaning

Both are configured through context_management.edits on the beta Messages endpoint. There is one rule that catches everyone, and it is a favourite item: when a compaction or context-management response comes back, you append the full response.content to your message history, not just the text block. The compaction block is part of that content, and the API uses it to replace the compacted history on the next turn. Extract only the text and you silently discard the compaction state; the next request re-sends the full uncompacted history and the feature does nothing.

python
import anthropic

client = anthropic.Anthropic()
messages: list[dict] = []

def turn(user_text: str) -> str:
    messages.append({"role": "user", "content": user_text})

    response = client.beta.messages.create(
        model="claude-opus-4-8",
        max_tokens=4096,
        betas=["compact-2026-01-12"],
        context_management={"edits": [{"type": "compact_20260112"}]},
        messages=messages,
    )

    # CRITICAL: append the FULL response.content, not just the text.
    # The compaction block lives in .content and carries the state the API
    # needs to replace compacted history next turn. Appending only the text
    # string silently discards it and the compaction never takes effect.
    messages.append({"role": "assistant", "content": response.content})

    return next(b.text for b in response.content if b.type == "text")

To clear stale tool results instead of summarizing, swap the edit and the beta:

python
response = client.beta.messages.create(
    model="claude-opus-4-8",
    max_tokens=4096,
    betas=["context-management-2025-06-27"],
    context_management={
        "edits": [{"type": "clear_tool_uses_20250919"}]
    },
    tools=tools,
    messages=messages,
)
# Context editing deletes old tool results. It is cheap and lossy about
# specifics. Use it when those results no longer matter; reach for
# compaction (above) when the conversation's meaning must survive.
Editing prunes; compaction summarizes. The distractor on this item is to describe context editing as if it kept a summary, or compaction as if it deleted content. It is the reverse: clear_tool_uses_20250919 removes and remembers nothing about what it removed, while compact_20260112 keeps the gist and blurs the detail. Many long-running agents use both: edit stale tool results, compact when the window nears its limit.

5. Coordination Failure Modes

Multi-agent systems fail in a small, recognizable set of ways. The exam describes the symptom and asks you to name the cause, and, usually, the fix.

FailureWhat it looks likeFix
Duplicated workTwo workers independently do the same subtask; you pay twice for one answer.Partition the work explicitly in the briefs. Non-overlapping scopes, not overlapping hopes.
Conflicting writesTwo agents edit the same resource; one clobbers the other, or the merge is incoherent.Single-writer per resource, or a synthesize step that owns all writes.
Lost constraintA worker returns a clean answer that violates something the manager knew (see §3).Self-contained delegation briefs. Everything the worker needs, in the prompt.
Infinite delegationManagers spawn workers that spawn managers; the loop never terminates.A hard depth or delegation cap, and a topology flat enough not to need one.
Cost blowupN agents each reload the same corpus; token spend scales with N, not with the work.Cache the shared prefix (order toolssystemmessages) so every worker reads it at ≈0.1×.

The last row is where cost architecture meets orchestration. When a fan-out shares a large corpus, put that corpus at the start of a stable prefix with a cache breakpoint. The first worker pays the write (1.25× for the 5-minute TTL); the rest read it at roughly a tenth of input price. Reorder or mutate that prefix per worker and you invalidate the cache for all of them, the same prefix-match discipline as Lab 3, applied across agents instead of across turns.

6. Decomposition Seams

Lab 1 established the rule: decompose along the seams where verification is possible: verifiability, trust, cost, context, and latency. Multi-agent is where two of those seams become physical.

SeamHow multi-agent expresses itTopology
ContextA subagent reads a large or untrusted corpus and returns a small finding; the parent never carries it.Orchestrator–worker (isolation)
LatencyIndependent subtasks run at once, then one call synthesizes the results.Parallel fan-out / fan-in
TrustUntrusted input is summarized in an isolated call that never touches the privileged tool-calling turn.Orchestrator–worker (isolation)
Verifiability / CostUsually a workflow, not a second agent. Split only if the boundary is checkable and worth a coordination cost.Sequential pipeline

The two seams that justify a second reasoning loop are context and latency, the same two halves of the bar from §1. Verifiability and cost seams are more often served by a workflow around a single agent than by multiple agents. If you cannot name the context seam or the latency seam a split sits on, you are looking at a diagram, not a decomposition.

Trust is the context seam wearing a security hat. When a scenario mentions scraped pages, user-supplied documents, or any untrusted content reaching a tool-calling agent, the fix is an isolated call: summarize the untrusted content in a subagent whose output cannot carry an injected instruction into the privileged turn. That is context isolation used defensively, and it is the correct answer even when parallelism is nowhere in the scenario.

7. Design Exercise

Self-driven lab Lab2_Self_Driven_Lab.ipynb

Objective: decide single-agent versus orchestrator–worker for a concrete system, and (if you split) write the delegation brief. About 45 minutes. This is the decision the exam tests; the brief is where most designs quietly fail.

Scenario. A litigation team runs discovery over 200,000 documents: emails, contracts, scanned PDFs. For a given matter they need every document responsive to a set of legal criteria, each flagged with the criterion it matches and a one-line justification a paralegal can verify. A privileged document that is accidentally produced is a serious, sometimes sanctionable, event. Turnaround is measured in hours, not seconds. The corpus does not fit in a single context window.

  1. Run the §1 bar first. Is this parallelizable? Is there a context-isolation reason? Write one sentence for each half before you choose anything. Do not proceed until you can say why a single agent cannot hold this, and "200,000 documents exceed one context window" is a real answer, not a hand-wave.
  2. Reject the naive single agent explicitly. Say the sentence: "One agent cannot do this because ___." If your reason is only "it would be slow," you have not found the isolation seam; look again.
  3. Choose the topology and justify it against the alternatives. Orchestrator–worker (a manager fans out document batches to workers, each worker returns responsive hits) versus a flat parallel fan-out. Which failure mode from §5 are you most exposed to, and how does your topology contain it?
  4. Write the worker's delegation brief. A worker sees one batch and nothing else. Enumerate exactly what must be in that prompt: the legal criteria, the definition of "responsive," the output contract (document ID, matched criterion, justification), and, critically, the privilege rule. What happens if the privilege constraint is the one the manager forgets to pass?
  5. Handle the privileged-document blast radius. A model flag is not a privilege determination. Where is the human gate, and does it sit on every produced document or only the ambiguous ones? Tie this back to Lab 1's egress plane.
  6. Defend the cost. 200,000 documents across N workers. What is the shared prefix (the criteria, the instructions), where does the cache breakpoint go, and roughly what does caching save versus each worker reloading the criteria cold? State the number you would put in front of the partner who signs the discovery bill.

Step 4 is the one the exam tests. Step 5 is the one that keeps the firm out of a sanctions hearing.

Check Yourself

Exam-style items. Commit to an answer before expanding.

A team proposes a five-agent system to answer support questions: one agent per knowledge-base section, each searching its section, with a coordinator merging the results. The five sections are small enough that all five fit comfortably in a single context window, and every question is answered from exactly one section. What is the strongest objection?
  • A. The coordinator should use a larger model than the workers.
  • B. Neither justification for multi-agent holds; the sections fit in one window (no isolation need) and the work is not parallel (one section answers each question), so a single agent is correct.
  • C. Five agents is too few; each section should be split further for accuracy.
  • D. The coordinator introduces a single point of failure that the design should remove.

Correct: B. Multi-agent needs parallelism or context isolation. Here the whole corpus fits in one window, so there is no isolation to buy, and each question touches one section, so there is nothing to parallelize. The five agents add coordination overhead, token duplication, and a fractured audit trail to a problem a single augmented-LLM call solves.

A optimizes a system that should not exist. C moves in exactly the wrong direction: more agents, more cost, no new justification. D names a real property of orchestrator–worker but not the load-bearing objection: the coordinator is not the problem, the entire multi-agent framing is. The discriminating facts are the two the scenario spends its words on: sections fit in one window, one section per question.

An orchestrator dispatches a worker to draft a customer refund email. The worker returns a fluent, correct-looking draft that offers a full refund, but company policy caps automated refunds at $50, a rule the orchestrator knew and applied when it decided to delegate. Which coordination failure is this, and what is the fix?
  • A. Conflicting writes — two agents edited the same draft; use a single writer.
  • B. Lost constraint — the worker never received the $50 cap; make the delegation brief self-contained.
  • C. Cost blowup — the worker reloaded the policy corpus; cache the shared prefix.
  • D. Infinite delegation — the worker spawned further agents; add a depth cap.

Correct: B. This is the #1 multi-agent bug. The worker does not inherit the orchestrator's conversation; it starts empty. The $50 cap lived in the manager's context and was never written into the brief, so the worker reasoned correctly over incomplete information and produced a confident, wrong answer. The fix is a self-contained brief that carries every constraint the manager knows.

A describes a write conflict that the scenario contains no evidence of; there is one draft, one writer. C is about token cost, not correctness; the draft is wrong, not expensive. D invents a delegation depth the scenario never mentions. The tell is always "a constraint the manager knew" reaching a worker that could not have known it.

A long-running research agent's context window is filling with the raw text of dozens of web pages it fetched earlier and no longer needs, but the conversation's overall direction must be preserved. Which two mechanisms are appropriate, and which single choice best fits? (Choose two.)
  • A. Context editing with clear_tool_uses_20250919 to delete the stale fetched-page tool results.
  • B. Prefill the assistant turn with a summary of what was read so far.
  • C. Compaction with compact_20260112 to summarize earlier history while preserving its gist.
  • D. Lower output_config.effort so the agent generates fewer tokens per turn.
  • E. Set thinking={"type":"enabled","budget_tokens":8000} to bound reasoning growth.

Correct: A and C. Context editing deletes the stale tool results cheaply, exactly right for the raw page text the agent no longer needs. Compaction summarizes earlier history while keeping the gist, which is what "the direction must be preserved" demands. Used together they trim the dead weight and protect the meaning, the common pairing for long-running agents.

B is a trap on two counts: prefilling the assistant turn is rejected (returns 400) on current models, and a prefill would not reclaim window space anyway. D reduces new output but does nothing about the pages already sitting in context. E is deprecated: budget_tokens returns 400 on current models; the current control is thinking={"type":"adaptive"} with output_config.effort, and it governs new reasoning, not accumulated tool results.

An architect enables server-side compaction on a long conversation. On each turn they extract the assistant's text block and append only that string to messages. Compaction appears to have no effect; requests keep growing and cost does not drop. What is the most likely cause?
  • A. Compaction requires a separate endpoint that the code is not calling.
  • B. Only the text was appended; the compaction block in response.content was discarded, so the API re-sends full history each turn.
  • C. Compaction only triggers above 1M tokens, which this conversation never reaches.
  • D. The beta header compact-2026-01-12 is incompatible with claude-opus-4-8.

Correct: B. The compaction state lives in a block inside response.content, not in the text. You must append the full response.content back to messages so the API can replace the compacted history on the next turn. Appending only the extracted text string silently drops the compaction block, and every subsequent request re-sends the entire uncompacted history, exactly the "no effect, cost keeps growing" symptom described.

A is false; compaction runs through the normal beta Messages endpoint via context_management.edits, no separate call. C misstates the trigger; compaction summarizes as context grows large, well before any 1M ceiling, and the threshold is configurable. D is wrong; claude-opus-4-8 supports compaction under that beta. The discriminating detail is "extract the text block and append only that," which is precisely the mistake.

Key Takeaways

  • The default is one agent. A second reasoning loop needs genuine parallelism or context isolation, and isolation is the stronger justification.
  • Multi-agent's costs are real and paid every run: coordination overhead, token duplication, and an audit trail no one can reconstruct.
  • Pick the flattest topology that expresses the work. Orchestrator–worker beats hierarchical almost every time; know each topology's signature failure mode.
  • Context isolation lets a subagent read forty files and return a 200-token finding the parent never carries, the single strongest reason to use subagents.
  • A subagent inherits nothing. Every constraint the parent knows must be in the delegation brief; the lost-constraint bug is the #1 multi-agent failure.
  • Context editing prunes, compaction summarizes. clear_tool_uses_20250919 deletes stale tool results cheaply; compact_20260112 preserves the gist. When either returns, append the full response.content, not just the text.
  • Coordination fails in five named ways: duplicated work, conflicting writes, lost constraint, infinite delegation, cost blowup. Fix the cost blowup by caching the shared prefix so N workers read it at ≈0.1×.
  • Multi-agent is the context seam plus the latency seam. If a split sits on neither, it is a diagram, not a decomposition.