[{"data":1,"prerenderedAt":3674},["ShallowReactive",2],{"navigation":3,"page-\u002Fchapters\u002Fsub-agents":102,"surround-\u002Fchapters\u002Fsub-agents":3669},[4,8],{"title":5,"path":6,"stem":7},"Home","\u002F","index",{"title":9,"path":10,"stem":11,"children":12,"page":101},"Chapters","\u002Fchapters","2.chapters",[13,17,21,25,29,33,37,41,45,49,53,57,61,65,69,73,77,81,85,89,93,97],{"title":14,"path":15,"stem":16},"Chapter 1. What an Agent Actually Is","\u002Fchapters\u002Fwhat-an-agent-actually-is","2.chapters\u002F01.what-an-agent-actually-is",{"title":18,"path":19,"stem":20},"Chapter 2. The Minimum Viable Loop","\u002Fchapters\u002Fminimum-viable-loop","2.chapters\u002F02.minimum-viable-loop",{"title":22,"path":23,"stem":24},"Chapter 3. Messages, Turns, and the Transcript","\u002Fchapters\u002Fmessages-turns-transcript","2.chapters\u002F03.messages-turns-transcript",{"title":26,"path":27,"stem":28},"Chapter 4. The Tool Protocol","\u002Fchapters\u002Ftool-protocol","2.chapters\u002F04.tool-protocol",{"title":30,"path":31,"stem":32},"Chapter 5. Streaming, Interruption, and Error Handling","\u002Fchapters\u002Fstreaming-interruption-errors","2.chapters\u002F05.streaming-interruption-errors",{"title":34,"path":35,"stem":36},"Chapter 6. Safe Tool Execution","\u002Fchapters\u002Fsafe-tool-execution","2.chapters\u002F06.safe-tool-execution",{"title":38,"path":39,"stem":40},"Chapter 7. The Context Window Is a Resource","\u002Fchapters\u002Fcontext-window-as-resource","2.chapters\u002F07.context-window-as-resource",{"title":42,"path":43,"stem":44},"Chapter 8. Compaction","\u002Fchapters\u002Fcompaction","2.chapters\u002F08.compaction",{"title":46,"path":47,"stem":48},"Chapter 9. External State: The Scratchpad","\u002Fchapters\u002Fscratchpad","2.chapters\u002F09.scratchpad",{"title":50,"path":51,"stem":52},"Chapter 10. Retrieval","\u002Fchapters\u002Fretrieval","2.chapters\u002F10.retrieval",{"title":54,"path":55,"stem":56},"Chapter 11. Designing Tools Models Can Actually Use","\u002Fchapters\u002Fdesigning-tools","2.chapters\u002F11.designing-tools",{"title":58,"path":59,"stem":60},"Chapter 12. The Tool Cliff and Dynamic Loading","\u002Fchapters\u002Ftool-cliff","2.chapters\u002F12.tool-cliff",{"title":62,"path":63,"stem":64},"Chapter 13. MCP: Tools From the Outside World","\u002Fchapters\u002Fmcp","2.chapters\u002F13.mcp",{"title":66,"path":67,"stem":68},"Chapter 14. Sandboxing and Permissions","\u002Fchapters\u002Fsandboxing-permissions","2.chapters\u002F14.sandboxing-permissions",{"title":70,"path":71,"stem":72},"Chapter 15. Sub-agents","\u002Fchapters\u002Fsub-agents","2.chapters\u002F15.sub-agents",{"title":74,"path":75,"stem":76},"Chapter 16. Structured Plans and Verified Completion","\u002Fchapters\u002Fplans-verified-completion","2.chapters\u002F16.plans-verified-completion",{"title":78,"path":79,"stem":80},"Chapter 17. Parallelism and Shared State","\u002Fchapters\u002Fparallelism-shared-state","2.chapters\u002F17.parallelism-shared-state",{"title":82,"path":83,"stem":84},"Chapter 18. Observability","\u002Fchapters\u002Fobservability","2.chapters\u002F18.observability",{"title":86,"path":87,"stem":88},"Chapter 19. Evals","\u002Fchapters\u002Fevals","2.chapters\u002F19.evals",{"title":90,"path":91,"stem":92},"Chapter 20. Cost Control","\u002Fchapters\u002Fcost-control","2.chapters\u002F20.cost-control",{"title":94,"path":95,"stem":96},"Chapter 21. Resumability and Durable State","\u002Fchapters\u002Fresumability","2.chapters\u002F21.resumability",{"title":98,"path":99,"stem":100},"Chapter 22. What Transfers, Where to Go","\u002Fchapters\u002Fwhat-transfers","2.chapters\u002F22.what-transfers",false,{"id":103,"title":70,"body":104,"description":117,"extension":3664,"meta":3665,"navigation":3666,"path":71,"seo":3667,"stem":72,"__hash__":3668},"content\u002F2.chapters\u002F15.sub-agents.md",{"type":105,"value":106,"toc":3654},"minimark",[107,111,118,135,142,145,172,256,259,264,267,603,614,617,619,623,1890,1893,1907,1937,1943,1977,1998,2106,2137,2139,2143,2169,2795,2798,2811,2819,2835,2837,2841,3377,3384,3391,3411,3413,3417,3428,3431,3443,3446,3448,3452,3459,3466,3549,3555,3557,3561,3608,3612,3639,3641,3650],[108,109,70],"h1",{"id":110},"chapter-15-sub-agents",[112,113,114],"p",{},[115,116,117],"em",{},"Previously: permissions, trust labels, sandbox interfaces. One well-governed agent can do a lot. Some tasks, though, decompose better into parallel or specialized work — and that's the case for sub-agents.",[112,119,120,121,128,129,134],{},"Two countervailing results bound the design space. Anthropic's June 2025 ",[122,123,127],"a",{"href":124,"rel":125},"https:\u002F\u002Fwww.anthropic.com\u002Fengineering\u002Fmulti-agent-research-system",[126],"nofollow","\"How We Built Our Multi-Agent Research System\""," reported that a multi-agent setup (Opus 4 orchestrator + Sonnet 4 sub-agents) outperformed single-agent baselines by over 90%, with the gain correlating strongly with token usage and the ability to distribute reasoning across independent context windows. On the other side, Towards Data Science's 2025 ",[122,130,133],{"href":131,"rel":132},"https:\u002F\u002Ftowardsdatascience.com\u002Fthe-multi-agent-trap\u002F",[126],"\"The Multi-Agent Trap\""," — focused on systems with low per-step accuracy — showed that naive multi-agent decomposition compounds error rates: three 85% agents in series give you about 61% end-to-end. Cemri et al.'s 2025 MAST study (cited in Chapter 1 for the \"why harnesses are hard\" discussion) backed that second finding empirically at scale, tracing 36.9% of observed multi-agent failures to coordination breakdowns rather than individual-agent errors. The research arc around formal multi-agent frameworks — Hong et al.'s 2024 ICLR paper \"MetaGPT: Meta Programming for a Multi-Agent Collaborative Framework\" is the most-cited — shows that both outcomes are reachable from the same primitive; the design choices determine which.",[112,136,137,138,141],{},"All of this is reconcilable once you name the determining factor: ",[115,139,140],{},"what the sub-agent decomposition is for",". Parallel research over independent sub-questions is a big win from multi-agent, because each sub-agent's context stays narrowly focused. A multi-step chain where agent B consumes agent A's output is a loss, because errors accumulate. Rewrite that chain as a single agent with structured state, and it works better.",[112,143,144],{},"This chapter builds the sub-agent primitive and the guardrails that keep it from becoming a trap. Three specific constraints, consciously chosen:",[146,147,148,156,162],"ol",{},[149,150,151,155],"li",{},[152,153,154],"strong",{},"One level deep."," Sub-agents cannot spawn sub-agents. Same choice as Claude Code, same reasoning — nested delegation compounds failure rates fast.",[149,157,158,161],{},[152,159,160],{},"Bounded spawning."," A per-session budget caps how many sub-agents can run, and every spawn carries a justification string for audit.",[149,163,164,167,168,171],{},[152,165,166],{},"Compact results."," Sub-agents return structured summaries, not full transcripts. The parent's context inflates by what the sub-agent ",[115,169,170],{},"concluded",", not by the full trace.",[173,174,178,179,178,249],"figure",{"className":175},[176,177],"not-prose","my-8","\n  ",[180,181,187,188,187,214,187,227,178],"div",{"className":182,"style":186},[183,184,185],"grid","gap-4","items-center","grid-template-columns: 1fr auto 1fr;","\n    ",[180,189,197,198,197,207,187],{"className":190},[191,192,193,194,195,196],"border-2","border-primary","rounded-lg","py-4","px-4","text-center","\n      ",[180,199,206],{"className":200},[201,202,203,204,205],"text-xs","uppercase","tracking-wide","text-muted","mb-2","Parent context",[180,208,213],{"className":209},[210,211,212],"text-sm","font-semibold","text-primary","plan · synth · summaries",[180,215,197,221,197,224,187],{"className":216},[217,218,219,201,220,204],"flex","flex-col","gap-2","font-mono",[180,222,223],{},"spec →",[180,225,226],{},"← summary",[180,228,197,230,197,241,197,245,187],{"className":229},[217,218,219],[180,231,240],{"className":232,"style":239},[233,234,235,236,237,201,238,196],"border","border-default","rounded-md","py-2","px-3","text-default","background:color-mix(in oklab, currentColor 10%, transparent);","sub-agent A · fresh ctx",[180,242,244],{"className":243,"style":239},[233,234,235,236,237,201,238,196],"sub-agent B · fresh ctx",[180,246,248],{"className":247,"style":239},[233,234,235,236,237,201,238,196],"sub-agent C · fresh ctx",[250,251,255],"figcaption",{"className":252},[201,204,253,196,254],"mt-3","italic","Parent sees compact summaries, never the full child transcripts.",[257,258],"hr",{},[260,261,263],"h2",{"id":262},"_151-the-sub-agent-contract","15.1 The Sub-agent Contract",[112,265,266],{},"A sub-agent is itself an agent — same loop, same tools, same harness. What distinguishes it is how the parent invokes it and what comes back:",[268,269,274],"pre",{"className":270,"code":271,"language":272,"meta":273,"style":273},"language-python shiki shiki-themes material-theme-lighter github-light github-dark","# src\u002Fharness\u002Fsubagents\u002Fsubagent.py\nfrom __future__ import annotations\n\nfrom dataclasses import dataclass, field\n\n\n@dataclass(frozen=True)\nclass SubagentSpec:\n    \"\"\"What a sub-agent is told to do.\"\"\"\n    objective: str               # the specific task, operationally specific\n    output_format: str           # how the result should be structured\n    tools_allowed: list[str]     # tool names available to the sub-agent\n    max_iterations: int = 20\n    max_tokens: int = 50_000     # hard context budget\n    system_override: str | None = None  # override parent's system prompt\n\n\n@dataclass\nclass SubagentResult:\n    \"\"\"What a sub-agent returns to its parent.\"\"\"\n    summary: str                 # the synthesized answer\n    tokens_used: int\n    iterations_used: int\n    error: str | None = None     # non-null if sub-agent failed\n","python","",[275,276,277,286,304,311,332,337,342,371,385,399,415,428,451,469,487,510,515,520,528,538,548,561,572,582],"code",{"__ignoreMap":273},[278,279,282],"span",{"class":280,"line":281},"line",1,[278,283,285],{"class":284},"sutJx","# src\u002Fharness\u002Fsubagents\u002Fsubagent.py\n",[278,287,289,293,297,300],{"class":280,"line":288},2,[278,290,292],{"class":291},"sVHd0","from",[278,294,296],{"class":295},"s_hVV"," __future__",[278,298,299],{"class":291}," import",[278,301,303],{"class":302},"su5hD"," annotations\n",[278,305,307],{"class":280,"line":306},3,[278,308,310],{"emptyLinePlaceholder":309},true,"\n",[278,312,314,316,319,322,325,329],{"class":280,"line":313},4,[278,315,292],{"class":291},[278,317,318],{"class":302}," dataclasses ",[278,320,321],{"class":291},"import",[278,323,324],{"class":302}," dataclass",[278,326,328],{"class":327},"sP7_E",",",[278,330,331],{"class":302}," field\n",[278,333,335],{"class":280,"line":334},5,[278,336,310],{"emptyLinePlaceholder":309},[278,338,340],{"class":280,"line":339},6,[278,341,310],{"emptyLinePlaceholder":309},[278,343,345,349,353,356,360,364,368],{"class":280,"line":344},7,[278,346,348],{"class":347},"stp6e","@",[278,350,352],{"class":351},"sGLFI","dataclass",[278,354,355],{"class":327},"(",[278,357,359],{"class":358},"s99_P","frozen",[278,361,363],{"class":362},"smGrS","=",[278,365,367],{"class":366},"s39Yj","True",[278,369,370],{"class":327},")\n",[278,372,374,378,382],{"class":280,"line":373},8,[278,375,377],{"class":376},"sbsja","class",[278,379,381],{"class":380},"sbgvK"," SubagentSpec",[278,383,384],{"class":327},":\n",[278,386,388,392,396],{"class":280,"line":387},9,[278,389,391],{"class":390},"s2W-s","    \"\"\"",[278,393,395],{"class":394},"sithA","What a sub-agent is told to do.",[278,397,398],{"class":390},"\"\"\"\n",[278,400,402,405,408,412],{"class":280,"line":401},10,[278,403,404],{"class":302},"    objective",[278,406,407],{"class":327},":",[278,409,411],{"class":410},"sZMiF"," str",[278,413,414],{"class":284},"               # the specific task, operationally specific\n",[278,416,418,421,423,425],{"class":280,"line":417},11,[278,419,420],{"class":302},"    output_format",[278,422,407],{"class":327},[278,424,411],{"class":410},[278,426,427],{"class":284},"           # how the result should be structured\n",[278,429,431,434,436,439,442,445,448],{"class":280,"line":430},12,[278,432,433],{"class":302},"    tools_allowed",[278,435,407],{"class":327},[278,437,438],{"class":302}," list",[278,440,441],{"class":327},"[",[278,443,444],{"class":410},"str",[278,446,447],{"class":327},"]",[278,449,450],{"class":284},"     # tool names available to the sub-agent\n",[278,452,454,457,459,462,465],{"class":280,"line":453},13,[278,455,456],{"class":302},"    max_iterations",[278,458,407],{"class":327},[278,460,461],{"class":410}," int",[278,463,464],{"class":362}," =",[278,466,468],{"class":467},"srdBf"," 20\n",[278,470,472,475,477,479,481,484],{"class":280,"line":471},14,[278,473,474],{"class":302},"    max_tokens",[278,476,407],{"class":327},[278,478,461],{"class":410},[278,480,464],{"class":362},[278,482,483],{"class":467}," 50_000",[278,485,486],{"class":284},"     # hard context budget\n",[278,488,490,493,495,497,500,503,505,507],{"class":280,"line":489},15,[278,491,492],{"class":302},"    system_override",[278,494,407],{"class":327},[278,496,411],{"class":410},[278,498,499],{"class":362}," |",[278,501,502],{"class":366}," None",[278,504,464],{"class":362},[278,506,502],{"class":366},[278,508,509],{"class":284},"  # override parent's system prompt\n",[278,511,513],{"class":280,"line":512},16,[278,514,310],{"emptyLinePlaceholder":309},[278,516,518],{"class":280,"line":517},17,[278,519,310],{"emptyLinePlaceholder":309},[278,521,523,525],{"class":280,"line":522},18,[278,524,348],{"class":347},[278,526,527],{"class":351},"dataclass\n",[278,529,531,533,536],{"class":280,"line":530},19,[278,532,377],{"class":376},[278,534,535],{"class":380}," SubagentResult",[278,537,384],{"class":327},[278,539,541,543,546],{"class":280,"line":540},20,[278,542,391],{"class":390},[278,544,545],{"class":394},"What a sub-agent returns to its parent.",[278,547,398],{"class":390},[278,549,551,554,556,558],{"class":280,"line":550},21,[278,552,553],{"class":302},"    summary",[278,555,407],{"class":327},[278,557,411],{"class":410},[278,559,560],{"class":284},"                 # the synthesized answer\n",[278,562,564,567,569],{"class":280,"line":563},22,[278,565,566],{"class":302},"    tokens_used",[278,568,407],{"class":327},[278,570,571],{"class":410}," int\n",[278,573,575,578,580],{"class":280,"line":574},23,[278,576,577],{"class":302},"    iterations_used",[278,579,407],{"class":327},[278,581,571],{"class":410},[278,583,585,588,590,592,594,596,598,600],{"class":280,"line":584},24,[278,586,587],{"class":302},"    error",[278,589,407],{"class":327},[278,591,411],{"class":410},[278,593,499],{"class":362},[278,595,502],{"class":366},[278,597,464],{"class":362},[278,599,502],{"class":366},[278,601,602],{"class":284},"     # non-null if sub-agent failed\n",[112,604,605,606,609,610,613],{},"The key design choice is in ",[275,607,608],{},"SubagentResult",". The sub-agent's full transcript doesn't come back. Only its ",[275,611,612],{},"summary"," does — a final text output that the parent inserts into its own context as one message. A 40-turn sub-agent run returns as ~500 tokens in the parent's context, not 50,000.",[112,615,616],{},"This is the pattern Anthropic's multi-agent research system documents: compact, structured summaries from sub-agents are what make multi-agent work at scale. A parent that received a full transcript from each sub-agent would suffer the context explosion — exactly the O(n×m) problem AutoGen's GroupChat hits.",[257,618],{},[260,620,622],{"id":621},"_152-the-spawner","15.2 The Spawner",[268,624,626],{"className":270,"code":625,"language":272,"meta":273,"style":273},"# src\u002Fharness\u002Fsubagents\u002Fspawner.py\nfrom __future__ import annotations\n\nimport asyncio\nfrom dataclasses import dataclass, field\n\nfrom ..agent import arun\nfrom ..context.accountant import ContextAccountant, ContextBudget\nfrom ..providers.base import Provider\nfrom ..tools.selector import ToolCatalog\nfrom .subagent import SubagentResult, SubagentSpec\n\n\nclass SubagentBudgetExceeded(Exception):\n    pass\n\n\n@dataclass\nclass SubagentSpawner:\n    provider: Provider\n    catalog: ToolCatalog\n    max_subagents_per_session: int = 5\n    _spawn_count: int = field(default=0, init=False)\n\n    async def spawn(\n        self,\n        spec: SubagentSpec,\n        parent_scratchpad_root: str | None = None,\n        justification: str = \"\",\n    ) -> SubagentResult:\n        if self._spawn_count >= self.max_subagents_per_session:\n            raise SubagentBudgetExceeded(\n                f\"spawn budget of {self.max_subagents_per_session} exhausted\"\n            )\n        self._spawn_count += 1\n\n        # restrict the catalog to the tools the sub-agent is allowed\n        allowed = [t for t in self.catalog.tools if t.name in spec.tools_allowed]\n        sub_catalog = ToolCatalog(tools=allowed)\n\n        # constrain context budget\n        budget = ContextBudget(window_size=spec.max_tokens)\n        accountant = ContextAccountant(budget=budget)\n\n        system = spec.system_override or _default_subagent_system(spec)\n\n        try:\n            result = await arun(\n                provider=self.provider,\n                catalog=sub_catalog,\n                user_message=(\n                    f\"Objective: {spec.objective}\\n\\n\"\n                    f\"Return format: {spec.output_format}\"\n                ),\n                system=system,\n                accountant=accountant,\n            )\n            return SubagentResult(\n                summary=result.summary,\n                tokens_used=result.tokens_used,\n                iterations_used=result.iterations_used,\n            )\n        except SubagentBudgetExceeded:\n            raise  # let budget failures propagate to the caller\n        except Exception as e:\n            return SubagentResult(\n                summary=\"\", tokens_used=0, iterations_used=0, error=str(e),\n            )\n\n\ndef _default_subagent_system(spec: SubagentSpec) -> str:\n    header = f\"\"\"\\\nYou are a sub-agent. You have one objective:\n\n{spec.objective}\n\nReturn your answer in this format:\n{spec.output_format}\n\nYou have the following tools available: {spec.tools_allowed}.\nYou have a maximum of {spec.max_iterations} iterations.\nYou have a maximum of {spec.max_tokens} tokens of context.\n\"\"\"\n    # Smaller \u002F weaker models sometimes narrate tool calls in text instead of\n    # actually dispatching them. When the spec allows tools at all, make the\n    # mandatory-execute rule explicit — see the callout below this snippet.\n    mandate = \"\"\n    if spec.tools_allowed:\n        mandate = (\n            \"\\nYou MUST call at least one tool from your allowed list before\\n\"\n            \"producing your final answer. Do not describe what you would do — do it.\\n\"\n            \"Describing a tool call in prose without actually invoking it is a failure.\\n\"\n        )\n    footer = \"\"\"\nWhen you have completed the objective, produce your final answer in the\nrequested format. Do not continue working after you have the answer.\nIf you cannot complete the objective (missing data, scope unclear), say\nso explicitly — do not fabricate.\n\"\"\"\n    return header + mandate + footer\n",[275,627,628,633,643,647,654,668,672,687,712,731,750,769,773,777,792,797,801,805,811,820,829,838,852,889,893,908,918,931,951,969,982,1009,1019,1045,1051,1066,1071,1077,1136,1158,1163,1169,1197,1218,1223,1250,1255,1263,1279,1296,1309,1319,1345,1366,1372,1385,1398,1403,1413,1430,1447,1464,1469,1479,1487,1503,1512,1557,1562,1567,1572,1597,1614,1620,1625,1639,1644,1650,1663,1668,1687,1707,1725,1730,1736,1742,1748,1759,1773,1784,1800,1812,1824,1830,1841,1847,1853,1859,1865,1870],{"__ignoreMap":273},[278,629,630],{"class":280,"line":281},[278,631,632],{"class":284},"# src\u002Fharness\u002Fsubagents\u002Fspawner.py\n",[278,634,635,637,639,641],{"class":280,"line":288},[278,636,292],{"class":291},[278,638,296],{"class":295},[278,640,299],{"class":291},[278,642,303],{"class":302},[278,644,645],{"class":280,"line":306},[278,646,310],{"emptyLinePlaceholder":309},[278,648,649,651],{"class":280,"line":313},[278,650,321],{"class":291},[278,652,653],{"class":302}," asyncio\n",[278,655,656,658,660,662,664,666],{"class":280,"line":334},[278,657,292],{"class":291},[278,659,318],{"class":302},[278,661,321],{"class":291},[278,663,324],{"class":302},[278,665,328],{"class":327},[278,667,331],{"class":302},[278,669,670],{"class":280,"line":339},[278,671,310],{"emptyLinePlaceholder":309},[278,673,674,676,679,682,684],{"class":280,"line":344},[278,675,292],{"class":291},[278,677,678],{"class":327}," ..",[278,680,681],{"class":302},"agent ",[278,683,321],{"class":291},[278,685,686],{"class":302}," arun\n",[278,688,689,691,693,696,699,702,704,707,709],{"class":280,"line":373},[278,690,292],{"class":291},[278,692,678],{"class":327},[278,694,695],{"class":302},"context",[278,697,698],{"class":327},".",[278,700,701],{"class":302},"accountant ",[278,703,321],{"class":291},[278,705,706],{"class":302}," ContextAccountant",[278,708,328],{"class":327},[278,710,711],{"class":302}," ContextBudget\n",[278,713,714,716,718,721,723,726,728],{"class":280,"line":387},[278,715,292],{"class":291},[278,717,678],{"class":327},[278,719,720],{"class":302},"providers",[278,722,698],{"class":327},[278,724,725],{"class":302},"base ",[278,727,321],{"class":291},[278,729,730],{"class":302}," Provider\n",[278,732,733,735,737,740,742,745,747],{"class":280,"line":401},[278,734,292],{"class":291},[278,736,678],{"class":327},[278,738,739],{"class":302},"tools",[278,741,698],{"class":327},[278,743,744],{"class":302},"selector ",[278,746,321],{"class":291},[278,748,749],{"class":302}," ToolCatalog\n",[278,751,752,754,757,760,762,764,766],{"class":280,"line":417},[278,753,292],{"class":291},[278,755,756],{"class":327}," .",[278,758,759],{"class":302},"subagent ",[278,761,321],{"class":291},[278,763,535],{"class":302},[278,765,328],{"class":327},[278,767,768],{"class":302}," SubagentSpec\n",[278,770,771],{"class":280,"line":430},[278,772,310],{"emptyLinePlaceholder":309},[278,774,775],{"class":280,"line":453},[278,776,310],{"emptyLinePlaceholder":309},[278,778,779,781,784,786,789],{"class":280,"line":471},[278,780,377],{"class":376},[278,782,783],{"class":380}," SubagentBudgetExceeded",[278,785,355],{"class":327},[278,787,788],{"class":410},"Exception",[278,790,791],{"class":327},"):\n",[278,793,794],{"class":280,"line":489},[278,795,796],{"class":291},"    pass\n",[278,798,799],{"class":280,"line":512},[278,800,310],{"emptyLinePlaceholder":309},[278,802,803],{"class":280,"line":517},[278,804,310],{"emptyLinePlaceholder":309},[278,806,807,809],{"class":280,"line":522},[278,808,348],{"class":347},[278,810,527],{"class":351},[278,812,813,815,818],{"class":280,"line":530},[278,814,377],{"class":376},[278,816,817],{"class":380}," SubagentSpawner",[278,819,384],{"class":327},[278,821,822,825,827],{"class":280,"line":540},[278,823,824],{"class":302},"    provider",[278,826,407],{"class":327},[278,828,730],{"class":302},[278,830,831,834,836],{"class":280,"line":550},[278,832,833],{"class":302},"    catalog",[278,835,407],{"class":327},[278,837,749],{"class":302},[278,839,840,843,845,847,849],{"class":280,"line":563},[278,841,842],{"class":302},"    max_subagents_per_session",[278,844,407],{"class":327},[278,846,461],{"class":410},[278,848,464],{"class":362},[278,850,851],{"class":467}," 5\n",[278,853,854,857,859,861,863,867,869,872,874,877,879,882,884,887],{"class":280,"line":574},[278,855,856],{"class":302},"    _spawn_count",[278,858,407],{"class":327},[278,860,461],{"class":410},[278,862,464],{"class":362},[278,864,866],{"class":865},"slqww"," field",[278,868,355],{"class":327},[278,870,871],{"class":358},"default",[278,873,363],{"class":362},[278,875,876],{"class":467},"0",[278,878,328],{"class":327},[278,880,881],{"class":358}," init",[278,883,363],{"class":362},[278,885,886],{"class":366},"False",[278,888,370],{"class":327},[278,890,891],{"class":280,"line":584},[278,892,310],{"emptyLinePlaceholder":309},[278,894,896,899,902,905],{"class":280,"line":895},25,[278,897,898],{"class":376},"    async",[278,900,901],{"class":376}," def",[278,903,904],{"class":351}," spawn",[278,906,907],{"class":327},"(\n",[278,909,911,915],{"class":280,"line":910},26,[278,912,914],{"class":913},"smCYv","        self",[278,916,917],{"class":327},",\n",[278,919,921,925,927,929],{"class":280,"line":920},27,[278,922,924],{"class":923},"sFwrP","        spec",[278,926,407],{"class":327},[278,928,381],{"class":302},[278,930,917],{"class":327},[278,932,934,937,939,941,943,945,947,949],{"class":280,"line":933},28,[278,935,936],{"class":923},"        parent_scratchpad_root",[278,938,407],{"class":327},[278,940,411],{"class":410},[278,942,499],{"class":362},[278,944,502],{"class":366},[278,946,464],{"class":362},[278,948,502],{"class":366},[278,950,917],{"class":327},[278,952,954,957,959,961,963,967],{"class":280,"line":953},29,[278,955,956],{"class":923},"        justification",[278,958,407],{"class":327},[278,960,411],{"class":410},[278,962,464],{"class":362},[278,964,966],{"class":965},"sjJ54"," \"\"",[278,968,917],{"class":327},[278,970,972,975,978,980],{"class":280,"line":971},30,[278,973,974],{"class":327},"    )",[278,976,977],{"class":327}," ->",[278,979,535],{"class":302},[278,981,384],{"class":327},[278,983,985,988,991,993,997,1000,1002,1004,1007],{"class":280,"line":984},31,[278,986,987],{"class":291},"        if",[278,989,990],{"class":295}," self",[278,992,698],{"class":327},[278,994,996],{"class":995},"skxfh","_spawn_count",[278,998,999],{"class":362}," >=",[278,1001,990],{"class":295},[278,1003,698],{"class":327},[278,1005,1006],{"class":995},"max_subagents_per_session",[278,1008,384],{"class":327},[278,1010,1012,1015,1017],{"class":280,"line":1011},32,[278,1013,1014],{"class":291},"            raise",[278,1016,783],{"class":865},[278,1018,907],{"class":327},[278,1020,1022,1025,1029,1032,1035,1037,1039,1042],{"class":280,"line":1021},33,[278,1023,1024],{"class":376},"                f",[278,1026,1028],{"class":1027},"s_sjI","\"spawn budget of ",[278,1030,1031],{"class":467},"{",[278,1033,1034],{"class":295},"self",[278,1036,698],{"class":327},[278,1038,1006],{"class":995},[278,1040,1041],{"class":467},"}",[278,1043,1044],{"class":1027}," exhausted\"\n",[278,1046,1048],{"class":280,"line":1047},34,[278,1049,1050],{"class":327},"            )\n",[278,1052,1054,1056,1058,1060,1063],{"class":280,"line":1053},35,[278,1055,914],{"class":295},[278,1057,698],{"class":327},[278,1059,996],{"class":995},[278,1061,1062],{"class":362}," +=",[278,1064,1065],{"class":467}," 1\n",[278,1067,1069],{"class":280,"line":1068},36,[278,1070,310],{"emptyLinePlaceholder":309},[278,1072,1074],{"class":280,"line":1073},37,[278,1075,1076],{"class":284},"        # restrict the catalog to the tools the sub-agent is allowed\n",[278,1078,1080,1083,1085,1088,1091,1094,1097,1100,1102,1104,1107,1109,1111,1114,1117,1119,1122,1125,1128,1130,1133],{"class":280,"line":1079},38,[278,1081,1082],{"class":302},"        allowed ",[278,1084,363],{"class":362},[278,1086,1087],{"class":327}," [",[278,1089,1090],{"class":302},"t ",[278,1092,1093],{"class":291},"for",[278,1095,1096],{"class":302}," t ",[278,1098,1099],{"class":291},"in",[278,1101,990],{"class":295},[278,1103,698],{"class":327},[278,1105,1106],{"class":995},"catalog",[278,1108,698],{"class":327},[278,1110,739],{"class":995},[278,1112,1113],{"class":291}," if",[278,1115,1116],{"class":302}," t",[278,1118,698],{"class":327},[278,1120,1121],{"class":995},"name",[278,1123,1124],{"class":362}," in",[278,1126,1127],{"class":302}," spec",[278,1129,698],{"class":327},[278,1131,1132],{"class":995},"tools_allowed",[278,1134,1135],{"class":327},"]\n",[278,1137,1139,1142,1144,1147,1149,1151,1153,1156],{"class":280,"line":1138},39,[278,1140,1141],{"class":302},"        sub_catalog ",[278,1143,363],{"class":362},[278,1145,1146],{"class":865}," ToolCatalog",[278,1148,355],{"class":327},[278,1150,739],{"class":358},[278,1152,363],{"class":362},[278,1154,1155],{"class":865},"allowed",[278,1157,370],{"class":327},[278,1159,1161],{"class":280,"line":1160},40,[278,1162,310],{"emptyLinePlaceholder":309},[278,1164,1166],{"class":280,"line":1165},41,[278,1167,1168],{"class":284},"        # constrain context budget\n",[278,1170,1172,1175,1177,1180,1182,1185,1187,1190,1192,1195],{"class":280,"line":1171},42,[278,1173,1174],{"class":302},"        budget ",[278,1176,363],{"class":362},[278,1178,1179],{"class":865}," ContextBudget",[278,1181,355],{"class":327},[278,1183,1184],{"class":358},"window_size",[278,1186,363],{"class":362},[278,1188,1189],{"class":865},"spec",[278,1191,698],{"class":327},[278,1193,1194],{"class":995},"max_tokens",[278,1196,370],{"class":327},[278,1198,1200,1203,1205,1207,1209,1212,1214,1216],{"class":280,"line":1199},43,[278,1201,1202],{"class":302},"        accountant ",[278,1204,363],{"class":362},[278,1206,706],{"class":865},[278,1208,355],{"class":327},[278,1210,1211],{"class":358},"budget",[278,1213,363],{"class":362},[278,1215,1211],{"class":865},[278,1217,370],{"class":327},[278,1219,1221],{"class":280,"line":1220},44,[278,1222,310],{"emptyLinePlaceholder":309},[278,1224,1226,1229,1231,1233,1235,1238,1241,1244,1246,1248],{"class":280,"line":1225},45,[278,1227,1228],{"class":302},"        system ",[278,1230,363],{"class":362},[278,1232,1127],{"class":302},[278,1234,698],{"class":327},[278,1236,1237],{"class":995},"system_override",[278,1239,1240],{"class":362}," or",[278,1242,1243],{"class":865}," _default_subagent_system",[278,1245,355],{"class":327},[278,1247,1189],{"class":865},[278,1249,370],{"class":327},[278,1251,1253],{"class":280,"line":1252},46,[278,1254,310],{"emptyLinePlaceholder":309},[278,1256,1258,1261],{"class":280,"line":1257},47,[278,1259,1260],{"class":291},"        try",[278,1262,384],{"class":327},[278,1264,1266,1269,1271,1274,1277],{"class":280,"line":1265},48,[278,1267,1268],{"class":302},"            result ",[278,1270,363],{"class":362},[278,1272,1273],{"class":291}," await",[278,1275,1276],{"class":865}," arun",[278,1278,907],{"class":327},[278,1280,1282,1285,1287,1289,1291,1294],{"class":280,"line":1281},49,[278,1283,1284],{"class":358},"                provider",[278,1286,363],{"class":362},[278,1288,1034],{"class":295},[278,1290,698],{"class":327},[278,1292,1293],{"class":995},"provider",[278,1295,917],{"class":327},[278,1297,1299,1302,1304,1307],{"class":280,"line":1298},50,[278,1300,1301],{"class":358},"                catalog",[278,1303,363],{"class":362},[278,1305,1306],{"class":865},"sub_catalog",[278,1308,917],{"class":327},[278,1310,1312,1315,1317],{"class":280,"line":1311},51,[278,1313,1314],{"class":358},"                user_message",[278,1316,363],{"class":362},[278,1318,907],{"class":327},[278,1320,1322,1325,1328,1330,1332,1334,1337,1339,1342],{"class":280,"line":1321},52,[278,1323,1324],{"class":376},"                    f",[278,1326,1327],{"class":1027},"\"Objective: ",[278,1329,1031],{"class":467},[278,1331,1189],{"class":865},[278,1333,698],{"class":327},[278,1335,1336],{"class":995},"objective",[278,1338,1041],{"class":467},[278,1340,1341],{"class":295},"\\n\\n",[278,1343,1344],{"class":1027},"\"\n",[278,1346,1348,1350,1353,1355,1357,1359,1362,1364],{"class":280,"line":1347},53,[278,1349,1324],{"class":376},[278,1351,1352],{"class":1027},"\"Return format: ",[278,1354,1031],{"class":467},[278,1356,1189],{"class":865},[278,1358,698],{"class":327},[278,1360,1361],{"class":995},"output_format",[278,1363,1041],{"class":467},[278,1365,1344],{"class":1027},[278,1367,1369],{"class":280,"line":1368},54,[278,1370,1371],{"class":327},"                ),\n",[278,1373,1375,1378,1380,1383],{"class":280,"line":1374},55,[278,1376,1377],{"class":358},"                system",[278,1379,363],{"class":362},[278,1381,1382],{"class":865},"system",[278,1384,917],{"class":327},[278,1386,1388,1391,1393,1396],{"class":280,"line":1387},56,[278,1389,1390],{"class":358},"                accountant",[278,1392,363],{"class":362},[278,1394,1395],{"class":865},"accountant",[278,1397,917],{"class":327},[278,1399,1401],{"class":280,"line":1400},57,[278,1402,1050],{"class":327},[278,1404,1406,1409,1411],{"class":280,"line":1405},58,[278,1407,1408],{"class":291},"            return",[278,1410,535],{"class":865},[278,1412,907],{"class":327},[278,1414,1416,1419,1421,1424,1426,1428],{"class":280,"line":1415},59,[278,1417,1418],{"class":358},"                summary",[278,1420,363],{"class":362},[278,1422,1423],{"class":865},"result",[278,1425,698],{"class":327},[278,1427,612],{"class":995},[278,1429,917],{"class":327},[278,1431,1433,1436,1438,1440,1442,1445],{"class":280,"line":1432},60,[278,1434,1435],{"class":358},"                tokens_used",[278,1437,363],{"class":362},[278,1439,1423],{"class":865},[278,1441,698],{"class":327},[278,1443,1444],{"class":995},"tokens_used",[278,1446,917],{"class":327},[278,1448,1450,1453,1455,1457,1459,1462],{"class":280,"line":1449},61,[278,1451,1452],{"class":358},"                iterations_used",[278,1454,363],{"class":362},[278,1456,1423],{"class":865},[278,1458,698],{"class":327},[278,1460,1461],{"class":995},"iterations_used",[278,1463,917],{"class":327},[278,1465,1467],{"class":280,"line":1466},62,[278,1468,1050],{"class":327},[278,1470,1472,1475,1477],{"class":280,"line":1471},63,[278,1473,1474],{"class":291},"        except",[278,1476,783],{"class":302},[278,1478,384],{"class":327},[278,1480,1482,1484],{"class":280,"line":1481},64,[278,1483,1014],{"class":291},[278,1485,1486],{"class":284},"  # let budget failures propagate to the caller\n",[278,1488,1490,1492,1495,1498,1501],{"class":280,"line":1489},65,[278,1491,1474],{"class":291},[278,1493,1494],{"class":410}," Exception",[278,1496,1497],{"class":291}," as",[278,1499,1500],{"class":302}," e",[278,1502,384],{"class":327},[278,1504,1506,1508,1510],{"class":280,"line":1505},66,[278,1507,1408],{"class":291},[278,1509,535],{"class":865},[278,1511,907],{"class":327},[278,1513,1515,1517,1519,1522,1524,1527,1529,1531,1533,1536,1538,1540,1542,1545,1547,1549,1551,1554],{"class":280,"line":1514},67,[278,1516,1418],{"class":358},[278,1518,363],{"class":362},[278,1520,1521],{"class":965},"\"\"",[278,1523,328],{"class":327},[278,1525,1526],{"class":358}," tokens_used",[278,1528,363],{"class":362},[278,1530,876],{"class":467},[278,1532,328],{"class":327},[278,1534,1535],{"class":358}," iterations_used",[278,1537,363],{"class":362},[278,1539,876],{"class":467},[278,1541,328],{"class":327},[278,1543,1544],{"class":358}," error",[278,1546,363],{"class":362},[278,1548,444],{"class":410},[278,1550,355],{"class":327},[278,1552,1553],{"class":865},"e",[278,1555,1556],{"class":327},"),\n",[278,1558,1560],{"class":280,"line":1559},68,[278,1561,1050],{"class":327},[278,1563,1565],{"class":280,"line":1564},69,[278,1566,310],{"emptyLinePlaceholder":309},[278,1568,1570],{"class":280,"line":1569},70,[278,1571,310],{"emptyLinePlaceholder":309},[278,1573,1575,1578,1580,1582,1584,1586,1588,1591,1593,1595],{"class":280,"line":1574},71,[278,1576,1577],{"class":376},"def",[278,1579,1243],{"class":351},[278,1581,355],{"class":327},[278,1583,1189],{"class":923},[278,1585,407],{"class":327},[278,1587,381],{"class":302},[278,1589,1590],{"class":327},")",[278,1592,977],{"class":327},[278,1594,411],{"class":410},[278,1596,384],{"class":327},[278,1598,1600,1603,1605,1608,1611],{"class":280,"line":1599},72,[278,1601,1602],{"class":302},"    header ",[278,1604,363],{"class":362},[278,1606,1607],{"class":376}," f",[278,1609,1610],{"class":1027},"\"\"\"",[278,1612,1613],{"class":366},"\\\n",[278,1615,1617],{"class":280,"line":1616},73,[278,1618,1619],{"class":1027},"You are a sub-agent. You have one objective:\n",[278,1621,1623],{"class":280,"line":1622},74,[278,1624,310],{"emptyLinePlaceholder":309},[278,1626,1628,1630,1632,1634,1636],{"class":280,"line":1627},75,[278,1629,1031],{"class":467},[278,1631,1189],{"class":302},[278,1633,698],{"class":327},[278,1635,1336],{"class":995},[278,1637,1638],{"class":467},"}\n",[278,1640,1642],{"class":280,"line":1641},76,[278,1643,310],{"emptyLinePlaceholder":309},[278,1645,1647],{"class":280,"line":1646},77,[278,1648,1649],{"class":1027},"Return your answer in this format:\n",[278,1651,1653,1655,1657,1659,1661],{"class":280,"line":1652},78,[278,1654,1031],{"class":467},[278,1656,1189],{"class":302},[278,1658,698],{"class":327},[278,1660,1361],{"class":995},[278,1662,1638],{"class":467},[278,1664,1666],{"class":280,"line":1665},79,[278,1667,310],{"emptyLinePlaceholder":309},[278,1669,1671,1674,1676,1678,1680,1682,1684],{"class":280,"line":1670},80,[278,1672,1673],{"class":1027},"You have the following tools available: ",[278,1675,1031],{"class":467},[278,1677,1189],{"class":302},[278,1679,698],{"class":327},[278,1681,1132],{"class":995},[278,1683,1041],{"class":467},[278,1685,1686],{"class":1027},".\n",[278,1688,1690,1693,1695,1697,1699,1702,1704],{"class":280,"line":1689},81,[278,1691,1692],{"class":1027},"You have a maximum of ",[278,1694,1031],{"class":467},[278,1696,1189],{"class":302},[278,1698,698],{"class":327},[278,1700,1701],{"class":995},"max_iterations",[278,1703,1041],{"class":467},[278,1705,1706],{"class":1027}," iterations.\n",[278,1708,1710,1712,1714,1716,1718,1720,1722],{"class":280,"line":1709},82,[278,1711,1692],{"class":1027},[278,1713,1031],{"class":467},[278,1715,1189],{"class":302},[278,1717,698],{"class":327},[278,1719,1194],{"class":995},[278,1721,1041],{"class":467},[278,1723,1724],{"class":1027}," tokens of context.\n",[278,1726,1728],{"class":280,"line":1727},83,[278,1729,398],{"class":1027},[278,1731,1733],{"class":280,"line":1732},84,[278,1734,1735],{"class":284},"    # Smaller \u002F weaker models sometimes narrate tool calls in text instead of\n",[278,1737,1739],{"class":280,"line":1738},85,[278,1740,1741],{"class":284},"    # actually dispatching them. When the spec allows tools at all, make the\n",[278,1743,1745],{"class":280,"line":1744},86,[278,1746,1747],{"class":284},"    # mandatory-execute rule explicit — see the callout below this snippet.\n",[278,1749,1751,1754,1756],{"class":280,"line":1750},87,[278,1752,1753],{"class":302},"    mandate ",[278,1755,363],{"class":362},[278,1757,1758],{"class":965}," \"\"\n",[278,1760,1762,1765,1767,1769,1771],{"class":280,"line":1761},88,[278,1763,1764],{"class":291},"    if",[278,1766,1127],{"class":302},[278,1768,698],{"class":327},[278,1770,1132],{"class":995},[278,1772,384],{"class":327},[278,1774,1776,1779,1781],{"class":280,"line":1775},89,[278,1777,1778],{"class":302},"        mandate ",[278,1780,363],{"class":362},[278,1782,1783],{"class":327}," (\n",[278,1785,1787,1790,1793,1796,1798],{"class":280,"line":1786},90,[278,1788,1789],{"class":965},"            \"",[278,1791,1792],{"class":295},"\\n",[278,1794,1795],{"class":1027},"You MUST call at least one tool from your allowed list before",[278,1797,1792],{"class":295},[278,1799,1344],{"class":965},[278,1801,1803,1805,1808,1810],{"class":280,"line":1802},91,[278,1804,1789],{"class":965},[278,1806,1807],{"class":1027},"producing your final answer. Do not describe what you would do — do it.",[278,1809,1792],{"class":295},[278,1811,1344],{"class":965},[278,1813,1815,1817,1820,1822],{"class":280,"line":1814},92,[278,1816,1789],{"class":965},[278,1818,1819],{"class":1027},"Describing a tool call in prose without actually invoking it is a failure.",[278,1821,1792],{"class":295},[278,1823,1344],{"class":965},[278,1825,1827],{"class":280,"line":1826},93,[278,1828,1829],{"class":327},"        )\n",[278,1831,1833,1836,1838],{"class":280,"line":1832},94,[278,1834,1835],{"class":302},"    footer ",[278,1837,363],{"class":362},[278,1839,1840],{"class":965}," \"\"\"\n",[278,1842,1844],{"class":280,"line":1843},95,[278,1845,1846],{"class":1027},"When you have completed the objective, produce your final answer in the\n",[278,1848,1850],{"class":280,"line":1849},96,[278,1851,1852],{"class":1027},"requested format. Do not continue working after you have the answer.\n",[278,1854,1856],{"class":280,"line":1855},97,[278,1857,1858],{"class":1027},"If you cannot complete the objective (missing data, scope unclear), say\n",[278,1860,1862],{"class":280,"line":1861},98,[278,1863,1864],{"class":1027},"so explicitly — do not fabricate.\n",[278,1866,1868],{"class":280,"line":1867},99,[278,1869,398],{"class":965},[278,1871,1873,1876,1879,1882,1885,1887],{"class":280,"line":1872},100,[278,1874,1875],{"class":291},"    return",[278,1877,1878],{"class":302}," header ",[278,1880,1881],{"class":362},"+",[278,1883,1884],{"class":302}," mandate ",[278,1886,1881],{"class":362},[278,1888,1889],{"class":302}," footer\n",[112,1891,1892],{},"A few pragmatic notes.",[112,1894,1895,1898,1899,1902,1903,1906],{},[152,1896,1897],{},"Sub-agents run in fresh contexts."," The spawner creates a new ",[275,1900,1901],{},"Transcript"," implicitly via ",[275,1904,1905],{},"arun",". The parent's context never touches the sub-agent's. This is the Anthropic finding — independent context windows are most of the multi-agent value.",[112,1908,1909,1912,1913,1915,1916,1919,1920,1919,1923,1926,1927,1919,1930,1919,1933,1936],{},[152,1910,1911],{},"Tool restriction via catalog filtering."," The sub-agent only sees tools in ",[275,1914,1132],{},". A researcher sub-agent might get ",[275,1917,1918],{},"search_docs",", ",[275,1921,1922],{},"read_file_viewport",[275,1924,1925],{},"scratchpad_read",". It does not get ",[275,1928,1929],{},"edit_lines",[275,1931,1932],{},"write_file",[275,1934,1935],{},"bash",". Scope restriction is automatic and enforced at the tool level, not trusted to the sub-agent's system prompt.",[112,1938,1939,1942],{},[152,1940,1941],{},"The spawner owns the budget counter."," A malicious sub-agent cannot spawn more sub-agents because sub-agents are one level deep by construction (we don't expose spawn as a tool they can call). But even a well-behaved parent can over-spawn; the manager caps it.",[112,1944,1945,1948,1949,1952,1953,1956,1957,1960,1961,1919,1963,1965,1966,1969,1970,1973,1974,1976],{},[152,1946,1947],{},"Sub-agents that narrate instead of execute."," There's a third failure mode the spec contract does ",[115,1950,1951],{},"not"," catch by itself, and the \"must call a tool\" clause above is what guards against it: sub-agents that understand their objective, describe what bash commands ",[115,1954,1955],{},"would"," run, and return a confident-sounding narrative without ever dispatching a single tool call. ",[275,1958,1959],{},"iterations_used=1",", no tool calls in the transcript, a summary full of plausible-looking numbers. Frontier models comply with implicit \"use your tools\" expectations; smaller local models (7B-class and below — think Gemma via Ollama) will sometimes hallucinate the execution and write a plan instead. The spec's ",[275,1962,1132],{},[275,1964,1361],{},", and ",[275,1967,1968],{},"justification"," are all present and correct — the contract held, but the model no-op'd the work. The fix is the explicit imperative in the system prompt above, paired with a check in your eval harness (Chapter 19) that counts sub-agent runs where ",[275,1971,1972],{},"iterations_used == 1"," and ",[275,1975,1132],{}," was non-empty. That number should be zero; if it's not, your prompt isn't strong enough for the model you're running.",[112,1978,1979,1988,1989,1991,1992,1994,1995,1997],{},[152,1980,1981,1983,1984,1987],{},[275,1982,1905],{}," returns an ",[275,1985,1986],{},"AgentRunResult",", not a bare string."," Earlier chapters showed ",[275,1990,1905],{}," returning ",[275,1993,444],{}," for brevity; at the point where sub-agents come in, the parent needs real accounting for each sub-run — token cost, iteration count, the sub-agent's transcript if you want to log it. So ",[275,1996,1905],{}," is promoted here to return a small dataclass:",[268,1999,2001],{"className":270,"code":2000,"language":272,"meta":273,"style":273},"# src\u002Fharness\u002Fagent.py (add alongside arun)\nfrom dataclasses import dataclass\n\nfrom .messages import Transcript\n\n\n@dataclass\nclass AgentRunResult:\n    summary: str               # the final answer text (was arun's bare return)\n    tokens_used: int           # input + output across all turns\n    iterations_used: int       # how many turns the loop took\n    transcript: Transcript     # full record — useful for logs \u002F debugging\n",[275,2002,2003,2008,2019,2023,2037,2041,2045,2051,2060,2071,2082,2093],{"__ignoreMap":273},[278,2004,2005],{"class":280,"line":281},[278,2006,2007],{"class":284},"# src\u002Fharness\u002Fagent.py (add alongside arun)\n",[278,2009,2010,2012,2014,2016],{"class":280,"line":288},[278,2011,292],{"class":291},[278,2013,318],{"class":302},[278,2015,321],{"class":291},[278,2017,2018],{"class":302}," dataclass\n",[278,2020,2021],{"class":280,"line":306},[278,2022,310],{"emptyLinePlaceholder":309},[278,2024,2025,2027,2029,2032,2034],{"class":280,"line":313},[278,2026,292],{"class":291},[278,2028,756],{"class":327},[278,2030,2031],{"class":302},"messages ",[278,2033,321],{"class":291},[278,2035,2036],{"class":302}," Transcript\n",[278,2038,2039],{"class":280,"line":334},[278,2040,310],{"emptyLinePlaceholder":309},[278,2042,2043],{"class":280,"line":339},[278,2044,310],{"emptyLinePlaceholder":309},[278,2046,2047,2049],{"class":280,"line":344},[278,2048,348],{"class":347},[278,2050,527],{"class":351},[278,2052,2053,2055,2058],{"class":280,"line":373},[278,2054,377],{"class":376},[278,2056,2057],{"class":380}," AgentRunResult",[278,2059,384],{"class":327},[278,2061,2062,2064,2066,2068],{"class":280,"line":387},[278,2063,553],{"class":302},[278,2065,407],{"class":327},[278,2067,411],{"class":410},[278,2069,2070],{"class":284},"               # the final answer text (was arun's bare return)\n",[278,2072,2073,2075,2077,2079],{"class":280,"line":401},[278,2074,566],{"class":302},[278,2076,407],{"class":327},[278,2078,461],{"class":410},[278,2080,2081],{"class":284},"           # input + output across all turns\n",[278,2083,2084,2086,2088,2090],{"class":280,"line":417},[278,2085,577],{"class":302},[278,2087,407],{"class":327},[278,2089,461],{"class":410},[278,2091,2092],{"class":284},"       # how many turns the loop took\n",[278,2094,2095,2098,2100,2103],{"class":280,"line":430},[278,2096,2097],{"class":302},"    transcript",[278,2099,407],{"class":327},[278,2101,2102],{"class":302}," Transcript     ",[278,2104,2105],{"class":284},"# full record — useful for logs \u002F debugging\n",[112,2107,2108,2110,2111,2114,2115,2118,2119,2122,2123,1973,2126,2129,2130,2133,2134,2136],{},[275,2109,1905],{},"'s signature changes from ",[275,2112,2113],{},"-> str"," to ",[275,2116,2117],{},"-> AgentRunResult",". Everything downstream uses ",[275,2120,2121],{},".summary"," where it used to use the raw return value. The spawner below reads ",[275,2124,2125],{},".tokens_used",[275,2127,2128],{},".iterations_used"," directly; Chapter 19's eval runner uses ",[275,2131,2132],{},".transcript"," for tool-call recording; Chapter 20's budget enforcer uses ",[275,2135,2125],{}," for post-run accounting.",[257,2138],{},[260,2140,2142],{"id":2141},"_153-the-spawn-tool","15.3 The Spawn Tool",[112,2144,2145,2146,2148,2149,2152,2153,2156,2157,2160,2161,2164,2165,2168],{},"The parent uses sub-agents via a tool, the same way it uses anything else. Because the spawner itself is async — it calls ",[275,2147,1905],{}," — the tool must be an ",[152,2150,2151],{},"async tool",". Chapter 13 §13.3 extended ",[275,2154,2155],{},"Tool"," with an optional ",[275,2158,2159],{},"arun: Callable[..., Awaitable[str]]"," field and added an ",[275,2162,2163],{},"@async_tool"," decorator that wires ",[275,2166,2167],{},"async def"," functions into it. We use that here:",[268,2170,2172],{"className":270,"code":2171,"language":272,"meta":273,"style":273},"# src\u002Fharness\u002Fsubagents\u002Fspawn_tool.py\nfrom __future__ import annotations\n\nfrom ..tools.base import Tool\nfrom ..tools.decorator import async_tool\nfrom .spawner import SubagentSpawner\nfrom .subagent import SubagentSpec\n\n\ndef spawn_tool(spawner: SubagentSpawner) -> Tool:\n\n    @async_tool(side_effects={\"mutate\"})  # conservative — sub-agents may do anything\n    async def spawn_subagent(\n        objective: str,\n        output_format: str,\n        tools_allowed: list[str],\n        max_iterations: int = 15,\n        justification: str = \"\",\n    ) -> str:\n        \"\"\"Spawn a sub-agent to handle a delegated task.\n\n        objective: the specific task for the sub-agent, operationally\n                   specific (\"read files X and Y and report their schemas\"),\n                   NOT vague (\"look into the database\").\n        output_format: exact format the sub-agent should return its answer\n                       in. Examples: \"a JSON object with keys X and Y\";\n                       \"a three-paragraph summary, each under 100 words\".\n        tools_allowed: names of tools the sub-agent is permitted to use.\n                       Narrower is better; the sub-agent can't use tools\n                       not in this list.\n        max_iterations: hard cap on sub-agent turns. Default 15; reduce\n                        for simple lookups.\n        justification: one sentence explaining WHY a sub-agent is better\n                       than handling this in-line. Required; if you can't\n                       articulate why, don't spawn.\n\n        Returns the sub-agent's summary, prefixed with its token cost.\n        Side effects: depend on sub-agent's tools; pessimistically 'mutate'.\n        \"\"\"\n        if not justification:\n            return (\"error: justification is required. If you cannot explain \"\n                    \"why a sub-agent is better than inline handling, do not \"\n                    \"spawn one.\")\n        if not tools_allowed:\n            return (\"error: tools_allowed must be non-empty. Specify which \"\n                    \"tools the sub-agent needs.\")\n\n        spec = SubagentSpec(\n            objective=objective,\n            output_format=output_format,\n            tools_allowed=tools_allowed,\n            max_iterations=max_iterations,\n        )\n        result = await spawner.spawn(spec, justification=justification)\n        if result.error:\n            return f\"sub-agent error: {result.error}\"\n        return (f\"[sub-agent result; {result.tokens_used} tokens, \"\n                f\"{result.iterations_used} iters]\\n{result.summary}\")\n\n    return spawn_subagent\n",[275,2173,2174,2179,2189,2193,2210,2228,2242,2254,2258,2262,2287,2291,2322,2333,2344,2355,2371,2387,2401,2411,2419,2423,2428,2433,2438,2443,2448,2453,2458,2463,2468,2473,2478,2483,2488,2493,2497,2502,2507,2512,2524,2538,2548,2559,2570,2583,2594,2598,2609,2620,2631,2642,2653,2657,2688,2702,2723,2749,2784,2788],{"__ignoreMap":273},[278,2175,2176],{"class":280,"line":281},[278,2177,2178],{"class":284},"# src\u002Fharness\u002Fsubagents\u002Fspawn_tool.py\n",[278,2180,2181,2183,2185,2187],{"class":280,"line":288},[278,2182,292],{"class":291},[278,2184,296],{"class":295},[278,2186,299],{"class":291},[278,2188,303],{"class":302},[278,2190,2191],{"class":280,"line":306},[278,2192,310],{"emptyLinePlaceholder":309},[278,2194,2195,2197,2199,2201,2203,2205,2207],{"class":280,"line":313},[278,2196,292],{"class":291},[278,2198,678],{"class":327},[278,2200,739],{"class":302},[278,2202,698],{"class":327},[278,2204,725],{"class":302},[278,2206,321],{"class":291},[278,2208,2209],{"class":302}," Tool\n",[278,2211,2212,2214,2216,2218,2220,2223,2225],{"class":280,"line":334},[278,2213,292],{"class":291},[278,2215,678],{"class":327},[278,2217,739],{"class":302},[278,2219,698],{"class":327},[278,2221,2222],{"class":302},"decorator ",[278,2224,321],{"class":291},[278,2226,2227],{"class":302}," async_tool\n",[278,2229,2230,2232,2234,2237,2239],{"class":280,"line":339},[278,2231,292],{"class":291},[278,2233,756],{"class":327},[278,2235,2236],{"class":302},"spawner ",[278,2238,321],{"class":291},[278,2240,2241],{"class":302}," SubagentSpawner\n",[278,2243,2244,2246,2248,2250,2252],{"class":280,"line":344},[278,2245,292],{"class":291},[278,2247,756],{"class":327},[278,2249,759],{"class":302},[278,2251,321],{"class":291},[278,2253,768],{"class":302},[278,2255,2256],{"class":280,"line":373},[278,2257,310],{"emptyLinePlaceholder":309},[278,2259,2260],{"class":280,"line":387},[278,2261,310],{"emptyLinePlaceholder":309},[278,2263,2264,2266,2269,2271,2274,2276,2278,2280,2282,2285],{"class":280,"line":401},[278,2265,1577],{"class":376},[278,2267,2268],{"class":351}," spawn_tool",[278,2270,355],{"class":327},[278,2272,2273],{"class":923},"spawner",[278,2275,407],{"class":327},[278,2277,817],{"class":302},[278,2279,1590],{"class":327},[278,2281,977],{"class":327},[278,2283,2284],{"class":302}," Tool",[278,2286,384],{"class":327},[278,2288,2289],{"class":280,"line":417},[278,2290,310],{"emptyLinePlaceholder":309},[278,2292,2293,2296,2299,2301,2304,2306,2308,2311,2314,2316,2319],{"class":280,"line":430},[278,2294,2295],{"class":347},"    @",[278,2297,2298],{"class":351},"async_tool",[278,2300,355],{"class":327},[278,2302,2303],{"class":358},"side_effects",[278,2305,363],{"class":362},[278,2307,1031],{"class":327},[278,2309,2310],{"class":965},"\"",[278,2312,2313],{"class":1027},"mutate",[278,2315,2310],{"class":965},[278,2317,2318],{"class":327},"})",[278,2320,2321],{"class":284},"  # conservative — sub-agents may do anything\n",[278,2323,2324,2326,2328,2331],{"class":280,"line":453},[278,2325,898],{"class":376},[278,2327,901],{"class":376},[278,2329,2330],{"class":351}," spawn_subagent",[278,2332,907],{"class":327},[278,2334,2335,2338,2340,2342],{"class":280,"line":471},[278,2336,2337],{"class":923},"        objective",[278,2339,407],{"class":327},[278,2341,411],{"class":410},[278,2343,917],{"class":327},[278,2345,2346,2349,2351,2353],{"class":280,"line":489},[278,2347,2348],{"class":923},"        output_format",[278,2350,407],{"class":327},[278,2352,411],{"class":410},[278,2354,917],{"class":327},[278,2356,2357,2360,2362,2364,2366,2368],{"class":280,"line":512},[278,2358,2359],{"class":923},"        tools_allowed",[278,2361,407],{"class":327},[278,2363,438],{"class":302},[278,2365,441],{"class":327},[278,2367,444],{"class":410},[278,2369,2370],{"class":327},"],\n",[278,2372,2373,2376,2378,2380,2382,2385],{"class":280,"line":517},[278,2374,2375],{"class":923},"        max_iterations",[278,2377,407],{"class":327},[278,2379,461],{"class":410},[278,2381,464],{"class":362},[278,2383,2384],{"class":467}," 15",[278,2386,917],{"class":327},[278,2388,2389,2391,2393,2395,2397,2399],{"class":280,"line":522},[278,2390,956],{"class":923},[278,2392,407],{"class":327},[278,2394,411],{"class":410},[278,2396,464],{"class":362},[278,2398,966],{"class":965},[278,2400,917],{"class":327},[278,2402,2403,2405,2407,2409],{"class":280,"line":530},[278,2404,974],{"class":327},[278,2406,977],{"class":327},[278,2408,411],{"class":410},[278,2410,384],{"class":327},[278,2412,2413,2416],{"class":280,"line":540},[278,2414,2415],{"class":390},"        \"\"\"",[278,2417,2418],{"class":394},"Spawn a sub-agent to handle a delegated task.\n",[278,2420,2421],{"class":280,"line":550},[278,2422,310],{"emptyLinePlaceholder":309},[278,2424,2425],{"class":280,"line":563},[278,2426,2427],{"class":394},"        objective: the specific task for the sub-agent, operationally\n",[278,2429,2430],{"class":280,"line":574},[278,2431,2432],{"class":394},"                   specific (\"read files X and Y and report their schemas\"),\n",[278,2434,2435],{"class":280,"line":584},[278,2436,2437],{"class":394},"                   NOT vague (\"look into the database\").\n",[278,2439,2440],{"class":280,"line":895},[278,2441,2442],{"class":394},"        output_format: exact format the sub-agent should return its answer\n",[278,2444,2445],{"class":280,"line":910},[278,2446,2447],{"class":394},"                       in. Examples: \"a JSON object with keys X and Y\";\n",[278,2449,2450],{"class":280,"line":920},[278,2451,2452],{"class":394},"                       \"a three-paragraph summary, each under 100 words\".\n",[278,2454,2455],{"class":280,"line":933},[278,2456,2457],{"class":394},"        tools_allowed: names of tools the sub-agent is permitted to use.\n",[278,2459,2460],{"class":280,"line":953},[278,2461,2462],{"class":394},"                       Narrower is better; the sub-agent can't use tools\n",[278,2464,2465],{"class":280,"line":971},[278,2466,2467],{"class":394},"                       not in this list.\n",[278,2469,2470],{"class":280,"line":984},[278,2471,2472],{"class":394},"        max_iterations: hard cap on sub-agent turns. Default 15; reduce\n",[278,2474,2475],{"class":280,"line":1011},[278,2476,2477],{"class":394},"                        for simple lookups.\n",[278,2479,2480],{"class":280,"line":1021},[278,2481,2482],{"class":394},"        justification: one sentence explaining WHY a sub-agent is better\n",[278,2484,2485],{"class":280,"line":1047},[278,2486,2487],{"class":394},"                       than handling this in-line. Required; if you can't\n",[278,2489,2490],{"class":280,"line":1053},[278,2491,2492],{"class":394},"                       articulate why, don't spawn.\n",[278,2494,2495],{"class":280,"line":1068},[278,2496,310],{"emptyLinePlaceholder":309},[278,2498,2499],{"class":280,"line":1073},[278,2500,2501],{"class":394},"        Returns the sub-agent's summary, prefixed with its token cost.\n",[278,2503,2504],{"class":280,"line":1079},[278,2505,2506],{"class":394},"        Side effects: depend on sub-agent's tools; pessimistically 'mutate'.\n",[278,2508,2509],{"class":280,"line":1138},[278,2510,2511],{"class":390},"        \"\"\"\n",[278,2513,2514,2516,2519,2522],{"class":280,"line":1160},[278,2515,987],{"class":291},[278,2517,2518],{"class":362}," not",[278,2520,2521],{"class":302}," justification",[278,2523,384],{"class":327},[278,2525,2526,2528,2531,2533,2536],{"class":280,"line":1165},[278,2527,1408],{"class":291},[278,2529,2530],{"class":327}," (",[278,2532,2310],{"class":965},[278,2534,2535],{"class":1027},"error: justification is required. If you cannot explain ",[278,2537,1344],{"class":965},[278,2539,2540,2543,2546],{"class":280,"line":1171},[278,2541,2542],{"class":965},"                    \"",[278,2544,2545],{"class":1027},"why a sub-agent is better than inline handling, do not ",[278,2547,1344],{"class":965},[278,2549,2550,2552,2555,2557],{"class":280,"line":1199},[278,2551,2542],{"class":965},[278,2553,2554],{"class":1027},"spawn one.",[278,2556,2310],{"class":965},[278,2558,370],{"class":327},[278,2560,2561,2563,2565,2568],{"class":280,"line":1220},[278,2562,987],{"class":291},[278,2564,2518],{"class":362},[278,2566,2567],{"class":302}," tools_allowed",[278,2569,384],{"class":327},[278,2571,2572,2574,2576,2578,2581],{"class":280,"line":1225},[278,2573,1408],{"class":291},[278,2575,2530],{"class":327},[278,2577,2310],{"class":965},[278,2579,2580],{"class":1027},"error: tools_allowed must be non-empty. Specify which ",[278,2582,1344],{"class":965},[278,2584,2585,2587,2590,2592],{"class":280,"line":1252},[278,2586,2542],{"class":965},[278,2588,2589],{"class":1027},"tools the sub-agent needs.",[278,2591,2310],{"class":965},[278,2593,370],{"class":327},[278,2595,2596],{"class":280,"line":1257},[278,2597,310],{"emptyLinePlaceholder":309},[278,2599,2600,2603,2605,2607],{"class":280,"line":1265},[278,2601,2602],{"class":302},"        spec ",[278,2604,363],{"class":362},[278,2606,381],{"class":865},[278,2608,907],{"class":327},[278,2610,2611,2614,2616,2618],{"class":280,"line":1281},[278,2612,2613],{"class":358},"            objective",[278,2615,363],{"class":362},[278,2617,1336],{"class":865},[278,2619,917],{"class":327},[278,2621,2622,2625,2627,2629],{"class":280,"line":1298},[278,2623,2624],{"class":358},"            output_format",[278,2626,363],{"class":362},[278,2628,1361],{"class":865},[278,2630,917],{"class":327},[278,2632,2633,2636,2638,2640],{"class":280,"line":1311},[278,2634,2635],{"class":358},"            tools_allowed",[278,2637,363],{"class":362},[278,2639,1132],{"class":865},[278,2641,917],{"class":327},[278,2643,2644,2647,2649,2651],{"class":280,"line":1321},[278,2645,2646],{"class":358},"            max_iterations",[278,2648,363],{"class":362},[278,2650,1701],{"class":865},[278,2652,917],{"class":327},[278,2654,2655],{"class":280,"line":1347},[278,2656,1829],{"class":327},[278,2658,2659,2662,2664,2666,2669,2671,2674,2676,2678,2680,2682,2684,2686],{"class":280,"line":1368},[278,2660,2661],{"class":302},"        result ",[278,2663,363],{"class":362},[278,2665,1273],{"class":291},[278,2667,2668],{"class":302}," spawner",[278,2670,698],{"class":327},[278,2672,2673],{"class":865},"spawn",[278,2675,355],{"class":327},[278,2677,1189],{"class":865},[278,2679,328],{"class":327},[278,2681,2521],{"class":358},[278,2683,363],{"class":362},[278,2685,1968],{"class":865},[278,2687,370],{"class":327},[278,2689,2690,2692,2695,2697,2700],{"class":280,"line":1374},[278,2691,987],{"class":291},[278,2693,2694],{"class":302}," result",[278,2696,698],{"class":327},[278,2698,2699],{"class":995},"error",[278,2701,384],{"class":327},[278,2703,2704,2706,2708,2711,2713,2715,2717,2719,2721],{"class":280,"line":1387},[278,2705,1408],{"class":291},[278,2707,1607],{"class":376},[278,2709,2710],{"class":1027},"\"sub-agent error: ",[278,2712,1031],{"class":467},[278,2714,1423],{"class":302},[278,2716,698],{"class":327},[278,2718,2699],{"class":995},[278,2720,1041],{"class":467},[278,2722,1344],{"class":1027},[278,2724,2725,2728,2730,2733,2736,2738,2740,2742,2744,2746],{"class":280,"line":1400},[278,2726,2727],{"class":291},"        return",[278,2729,2530],{"class":327},[278,2731,2732],{"class":376},"f",[278,2734,2735],{"class":1027},"\"[sub-agent result; ",[278,2737,1031],{"class":467},[278,2739,1423],{"class":302},[278,2741,698],{"class":327},[278,2743,1444],{"class":995},[278,2745,1041],{"class":467},[278,2747,2748],{"class":1027}," tokens, \"\n",[278,2750,2751,2753,2755,2757,2759,2761,2763,2765,2768,2770,2772,2774,2776,2778,2780,2782],{"class":280,"line":1405},[278,2752,1024],{"class":376},[278,2754,2310],{"class":1027},[278,2756,1031],{"class":467},[278,2758,1423],{"class":302},[278,2760,698],{"class":327},[278,2762,1461],{"class":995},[278,2764,1041],{"class":467},[278,2766,2767],{"class":1027}," iters]",[278,2769,1792],{"class":295},[278,2771,1031],{"class":467},[278,2773,1423],{"class":302},[278,2775,698],{"class":327},[278,2777,612],{"class":995},[278,2779,1041],{"class":467},[278,2781,2310],{"class":1027},[278,2783,370],{"class":327},[278,2785,2786],{"class":280,"line":1415},[278,2787,310],{"emptyLinePlaceholder":309},[278,2789,2790,2792],{"class":280,"line":1432},[278,2791,1875],{"class":291},[278,2793,2794],{"class":302}," spawn_subagent\n",[112,2796,2797],{},"Three deliberate frictions.",[112,2799,2800,2803,2804,2806,2807,2810],{},[152,2801,2802],{},"Justification is required."," An empty ",[275,2805,1968],{}," returns an error. This forces the model to articulate ",[115,2808,2809],{},"why"," it's spawning — the Multi-Agent Trap paper's finding that over-delegation happens because spawning feels like doing work is the failure mode this counters directly.",[112,2812,2813,2818],{},[152,2814,2815,2817],{},[275,2816,1132],{}," must be non-empty and specific."," An unset tool list would give the sub-agent everything, which negates the blast-radius argument for sub-agents in the first place. Forcing the parent to list specific tools makes the scope contract explicit.",[112,2820,2821,2824,2825,1919,2828,1919,2831,2834],{},[152,2822,2823],{},"Output format is required."," \"Return your findings\" produces rambling summaries; \"Return a JSON object with keys ",[275,2826,2827],{},"files_found",[275,2829,2830],{},"bugs_identified",[275,2832,2833],{},"recommendations","\" produces structured output the parent can parse. The Anthropic research post was emphatic: the biggest multi-agent quality lever is precise output format specifications.",[257,2836],{},[260,2838,2840],{"id":2839},"_154-a-two-agent-scenario","15.4 A Two-agent Scenario",[268,2842,2844],{"className":270,"code":2843,"language":272,"meta":273,"style":273},"# examples\u002Fch15_research_and_report.py\nimport asyncio\nfrom pathlib import Path\n\nfrom harness.agent import arun\nfrom harness.providers.anthropic import AnthropicProvider\nfrom harness.subagents.spawn_tool import spawn_tool\nfrom harness.subagents.spawner import SubagentSpawner\nfrom harness.tools.selector import ToolCatalog, discovery_tool\nfrom harness.tools.std import STANDARD_TOOLS\n\n\nSYSTEM = \"\"\"\\\nYou are a research coordinator. You have a spawn_subagent tool to delegate\nspecific research tasks to sub-agents. A sub-agent is appropriate when:\n- The subtask can be stated operationally in one sentence.\n- The subtask uses a narrow set of tools.\n- You want the sub-agent to return a structured summary you synthesize.\n\nDo NOT use sub-agents for:\n- Simple lookups you can do in-line.\n- Multi-step chains where each step depends on the last — do those yourself.\n\nFor each sub-agent, provide a justification explaining WHY it's better than\nhandling the work in-line.\n\"\"\"\n\n\nasync def main() -> None:\n    provider = AnthropicProvider()\n    catalog = ToolCatalog(tools=STANDARD_TOOLS)\n    spawner = SubagentSpawner(provider=provider, catalog=catalog,\n                              max_subagents_per_session=3)\n    coordinator_catalog = ToolCatalog(\n        tools=STANDARD_TOOLS + [spawn_tool(spawner), discovery_tool(catalog)]\n    )\n\n    await arun(\n        provider=provider,\n        catalog=coordinator_catalog,\n        system=SYSTEM,\n        user_message=(\n            \"Investigate this machine's package management setup. \"\n            \"Spawn one sub-agent for each package manager likely installed \"\n            \"(apt, brew, pip, npm). Each sub-agent should return: \"\n            \"(1) whether the package manager is installed, \"\n            \"(2) the version, \"\n            \"(3) a count of installed packages. \"\n            \"Then synthesize a one-paragraph summary.\"\n        ),\n    )\n\n\nasyncio.run(main())\n",[275,2845,2846,2851,2857,2869,2873,2888,2908,2929,2947,2970,2990,2994,2998,3010,3015,3020,3025,3030,3035,3039,3044,3049,3054,3058,3063,3068,3072,3076,3080,3099,3112,3133,3161,3173,3184,3218,3223,3227,3236,3247,3259,3270,3279,3288,3297,3306,3315,3324,3333,3342,3347,3351,3355,3359],{"__ignoreMap":273},[278,2847,2848],{"class":280,"line":281},[278,2849,2850],{"class":284},"# examples\u002Fch15_research_and_report.py\n",[278,2852,2853,2855],{"class":280,"line":288},[278,2854,321],{"class":291},[278,2856,653],{"class":302},[278,2858,2859,2861,2864,2866],{"class":280,"line":306},[278,2860,292],{"class":291},[278,2862,2863],{"class":302}," pathlib ",[278,2865,321],{"class":291},[278,2867,2868],{"class":302}," Path\n",[278,2870,2871],{"class":280,"line":313},[278,2872,310],{"emptyLinePlaceholder":309},[278,2874,2875,2877,2880,2882,2884,2886],{"class":280,"line":334},[278,2876,292],{"class":291},[278,2878,2879],{"class":302}," harness",[278,2881,698],{"class":327},[278,2883,681],{"class":302},[278,2885,321],{"class":291},[278,2887,686],{"class":302},[278,2889,2890,2892,2894,2896,2898,2900,2903,2905],{"class":280,"line":339},[278,2891,292],{"class":291},[278,2893,2879],{"class":302},[278,2895,698],{"class":327},[278,2897,720],{"class":302},[278,2899,698],{"class":327},[278,2901,2902],{"class":302},"anthropic ",[278,2904,321],{"class":291},[278,2906,2907],{"class":302}," AnthropicProvider\n",[278,2909,2910,2912,2914,2916,2919,2921,2924,2926],{"class":280,"line":344},[278,2911,292],{"class":291},[278,2913,2879],{"class":302},[278,2915,698],{"class":327},[278,2917,2918],{"class":302},"subagents",[278,2920,698],{"class":327},[278,2922,2923],{"class":302},"spawn_tool ",[278,2925,321],{"class":291},[278,2927,2928],{"class":302}," spawn_tool\n",[278,2930,2931,2933,2935,2937,2939,2941,2943,2945],{"class":280,"line":373},[278,2932,292],{"class":291},[278,2934,2879],{"class":302},[278,2936,698],{"class":327},[278,2938,2918],{"class":302},[278,2940,698],{"class":327},[278,2942,2236],{"class":302},[278,2944,321],{"class":291},[278,2946,2241],{"class":302},[278,2948,2949,2951,2953,2955,2957,2959,2961,2963,2965,2967],{"class":280,"line":387},[278,2950,292],{"class":291},[278,2952,2879],{"class":302},[278,2954,698],{"class":327},[278,2956,739],{"class":302},[278,2958,698],{"class":327},[278,2960,744],{"class":302},[278,2962,321],{"class":291},[278,2964,1146],{"class":302},[278,2966,328],{"class":327},[278,2968,2969],{"class":302}," discovery_tool\n",[278,2971,2972,2974,2976,2978,2980,2982,2985,2987],{"class":280,"line":401},[278,2973,292],{"class":291},[278,2975,2879],{"class":302},[278,2977,698],{"class":327},[278,2979,739],{"class":302},[278,2981,698],{"class":327},[278,2983,2984],{"class":302},"std ",[278,2986,321],{"class":291},[278,2988,2989],{"class":295}," STANDARD_TOOLS\n",[278,2991,2992],{"class":280,"line":417},[278,2993,310],{"emptyLinePlaceholder":309},[278,2995,2996],{"class":280,"line":430},[278,2997,310],{"emptyLinePlaceholder":309},[278,2999,3000,3003,3005,3008],{"class":280,"line":453},[278,3001,3002],{"class":295},"SYSTEM",[278,3004,464],{"class":362},[278,3006,3007],{"class":965}," \"\"\"",[278,3009,1613],{"class":366},[278,3011,3012],{"class":280,"line":471},[278,3013,3014],{"class":1027},"You are a research coordinator. You have a spawn_subagent tool to delegate\n",[278,3016,3017],{"class":280,"line":489},[278,3018,3019],{"class":1027},"specific research tasks to sub-agents. A sub-agent is appropriate when:\n",[278,3021,3022],{"class":280,"line":512},[278,3023,3024],{"class":1027},"- The subtask can be stated operationally in one sentence.\n",[278,3026,3027],{"class":280,"line":517},[278,3028,3029],{"class":1027},"- The subtask uses a narrow set of tools.\n",[278,3031,3032],{"class":280,"line":522},[278,3033,3034],{"class":1027},"- You want the sub-agent to return a structured summary you synthesize.\n",[278,3036,3037],{"class":280,"line":530},[278,3038,310],{"emptyLinePlaceholder":309},[278,3040,3041],{"class":280,"line":540},[278,3042,3043],{"class":1027},"Do NOT use sub-agents for:\n",[278,3045,3046],{"class":280,"line":550},[278,3047,3048],{"class":1027},"- Simple lookups you can do in-line.\n",[278,3050,3051],{"class":280,"line":563},[278,3052,3053],{"class":1027},"- Multi-step chains where each step depends on the last — do those yourself.\n",[278,3055,3056],{"class":280,"line":574},[278,3057,310],{"emptyLinePlaceholder":309},[278,3059,3060],{"class":280,"line":584},[278,3061,3062],{"class":1027},"For each sub-agent, provide a justification explaining WHY it's better than\n",[278,3064,3065],{"class":280,"line":895},[278,3066,3067],{"class":1027},"handling the work in-line.\n",[278,3069,3070],{"class":280,"line":910},[278,3071,398],{"class":965},[278,3073,3074],{"class":280,"line":920},[278,3075,310],{"emptyLinePlaceholder":309},[278,3077,3078],{"class":280,"line":933},[278,3079,310],{"emptyLinePlaceholder":309},[278,3081,3082,3085,3087,3090,3093,3095,3097],{"class":280,"line":953},[278,3083,3084],{"class":376},"async",[278,3086,901],{"class":376},[278,3088,3089],{"class":351}," main",[278,3091,3092],{"class":327},"()",[278,3094,977],{"class":327},[278,3096,502],{"class":366},[278,3098,384],{"class":327},[278,3100,3101,3104,3106,3109],{"class":280,"line":971},[278,3102,3103],{"class":302},"    provider ",[278,3105,363],{"class":362},[278,3107,3108],{"class":865}," AnthropicProvider",[278,3110,3111],{"class":327},"()\n",[278,3113,3114,3117,3119,3121,3123,3125,3127,3131],{"class":280,"line":984},[278,3115,3116],{"class":302},"    catalog ",[278,3118,363],{"class":362},[278,3120,1146],{"class":865},[278,3122,355],{"class":327},[278,3124,739],{"class":358},[278,3126,363],{"class":362},[278,3128,3130],{"class":3129},"sptTA","STANDARD_TOOLS",[278,3132,370],{"class":327},[278,3134,3135,3138,3140,3142,3144,3146,3148,3150,3152,3155,3157,3159],{"class":280,"line":1011},[278,3136,3137],{"class":302},"    spawner ",[278,3139,363],{"class":362},[278,3141,817],{"class":865},[278,3143,355],{"class":327},[278,3145,1293],{"class":358},[278,3147,363],{"class":362},[278,3149,1293],{"class":865},[278,3151,328],{"class":327},[278,3153,3154],{"class":358}," catalog",[278,3156,363],{"class":362},[278,3158,1106],{"class":865},[278,3160,917],{"class":327},[278,3162,3163,3166,3168,3171],{"class":280,"line":1021},[278,3164,3165],{"class":358},"                              max_subagents_per_session",[278,3167,363],{"class":362},[278,3169,3170],{"class":467},"3",[278,3172,370],{"class":327},[278,3174,3175,3178,3180,3182],{"class":280,"line":1047},[278,3176,3177],{"class":302},"    coordinator_catalog ",[278,3179,363],{"class":362},[278,3181,1146],{"class":865},[278,3183,907],{"class":327},[278,3185,3186,3189,3191,3193,3196,3198,3201,3203,3205,3208,3211,3213,3215],{"class":280,"line":1053},[278,3187,3188],{"class":358},"        tools",[278,3190,363],{"class":362},[278,3192,3130],{"class":3129},[278,3194,3195],{"class":362}," +",[278,3197,1087],{"class":327},[278,3199,3200],{"class":865},"spawn_tool",[278,3202,355],{"class":327},[278,3204,2273],{"class":865},[278,3206,3207],{"class":327},"),",[278,3209,3210],{"class":865}," discovery_tool",[278,3212,355],{"class":327},[278,3214,1106],{"class":865},[278,3216,3217],{"class":327},")]\n",[278,3219,3220],{"class":280,"line":1068},[278,3221,3222],{"class":327},"    )\n",[278,3224,3225],{"class":280,"line":1073},[278,3226,310],{"emptyLinePlaceholder":309},[278,3228,3229,3232,3234],{"class":280,"line":1079},[278,3230,3231],{"class":291},"    await",[278,3233,1276],{"class":865},[278,3235,907],{"class":327},[278,3237,3238,3241,3243,3245],{"class":280,"line":1138},[278,3239,3240],{"class":358},"        provider",[278,3242,363],{"class":362},[278,3244,1293],{"class":865},[278,3246,917],{"class":327},[278,3248,3249,3252,3254,3257],{"class":280,"line":1160},[278,3250,3251],{"class":358},"        catalog",[278,3253,363],{"class":362},[278,3255,3256],{"class":865},"coordinator_catalog",[278,3258,917],{"class":327},[278,3260,3261,3264,3266,3268],{"class":280,"line":1165},[278,3262,3263],{"class":358},"        system",[278,3265,363],{"class":362},[278,3267,3002],{"class":3129},[278,3269,917],{"class":327},[278,3271,3272,3275,3277],{"class":280,"line":1171},[278,3273,3274],{"class":358},"        user_message",[278,3276,363],{"class":362},[278,3278,907],{"class":327},[278,3280,3281,3283,3286],{"class":280,"line":1199},[278,3282,1789],{"class":965},[278,3284,3285],{"class":1027},"Investigate this machine's package management setup. ",[278,3287,1344],{"class":965},[278,3289,3290,3292,3295],{"class":280,"line":1220},[278,3291,1789],{"class":965},[278,3293,3294],{"class":1027},"Spawn one sub-agent for each package manager likely installed ",[278,3296,1344],{"class":965},[278,3298,3299,3301,3304],{"class":280,"line":1225},[278,3300,1789],{"class":965},[278,3302,3303],{"class":1027},"(apt, brew, pip, npm). Each sub-agent should return: ",[278,3305,1344],{"class":965},[278,3307,3308,3310,3313],{"class":280,"line":1252},[278,3309,1789],{"class":965},[278,3311,3312],{"class":1027},"(1) whether the package manager is installed, ",[278,3314,1344],{"class":965},[278,3316,3317,3319,3322],{"class":280,"line":1257},[278,3318,1789],{"class":965},[278,3320,3321],{"class":1027},"(2) the version, ",[278,3323,1344],{"class":965},[278,3325,3326,3328,3331],{"class":280,"line":1265},[278,3327,1789],{"class":965},[278,3329,3330],{"class":1027},"(3) a count of installed packages. ",[278,3332,1344],{"class":965},[278,3334,3335,3337,3340],{"class":280,"line":1281},[278,3336,1789],{"class":965},[278,3338,3339],{"class":1027},"Then synthesize a one-paragraph summary.",[278,3341,1344],{"class":965},[278,3343,3344],{"class":280,"line":1298},[278,3345,3346],{"class":327},"        ),\n",[278,3348,3349],{"class":280,"line":1311},[278,3350,3222],{"class":327},[278,3352,3353],{"class":280,"line":1321},[278,3354,310],{"emptyLinePlaceholder":309},[278,3356,3357],{"class":280,"line":1347},[278,3358,310],{"emptyLinePlaceholder":309},[278,3360,3361,3364,3366,3369,3371,3374],{"class":280,"line":1368},[278,3362,3363],{"class":302},"asyncio",[278,3365,698],{"class":327},[278,3367,3368],{"class":865},"run",[278,3370,355],{"class":327},[278,3372,3373],{"class":865},"main",[278,3375,3376],{"class":327},"())\n",[112,3378,3379,3380,3383],{},"Run it. The coordinator spawns three or four sub-agents in sequence, each with a narrow tool list (",[275,3381,3382],{},"[\"bash\"]"," probably), and each returns a tiny structured result (\"apt: installed, version X, N packages\"). The coordinator synthesizes. Total context in the parent: well under what a single-agent version of the same task would accumulate.",[112,3385,3386,3387,3390],{},"A note: this example is sequential — each ",[275,3388,3389],{},"spawn_subagent"," call blocks until the sub-agent finishes. Chapter 17 covers parallel spawning and the shared-state problems that introduces.",[112,3392,3393,3396,3397,3400,3401,3403,3404,3406,3407,3410],{},[152,3394,3395],{},"If you run this on a small local model"," (Gemma via Ollama, a 7B-class open model) and the sub-agents come back with paragraphs describing what ",[275,3398,3399],{},"brew list"," ",[115,3402,1955],{}," print instead of what it actually printed, you're seeing the narrate-instead-of-execute mode from §15.2. ",[275,3405,1959],{},", no tool calls, a confident-sounding summary. The mandatory-tool clause in ",[275,3408,3409],{},"_default_subagent_system"," is what's meant to prevent this; if it still happens, your model needs the clause stronger, or your sub-agent objective needs to be operationally specific enough that \"just describe\" isn't a plausible interpretation. Frontier sub-agents (Opus, Sonnet) won't hit this; harness authors testing locally will, and it's worth watching for.",[257,3412],{},[260,3414,3416],{"id":3415},"_155-agent-as-tool-vs-handoffs","15.5 Agent-as-tool vs. Handoffs",[112,3418,3419,3420,3423,3424,3427],{},"The OpenAI Agents SDK distinguishes two multi-agent patterns: ",[152,3421,3422],{},"agent-as-tool"," (what we built — the parent calls a sub-agent, gets a result, continues) and ",[152,3425,3426],{},"handoff"," (control transfers permanently to the new agent; the original agent doesn't get control back).",[112,3429,3430],{},"We built agent-as-tool. Handoffs are rarely the right pattern for the harness cases this book cares about:",[3432,3433,3434,3437,3440],"ul",{},[149,3435,3436],{},"Handoffs are hard to observe — you don't have a parent that can summarize across delegations.",[149,3438,3439],{},"Handoffs make the control flow hard to reason about — the agent you're looking at isn't necessarily the one that started.",[149,3441,3442],{},"Handoffs can be simulated with agent-as-tool plus explicit return-from-delegate logic; the reverse is harder.",[112,3444,3445],{},"For workflows that feel like handoffs — a triage agent that routes to a specialist — agent-as-tool plus the coordinator pattern from 15.4 is usually clearer.",[257,3447],{},[260,3449,3451],{"id":3450},"_156-permissions-for-sub-agents","15.6 Permissions for Sub-agents",[112,3453,3454,3455,3458],{},"A sub-agent shares the parent's permission manager by default — any tool it calls goes through the same policy check. This matters: a sub-agent cannot escalate privilege by being a sub-agent. If the parent can't ",[275,3456,3457],{},"bash rm -rf \u002F",", neither can the sub-agent.",[112,3460,3461,3462,3465],{},"For some deployments, you want ",[115,3463,3464],{},"tighter"," sub-agent permissions. A research sub-agent might be fully read-only even though the parent has write permissions. The pattern:",[268,3467,3469],{"className":270,"code":3468,"language":272,"meta":273,"style":273},"spec = SubagentSpec(\n    objective=\"...\",\n    output_format=\"...\",\n    tools_allowed=[\"search_docs\", \"read_file_viewport\"],  # read-only subset\n    ...\n)\n",[275,3470,3471,3482,3497,3511,3540,3545],{"__ignoreMap":273},[278,3472,3473,3476,3478,3480],{"class":280,"line":281},[278,3474,3475],{"class":302},"spec ",[278,3477,363],{"class":362},[278,3479,381],{"class":865},[278,3481,907],{"class":327},[278,3483,3484,3486,3488,3490,3493,3495],{"class":280,"line":288},[278,3485,404],{"class":358},[278,3487,363],{"class":362},[278,3489,2310],{"class":965},[278,3491,3492],{"class":1027},"...",[278,3494,2310],{"class":965},[278,3496,917],{"class":327},[278,3498,3499,3501,3503,3505,3507,3509],{"class":280,"line":306},[278,3500,420],{"class":358},[278,3502,363],{"class":362},[278,3504,2310],{"class":965},[278,3506,3492],{"class":1027},[278,3508,2310],{"class":965},[278,3510,917],{"class":327},[278,3512,3513,3515,3517,3519,3521,3523,3525,3527,3530,3532,3534,3537],{"class":280,"line":313},[278,3514,433],{"class":358},[278,3516,363],{"class":362},[278,3518,441],{"class":327},[278,3520,2310],{"class":965},[278,3522,1918],{"class":1027},[278,3524,2310],{"class":965},[278,3526,328],{"class":327},[278,3528,3529],{"class":965}," \"",[278,3531,1922],{"class":1027},[278,3533,2310],{"class":965},[278,3535,3536],{"class":327},"],",[278,3538,3539],{"class":284},"  # read-only subset\n",[278,3541,3542],{"class":280,"line":334},[278,3543,3544],{"class":3129},"    ...\n",[278,3546,3547],{"class":280,"line":339},[278,3548,370],{"class":327},[112,3550,3551,3552,3554],{},"The spawner filters the catalog by ",[275,3553,1132],{},"; tools not in the list aren't even visible to the sub-agent. Combined with the permission manager, this gives you layered scoping: tool list for positive restriction, permission policy for negative enforcement.",[257,3556],{},[260,3558,3560],{"id":3559},"_157-commit","15.7 Commit",[268,3562,3565],{"className":3563,"code":3564,"language":1935,"meta":273,"style":273},"language-bash shiki shiki-themes material-theme-lighter github-light github-dark","git add -A && git commit -m \"ch15: sub-agents — agent-as-tool with spawn budget\"\ngit tag ch15-subagents\n",[275,3566,3567,3598],{"__ignoreMap":273},[278,3568,3569,3572,3575,3579,3582,3585,3588,3591,3593,3596],{"class":280,"line":281},[278,3570,3571],{"class":380},"git",[278,3573,3574],{"class":1027}," add",[278,3576,3578],{"class":3577},"stzsN"," -A",[278,3580,3581],{"class":327}," &&",[278,3583,3584],{"class":380}," git",[278,3586,3587],{"class":1027}," commit",[278,3589,3590],{"class":3577}," -m",[278,3592,3529],{"class":965},[278,3594,3595],{"class":1027},"ch15: sub-agents — agent-as-tool with spawn budget",[278,3597,1344],{"class":965},[278,3599,3600,3602,3605],{"class":280,"line":288},[278,3601,3571],{"class":380},[278,3603,3604],{"class":1027}," tag",[278,3606,3607],{"class":1027}," ch15-subagents\n",[260,3609,3611],{"id":3610},"_158-try-it-yourself","15.8 Try It Yourself",[146,3613,3614,3620,3626],{},[149,3615,3616,3619],{},[152,3617,3618],{},"Measure the overhead."," Run a task that can be done either in-line or by spawning one sub-agent. Compare total tokens, total latency, final output quality. Is the sub-agent ever a net win on a small task? When, if so?",[149,3621,3622,3625],{},[152,3623,3624],{},"Force the Trap."," Rewrite the scenario so the parent's second sub-agent depends on the first's output. Does the compounding-error pattern from the Multi-Agent Trap paper show up? How often does the second sub-agent misread the first's summary?",[149,3627,3628,3631,3632,3634,3635,3638],{},[152,3629,3630],{},"Add a pre-spawn approval policy."," Extend your permission manager so ",[275,3633,3389],{}," triggers an ",[275,3636,3637],{},"ask"," decision every time. Run a long session. Does the prompt frequency match your intuition? Does the justification field tell you enough to decide well?",[257,3640],{},[3642,3643,3644,3647],"what-you-understand",{},[112,3645,3646],{},"The harness can delegate. Sub-agents run in fresh contexts with narrow tool lists and bounded iteration budgets; parents call them via a tool that enforces justifications and output formats; results come back as compact summaries, not full transcripts. One level deep, bounded spawn count per session. The permission layer scopes what a sub-agent can do. The Multi-Agent Trap is mitigated by the friction we built into the spawn tool — empty justifications return errors, tools_allowed must be explicit, output_format is required.",[112,3648,3649],{},"What's still missing: sub-agents today run sequentially. Real research parallelism wants four sub-agents running at once, each pursuing a sub-question, returning when ready. That's coordination across concurrent agents writing to potentially shared state — the subject of Chapter 17. Before that, Chapter 16 fixes a different open gap: the agent's \"plan\" and its \"completion criteria\" have been implicit in prose all along. Making them structured objects unlocks the plan-execution consistency check that catches premature finalization.",[3651,3652,3653],"style",{},"html pre.shiki code .sutJx, html code.shiki .sutJx{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#6A737D;--shiki-dark-font-style:inherit}html pre.shiki code .sVHd0, html code.shiki .sVHd0{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#F97583;--shiki-dark-font-style:inherit}html pre.shiki code .s_hVV, html code.shiki .s_hVV{--shiki-light:#90A4AE;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .su5hD, html code.shiki .su5hD{--shiki-light:#90A4AE;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sP7_E, html code.shiki .sP7_E{--shiki-light:#39ADB5;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .stp6e, html code.shiki .stp6e{--shiki-light:#39ADB5;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sGLFI, html code.shiki .sGLFI{--shiki-light:#6182B8;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .s99_P, html code.shiki .s99_P{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#E36209;--shiki-default-font-style:inherit;--shiki-dark:#FFAB70;--shiki-dark-font-style:inherit}html pre.shiki code .smGrS, html code.shiki .smGrS{--shiki-light:#39ADB5;--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .s39Yj, html code.shiki .s39Yj{--shiki-light:#39ADB5;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sbsja, html code.shiki .sbsja{--shiki-light:#9C3EDA;--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sbgvK, html code.shiki .sbgvK{--shiki-light:#E2931D;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .s2W-s, html code.shiki .s2W-s{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#032F62;--shiki-default-font-style:inherit;--shiki-dark:#9ECBFF;--shiki-dark-font-style:inherit}html pre.shiki code .sithA, html code.shiki .sithA{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#032F62;--shiki-default-font-style:inherit;--shiki-dark:#9ECBFF;--shiki-dark-font-style:inherit}html pre.shiki code .sZMiF, html code.shiki .sZMiF{--shiki-light:#E2931D;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .srdBf, html code.shiki .srdBf{--shiki-light:#F76D47;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .slqww, html code.shiki .slqww{--shiki-light:#6182B8;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .smCYv, html code.shiki .smCYv{--shiki-light:#E53935;--shiki-light-font-style:italic;--shiki-default:#24292E;--shiki-default-font-style:inherit;--shiki-dark:#E1E4E8;--shiki-dark-font-style:inherit}html pre.shiki code .sFwrP, html code.shiki .sFwrP{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#24292E;--shiki-default-font-style:inherit;--shiki-dark:#E1E4E8;--shiki-dark-font-style:inherit}html pre.shiki code .sjJ54, html code.shiki .sjJ54{--shiki-light:#39ADB5;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .skxfh, html code.shiki .skxfh{--shiki-light:#E53935;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .s_sjI, html code.shiki .s_sjI{--shiki-light:#91B859;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sptTA, html code.shiki .sptTA{--shiki-light:#6182B8;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .stzsN, html code.shiki .stzsN{--shiki-light:#91B859;--shiki-default:#005CC5;--shiki-dark:#79B8FF}",{"title":273,"searchDepth":288,"depth":288,"links":3655},[3656,3657,3658,3659,3660,3661,3662,3663],{"id":262,"depth":288,"text":263},{"id":621,"depth":288,"text":622},{"id":2141,"depth":288,"text":2142},{"id":2839,"depth":288,"text":2840},{"id":3415,"depth":288,"text":3416},{"id":3450,"depth":288,"text":3451},{"id":3559,"depth":288,"text":3560},{"id":3610,"depth":288,"text":3611},"md",{},null,{"title":70,"description":117},"2TVCaTQzTJRzt8XzDLwI05uAA-1_u85eMgamqvygpzg",[3670,3672],{"title":66,"path":67,"stem":68,"description":3671,"children":-1},"Previously: MCP lets any external tool server plug into the harness. The harness has also been running happily without any permission controls. This is the moment both facts become untenable.",{"title":74,"path":75,"stem":76,"description":3673,"children":-1},"Previously: sub-agents with bounded delegation. A coordinator can now split work across sub-agents and synthesize. What it cannot yet do — and what single-agent runs also cannot — is verify that what it claims to have done, it actually did.",1776848985382]