[{"data":1,"prerenderedAt":1816},["ShallowReactive",2],{"page-\u002Fprompt-engineering\u002F14-multi-agent-and-agentic-workflows":3},{"id":4,"title":5,"body":6,"description":1809,"extension":1810,"meta":1811,"navigation":58,"path":1812,"seo":1813,"stem":1814,"__hash__":1815},"content\u002Fprompt-engineering\u002F14-multi-agent-and-agentic-workflows.md","14 — Multi-Agent & Agentic Workflows",{"type":7,"value":8,"toc":1797},"minimark",[9,13,18,182,186,231,269,458,462,604,675,679,868,872,965,1012,1016,1054,1392,1396,1500,1504,1623,1627,1631,1667,1671,1793],[10,11,5],"h1",{"id":12},"_14-multi-agent-agentic-workflows",[14,15,17],"h2",{"id":16},"single-agent-vs-multi-agent-the-actual-decision","Single Agent vs. Multi-Agent: The Actual Decision",[19,20,23],"code-wrapper",{"filename":21,"language":22},"single_vs_multi.py","python",[24,25,29],"pre",{"className":26,"code":27,"language":22,"meta":28,"style":28},"language-python shiki shiki-themes github-light github-dark","# An AGENT = a model given a goal + tools + autonomy to decide its own steps.\n# A MULTI-AGENT SYSTEM = autonomy distributed across several narrower agents,\n# coordinated by an orchestrator (which may itself be an agent).\n\n# The instinct to reach for multiple agents the moment a task feels complex is\n# COMMON and OFTEN WRONG. A single agent with good tools and a well-structured\n# prompt handles more than people expect.\n\nMULTI_AGENT_JUSTIFICATION = {\n    \"distinct_tools_permissions\": \"Separate naturally — research agent with web access ≠ code-execution agent with sandbox\",\n    \"parallel_exploration\": \"Several sub-agents investigating different hypotheses\u002Fparts simultaneously\",\n    \"unmanageable_single_context\": \"Agent doing both deep research AND polished prose → prompt\u002Ftools\u002Fcontext all fighting for attention\",\n    \"independent_review\": \"A separate reviewing agent with fresh context, no stake in the original output\",\n}\n\n# If NONE of these apply, a well-designed single agent is usually more reliable\n# and dramatically cheaper to build, debug, and run. The burden of proof is on\n# multi-agent complexity, not on staying simple.\n","",[30,31,32,41,47,53,60,66,72,78,83,98,114,127,140,153,159,164,170,176],"code",{"__ignoreMap":28},[33,34,37],"span",{"class":35,"line":36},"line",1,[33,38,40],{"class":39},"sdCPZ","# An AGENT = a model given a goal + tools + autonomy to decide its own steps.\n",[33,42,44],{"class":35,"line":43},2,[33,45,46],{"class":39},"# A MULTI-AGENT SYSTEM = autonomy distributed across several narrower agents,\n",[33,48,50],{"class":35,"line":49},3,[33,51,52],{"class":39},"# coordinated by an orchestrator (which may itself be an agent).\n",[33,54,56],{"class":35,"line":55},4,[33,57,59],{"emptyLinePlaceholder":58},true,"\n",[33,61,63],{"class":35,"line":62},5,[33,64,65],{"class":39},"# The instinct to reach for multiple agents the moment a task feels complex is\n",[33,67,69],{"class":35,"line":68},6,[33,70,71],{"class":39},"# COMMON and OFTEN WRONG. A single agent with good tools and a well-structured\n",[33,73,75],{"class":35,"line":74},7,[33,76,77],{"class":39},"# prompt handles more than people expect.\n",[33,79,81],{"class":35,"line":80},8,[33,82,59],{"emptyLinePlaceholder":58},[33,84,86,90,94],{"class":35,"line":85},9,[33,87,89],{"class":88},"snvgF","MULTI_AGENT_JUSTIFICATION",[33,91,93],{"class":92},"svdQ7"," =",[33,95,97],{"class":96},"ssxIu"," {\n",[33,99,101,105,108,111],{"class":35,"line":100},10,[33,102,104],{"class":103},"sJ6F3","    \"distinct_tools_permissions\"",[33,106,107],{"class":96},": ",[33,109,110],{"class":103},"\"Separate naturally — research agent with web access ≠ code-execution agent with sandbox\"",[33,112,113],{"class":96},",\n",[33,115,117,120,122,125],{"class":35,"line":116},11,[33,118,119],{"class":103},"    \"parallel_exploration\"",[33,121,107],{"class":96},[33,123,124],{"class":103},"\"Several sub-agents investigating different hypotheses\u002Fparts simultaneously\"",[33,126,113],{"class":96},[33,128,130,133,135,138],{"class":35,"line":129},12,[33,131,132],{"class":103},"    \"unmanageable_single_context\"",[33,134,107],{"class":96},[33,136,137],{"class":103},"\"Agent doing both deep research AND polished prose → prompt\u002Ftools\u002Fcontext all fighting for attention\"",[33,139,113],{"class":96},[33,141,143,146,148,151],{"class":35,"line":142},13,[33,144,145],{"class":103},"    \"independent_review\"",[33,147,107],{"class":96},[33,149,150],{"class":103},"\"A separate reviewing agent with fresh context, no stake in the original output\"",[33,152,113],{"class":96},[33,154,156],{"class":35,"line":155},14,[33,157,158],{"class":96},"}\n",[33,160,162],{"class":35,"line":161},15,[33,163,59],{"emptyLinePlaceholder":58},[33,165,167],{"class":35,"line":166},16,[33,168,169],{"class":39},"# If NONE of these apply, a well-designed single agent is usually more reliable\n",[33,171,173],{"class":35,"line":172},17,[33,174,175],{"class":39},"# and dramatically cheaper to build, debug, and run. The burden of proof is on\n",[33,177,179],{"class":35,"line":178},18,[33,180,181],{"class":39},"# multi-agent complexity, not on staying simple.\n",[14,183,185],{"id":184},"the-orchestratorsub-agent-pattern","The Orchestrator\u002FSub-Agent Pattern",[19,187,190],{"filename":188,"language":189},"orchestrator_prompt.md","markdown",[24,191,194],{"className":192,"code":193,"language":189,"meta":28,"style":28},"language-markdown shiki shiki-themes github-light github-dark","You are a research coordinator. Given a research question, break it into\n2-4 independent sub-questions that can be investigated separately. For each,\ndispatch a research task to a sub-agent with a clear, self-contained brief\n(the sub-agent will not see this conversation, only the brief you write).\nOnce all sub-agent results return, synthesize them into a single coherent\nanswer, noting any contradictions between sub-agent findings rather than\nsilently picking one.\n",[30,195,196,201,206,211,216,221,226],{"__ignoreMap":28},[33,197,198],{"class":35,"line":36},[33,199,200],{"class":96},"You are a research coordinator. Given a research question, break it into\n",[33,202,203],{"class":35,"line":43},[33,204,205],{"class":96},"2-4 independent sub-questions that can be investigated separately. For each,\n",[33,207,208],{"class":35,"line":49},[33,209,210],{"class":96},"dispatch a research task to a sub-agent with a clear, self-contained brief\n",[33,212,213],{"class":35,"line":55},[33,214,215],{"class":96},"(the sub-agent will not see this conversation, only the brief you write).\n",[33,217,218],{"class":35,"line":62},[33,219,220],{"class":96},"Once all sub-agent results return, synthesize them into a single coherent\n",[33,222,223],{"class":35,"line":68},[33,224,225],{"class":96},"answer, noting any contradictions between sub-agent findings rather than\n",[33,227,228],{"class":35,"line":74},[33,229,230],{"class":96},"silently picking one.\n",[19,232,234],{"filename":233,"language":189},"sub_agent_brief.md",[24,235,237],{"className":192,"code":236,"language":189,"meta":28,"style":28},"\u003C!-- Written by the orchestrator, given to a FRESH sub-agent with no other context -->\nResearch task: Determine the current regulatory status of autonomous\nvehicle testing in California as of 2026. Focus on: which agency has\njurisdiction, what permits are required, and any recent (last 12 months)\nrule changes. Cite sources. Do not speculate beyond what your sources\nsupport. Return a structured summary, not raw search results.\n",[30,238,239,244,249,254,259,264],{"__ignoreMap":28},[33,240,241],{"class":35,"line":36},[33,242,243],{"class":39},"\u003C!-- Written by the orchestrator, given to a FRESH sub-agent with no other context -->\n",[33,245,246],{"class":35,"line":43},[33,247,248],{"class":96},"Research task: Determine the current regulatory status of autonomous\n",[33,250,251],{"class":35,"line":49},[33,252,253],{"class":96},"vehicle testing in California as of 2026. Focus on: which agency has\n",[33,255,256],{"class":35,"line":55},[33,257,258],{"class":96},"jurisdiction, what permits are required, and any recent (last 12 months)\n",[33,260,261],{"class":35,"line":62},[33,262,263],{"class":96},"rule changes. Cite sources. Do not speculate beyond what your sources\n",[33,265,266],{"class":35,"line":68},[33,267,268],{"class":96},"support. Return a structured summary, not raw search results.\n",[19,270,272],{"filename":271,"language":22},"sub_agent_isolation.py",[24,273,275],{"className":26,"code":274,"language":22,"meta":28,"style":28},"# CRITICAL: the sub-agent brief is COMPLETE and SELF-CONTAINED.\n# The sub-agent does NOT inherit the orchestrator's full conversation history.\n# It only sees what the orchestrator deliberately writes into the brief.\n\n# This is a FEATURE, not a limitation:\n# - Forces the orchestrator to be EXPLICIT about what context a sub-task needs\n# - Same discipline as Chapter 10's structured pipeline handoffs\n# - Prevents context bloat from accumulating across agent boundaries\n\nasync def dispatch_sub_agent(brief: str, tools: list) -> dict:\n    \"\"\"Run a sub-agent with ONLY the brief — no orchestrator context.\"\"\"\n    sub_agent_messages = [{\"role\": \"user\", \"content\": brief}]\n    result = await run_agent_loop(\n        system_prompt=SUB_AGENT_SYSTEM_PROMPT,\n        tools=tools,\n        messages=sub_agent_messages,\n        max_iterations=5,\n    )\n    return parse_structured_result(result)\n",[30,276,277,282,287,292,296,301,306,311,316,320,353,358,386,399,412,422,432,444,449],{"__ignoreMap":28},[33,278,279],{"class":35,"line":36},[33,280,281],{"class":39},"# CRITICAL: the sub-agent brief is COMPLETE and SELF-CONTAINED.\n",[33,283,284],{"class":35,"line":43},[33,285,286],{"class":39},"# The sub-agent does NOT inherit the orchestrator's full conversation history.\n",[33,288,289],{"class":35,"line":49},[33,290,291],{"class":39},"# It only sees what the orchestrator deliberately writes into the brief.\n",[33,293,294],{"class":35,"line":55},[33,295,59],{"emptyLinePlaceholder":58},[33,297,298],{"class":35,"line":62},[33,299,300],{"class":39},"# This is a FEATURE, not a limitation:\n",[33,302,303],{"class":35,"line":68},[33,304,305],{"class":39},"# - Forces the orchestrator to be EXPLICIT about what context a sub-task needs\n",[33,307,308],{"class":35,"line":74},[33,309,310],{"class":39},"# - Same discipline as Chapter 10's structured pipeline handoffs\n",[33,312,313],{"class":35,"line":80},[33,314,315],{"class":39},"# - Prevents context bloat from accumulating across agent boundaries\n",[33,317,318],{"class":35,"line":85},[33,319,59],{"emptyLinePlaceholder":58},[33,321,322,325,328,332,335,338,341,344,347,350],{"class":35,"line":100},[33,323,324],{"class":92},"async",[33,326,327],{"class":92}," def",[33,329,331],{"class":330},"sIsaT"," dispatch_sub_agent",[33,333,334],{"class":96},"(brief: ",[33,336,337],{"class":88},"str",[33,339,340],{"class":96},", tools: ",[33,342,343],{"class":88},"list",[33,345,346],{"class":96},") -> ",[33,348,349],{"class":88},"dict",[33,351,352],{"class":96},":\n",[33,354,355],{"class":35,"line":116},[33,356,357],{"class":103},"    \"\"\"Run a sub-agent with ONLY the brief — no orchestrator context.\"\"\"\n",[33,359,360,363,366,369,372,374,377,380,383],{"class":35,"line":129},[33,361,362],{"class":96},"    sub_agent_messages ",[33,364,365],{"class":92},"=",[33,367,368],{"class":96}," [{",[33,370,371],{"class":103},"\"role\"",[33,373,107],{"class":96},[33,375,376],{"class":103},"\"user\"",[33,378,379],{"class":96},", ",[33,381,382],{"class":103},"\"content\"",[33,384,385],{"class":96},": brief}]\n",[33,387,388,391,393,396],{"class":35,"line":142},[33,389,390],{"class":96},"    result ",[33,392,365],{"class":92},[33,394,395],{"class":92}," await",[33,397,398],{"class":96}," run_agent_loop(\n",[33,400,401,405,407,410],{"class":35,"line":155},[33,402,404],{"class":403},"sCrzJ","        system_prompt",[33,406,365],{"class":92},[33,408,409],{"class":88},"SUB_AGENT_SYSTEM_PROMPT",[33,411,113],{"class":96},[33,413,414,417,419],{"class":35,"line":161},[33,415,416],{"class":403},"        tools",[33,418,365],{"class":92},[33,420,421],{"class":96},"tools,\n",[33,423,424,427,429],{"class":35,"line":166},[33,425,426],{"class":403},"        messages",[33,428,365],{"class":92},[33,430,431],{"class":96},"sub_agent_messages,\n",[33,433,434,437,439,442],{"class":35,"line":172},[33,435,436],{"class":403},"        max_iterations",[33,438,365],{"class":92},[33,440,441],{"class":88},"5",[33,443,113],{"class":96},[33,445,446],{"class":35,"line":178},[33,447,448],{"class":96},"    )\n",[33,450,452,455],{"class":35,"line":451},19,[33,453,454],{"class":92},"    return",[33,456,457],{"class":96}," parse_structured_result(result)\n",[14,459,461],{"id":460},"structured-handoffs","Structured Handoffs",[19,463,466],{"filename":464,"language":465},"structured_handoff.json","json",[24,467,470],{"className":468,"code":469,"language":465,"meta":28,"style":28},"language-json shiki shiki-themes github-light github-dark","{\n  \"task_id\": \"research-002\",\n  \"status\": \"complete\",\n  \"summary\": \"The DMV has primary jurisdiction over AV testing permits in California; CPUC governs commercial deployment separately.\",\n  \"key_facts\": [\n    {\"fact\": \"SB-XXX amended permit requirements in March 2026\", \"source\": \"ca-dmv.gov\u002Fav-permits\"},\n    {\"fact\": \"CPUC requires separate deployment permit distinct from testing permit\", \"source\": \"cpuc.ca.gov\"}\n  ],\n  \"confidence\": \"high\",\n  \"open_questions\": [\"Unclear whether the March 2026 amendment applies retroactively to existing permit holders\"]\n}\n",[30,471,472,477,489,501,513,521,547,569,574,586,600],{"__ignoreMap":28},[33,473,474],{"class":35,"line":36},[33,475,476],{"class":96},"{\n",[33,478,479,482,484,487],{"class":35,"line":43},[33,480,481],{"class":88},"  \"task_id\"",[33,483,107],{"class":96},[33,485,486],{"class":103},"\"research-002\"",[33,488,113],{"class":96},[33,490,491,494,496,499],{"class":35,"line":49},[33,492,493],{"class":88},"  \"status\"",[33,495,107],{"class":96},[33,497,498],{"class":103},"\"complete\"",[33,500,113],{"class":96},[33,502,503,506,508,511],{"class":35,"line":55},[33,504,505],{"class":88},"  \"summary\"",[33,507,107],{"class":96},[33,509,510],{"class":103},"\"The DMV has primary jurisdiction over AV testing permits in California; CPUC governs commercial deployment separately.\"",[33,512,113],{"class":96},[33,514,515,518],{"class":35,"line":62},[33,516,517],{"class":88},"  \"key_facts\"",[33,519,520],{"class":96},": [\n",[33,522,523,526,529,531,534,536,539,541,544],{"class":35,"line":68},[33,524,525],{"class":96},"    {",[33,527,528],{"class":88},"\"fact\"",[33,530,107],{"class":96},[33,532,533],{"class":103},"\"SB-XXX amended permit requirements in March 2026\"",[33,535,379],{"class":96},[33,537,538],{"class":88},"\"source\"",[33,540,107],{"class":96},[33,542,543],{"class":103},"\"ca-dmv.gov\u002Fav-permits\"",[33,545,546],{"class":96},"},\n",[33,548,549,551,553,555,558,560,562,564,567],{"class":35,"line":74},[33,550,525],{"class":96},[33,552,528],{"class":88},[33,554,107],{"class":96},[33,556,557],{"class":103},"\"CPUC requires separate deployment permit distinct from testing permit\"",[33,559,379],{"class":96},[33,561,538],{"class":88},[33,563,107],{"class":96},[33,565,566],{"class":103},"\"cpuc.ca.gov\"",[33,568,158],{"class":96},[33,570,571],{"class":35,"line":80},[33,572,573],{"class":96},"  ],\n",[33,575,576,579,581,584],{"class":35,"line":85},[33,577,578],{"class":88},"  \"confidence\"",[33,580,107],{"class":96},[33,582,583],{"class":103},"\"high\"",[33,585,113],{"class":96},[33,587,588,591,594,597],{"class":35,"line":100},[33,589,590],{"class":88},"  \"open_questions\"",[33,592,593],{"class":96},": [",[33,595,596],{"class":103},"\"Unclear whether the March 2026 amendment applies retroactively to existing permit holders\"",[33,598,599],{"class":96},"]\n",[33,601,602],{"class":35,"line":116},[33,603,158],{"class":96},[19,605,607],{"filename":606,"language":22},"handoff_vs_transcript.py",[24,608,610],{"className":26,"code":609,"language":22,"meta":28,"style":28},"# A structured handoff (above) vs passing a sub-agent's raw transcript:\n# - Structured: the receiving agent gets exactly what it needs, in a form it can\n#   validate, without re-processing an entire transcript of false starts and tool calls\n# - Transcript: works, but burns context for no benefit — the receiving agent must\n#   parse meaning from free text containing irrelevant exploration\n\n# The `confidence` and `open_questions` fields are particularly important — they\n# let the receiving agent distinguish a well-established finding from a tentative one,\n# rather than treating everything with uniform, unwarranted confidence.\n\n# This mirrors Chapter 10's argument for structured pipeline handoffs precisely:\n# passing a sub-agent's full raw transcript forward = passing unstructured prose\n# between pipeline stages — brittle and context-wasteful.\n",[30,611,612,617,622,627,632,637,641,646,651,656,660,665,670],{"__ignoreMap":28},[33,613,614],{"class":35,"line":36},[33,615,616],{"class":39},"# A structured handoff (above) vs passing a sub-agent's raw transcript:\n",[33,618,619],{"class":35,"line":43},[33,620,621],{"class":39},"# - Structured: the receiving agent gets exactly what it needs, in a form it can\n",[33,623,624],{"class":35,"line":49},[33,625,626],{"class":39},"#   validate, without re-processing an entire transcript of false starts and tool calls\n",[33,628,629],{"class":35,"line":55},[33,630,631],{"class":39},"# - Transcript: works, but burns context for no benefit — the receiving agent must\n",[33,633,634],{"class":35,"line":62},[33,635,636],{"class":39},"#   parse meaning from free text containing irrelevant exploration\n",[33,638,639],{"class":35,"line":68},[33,640,59],{"emptyLinePlaceholder":58},[33,642,643],{"class":35,"line":74},[33,644,645],{"class":39},"# The `confidence` and `open_questions` fields are particularly important — they\n",[33,647,648],{"class":35,"line":80},[33,649,650],{"class":39},"# let the receiving agent distinguish a well-established finding from a tentative one,\n",[33,652,653],{"class":35,"line":85},[33,654,655],{"class":39},"# rather than treating everything with uniform, unwarranted confidence.\n",[33,657,658],{"class":35,"line":100},[33,659,59],{"emptyLinePlaceholder":58},[33,661,662],{"class":35,"line":116},[33,663,664],{"class":39},"# This mirrors Chapter 10's argument for structured pipeline handoffs precisely:\n",[33,666,667],{"class":35,"line":129},[33,668,669],{"class":39},"# passing a sub-agent's full raw transcript forward = passing unstructured prose\n",[33,671,672],{"class":35,"line":142},[33,673,674],{"class":39},"# between pipeline stages — brittle and context-wasteful.\n",[14,676,678],{"id":677},"parallel-vs-sequential-execution","Parallel vs. Sequential Execution",[19,680,682],{"filename":681,"language":22},"parallel_agents.py",[24,683,685],{"className":26,"code":684,"language":22,"meta":28,"style":28},"import asyncio\n\nasync def run_research_agents(sub_questions: list[str]) -> list[dict]:\n    \"\"\"Sub-agents that don't depend on each other → run concurrently.\"\"\"\n    tasks = [dispatch_sub_agent(q, research_tools) for q in sub_questions]\n    results = await asyncio.gather(*tasks)\n    return results\n\nasync def orchestrate(research_question: str) -> dict:\n    sub_questions = await decompose_question(research_question)\n    results = await run_research_agents(sub_questions)\n    synthesized = await synthesize(research_question, results)\n    return synthesized\n\n# Sequential multi-agent chains are necessary when a later agent's task genuinely\n# depends on an earlier one's output (planning agent → execution agent).\n# But should NEVER be the default just because it's simpler to implement —\n# an unnecessarily sequential system pays the full latency cost of every agent's\n# runtime, stacked, for no correctness benefit over a parallel design.\n",[30,686,687,695,699,721,726,748,766,773,777,797,809,820,832,839,843,848,853,858,863],{"__ignoreMap":28},[33,688,689,692],{"class":35,"line":36},[33,690,691],{"class":92},"import",[33,693,694],{"class":96}," asyncio\n",[33,696,697],{"class":35,"line":43},[33,698,59],{"emptyLinePlaceholder":58},[33,700,701,703,705,708,711,713,716,718],{"class":35,"line":49},[33,702,324],{"class":92},[33,704,327],{"class":92},[33,706,707],{"class":330}," run_research_agents",[33,709,710],{"class":96},"(sub_questions: list[",[33,712,337],{"class":88},[33,714,715],{"class":96},"]) -> list[",[33,717,349],{"class":88},[33,719,720],{"class":96},"]:\n",[33,722,723],{"class":35,"line":55},[33,724,725],{"class":103},"    \"\"\"Sub-agents that don't depend on each other → run concurrently.\"\"\"\n",[33,727,728,731,733,736,739,742,745],{"class":35,"line":62},[33,729,730],{"class":96},"    tasks ",[33,732,365],{"class":92},[33,734,735],{"class":96}," [dispatch_sub_agent(q, research_tools) ",[33,737,738],{"class":92},"for",[33,740,741],{"class":96}," q ",[33,743,744],{"class":92},"in",[33,746,747],{"class":96}," sub_questions]\n",[33,749,750,753,755,757,760,763],{"class":35,"line":68},[33,751,752],{"class":96},"    results ",[33,754,365],{"class":92},[33,756,395],{"class":92},[33,758,759],{"class":96}," asyncio.gather(",[33,761,762],{"class":92},"*",[33,764,765],{"class":96},"tasks)\n",[33,767,768,770],{"class":35,"line":74},[33,769,454],{"class":92},[33,771,772],{"class":96}," results\n",[33,774,775],{"class":35,"line":80},[33,776,59],{"emptyLinePlaceholder":58},[33,778,779,781,783,786,789,791,793,795],{"class":35,"line":85},[33,780,324],{"class":92},[33,782,327],{"class":92},[33,784,785],{"class":330}," orchestrate",[33,787,788],{"class":96},"(research_question: ",[33,790,337],{"class":88},[33,792,346],{"class":96},[33,794,349],{"class":88},[33,796,352],{"class":96},[33,798,799,802,804,806],{"class":35,"line":100},[33,800,801],{"class":96},"    sub_questions ",[33,803,365],{"class":92},[33,805,395],{"class":92},[33,807,808],{"class":96}," decompose_question(research_question)\n",[33,810,811,813,815,817],{"class":35,"line":116},[33,812,752],{"class":96},[33,814,365],{"class":92},[33,816,395],{"class":92},[33,818,819],{"class":96}," run_research_agents(sub_questions)\n",[33,821,822,825,827,829],{"class":35,"line":129},[33,823,824],{"class":96},"    synthesized ",[33,826,365],{"class":92},[33,828,395],{"class":92},[33,830,831],{"class":96}," synthesize(research_question, results)\n",[33,833,834,836],{"class":35,"line":142},[33,835,454],{"class":92},[33,837,838],{"class":96}," synthesized\n",[33,840,841],{"class":35,"line":155},[33,842,59],{"emptyLinePlaceholder":58},[33,844,845],{"class":35,"line":161},[33,846,847],{"class":39},"# Sequential multi-agent chains are necessary when a later agent's task genuinely\n",[33,849,850],{"class":35,"line":166},[33,851,852],{"class":39},"# depends on an earlier one's output (planning agent → execution agent).\n",[33,854,855],{"class":35,"line":172},[33,856,857],{"class":39},"# But should NEVER be the default just because it's simpler to implement —\n",[33,859,860],{"class":35,"line":178},[33,861,862],{"class":39},"# an unnecessarily sequential system pays the full latency cost of every agent's\n",[33,864,865],{"class":35,"line":451},[33,866,867],{"class":39},"# runtime, stacked, for no correctness benefit over a parallel design.\n",[14,869,871],{"id":870},"synthesis-step-design","Synthesis Step Design",[19,873,875],{"filename":874,"language":189},"synthesis_prompt.md",[24,876,878],{"className":192,"code":877,"language":189,"meta":28,"style":28},"You have results from three independent research sub-agents on related\nsub-questions. Synthesize a single coherent answer to the original\nquestion: {original_question}\n\nSub-agent results:\n{result_1}\n{result_2}\n{result_3}\n\nWhen synthesizing:\n- If sub-agents agree on a fact, state it directly.\n- If sub-agents disagree or one flagged low confidence, surface the\n  disagreement explicitly rather than silently picking one version.\n- Do not simply concatenate the three results — produce one unified\n  narrative that a reader who never saw the individual sub-agent outputs\n  would find complete and non-repetitive.\n",[30,879,880,885,890,895,899,904,909,914,919,923,928,936,943,948,955,960],{"__ignoreMap":28},[33,881,882],{"class":35,"line":36},[33,883,884],{"class":96},"You have results from three independent research sub-agents on related\n",[33,886,887],{"class":35,"line":43},[33,888,889],{"class":96},"sub-questions. Synthesize a single coherent answer to the original\n",[33,891,892],{"class":35,"line":49},[33,893,894],{"class":96},"question: {original_question}\n",[33,896,897],{"class":35,"line":55},[33,898,59],{"emptyLinePlaceholder":58},[33,900,901],{"class":35,"line":62},[33,902,903],{"class":96},"Sub-agent results:\n",[33,905,906],{"class":35,"line":68},[33,907,908],{"class":96},"{result_1}\n",[33,910,911],{"class":35,"line":74},[33,912,913],{"class":96},"{result_2}\n",[33,915,916],{"class":35,"line":80},[33,917,918],{"class":96},"{result_3}\n",[33,920,921],{"class":35,"line":85},[33,922,59],{"emptyLinePlaceholder":58},[33,924,925],{"class":35,"line":100},[33,926,927],{"class":96},"When synthesizing:\n",[33,929,930,933],{"class":35,"line":116},[33,931,932],{"class":403},"-",[33,934,935],{"class":96}," If sub-agents agree on a fact, state it directly.\n",[33,937,938,940],{"class":35,"line":129},[33,939,932],{"class":403},[33,941,942],{"class":96}," If sub-agents disagree or one flagged low confidence, surface the\n",[33,944,945],{"class":35,"line":142},[33,946,947],{"class":96},"  disagreement explicitly rather than silently picking one version.\n",[33,949,950,952],{"class":35,"line":155},[33,951,932],{"class":403},[33,953,954],{"class":96}," Do not simply concatenate the three results — produce one unified\n",[33,956,957],{"class":35,"line":161},[33,958,959],{"class":96},"  narrative that a reader who never saw the individual sub-agent outputs\n",[33,961,962],{"class":35,"line":166},[33,963,964],{"class":96},"  would find complete and non-repetitive.\n",[19,966,968],{"filename":967,"language":22},"synthesis_principle.py",[24,969,971],{"className":26,"code":970,"language":22,"meta":28,"style":28},"# The synthesis step is EASY TO UNDER-DESIGN. \"Combine these results\" tends to\n# produce shallow concatenation, not genuine integration.\n\n# The explicit instruction to SURFACE DISAGREEMENT matters for the same reason\n# Chapter 12 emphasized it for contradictory retrieved documents:\n# an orchestrator that quietly picks one of two conflicting sub-agent findings\n# is manufacturing FALSE CONFIDENCE — the consumer has no way to know a\n# disagreement ever existed.\n",[30,972,973,978,983,987,992,997,1002,1007],{"__ignoreMap":28},[33,974,975],{"class":35,"line":36},[33,976,977],{"class":39},"# The synthesis step is EASY TO UNDER-DESIGN. \"Combine these results\" tends to\n",[33,979,980],{"class":35,"line":43},[33,981,982],{"class":39},"# produce shallow concatenation, not genuine integration.\n",[33,984,985],{"class":35,"line":49},[33,986,59],{"emptyLinePlaceholder":58},[33,988,989],{"class":35,"line":55},[33,990,991],{"class":39},"# The explicit instruction to SURFACE DISAGREEMENT matters for the same reason\n",[33,993,994],{"class":35,"line":62},[33,995,996],{"class":39},"# Chapter 12 emphasized it for contradictory retrieved documents:\n",[33,998,999],{"class":35,"line":68},[33,1000,1001],{"class":39},"# an orchestrator that quietly picks one of two conflicting sub-agent findings\n",[33,1003,1004],{"class":35,"line":74},[33,1005,1006],{"class":39},"# is manufacturing FALSE CONFIDENCE — the consumer has no way to know a\n",[33,1008,1009],{"class":35,"line":80},[33,1010,1011],{"class":39},"# disagreement ever existed.\n",[14,1013,1015],{"id":1014},"human-in-the-loop-checkpoints","Human-in-the-Loop Checkpoints",[19,1017,1019],{"filename":1018,"language":189},"human_checkpoint.md",[24,1020,1022],{"className":192,"code":1021,"language":189,"meta":28,"style":28},"Before calling any tool that sends external communication (email, Slack\nmessage, API call to a third-party system) or modifies persistent data\n(database writes, file deletions), stop and present the exact action you\nintend to take, including all parameters, for explicit human approval.\nDo not proceed until approval is given. Read-only actions (searches,\nlookups, calculations) do not require this pause.\n",[30,1023,1024,1029,1034,1039,1044,1049],{"__ignoreMap":28},[33,1025,1026],{"class":35,"line":36},[33,1027,1028],{"class":96},"Before calling any tool that sends external communication (email, Slack\n",[33,1030,1031],{"class":35,"line":43},[33,1032,1033],{"class":96},"message, API call to a third-party system) or modifies persistent data\n",[33,1035,1036],{"class":35,"line":49},[33,1037,1038],{"class":96},"(database writes, file deletions), stop and present the exact action you\n",[33,1040,1041],{"class":35,"line":55},[33,1042,1043],{"class":96},"intend to take, including all parameters, for explicit human approval.\n",[33,1045,1046],{"class":35,"line":62},[33,1047,1048],{"class":96},"Do not proceed until approval is given. Read-only actions (searches,\n",[33,1050,1051],{"class":35,"line":68},[33,1052,1053],{"class":96},"lookups, calculations) do not require this pause.\n",[19,1055,1057],{"filename":1056,"language":22},"enforced_checkpoint.py",[24,1058,1060],{"className":26,"code":1059,"language":22,"meta":28,"style":28},"# This instruction is PROMPTED, not ENFORCED — the prompted-vs-enforced distinction\n# from Chapters 7 and 13. For genuinely high-stakes actions, the actual gating\n# belongs in your ARCHITECTURE, not solely in prompt wording.\n\nclass GatedToolExecutor:\n    \"\"\"Architecture-level enforcement: high-stakes tools require human approval.\"\"\"\n    \n    HIGH_STAKES_TOOLS = {\"send_email\", \"refund_order\", \"delete_record\", \"deploy_code\"}\n    \n    async def execute(self, tool_name: str, tool_input: dict) -> dict:\n        if tool_name in self.HIGH_STAKES_TOOLS:\n            # Present to human for approval — the prompt SUGGESTS this, but\n            # the ARCHITECTURE GUARANTEES it. The tool simply can't execute\n            # without a separate approval signal from the application.\n            approval = await self.request_human_approval(tool_name, tool_input)\n            if not approval.approved:\n                return {\"error\": \"Action not approved by human reviewer\", \"reason\": approval.reason}\n        \n        return await self._execute_tool(tool_name, tool_input)\n\n    async def request_human_approval(self, tool_name: str, tool_input: dict) -> dict:\n        \"\"\"Present the action in a way that highlights what's RISKY about it —\n        not just dumping raw parameters for rubber-stamping.\"\"\"\n        return await self.approval_ui.show(\n            tool=tool_name,\n            params=tool_input,\n            risk_flags=self._assess_risk(tool_name, tool_input),\n            # risk_flags highlight: first-time action? unusually large amount?\n            # external recipient? irreversible? — what's DIFFERENT about this call.\n        )\n\n# A checkpoint that dumps raw parameters with no highlighting gets rubber-stamped\n# exactly like naive self-verification (Chapter 11). Design the approval interface\n# to surface what's UNUSUAL or RISKY about this specific action.\n",[30,1061,1062,1067,1072,1077,1081,1091,1096,1101,1131,1135,1161,1182,1187,1192,1197,1211,1222,1245,1250,1262,1267,1291,1297,1303,1315,1326,1337,1351,1357,1363,1369,1374,1380,1386],{"__ignoreMap":28},[33,1063,1064],{"class":35,"line":36},[33,1065,1066],{"class":39},"# This instruction is PROMPTED, not ENFORCED — the prompted-vs-enforced distinction\n",[33,1068,1069],{"class":35,"line":43},[33,1070,1071],{"class":39},"# from Chapters 7 and 13. For genuinely high-stakes actions, the actual gating\n",[33,1073,1074],{"class":35,"line":49},[33,1075,1076],{"class":39},"# belongs in your ARCHITECTURE, not solely in prompt wording.\n",[33,1078,1079],{"class":35,"line":55},[33,1080,59],{"emptyLinePlaceholder":58},[33,1082,1083,1086,1089],{"class":35,"line":62},[33,1084,1085],{"class":92},"class",[33,1087,1088],{"class":330}," GatedToolExecutor",[33,1090,352],{"class":96},[33,1092,1093],{"class":35,"line":68},[33,1094,1095],{"class":103},"    \"\"\"Architecture-level enforcement: high-stakes tools require human approval.\"\"\"\n",[33,1097,1098],{"class":35,"line":74},[33,1099,1100],{"class":96},"    \n",[33,1102,1103,1106,1108,1111,1114,1116,1119,1121,1124,1126,1129],{"class":35,"line":80},[33,1104,1105],{"class":88},"    HIGH_STAKES_TOOLS",[33,1107,93],{"class":92},[33,1109,1110],{"class":96}," {",[33,1112,1113],{"class":103},"\"send_email\"",[33,1115,379],{"class":96},[33,1117,1118],{"class":103},"\"refund_order\"",[33,1120,379],{"class":96},[33,1122,1123],{"class":103},"\"delete_record\"",[33,1125,379],{"class":96},[33,1127,1128],{"class":103},"\"deploy_code\"",[33,1130,158],{"class":96},[33,1132,1133],{"class":35,"line":85},[33,1134,1100],{"class":96},[33,1136,1137,1140,1142,1145,1148,1150,1153,1155,1157,1159],{"class":35,"line":100},[33,1138,1139],{"class":92},"    async",[33,1141,327],{"class":92},[33,1143,1144],{"class":330}," execute",[33,1146,1147],{"class":96},"(self, tool_name: ",[33,1149,337],{"class":88},[33,1151,1152],{"class":96},", tool_input: ",[33,1154,349],{"class":88},[33,1156,346],{"class":96},[33,1158,349],{"class":88},[33,1160,352],{"class":96},[33,1162,1163,1166,1169,1171,1174,1177,1180],{"class":35,"line":116},[33,1164,1165],{"class":92},"        if",[33,1167,1168],{"class":96}," tool_name ",[33,1170,744],{"class":92},[33,1172,1173],{"class":88}," self",[33,1175,1176],{"class":96},".",[33,1178,1179],{"class":88},"HIGH_STAKES_TOOLS",[33,1181,352],{"class":96},[33,1183,1184],{"class":35,"line":129},[33,1185,1186],{"class":39},"            # Present to human for approval — the prompt SUGGESTS this, but\n",[33,1188,1189],{"class":35,"line":142},[33,1190,1191],{"class":39},"            # the ARCHITECTURE GUARANTEES it. The tool simply can't execute\n",[33,1193,1194],{"class":35,"line":155},[33,1195,1196],{"class":39},"            # without a separate approval signal from the application.\n",[33,1198,1199,1202,1204,1206,1208],{"class":35,"line":161},[33,1200,1201],{"class":96},"            approval ",[33,1203,365],{"class":92},[33,1205,395],{"class":92},[33,1207,1173],{"class":88},[33,1209,1210],{"class":96},".request_human_approval(tool_name, tool_input)\n",[33,1212,1213,1216,1219],{"class":35,"line":166},[33,1214,1215],{"class":92},"            if",[33,1217,1218],{"class":92}," not",[33,1220,1221],{"class":96}," approval.approved:\n",[33,1223,1224,1227,1229,1232,1234,1237,1239,1242],{"class":35,"line":172},[33,1225,1226],{"class":92},"                return",[33,1228,1110],{"class":96},[33,1230,1231],{"class":103},"\"error\"",[33,1233,107],{"class":96},[33,1235,1236],{"class":103},"\"Action not approved by human reviewer\"",[33,1238,379],{"class":96},[33,1240,1241],{"class":103},"\"reason\"",[33,1243,1244],{"class":96},": approval.reason}\n",[33,1246,1247],{"class":35,"line":178},[33,1248,1249],{"class":96},"        \n",[33,1251,1252,1255,1257,1259],{"class":35,"line":451},[33,1253,1254],{"class":92},"        return",[33,1256,395],{"class":92},[33,1258,1173],{"class":88},[33,1260,1261],{"class":96},"._execute_tool(tool_name, tool_input)\n",[33,1263,1265],{"class":35,"line":1264},20,[33,1266,59],{"emptyLinePlaceholder":58},[33,1268,1270,1272,1274,1277,1279,1281,1283,1285,1287,1289],{"class":35,"line":1269},21,[33,1271,1139],{"class":92},[33,1273,327],{"class":92},[33,1275,1276],{"class":330}," request_human_approval",[33,1278,1147],{"class":96},[33,1280,337],{"class":88},[33,1282,1152],{"class":96},[33,1284,349],{"class":88},[33,1286,346],{"class":96},[33,1288,349],{"class":88},[33,1290,352],{"class":96},[33,1292,1294],{"class":35,"line":1293},22,[33,1295,1296],{"class":103},"        \"\"\"Present the action in a way that highlights what's RISKY about it —\n",[33,1298,1300],{"class":35,"line":1299},23,[33,1301,1302],{"class":103},"        not just dumping raw parameters for rubber-stamping.\"\"\"\n",[33,1304,1306,1308,1310,1312],{"class":35,"line":1305},24,[33,1307,1254],{"class":92},[33,1309,395],{"class":92},[33,1311,1173],{"class":88},[33,1313,1314],{"class":96},".approval_ui.show(\n",[33,1316,1318,1321,1323],{"class":35,"line":1317},25,[33,1319,1320],{"class":403},"            tool",[33,1322,365],{"class":92},[33,1324,1325],{"class":96},"tool_name,\n",[33,1327,1329,1332,1334],{"class":35,"line":1328},26,[33,1330,1331],{"class":403},"            params",[33,1333,365],{"class":92},[33,1335,1336],{"class":96},"tool_input,\n",[33,1338,1340,1343,1345,1348],{"class":35,"line":1339},27,[33,1341,1342],{"class":403},"            risk_flags",[33,1344,365],{"class":92},[33,1346,1347],{"class":88},"self",[33,1349,1350],{"class":96},"._assess_risk(tool_name, tool_input),\n",[33,1352,1354],{"class":35,"line":1353},28,[33,1355,1356],{"class":39},"            # risk_flags highlight: first-time action? unusually large amount?\n",[33,1358,1360],{"class":35,"line":1359},29,[33,1361,1362],{"class":39},"            # external recipient? irreversible? — what's DIFFERENT about this call.\n",[33,1364,1366],{"class":35,"line":1365},30,[33,1367,1368],{"class":96},"        )\n",[33,1370,1372],{"class":35,"line":1371},31,[33,1373,59],{"emptyLinePlaceholder":58},[33,1375,1377],{"class":35,"line":1376},32,[33,1378,1379],{"class":39},"# A checkpoint that dumps raw parameters with no highlighting gets rubber-stamped\n",[33,1381,1383],{"class":35,"line":1382},33,[33,1384,1385],{"class":39},"# exactly like naive self-verification (Chapter 11). Design the approval interface\n",[33,1387,1389],{"class":35,"line":1388},34,[33,1390,1391],{"class":39},"# to surface what's UNUSUAL or RISKY about this specific action.\n",[14,1393,1395],{"id":1394},"tips-tricks","💡 Tips & Tricks",[19,1397,1399],{"filename":1398,"language":22},"tips.py",[24,1400,1402],{"className":26,"code":1401,"language":22,"meta":28,"style":28},"# [Idiom] Start with a single agent and only split when you have a CONCRETE,\n# SPECIFIC reason. Write down the specific failure a single agent hit before\n# reaching for multi-agent. \"It felt complex\" is not specific enough.\n\n# [Idiom] Give every sub-agent brief a strict, explicit scope boundary.\n# \"research the regulatory landscape\" → wanders broadly.\n# \"determine which agency has AV testing jurisdiction in CA, as of 2026\" → stays on-task.\n\n# [Debug] Log every agent's full input and output, keyed by task id, from day one.\n# Retrofitting observability into a multi-agent system after it's already misbehaving\n# in production is dramatically harder. Diffused accountability makes post-hoc\n# debugging hard without per-agent logging.\n\n# [Idiom] Cap total sub-agent dispatches and total orchestration rounds explicitly.\n# An unbounded \"re-dispatch until satisfied\" loop is a cost and latency risk that's\n# easy to overlook during development and expensive to discover in production.\n\n# [Idiom] Treat the orchestrator's synthesis prompt with as much care as any\n# sub-agent's. It's often where the most consequential integration errors happen:\n# silently resolved contradictions, dropped caveats.\n",[30,1403,1404,1409,1414,1419,1423,1428,1433,1438,1442,1447,1452,1457,1462,1466,1471,1476,1481,1485,1490,1495],{"__ignoreMap":28},[33,1405,1406],{"class":35,"line":36},[33,1407,1408],{"class":39},"# [Idiom] Start with a single agent and only split when you have a CONCRETE,\n",[33,1410,1411],{"class":35,"line":43},[33,1412,1413],{"class":39},"# SPECIFIC reason. Write down the specific failure a single agent hit before\n",[33,1415,1416],{"class":35,"line":49},[33,1417,1418],{"class":39},"# reaching for multi-agent. \"It felt complex\" is not specific enough.\n",[33,1420,1421],{"class":35,"line":55},[33,1422,59],{"emptyLinePlaceholder":58},[33,1424,1425],{"class":35,"line":62},[33,1426,1427],{"class":39},"# [Idiom] Give every sub-agent brief a strict, explicit scope boundary.\n",[33,1429,1430],{"class":35,"line":68},[33,1431,1432],{"class":39},"# \"research the regulatory landscape\" → wanders broadly.\n",[33,1434,1435],{"class":35,"line":74},[33,1436,1437],{"class":39},"# \"determine which agency has AV testing jurisdiction in CA, as of 2026\" → stays on-task.\n",[33,1439,1440],{"class":35,"line":80},[33,1441,59],{"emptyLinePlaceholder":58},[33,1443,1444],{"class":35,"line":85},[33,1445,1446],{"class":39},"# [Debug] Log every agent's full input and output, keyed by task id, from day one.\n",[33,1448,1449],{"class":35,"line":100},[33,1450,1451],{"class":39},"# Retrofitting observability into a multi-agent system after it's already misbehaving\n",[33,1453,1454],{"class":35,"line":116},[33,1455,1456],{"class":39},"# in production is dramatically harder. Diffused accountability makes post-hoc\n",[33,1458,1459],{"class":35,"line":129},[33,1460,1461],{"class":39},"# debugging hard without per-agent logging.\n",[33,1463,1464],{"class":35,"line":142},[33,1465,59],{"emptyLinePlaceholder":58},[33,1467,1468],{"class":35,"line":155},[33,1469,1470],{"class":39},"# [Idiom] Cap total sub-agent dispatches and total orchestration rounds explicitly.\n",[33,1472,1473],{"class":35,"line":161},[33,1474,1475],{"class":39},"# An unbounded \"re-dispatch until satisfied\" loop is a cost and latency risk that's\n",[33,1477,1478],{"class":35,"line":166},[33,1479,1480],{"class":39},"# easy to overlook during development and expensive to discover in production.\n",[33,1482,1483],{"class":35,"line":172},[33,1484,59],{"emptyLinePlaceholder":58},[33,1486,1487],{"class":35,"line":178},[33,1488,1489],{"class":39},"# [Idiom] Treat the orchestrator's synthesis prompt with as much care as any\n",[33,1491,1492],{"class":35,"line":451},[33,1493,1494],{"class":39},"# sub-agent's. It's often where the most consequential integration errors happen:\n",[33,1496,1497],{"class":35,"line":1264},[33,1498,1499],{"class":39},"# silently resolved contradictions, dropped caveats.\n",[14,1501,1503],{"id":1502},"️-edge-cases-gotchas","⚠️ Edge Cases & Gotchas",[19,1505,1507],{"filename":1506,"language":22},"edge_cases.py",[24,1508,1510],{"className":26,"code":1509,"language":22,"meta":28,"style":28},"# [Gotcha] A sub-agent with too little context makes confidently wrong assumptions\n# — a brief omitting a constraint the orchestrator considered \"obvious\" produces a\n# technically-responsive but practically-useless result, with no way for the sub-agent\n# to know what it wasn't told.\n\n# [Safety] Multi-agent systems can be MORE vulnerable to prompt injection, not less.\n# Untrusted content encountered by one sub-agent can be passed along in its report\n# and influence the orchestrator downstream — laundering an injection through what\n# looks like a trusted internal handoff. Treat sub-agent outputs derived from\n# untrusted sources with the SAME caution as the original untrusted content (Chapter 18).\n\n# [Gotcha] Parallel sub-agents can silently DUPLICATE cost on overlapping work if\n# the orchestrator's decomposition wasn't actually independent — two \"independent\"\n# sub-questions requiring the same source waste tokens and produce conflicting partials.\n\n# [Gotcha] A synthesis step can be fooled by confidence mismatches — a sub-agent\n# phrasing a shaky finding assertively and another hedging a solid finding leads\n# the orchestrator to weight them backwards, unless briefs require honest confidence.\n\n# [Safety] Human-in-the-loop checkpoints only work if a human is actually positioned\n# to catch a problem — a wall of tool-call parameters with no highlighting gets\n# rubber-stamped. Design the approval interface to highlight what's RISKY about\n# this specific action.\n",[30,1511,1512,1517,1522,1527,1532,1536,1541,1546,1551,1556,1561,1565,1570,1575,1580,1584,1589,1594,1599,1603,1608,1613,1618],{"__ignoreMap":28},[33,1513,1514],{"class":35,"line":36},[33,1515,1516],{"class":39},"# [Gotcha] A sub-agent with too little context makes confidently wrong assumptions\n",[33,1518,1519],{"class":35,"line":43},[33,1520,1521],{"class":39},"# — a brief omitting a constraint the orchestrator considered \"obvious\" produces a\n",[33,1523,1524],{"class":35,"line":49},[33,1525,1526],{"class":39},"# technically-responsive but practically-useless result, with no way for the sub-agent\n",[33,1528,1529],{"class":35,"line":55},[33,1530,1531],{"class":39},"# to know what it wasn't told.\n",[33,1533,1534],{"class":35,"line":62},[33,1535,59],{"emptyLinePlaceholder":58},[33,1537,1538],{"class":35,"line":68},[33,1539,1540],{"class":39},"# [Safety] Multi-agent systems can be MORE vulnerable to prompt injection, not less.\n",[33,1542,1543],{"class":35,"line":74},[33,1544,1545],{"class":39},"# Untrusted content encountered by one sub-agent can be passed along in its report\n",[33,1547,1548],{"class":35,"line":80},[33,1549,1550],{"class":39},"# and influence the orchestrator downstream — laundering an injection through what\n",[33,1552,1553],{"class":35,"line":85},[33,1554,1555],{"class":39},"# looks like a trusted internal handoff. Treat sub-agent outputs derived from\n",[33,1557,1558],{"class":35,"line":100},[33,1559,1560],{"class":39},"# untrusted sources with the SAME caution as the original untrusted content (Chapter 18).\n",[33,1562,1563],{"class":35,"line":116},[33,1564,59],{"emptyLinePlaceholder":58},[33,1566,1567],{"class":35,"line":129},[33,1568,1569],{"class":39},"# [Gotcha] Parallel sub-agents can silently DUPLICATE cost on overlapping work if\n",[33,1571,1572],{"class":35,"line":142},[33,1573,1574],{"class":39},"# the orchestrator's decomposition wasn't actually independent — two \"independent\"\n",[33,1576,1577],{"class":35,"line":155},[33,1578,1579],{"class":39},"# sub-questions requiring the same source waste tokens and produce conflicting partials.\n",[33,1581,1582],{"class":35,"line":161},[33,1583,59],{"emptyLinePlaceholder":58},[33,1585,1586],{"class":35,"line":166},[33,1587,1588],{"class":39},"# [Gotcha] A synthesis step can be fooled by confidence mismatches — a sub-agent\n",[33,1590,1591],{"class":35,"line":172},[33,1592,1593],{"class":39},"# phrasing a shaky finding assertively and another hedging a solid finding leads\n",[33,1595,1596],{"class":35,"line":178},[33,1597,1598],{"class":39},"# the orchestrator to weight them backwards, unless briefs require honest confidence.\n",[33,1600,1601],{"class":35,"line":451},[33,1602,59],{"emptyLinePlaceholder":58},[33,1604,1605],{"class":35,"line":1264},[33,1606,1607],{"class":39},"# [Safety] Human-in-the-loop checkpoints only work if a human is actually positioned\n",[33,1609,1610],{"class":35,"line":1269},[33,1611,1612],{"class":39},"# to catch a problem — a wall of tool-call parameters with no highlighting gets\n",[33,1614,1615],{"class":35,"line":1293},[33,1616,1617],{"class":39},"# rubber-stamped. Design the approval interface to highlight what's RISKY about\n",[33,1619,1620],{"class":35,"line":1299},[33,1621,1622],{"class":39},"# this specific action.\n",[14,1624,1626],{"id":1625},"spot-the-bug","🧠 Spot the Bug",[1628,1629,1630],"p",{},"A multi-agent system: triage agent classifies issues and dispatches to one of three specialists (billing\u002Ftechnical\u002Faccount). Each specialist independently resolves and responds directly to the customer. A message mentions a billing issue AND an account lockout. Triage classifies as BILLING, passes only a one-line billing summary. The billing specialist resolves the billing question and closes the ticket — the account lockout is never addressed. What's the architectural flaw?",[1632,1633,1634,1638,1641,1649,1659],"details",{},[1635,1636,1637],"summary",{},"Answer",[1628,1639,1640],{},"The triage agent's brief was reduced to a single classification-driven summary, which necessarily discards anything that doesn't fit the chosen category. The account lockout was lost because the billing specialist never saw it, and the triage agent's one-line summary didn't include it.",[1628,1642,1643,1644,1648],{},"A better prompt for the triage agent (explicitly instructing it to flag ALL distinct issues, not just the primary one) would help marginally. But the deeper fix is ",[1645,1646,1647],"strong",{},"structural",": a message containing multiple distinct issues shouldn't be forced through a single-category dispatch at all. The more robust architecture either:",[1650,1651,1652,1656],"ol",{},[1653,1654,1655],"li",{},"Lets the triage agent dispatch to multiple specialists when multiple distinct issues are present, or",[1653,1657,1658],{},"Passes the FULL original customer message to the specialist (not a lossy one-line summary), so the specialist can notice a secondary issue outside its specialty and flag it for escalation.",[1628,1660,1661,1662,1666],{},"The lesson: forcing a multi-issue input through a single classification-and-summarize handoff will systematically lose whatever the classification step didn't prioritize. When messages can contain more than one distinct concern, the handoff ",[1663,1664,1665],"em",{},"design"," (not just the prompt wording) needs to account for that.",[14,1668,1670],{"id":1669},"key-takeaways","Key Takeaways",[19,1672,1674],{"filename":1673,"language":22},"key_takeaways.py",[24,1675,1677],{"className":26,"code":1676,"language":22,"meta":28,"style":28},"\"\"\"\nMulti-agent & agentic workflows — distributing autonomy.\n\"\"\"\n\n# 1. An agent = goal + tools + autonomy. Multi-agent = autonomy across narrower\n#    agents coordinated by an orchestrator. Treat multi-agent as added-complexity\n#    needing SPECIFIC justification, not a default for anything complex.\n\n# 2. Multi-agent earns its cost when: roles need different tools\u002Fpermissions,\n#    parallel exploration is valuable, single-agent context would be unmanageable,\n#    or an independent reviewing agent provides a real check.\n\n# 3. Sub-agent briefs must be COMPLETE and SELF-CONTAINED — sub-agents don't\n#    inherit orchestrator context. Handoffs should be STRUCTURED (facts, confidence,\n#    open_questions), not raw transcripts.\n\n# 4. Multi-agent failure modes: ambiguous handoffs, redundant\u002Fcontradictory parallel\n#    work, runaway coordination loops, diffused accountability. Log everything\n#    per-agent from day one — debugging without per-agent logs is nearly impossible.\n\n# 5. Prompted caution (\"ask for approval before high-stakes actions\") must be backed\n#    by ARCHITECTURAL enforcement for genuinely irreversible actions. And human\n#    checkpoints must highlight what's RISKY about a specific action — not just\n#    dump parameters for rubber-stamping.\n",[30,1678,1679,1684,1689,1693,1697,1702,1707,1712,1716,1721,1726,1731,1735,1740,1745,1750,1754,1759,1764,1769,1773,1778,1783,1788],{"__ignoreMap":28},[33,1680,1681],{"class":35,"line":36},[33,1682,1683],{"class":103},"\"\"\"\n",[33,1685,1686],{"class":35,"line":43},[33,1687,1688],{"class":103},"Multi-agent & agentic workflows — distributing autonomy.\n",[33,1690,1691],{"class":35,"line":49},[33,1692,1683],{"class":103},[33,1694,1695],{"class":35,"line":55},[33,1696,59],{"emptyLinePlaceholder":58},[33,1698,1699],{"class":35,"line":62},[33,1700,1701],{"class":39},"# 1. An agent = goal + tools + autonomy. Multi-agent = autonomy across narrower\n",[33,1703,1704],{"class":35,"line":68},[33,1705,1706],{"class":39},"#    agents coordinated by an orchestrator. Treat multi-agent as added-complexity\n",[33,1708,1709],{"class":35,"line":74},[33,1710,1711],{"class":39},"#    needing SPECIFIC justification, not a default for anything complex.\n",[33,1713,1714],{"class":35,"line":80},[33,1715,59],{"emptyLinePlaceholder":58},[33,1717,1718],{"class":35,"line":85},[33,1719,1720],{"class":39},"# 2. Multi-agent earns its cost when: roles need different tools\u002Fpermissions,\n",[33,1722,1723],{"class":35,"line":100},[33,1724,1725],{"class":39},"#    parallel exploration is valuable, single-agent context would be unmanageable,\n",[33,1727,1728],{"class":35,"line":116},[33,1729,1730],{"class":39},"#    or an independent reviewing agent provides a real check.\n",[33,1732,1733],{"class":35,"line":129},[33,1734,59],{"emptyLinePlaceholder":58},[33,1736,1737],{"class":35,"line":142},[33,1738,1739],{"class":39},"# 3. Sub-agent briefs must be COMPLETE and SELF-CONTAINED — sub-agents don't\n",[33,1741,1742],{"class":35,"line":155},[33,1743,1744],{"class":39},"#    inherit orchestrator context. Handoffs should be STRUCTURED (facts, confidence,\n",[33,1746,1747],{"class":35,"line":161},[33,1748,1749],{"class":39},"#    open_questions), not raw transcripts.\n",[33,1751,1752],{"class":35,"line":166},[33,1753,59],{"emptyLinePlaceholder":58},[33,1755,1756],{"class":35,"line":172},[33,1757,1758],{"class":39},"# 4. Multi-agent failure modes: ambiguous handoffs, redundant\u002Fcontradictory parallel\n",[33,1760,1761],{"class":35,"line":178},[33,1762,1763],{"class":39},"#    work, runaway coordination loops, diffused accountability. Log everything\n",[33,1765,1766],{"class":35,"line":451},[33,1767,1768],{"class":39},"#    per-agent from day one — debugging without per-agent logs is nearly impossible.\n",[33,1770,1771],{"class":35,"line":1264},[33,1772,59],{"emptyLinePlaceholder":58},[33,1774,1775],{"class":35,"line":1269},[33,1776,1777],{"class":39},"# 5. Prompted caution (\"ask for approval before high-stakes actions\") must be backed\n",[33,1779,1780],{"class":35,"line":1293},[33,1781,1782],{"class":39},"#    by ARCHITECTURAL enforcement for genuinely irreversible actions. And human\n",[33,1784,1785],{"class":35,"line":1299},[33,1786,1787],{"class":39},"#    checkpoints must highlight what's RISKY about a specific action — not just\n",[33,1789,1790],{"class":35,"line":1305},[33,1791,1792],{"class":39},"#    dump parameters for rubber-stamping.\n",[1794,1795,1796],"style",{},"html pre.shiki code .sdCPZ, html code.shiki .sdCPZ{--shiki-default:#6A737D;--shiki-github-dark:#6A737D}html pre.shiki code .snvgF, html code.shiki .snvgF{--shiki-default:#005CC5;--shiki-github-dark:#79B8FF}html pre.shiki code .svdQ7, html code.shiki .svdQ7{--shiki-default:#D73A49;--shiki-github-dark:#F97583}html pre.shiki code .ssxIu, html code.shiki .ssxIu{--shiki-default:#24292E;--shiki-github-dark:#E1E4E8}html pre.shiki code .sJ6F3, html code.shiki .sJ6F3{--shiki-default:#032F62;--shiki-github-dark:#9ECBFF}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 .github-dark .shiki span {color: var(--shiki-github-dark);background: var(--shiki-github-dark-bg);font-style: var(--shiki-github-dark-font-style);font-weight: var(--shiki-github-dark-font-weight);text-decoration: var(--shiki-github-dark-text-decoration);}html.github-dark .shiki span {color: var(--shiki-github-dark);background: var(--shiki-github-dark-bg);font-style: var(--shiki-github-dark-font-style);font-weight: var(--shiki-github-dark-font-weight);text-decoration: var(--shiki-github-dark-text-decoration);}html pre.shiki code .sIsaT, html code.shiki .sIsaT{--shiki-default:#6F42C1;--shiki-github-dark:#B392F0}html pre.shiki code .sCrzJ, html code.shiki .sCrzJ{--shiki-default:#E36209;--shiki-github-dark:#FFAB70}",{"title":28,"searchDepth":43,"depth":43,"links":1798},[1799,1800,1801,1802,1803,1804,1805,1806,1807,1808],{"id":16,"depth":43,"text":17},{"id":184,"depth":43,"text":185},{"id":460,"depth":43,"text":461},{"id":677,"depth":43,"text":678},{"id":870,"depth":43,"text":871},{"id":1014,"depth":43,"text":1015},{"id":1394,"depth":43,"text":1395},{"id":1502,"depth":43,"text":1503},{"id":1625,"depth":43,"text":1626},{"id":1669,"depth":43,"text":1670},"Orchestrator\u002Fsub-agent patterns, structured handoffs, parallel vs sequential execution, synthesis design, human-in-the-loop checkpoints, and multi-agent failure modes. Code-first reference for mid-to-senior engineers.","md",{},"\u002Fprompt-engineering\u002F14-multi-agent-and-agentic-workflows",{"title":5,"description":1809},"prompt-engineering\u002F14-multi-agent-and-agentic-workflows","kMTzqGjf6JRyegYZ-JsHXrKTkCctdpUONt79z871As4",1789924651056]