[{"data":1,"prerenderedAt":2271},["ShallowReactive",2],{"page-\u002Fprompt-engineering\u002F10-decomposition-and-task-breakdown":3},{"id":4,"title":5,"body":6,"description":2264,"extension":2265,"meta":2266,"navigation":73,"path":2267,"seo":2268,"stem":2269,"__hash__":2270},"content\u002Fprompt-engineering\u002F10-decomposition-and-task-breakdown.md","10 — Decomposition & Task Breakdown",{"type":7,"value":8,"toc":2252},"minimark",[9,13,18,328,332,624,628,1048,1052,1286,1290,1581,1585,1844,1848,1972,1976,2105,2109,2113,2143,2147,2248],[10,11,5],"h1",{"id":12},"_10-decomposition-task-breakdown",[14,15,17],"h2",{"id":16},"one-giant-prompt-vs-several-focused-ones","One Giant Prompt vs. Several Focused Ones",[19,20,23],"code-wrapper",{"filename":21,"language":22},"monolithic_vs_decomposed.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","# ANTI-PATTERN: one monolithic prompt doing 5 things at once\nMONOLITHIC_PROMPT = \"\"\"\nRead this contract. Summarize it, flag risky clauses, draft a response email\naddressing the risky clauses, and translate the email to Spanish.\n\nContract: [long legal document]\n\"\"\"\n# Every part is individually something the model handles well. Bundled, quality\n# on each part quietly degrades — the model divides a fixed attention and output\n# budget across 5 sub-tasks, each competing for the same context, with no ability\n# to fully \"finish\" one before starting the next.\n\n# PRODUCTION: decompose into a pipeline, each step with one job\nDECOMPOSED_PIPELINE = [\n    {\"step\": 1, \"job\": \"summarize\", \"input\": \"contract_text\", \"output\": \"summary\"},\n    {\"step\": 2, \"job\": \"risk_analysis\", \"input\": \"summary + contract\", \"output\": \"risk_list\"},\n    {\"step\": 3, \"job\": \"draft_email\", \"input\": \"risk_list\", \"output\": \"email_draft\"},\n    {\"step\": 4, \"job\": \"translate\", \"input\": \"email_draft\", \"output\": \"spanish_email\"},\n]\n# Each step: one job, independently testable, can use different techniques\u002Fmodels,\n# and produces an intermediate artifact a human can inspect\u002Fcorrect BEFORE it feeds\n# into the next step — rather than only reviewing a single opaque final output.\n","",[30,31,32,41,56,62,68,75,81,87,93,99,105,111,116,122,134,183,224,264,304,310,316,322],"code",{"__ignoreMap":28},[33,34,37],"span",{"class":35,"line":36},"line",1,[33,38,40],{"class":39},"sdCPZ","# ANTI-PATTERN: one monolithic prompt doing 5 things at once\n",[33,42,44,48,52],{"class":35,"line":43},2,[33,45,47],{"class":46},"snvgF","MONOLITHIC_PROMPT",[33,49,51],{"class":50},"svdQ7"," =",[33,53,55],{"class":54},"sJ6F3"," \"\"\"\n",[33,57,59],{"class":35,"line":58},3,[33,60,61],{"class":54},"Read this contract. Summarize it, flag risky clauses, draft a response email\n",[33,63,65],{"class":35,"line":64},4,[33,66,67],{"class":54},"addressing the risky clauses, and translate the email to Spanish.\n",[33,69,71],{"class":35,"line":70},5,[33,72,74],{"emptyLinePlaceholder":73},true,"\n",[33,76,78],{"class":35,"line":77},6,[33,79,80],{"class":54},"Contract: [long legal document]\n",[33,82,84],{"class":35,"line":83},7,[33,85,86],{"class":54},"\"\"\"\n",[33,88,90],{"class":35,"line":89},8,[33,91,92],{"class":39},"# Every part is individually something the model handles well. Bundled, quality\n",[33,94,96],{"class":35,"line":95},9,[33,97,98],{"class":39},"# on each part quietly degrades — the model divides a fixed attention and output\n",[33,100,102],{"class":35,"line":101},10,[33,103,104],{"class":39},"# budget across 5 sub-tasks, each competing for the same context, with no ability\n",[33,106,108],{"class":35,"line":107},11,[33,109,110],{"class":39},"# to fully \"finish\" one before starting the next.\n",[33,112,114],{"class":35,"line":113},12,[33,115,74],{"emptyLinePlaceholder":73},[33,117,119],{"class":35,"line":118},13,[33,120,121],{"class":39},"# PRODUCTION: decompose into a pipeline, each step with one job\n",[33,123,125,128,130],{"class":35,"line":124},14,[33,126,127],{"class":46},"DECOMPOSED_PIPELINE",[33,129,51],{"class":50},[33,131,133],{"class":132},"ssxIu"," [\n",[33,135,137,140,143,146,149,152,155,157,160,162,165,167,170,172,175,177,180],{"class":35,"line":136},15,[33,138,139],{"class":132},"    {",[33,141,142],{"class":54},"\"step\"",[33,144,145],{"class":132},": ",[33,147,148],{"class":46},"1",[33,150,151],{"class":132},", ",[33,153,154],{"class":54},"\"job\"",[33,156,145],{"class":132},[33,158,159],{"class":54},"\"summarize\"",[33,161,151],{"class":132},[33,163,164],{"class":54},"\"input\"",[33,166,145],{"class":132},[33,168,169],{"class":54},"\"contract_text\"",[33,171,151],{"class":132},[33,173,174],{"class":54},"\"output\"",[33,176,145],{"class":132},[33,178,179],{"class":54},"\"summary\"",[33,181,182],{"class":132},"},\n",[33,184,186,188,190,192,195,197,199,201,204,206,208,210,213,215,217,219,222],{"class":35,"line":185},16,[33,187,139],{"class":132},[33,189,142],{"class":54},[33,191,145],{"class":132},[33,193,194],{"class":46},"2",[33,196,151],{"class":132},[33,198,154],{"class":54},[33,200,145],{"class":132},[33,202,203],{"class":54},"\"risk_analysis\"",[33,205,151],{"class":132},[33,207,164],{"class":54},[33,209,145],{"class":132},[33,211,212],{"class":54},"\"summary + contract\"",[33,214,151],{"class":132},[33,216,174],{"class":54},[33,218,145],{"class":132},[33,220,221],{"class":54},"\"risk_list\"",[33,223,182],{"class":132},[33,225,227,229,231,233,236,238,240,242,245,247,249,251,253,255,257,259,262],{"class":35,"line":226},17,[33,228,139],{"class":132},[33,230,142],{"class":54},[33,232,145],{"class":132},[33,234,235],{"class":46},"3",[33,237,151],{"class":132},[33,239,154],{"class":54},[33,241,145],{"class":132},[33,243,244],{"class":54},"\"draft_email\"",[33,246,151],{"class":132},[33,248,164],{"class":54},[33,250,145],{"class":132},[33,252,221],{"class":54},[33,254,151],{"class":132},[33,256,174],{"class":54},[33,258,145],{"class":132},[33,260,261],{"class":54},"\"email_draft\"",[33,263,182],{"class":132},[33,265,267,269,271,273,276,278,280,282,285,287,289,291,293,295,297,299,302],{"class":35,"line":266},18,[33,268,139],{"class":132},[33,270,142],{"class":54},[33,272,145],{"class":132},[33,274,275],{"class":46},"4",[33,277,151],{"class":132},[33,279,154],{"class":54},[33,281,145],{"class":132},[33,283,284],{"class":54},"\"translate\"",[33,286,151],{"class":132},[33,288,164],{"class":54},[33,290,145],{"class":132},[33,292,261],{"class":54},[33,294,151],{"class":132},[33,296,174],{"class":54},[33,298,145],{"class":132},[33,300,301],{"class":54},"\"spanish_email\"",[33,303,182],{"class":132},[33,305,307],{"class":35,"line":306},19,[33,308,309],{"class":132},"]\n",[33,311,313],{"class":35,"line":312},20,[33,314,315],{"class":39},"# Each step: one job, independently testable, can use different techniques\u002Fmodels,\n",[33,317,319],{"class":35,"line":318},21,[33,320,321],{"class":39},"# and produces an intermediate artifact a human can inspect\u002Fcorrect BEFORE it feeds\n",[33,323,325],{"class":35,"line":324},22,[33,326,327],{"class":39},"# into the next step — rather than only reviewing a single opaque final output.\n",[14,329,331],{"id":330},"sequential-vs-parallel-decomposition","Sequential vs. Parallel Decomposition",[19,333,335],{"filename":334,"language":22},"parallel_decomposition.py",[24,336,338],{"className":26,"code":337,"language":22,"meta":28,"style":28},"import asyncio\n\nasync def call_model(prompt: str) -> str:\n    \"\"\"Simulated model call.\"\"\"\n    await asyncio.sleep(0.5)  # simulate latency\n    return f\"result for: {prompt[:50]}\"\n\nasync def analyze_document(doc: str) -> dict:\n    \"\"\"Three independent views of the same document — run concurrently.\"\"\"\n    # These don't depend on each other's outputs → parallel, not sequential.\n    # Cost: ~latency of the SLOWEST single call, not the SUM of all three.\n    summary_task = call_model(f\"Summarize: {doc}\")\n    entities_task = call_model(f\"Extract all named entities as JSON: {doc}\")\n    sentiment_task = call_model(f\"Classify sentiment (positive\u002Fnegative\u002Fneutral): {doc}\")\n\n    summary, entities, sentiment = await asyncio.gather(\n        summary_task, entities_task, sentiment_task\n    )\n    return {\"summary\": summary, \"entities\": entities, \"sentiment\": sentiment}\n\n# PRINCIPLE: decompose along GENUINE dependencies. Only serialize steps that are\n# actually sequential. A common mistake: chaining steps sequentially out of habit\n# when nothing in step 2 needs step 1's output — paying sequential latency for a\n# dependency that doesn't exist.\n",[30,339,340,348,352,378,383,400,429,433,454,459,464,469,499,523,547,551,564,569,574,598,602,607,612,618],{"__ignoreMap":28},[33,341,342,345],{"class":35,"line":36},[33,343,344],{"class":50},"import",[33,346,347],{"class":132}," asyncio\n",[33,349,350],{"class":35,"line":43},[33,351,74],{"emptyLinePlaceholder":73},[33,353,354,357,360,364,367,370,373,375],{"class":35,"line":58},[33,355,356],{"class":50},"async",[33,358,359],{"class":50}," def",[33,361,363],{"class":362},"sIsaT"," call_model",[33,365,366],{"class":132},"(prompt: ",[33,368,369],{"class":46},"str",[33,371,372],{"class":132},") -> ",[33,374,369],{"class":46},[33,376,377],{"class":132},":\n",[33,379,380],{"class":35,"line":64},[33,381,382],{"class":54},"    \"\"\"Simulated model call.\"\"\"\n",[33,384,385,388,391,394,397],{"class":35,"line":70},[33,386,387],{"class":50},"    await",[33,389,390],{"class":132}," asyncio.sleep(",[33,392,393],{"class":46},"0.5",[33,395,396],{"class":132},")  ",[33,398,399],{"class":39},"# simulate latency\n",[33,401,402,405,408,411,414,417,420,423,426],{"class":35,"line":77},[33,403,404],{"class":50},"    return",[33,406,407],{"class":50}," f",[33,409,410],{"class":54},"\"result for: ",[33,412,413],{"class":46},"{",[33,415,416],{"class":132},"prompt[:",[33,418,419],{"class":46},"50",[33,421,422],{"class":132},"]",[33,424,425],{"class":46},"}",[33,427,428],{"class":54},"\"\n",[33,430,431],{"class":35,"line":83},[33,432,74],{"emptyLinePlaceholder":73},[33,434,435,437,439,442,445,447,449,452],{"class":35,"line":89},[33,436,356],{"class":50},[33,438,359],{"class":50},[33,440,441],{"class":362}," analyze_document",[33,443,444],{"class":132},"(doc: ",[33,446,369],{"class":46},[33,448,372],{"class":132},[33,450,451],{"class":46},"dict",[33,453,377],{"class":132},[33,455,456],{"class":35,"line":95},[33,457,458],{"class":54},"    \"\"\"Three independent views of the same document — run concurrently.\"\"\"\n",[33,460,461],{"class":35,"line":101},[33,462,463],{"class":39},"    # These don't depend on each other's outputs → parallel, not sequential.\n",[33,465,466],{"class":35,"line":107},[33,467,468],{"class":39},"    # Cost: ~latency of the SLOWEST single call, not the SUM of all three.\n",[33,470,471,474,477,480,483,486,488,491,493,496],{"class":35,"line":113},[33,472,473],{"class":132},"    summary_task ",[33,475,476],{"class":50},"=",[33,478,479],{"class":132}," call_model(",[33,481,482],{"class":50},"f",[33,484,485],{"class":54},"\"Summarize: ",[33,487,413],{"class":46},[33,489,490],{"class":132},"doc",[33,492,425],{"class":46},[33,494,495],{"class":54},"\"",[33,497,498],{"class":132},")\n",[33,500,501,504,506,508,510,513,515,517,519,521],{"class":35,"line":118},[33,502,503],{"class":132},"    entities_task ",[33,505,476],{"class":50},[33,507,479],{"class":132},[33,509,482],{"class":50},[33,511,512],{"class":54},"\"Extract all named entities as JSON: ",[33,514,413],{"class":46},[33,516,490],{"class":132},[33,518,425],{"class":46},[33,520,495],{"class":54},[33,522,498],{"class":132},[33,524,525,528,530,532,534,537,539,541,543,545],{"class":35,"line":124},[33,526,527],{"class":132},"    sentiment_task ",[33,529,476],{"class":50},[33,531,479],{"class":132},[33,533,482],{"class":50},[33,535,536],{"class":54},"\"Classify sentiment (positive\u002Fnegative\u002Fneutral): ",[33,538,413],{"class":46},[33,540,490],{"class":132},[33,542,425],{"class":46},[33,544,495],{"class":54},[33,546,498],{"class":132},[33,548,549],{"class":35,"line":136},[33,550,74],{"emptyLinePlaceholder":73},[33,552,553,556,558,561],{"class":35,"line":185},[33,554,555],{"class":132},"    summary, entities, sentiment ",[33,557,476],{"class":50},[33,559,560],{"class":50}," await",[33,562,563],{"class":132}," asyncio.gather(\n",[33,565,566],{"class":35,"line":226},[33,567,568],{"class":132},"        summary_task, entities_task, sentiment_task\n",[33,570,571],{"class":35,"line":266},[33,572,573],{"class":132},"    )\n",[33,575,576,578,581,583,586,589,592,595],{"class":35,"line":306},[33,577,404],{"class":50},[33,579,580],{"class":132}," {",[33,582,179],{"class":54},[33,584,585],{"class":132},": summary, ",[33,587,588],{"class":54},"\"entities\"",[33,590,591],{"class":132},": entities, ",[33,593,594],{"class":54},"\"sentiment\"",[33,596,597],{"class":132},": sentiment}\n",[33,599,600],{"class":35,"line":312},[33,601,74],{"emptyLinePlaceholder":73},[33,603,604],{"class":35,"line":318},[33,605,606],{"class":39},"# PRINCIPLE: decompose along GENUINE dependencies. Only serialize steps that are\n",[33,608,609],{"class":35,"line":324},[33,610,611],{"class":39},"# actually sequential. A common mistake: chaining steps sequentially out of habit\n",[33,613,615],{"class":35,"line":614},23,[33,616,617],{"class":39},"# when nothing in step 2 needs step 1's output — paying sequential latency for a\n",[33,619,621],{"class":35,"line":620},24,[33,622,623],{"class":39},"# dependency that doesn't exist.\n",[14,625,627],{"id":626},"structured-handoffs-between-stages","Structured Handoffs Between Stages",[19,629,631],{"filename":630,"language":22},"structured_handoff.py",[24,632,634],{"className":26,"code":633,"language":22,"meta":28,"style":28},"import json\n\n# The quality of a decomposed pipeline lives or dies on what gets passed between\n# steps. Passing raw prose is brittle — the next step must parse meaning from free\n# text. Passing STRUCTURED output is far more robust.\n\nRISK_SCHEMA = {\n    \"type\": \"object\",\n    \"properties\": {\n        \"risks\": {\n            \"type\": \"array\",\n            \"items\": {\n                \"type\": \"object\",\n                \"properties\": {\n                    \"clause_quote\": {\"type\": \"string\"},\n                    \"risk_description\": {\"type\": \"string\"},\n                    \"severity\": {\"type\": \"string\", \"enum\": [\"low\", \"medium\", \"high\"]},\n                },\n                \"required\": [\"clause_quote\", \"risk_description\", \"severity\"],\n            },\n        }\n    },\n}\n\nasync def risk_pipeline(contract_text: str) -> str:\n    # Step 1: extract risks with enforced schema\n    risks = extract_with_schema(contract_text, RISK_SCHEMA)\n\n    # Step 2: application code filters — no model call needed for this logic\n    high_severity = [r for r in risks[\"risks\"] if r[\"severity\"] == \"high\"]\n\n    # Step 3: draft email using only high-severity risks (structured input)\n    email_draft = await call_model(\n        f\"Draft a firm-but-collaborative email raising these specific concerns: \"\n        f\"{json.dumps(high_severity)}\"\n    )\n    return email_draft\n\n# Structured handoffs let ordinary application code validate, filter, and branch\n# on intermediate results — cheaper and more reliable than asking a later prompt\n# to re-derive \"only mention the important ones\" from unstructured prior output.\n",[30,635,636,643,647,652,657,662,666,676,689,697,704,716,723,734,741,759,774,811,816,839,844,849,854,859,863,884,890,905,910,916,963,968,974,987,996,1012,1017,1025,1030,1036,1042],{"__ignoreMap":28},[33,637,638,640],{"class":35,"line":36},[33,639,344],{"class":50},[33,641,642],{"class":132}," json\n",[33,644,645],{"class":35,"line":43},[33,646,74],{"emptyLinePlaceholder":73},[33,648,649],{"class":35,"line":58},[33,650,651],{"class":39},"# The quality of a decomposed pipeline lives or dies on what gets passed between\n",[33,653,654],{"class":35,"line":64},[33,655,656],{"class":39},"# steps. Passing raw prose is brittle — the next step must parse meaning from free\n",[33,658,659],{"class":35,"line":70},[33,660,661],{"class":39},"# text. Passing STRUCTURED output is far more robust.\n",[33,663,664],{"class":35,"line":77},[33,665,74],{"emptyLinePlaceholder":73},[33,667,668,671,673],{"class":35,"line":83},[33,669,670],{"class":46},"RISK_SCHEMA",[33,672,51],{"class":50},[33,674,675],{"class":132}," {\n",[33,677,678,681,683,686],{"class":35,"line":89},[33,679,680],{"class":54},"    \"type\"",[33,682,145],{"class":132},[33,684,685],{"class":54},"\"object\"",[33,687,688],{"class":132},",\n",[33,690,691,694],{"class":35,"line":95},[33,692,693],{"class":54},"    \"properties\"",[33,695,696],{"class":132},": {\n",[33,698,699,702],{"class":35,"line":101},[33,700,701],{"class":54},"        \"risks\"",[33,703,696],{"class":132},[33,705,706,709,711,714],{"class":35,"line":107},[33,707,708],{"class":54},"            \"type\"",[33,710,145],{"class":132},[33,712,713],{"class":54},"\"array\"",[33,715,688],{"class":132},[33,717,718,721],{"class":35,"line":113},[33,719,720],{"class":54},"            \"items\"",[33,722,696],{"class":132},[33,724,725,728,730,732],{"class":35,"line":118},[33,726,727],{"class":54},"                \"type\"",[33,729,145],{"class":132},[33,731,685],{"class":54},[33,733,688],{"class":132},[33,735,736,739],{"class":35,"line":124},[33,737,738],{"class":54},"                \"properties\"",[33,740,696],{"class":132},[33,742,743,746,749,752,754,757],{"class":35,"line":136},[33,744,745],{"class":54},"                    \"clause_quote\"",[33,747,748],{"class":132},": {",[33,750,751],{"class":54},"\"type\"",[33,753,145],{"class":132},[33,755,756],{"class":54},"\"string\"",[33,758,182],{"class":132},[33,760,761,764,766,768,770,772],{"class":35,"line":185},[33,762,763],{"class":54},"                    \"risk_description\"",[33,765,748],{"class":132},[33,767,751],{"class":54},[33,769,145],{"class":132},[33,771,756],{"class":54},[33,773,182],{"class":132},[33,775,776,779,781,783,785,787,789,792,795,798,800,803,805,808],{"class":35,"line":226},[33,777,778],{"class":54},"                    \"severity\"",[33,780,748],{"class":132},[33,782,751],{"class":54},[33,784,145],{"class":132},[33,786,756],{"class":54},[33,788,151],{"class":132},[33,790,791],{"class":54},"\"enum\"",[33,793,794],{"class":132},": [",[33,796,797],{"class":54},"\"low\"",[33,799,151],{"class":132},[33,801,802],{"class":54},"\"medium\"",[33,804,151],{"class":132},[33,806,807],{"class":54},"\"high\"",[33,809,810],{"class":132},"]},\n",[33,812,813],{"class":35,"line":266},[33,814,815],{"class":132},"                },\n",[33,817,818,821,823,826,828,831,833,836],{"class":35,"line":306},[33,819,820],{"class":54},"                \"required\"",[33,822,794],{"class":132},[33,824,825],{"class":54},"\"clause_quote\"",[33,827,151],{"class":132},[33,829,830],{"class":54},"\"risk_description\"",[33,832,151],{"class":132},[33,834,835],{"class":54},"\"severity\"",[33,837,838],{"class":132},"],\n",[33,840,841],{"class":35,"line":312},[33,842,843],{"class":132},"            },\n",[33,845,846],{"class":35,"line":318},[33,847,848],{"class":132},"        }\n",[33,850,851],{"class":35,"line":324},[33,852,853],{"class":132},"    },\n",[33,855,856],{"class":35,"line":614},[33,857,858],{"class":132},"}\n",[33,860,861],{"class":35,"line":620},[33,862,74],{"emptyLinePlaceholder":73},[33,864,866,868,870,873,876,878,880,882],{"class":35,"line":865},25,[33,867,356],{"class":50},[33,869,359],{"class":50},[33,871,872],{"class":362}," risk_pipeline",[33,874,875],{"class":132},"(contract_text: ",[33,877,369],{"class":46},[33,879,372],{"class":132},[33,881,369],{"class":46},[33,883,377],{"class":132},[33,885,887],{"class":35,"line":886},26,[33,888,889],{"class":39},"    # Step 1: extract risks with enforced schema\n",[33,891,893,896,898,901,903],{"class":35,"line":892},27,[33,894,895],{"class":132},"    risks ",[33,897,476],{"class":50},[33,899,900],{"class":132}," extract_with_schema(contract_text, ",[33,902,670],{"class":46},[33,904,498],{"class":132},[33,906,908],{"class":35,"line":907},28,[33,909,74],{"emptyLinePlaceholder":73},[33,911,913],{"class":35,"line":912},29,[33,914,915],{"class":39},"    # Step 2: application code filters — no model call needed for this logic\n",[33,917,919,922,924,927,930,933,936,939,942,945,948,951,953,955,958,961],{"class":35,"line":918},30,[33,920,921],{"class":132},"    high_severity ",[33,923,476],{"class":50},[33,925,926],{"class":132}," [r ",[33,928,929],{"class":50},"for",[33,931,932],{"class":132}," r ",[33,934,935],{"class":50},"in",[33,937,938],{"class":132}," risks[",[33,940,941],{"class":54},"\"risks\"",[33,943,944],{"class":132},"] ",[33,946,947],{"class":50},"if",[33,949,950],{"class":132}," r[",[33,952,835],{"class":54},[33,954,944],{"class":132},[33,956,957],{"class":50},"==",[33,959,960],{"class":54}," \"high\"",[33,962,309],{"class":132},[33,964,966],{"class":35,"line":965},31,[33,967,74],{"emptyLinePlaceholder":73},[33,969,971],{"class":35,"line":970},32,[33,972,973],{"class":39},"    # Step 3: draft email using only high-severity risks (structured input)\n",[33,975,977,980,982,984],{"class":35,"line":976},33,[33,978,979],{"class":132},"    email_draft ",[33,981,476],{"class":50},[33,983,560],{"class":50},[33,985,986],{"class":132}," call_model(\n",[33,988,990,993],{"class":35,"line":989},34,[33,991,992],{"class":50},"        f",[33,994,995],{"class":54},"\"Draft a firm-but-collaborative email raising these specific concerns: \"\n",[33,997,999,1001,1003,1005,1008,1010],{"class":35,"line":998},35,[33,1000,992],{"class":50},[33,1002,495],{"class":54},[33,1004,413],{"class":46},[33,1006,1007],{"class":132},"json.dumps(high_severity)",[33,1009,425],{"class":46},[33,1011,428],{"class":54},[33,1013,1015],{"class":35,"line":1014},36,[33,1016,573],{"class":132},[33,1018,1020,1022],{"class":35,"line":1019},37,[33,1021,404],{"class":50},[33,1023,1024],{"class":132}," email_draft\n",[33,1026,1028],{"class":35,"line":1027},38,[33,1029,74],{"emptyLinePlaceholder":73},[33,1031,1033],{"class":35,"line":1032},39,[33,1034,1035],{"class":39},"# Structured handoffs let ordinary application code validate, filter, and branch\n",[33,1037,1039],{"class":35,"line":1038},40,[33,1040,1041],{"class":39},"# on intermediate results — cheaper and more reliable than asking a later prompt\n",[33,1043,1045],{"class":35,"line":1044},41,[33,1046,1047],{"class":39},"# to re-derive \"only mention the important ones\" from unstructured prior output.\n",[14,1049,1051],{"id":1050},"conditional-branching","Conditional Branching",[19,1053,1055],{"filename":1054,"language":22},"conditional_branching.py",[24,1056,1058],{"className":26,"code":1057,"language":22,"meta":28,"style":28},"# A step's output can determine which step runs next — a flowchart, not a line.\n\nasync def triage_pipeline(ticket: str) -> str:\n    # Step 1: classify (always runs)\n    category = await call_model(f\"Classify as BILLING, BUG_REPORT, or OTHER: {ticket}\")\n    category = category.strip()\n\n    # Branch in APPLICATION CODE, not in a single \"handle all three cases\" prompt.\n    # This makes behavior explicit, testable per-branch (Chapter 9), and easy to\n    # extend with a new category without touching other branches' prompts.\n    if category == \"BILLING\":\n        result = await call_model(f\"Extract invoice number and disputed amount, then draft billing response: {ticket}\")\n    elif category == \"BUG_REPORT\":\n        result = await call_model(f\"Extract reproduction steps and severity, then draft engineering triage: {ticket}\")\n    else:\n        result = await call_model(f\"Draft general response: {ticket}\")\n\n    return result\n\n# Each branch can have its own prompt, its own model, its own tool set.\n# Adding a new category = adding a new branch — existing branches are untouched.\n",[30,1059,1060,1065,1069,1089,1094,1121,1130,1134,1139,1144,1149,1164,1190,1204,1229,1236,1261,1265,1272,1276,1281],{"__ignoreMap":28},[33,1061,1062],{"class":35,"line":36},[33,1063,1064],{"class":39},"# A step's output can determine which step runs next — a flowchart, not a line.\n",[33,1066,1067],{"class":35,"line":43},[33,1068,74],{"emptyLinePlaceholder":73},[33,1070,1071,1073,1075,1078,1081,1083,1085,1087],{"class":35,"line":58},[33,1072,356],{"class":50},[33,1074,359],{"class":50},[33,1076,1077],{"class":362}," triage_pipeline",[33,1079,1080],{"class":132},"(ticket: ",[33,1082,369],{"class":46},[33,1084,372],{"class":132},[33,1086,369],{"class":46},[33,1088,377],{"class":132},[33,1090,1091],{"class":35,"line":64},[33,1092,1093],{"class":39},"    # Step 1: classify (always runs)\n",[33,1095,1096,1099,1101,1103,1105,1107,1110,1112,1115,1117,1119],{"class":35,"line":70},[33,1097,1098],{"class":132},"    category ",[33,1100,476],{"class":50},[33,1102,560],{"class":50},[33,1104,479],{"class":132},[33,1106,482],{"class":50},[33,1108,1109],{"class":54},"\"Classify as BILLING, BUG_REPORT, or OTHER: ",[33,1111,413],{"class":46},[33,1113,1114],{"class":132},"ticket",[33,1116,425],{"class":46},[33,1118,495],{"class":54},[33,1120,498],{"class":132},[33,1122,1123,1125,1127],{"class":35,"line":77},[33,1124,1098],{"class":132},[33,1126,476],{"class":50},[33,1128,1129],{"class":132}," category.strip()\n",[33,1131,1132],{"class":35,"line":83},[33,1133,74],{"emptyLinePlaceholder":73},[33,1135,1136],{"class":35,"line":89},[33,1137,1138],{"class":39},"    # Branch in APPLICATION CODE, not in a single \"handle all three cases\" prompt.\n",[33,1140,1141],{"class":35,"line":95},[33,1142,1143],{"class":39},"    # This makes behavior explicit, testable per-branch (Chapter 9), and easy to\n",[33,1145,1146],{"class":35,"line":101},[33,1147,1148],{"class":39},"    # extend with a new category without touching other branches' prompts.\n",[33,1150,1151,1154,1157,1159,1162],{"class":35,"line":107},[33,1152,1153],{"class":50},"    if",[33,1155,1156],{"class":132}," category ",[33,1158,957],{"class":50},[33,1160,1161],{"class":54}," \"BILLING\"",[33,1163,377],{"class":132},[33,1165,1166,1169,1171,1173,1175,1177,1180,1182,1184,1186,1188],{"class":35,"line":113},[33,1167,1168],{"class":132},"        result ",[33,1170,476],{"class":50},[33,1172,560],{"class":50},[33,1174,479],{"class":132},[33,1176,482],{"class":50},[33,1178,1179],{"class":54},"\"Extract invoice number and disputed amount, then draft billing response: ",[33,1181,413],{"class":46},[33,1183,1114],{"class":132},[33,1185,425],{"class":46},[33,1187,495],{"class":54},[33,1189,498],{"class":132},[33,1191,1192,1195,1197,1199,1202],{"class":35,"line":118},[33,1193,1194],{"class":50},"    elif",[33,1196,1156],{"class":132},[33,1198,957],{"class":50},[33,1200,1201],{"class":54}," \"BUG_REPORT\"",[33,1203,377],{"class":132},[33,1205,1206,1208,1210,1212,1214,1216,1219,1221,1223,1225,1227],{"class":35,"line":124},[33,1207,1168],{"class":132},[33,1209,476],{"class":50},[33,1211,560],{"class":50},[33,1213,479],{"class":132},[33,1215,482],{"class":50},[33,1217,1218],{"class":54},"\"Extract reproduction steps and severity, then draft engineering triage: ",[33,1220,413],{"class":46},[33,1222,1114],{"class":132},[33,1224,425],{"class":46},[33,1226,495],{"class":54},[33,1228,498],{"class":132},[33,1230,1231,1234],{"class":35,"line":136},[33,1232,1233],{"class":50},"    else",[33,1235,377],{"class":132},[33,1237,1238,1240,1242,1244,1246,1248,1251,1253,1255,1257,1259],{"class":35,"line":185},[33,1239,1168],{"class":132},[33,1241,476],{"class":50},[33,1243,560],{"class":50},[33,1245,479],{"class":132},[33,1247,482],{"class":50},[33,1249,1250],{"class":54},"\"Draft general response: ",[33,1252,413],{"class":46},[33,1254,1114],{"class":132},[33,1256,425],{"class":46},[33,1258,495],{"class":54},[33,1260,498],{"class":132},[33,1262,1263],{"class":35,"line":226},[33,1264,74],{"emptyLinePlaceholder":73},[33,1266,1267,1269],{"class":35,"line":266},[33,1268,404],{"class":50},[33,1270,1271],{"class":132}," result\n",[33,1273,1274],{"class":35,"line":306},[33,1275,74],{"emptyLinePlaceholder":73},[33,1277,1278],{"class":35,"line":312},[33,1279,1280],{"class":39},"# Each branch can have its own prompt, its own model, its own tool set.\n",[33,1282,1283],{"class":35,"line":318},[33,1284,1285],{"class":39},"# Adding a new category = adding a new branch — existing branches are untouched.\n",[14,1287,1289],{"id":1288},"error-compounding-across-stages","Error Compounding Across Stages",[19,1291,1293],{"filename":1292,"language":22},"error_compounding.py",[24,1294,1296],{"className":26,"code":1295,"language":22,"meta":28,"style":28},"# CRITICAL: errors compound MULTIPLICATIVELY across chained stages.\n# A pipeline with four 95%-reliable stages has a combined success rate of:\n#   0.95^4 ≈ 0.815 → 81.5%, NOT 95%\n\nstage_reliability = 0.95\nnum_stages = 4\ncombined = stage_reliability ** num_stages\nprint(f\"Pipeline reliability: {combined:.1%}\")  # 81.5%\n\n# This means \"each step usually works\" does NOT add up to \"the pipeline usually works.\"\n# Mitigations:\n# 1. VALIDATE at each stage — catch broken intermediate results before they propagate\n# 2. RETRY or fall back at each stage individually\n# 3. Don't assume step reliability compounds linearly — measure end-to-end\n\ndef pipeline_with_validation(stages: list, input_data):\n    \"\"\"Each stage validates its input before processing and output before returning.\"\"\"\n    data = input_data\n    for i, stage in enumerate(stages):\n        # Validate input to this stage\n        if not stage.validate_input(data):\n            raise PipelineError(f\"Stage {i} received invalid input from stage {i-1}\")\n\n        data = stage.process(data)\n\n        # Validate output from this stage before passing forward\n        if not stage.validate_output(data):\n            raise PipelineError(f\"Stage {i} produced invalid output\")\n\n    return data\n",[30,1297,1298,1303,1308,1313,1317,1327,1337,1353,1383,1387,1392,1397,1402,1407,1412,1416,1433,1438,1448,1464,1469,1480,1517,1521,1531,1535,1540,1549,1570,1574],{"__ignoreMap":28},[33,1299,1300],{"class":35,"line":36},[33,1301,1302],{"class":39},"# CRITICAL: errors compound MULTIPLICATIVELY across chained stages.\n",[33,1304,1305],{"class":35,"line":43},[33,1306,1307],{"class":39},"# A pipeline with four 95%-reliable stages has a combined success rate of:\n",[33,1309,1310],{"class":35,"line":58},[33,1311,1312],{"class":39},"#   0.95^4 ≈ 0.815 → 81.5%, NOT 95%\n",[33,1314,1315],{"class":35,"line":64},[33,1316,74],{"emptyLinePlaceholder":73},[33,1318,1319,1322,1324],{"class":35,"line":70},[33,1320,1321],{"class":132},"stage_reliability ",[33,1323,476],{"class":50},[33,1325,1326],{"class":46}," 0.95\n",[33,1328,1329,1332,1334],{"class":35,"line":77},[33,1330,1331],{"class":132},"num_stages ",[33,1333,476],{"class":50},[33,1335,1336],{"class":46}," 4\n",[33,1338,1339,1342,1344,1347,1350],{"class":35,"line":83},[33,1340,1341],{"class":132},"combined ",[33,1343,476],{"class":50},[33,1345,1346],{"class":132}," stage_reliability ",[33,1348,1349],{"class":50},"**",[33,1351,1352],{"class":132}," num_stages\n",[33,1354,1355,1358,1361,1363,1366,1368,1371,1374,1376,1378,1380],{"class":35,"line":89},[33,1356,1357],{"class":46},"print",[33,1359,1360],{"class":132},"(",[33,1362,482],{"class":50},[33,1364,1365],{"class":54},"\"Pipeline reliability: ",[33,1367,413],{"class":46},[33,1369,1370],{"class":132},"combined",[33,1372,1373],{"class":50},":.1%",[33,1375,425],{"class":46},[33,1377,495],{"class":54},[33,1379,396],{"class":132},[33,1381,1382],{"class":39},"# 81.5%\n",[33,1384,1385],{"class":35,"line":95},[33,1386,74],{"emptyLinePlaceholder":73},[33,1388,1389],{"class":35,"line":101},[33,1390,1391],{"class":39},"# This means \"each step usually works\" does NOT add up to \"the pipeline usually works.\"\n",[33,1393,1394],{"class":35,"line":107},[33,1395,1396],{"class":39},"# Mitigations:\n",[33,1398,1399],{"class":35,"line":113},[33,1400,1401],{"class":39},"# 1. VALIDATE at each stage — catch broken intermediate results before they propagate\n",[33,1403,1404],{"class":35,"line":118},[33,1405,1406],{"class":39},"# 2. RETRY or fall back at each stage individually\n",[33,1408,1409],{"class":35,"line":124},[33,1410,1411],{"class":39},"# 3. Don't assume step reliability compounds linearly — measure end-to-end\n",[33,1413,1414],{"class":35,"line":136},[33,1415,74],{"emptyLinePlaceholder":73},[33,1417,1418,1421,1424,1427,1430],{"class":35,"line":185},[33,1419,1420],{"class":50},"def",[33,1422,1423],{"class":362}," pipeline_with_validation",[33,1425,1426],{"class":132},"(stages: ",[33,1428,1429],{"class":46},"list",[33,1431,1432],{"class":132},", input_data):\n",[33,1434,1435],{"class":35,"line":226},[33,1436,1437],{"class":54},"    \"\"\"Each stage validates its input before processing and output before returning.\"\"\"\n",[33,1439,1440,1443,1445],{"class":35,"line":266},[33,1441,1442],{"class":132},"    data ",[33,1444,476],{"class":50},[33,1446,1447],{"class":132}," input_data\n",[33,1449,1450,1453,1456,1458,1461],{"class":35,"line":306},[33,1451,1452],{"class":50},"    for",[33,1454,1455],{"class":132}," i, stage ",[33,1457,935],{"class":50},[33,1459,1460],{"class":46}," enumerate",[33,1462,1463],{"class":132},"(stages):\n",[33,1465,1466],{"class":35,"line":312},[33,1467,1468],{"class":39},"        # Validate input to this stage\n",[33,1470,1471,1474,1477],{"class":35,"line":318},[33,1472,1473],{"class":50},"        if",[33,1475,1476],{"class":50}," not",[33,1478,1479],{"class":132}," stage.validate_input(data):\n",[33,1481,1482,1485,1488,1490,1493,1495,1498,1500,1503,1505,1507,1510,1513,1515],{"class":35,"line":324},[33,1483,1484],{"class":50},"            raise",[33,1486,1487],{"class":132}," PipelineError(",[33,1489,482],{"class":50},[33,1491,1492],{"class":54},"\"Stage ",[33,1494,413],{"class":46},[33,1496,1497],{"class":132},"i",[33,1499,425],{"class":46},[33,1501,1502],{"class":54}," received invalid input from stage ",[33,1504,413],{"class":46},[33,1506,1497],{"class":132},[33,1508,1509],{"class":50},"-",[33,1511,1512],{"class":46},"1}",[33,1514,495],{"class":54},[33,1516,498],{"class":132},[33,1518,1519],{"class":35,"line":614},[33,1520,74],{"emptyLinePlaceholder":73},[33,1522,1523,1526,1528],{"class":35,"line":620},[33,1524,1525],{"class":132},"        data ",[33,1527,476],{"class":50},[33,1529,1530],{"class":132}," stage.process(data)\n",[33,1532,1533],{"class":35,"line":865},[33,1534,74],{"emptyLinePlaceholder":73},[33,1536,1537],{"class":35,"line":886},[33,1538,1539],{"class":39},"        # Validate output from this stage before passing forward\n",[33,1541,1542,1544,1546],{"class":35,"line":892},[33,1543,1473],{"class":50},[33,1545,1476],{"class":50},[33,1547,1548],{"class":132}," stage.validate_output(data):\n",[33,1550,1551,1553,1555,1557,1559,1561,1563,1565,1568],{"class":35,"line":907},[33,1552,1484],{"class":50},[33,1554,1487],{"class":132},[33,1556,482],{"class":50},[33,1558,1492],{"class":54},[33,1560,413],{"class":46},[33,1562,1497],{"class":132},[33,1564,425],{"class":46},[33,1566,1567],{"class":54}," produced invalid output\"",[33,1569,498],{"class":132},[33,1571,1572],{"class":35,"line":912},[33,1573,74],{"emptyLinePlaceholder":73},[33,1575,1576,1578],{"class":35,"line":918},[33,1577,404],{"class":50},[33,1579,1580],{"class":132}," data\n",[14,1582,1584],{"id":1583},"cot-vs-decomposition","CoT vs. Decomposition",[19,1586,1588],{"filename":1587,"language":22},"cot_vs_decomposition.py",[24,1589,1591],{"className":26,"code":1590,"language":22,"meta":28,"style":28},"# CoT and decomposition solve related but DISTINCT problems:\n\n# CHAIN-OF-THOUGHT (Chapter 5):\n# - ONE model call reasons through multiple steps internally\n# - Single context, single generation\n# - Cheaper (one call), keeps reasoning within the model's working context\n# - No inspection points between steps\n\n# DECOMPOSITION (this chapter):\n# - MULTIPLE separate calls, each with its own context\n# - Human or program can inspect between steps\n# - More expensive but: inspectable intermediate results, different techniques\u002F\n#   models per step, resilience to any single stage's context\u002Foutput overload\n\n# FREQUENT EFFECTIVE PATTERN: combine both.\n# Decompose a task into major stages, and use CoT WITHIN any individual stage\n# that benefits from step-by-step reasoning.\n\nasync def combined_approach(document: str) -> dict:\n    # Stage 1: decomposed — extract entities (structured, no CoT needed)\n    entities = extract_with_schema(document, ENTITY_SCHEMA)\n\n    # Stage 2: decomposed + CoT — analyze risk (needs reasoning, structured output)\n    risk_analysis = await call_model(f\"\"\"\n        Think step by step about the risks in this document.\n        Document: {document}\n        Entities found: {json.dumps(entities)}\n        Then output risks as JSON matching this schema: {RISK_SCHEMA}\n    \"\"\")\n\n    # Stage 3: decomposed — draft response (generation, no CoT)\n    response = await call_model(f\"Draft a response addressing these risks: {risk_analysis}\")\n    return {\"entities\": entities, \"risks\": risk_analysis, \"response\": response}\n",[30,1592,1593,1598,1602,1607,1612,1617,1622,1627,1631,1636,1641,1646,1651,1656,1660,1665,1670,1675,1679,1699,1704,1719,1723,1728,1743,1748,1760,1772,1780,1787,1791,1796,1823],{"__ignoreMap":28},[33,1594,1595],{"class":35,"line":36},[33,1596,1597],{"class":39},"# CoT and decomposition solve related but DISTINCT problems:\n",[33,1599,1600],{"class":35,"line":43},[33,1601,74],{"emptyLinePlaceholder":73},[33,1603,1604],{"class":35,"line":58},[33,1605,1606],{"class":39},"# CHAIN-OF-THOUGHT (Chapter 5):\n",[33,1608,1609],{"class":35,"line":64},[33,1610,1611],{"class":39},"# - ONE model call reasons through multiple steps internally\n",[33,1613,1614],{"class":35,"line":70},[33,1615,1616],{"class":39},"# - Single context, single generation\n",[33,1618,1619],{"class":35,"line":77},[33,1620,1621],{"class":39},"# - Cheaper (one call), keeps reasoning within the model's working context\n",[33,1623,1624],{"class":35,"line":83},[33,1625,1626],{"class":39},"# - No inspection points between steps\n",[33,1628,1629],{"class":35,"line":89},[33,1630,74],{"emptyLinePlaceholder":73},[33,1632,1633],{"class":35,"line":95},[33,1634,1635],{"class":39},"# DECOMPOSITION (this chapter):\n",[33,1637,1638],{"class":35,"line":101},[33,1639,1640],{"class":39},"# - MULTIPLE separate calls, each with its own context\n",[33,1642,1643],{"class":35,"line":107},[33,1644,1645],{"class":39},"# - Human or program can inspect between steps\n",[33,1647,1648],{"class":35,"line":113},[33,1649,1650],{"class":39},"# - More expensive but: inspectable intermediate results, different techniques\u002F\n",[33,1652,1653],{"class":35,"line":118},[33,1654,1655],{"class":39},"#   models per step, resilience to any single stage's context\u002Foutput overload\n",[33,1657,1658],{"class":35,"line":124},[33,1659,74],{"emptyLinePlaceholder":73},[33,1661,1662],{"class":35,"line":136},[33,1663,1664],{"class":39},"# FREQUENT EFFECTIVE PATTERN: combine both.\n",[33,1666,1667],{"class":35,"line":185},[33,1668,1669],{"class":39},"# Decompose a task into major stages, and use CoT WITHIN any individual stage\n",[33,1671,1672],{"class":35,"line":226},[33,1673,1674],{"class":39},"# that benefits from step-by-step reasoning.\n",[33,1676,1677],{"class":35,"line":266},[33,1678,74],{"emptyLinePlaceholder":73},[33,1680,1681,1683,1685,1688,1691,1693,1695,1697],{"class":35,"line":306},[33,1682,356],{"class":50},[33,1684,359],{"class":50},[33,1686,1687],{"class":362}," combined_approach",[33,1689,1690],{"class":132},"(document: ",[33,1692,369],{"class":46},[33,1694,372],{"class":132},[33,1696,451],{"class":46},[33,1698,377],{"class":132},[33,1700,1701],{"class":35,"line":312},[33,1702,1703],{"class":39},"    # Stage 1: decomposed — extract entities (structured, no CoT needed)\n",[33,1705,1706,1709,1711,1714,1717],{"class":35,"line":318},[33,1707,1708],{"class":132},"    entities ",[33,1710,476],{"class":50},[33,1712,1713],{"class":132}," extract_with_schema(document, ",[33,1715,1716],{"class":46},"ENTITY_SCHEMA",[33,1718,498],{"class":132},[33,1720,1721],{"class":35,"line":324},[33,1722,74],{"emptyLinePlaceholder":73},[33,1724,1725],{"class":35,"line":614},[33,1726,1727],{"class":39},"    # Stage 2: decomposed + CoT — analyze risk (needs reasoning, structured output)\n",[33,1729,1730,1733,1735,1737,1739,1741],{"class":35,"line":620},[33,1731,1732],{"class":132},"    risk_analysis ",[33,1734,476],{"class":50},[33,1736,560],{"class":50},[33,1738,479],{"class":132},[33,1740,482],{"class":50},[33,1742,86],{"class":54},[33,1744,1745],{"class":35,"line":865},[33,1746,1747],{"class":54},"        Think step by step about the risks in this document.\n",[33,1749,1750,1753,1755,1758],{"class":35,"line":886},[33,1751,1752],{"class":54},"        Document: ",[33,1754,413],{"class":46},[33,1756,1757],{"class":132},"document",[33,1759,858],{"class":46},[33,1761,1762,1765,1767,1770],{"class":35,"line":892},[33,1763,1764],{"class":54},"        Entities found: ",[33,1766,413],{"class":46},[33,1768,1769],{"class":132},"json.dumps(entities)",[33,1771,858],{"class":46},[33,1773,1774,1777],{"class":35,"line":907},[33,1775,1776],{"class":54},"        Then output risks as JSON matching this schema: ",[33,1778,1779],{"class":46},"{RISK_SCHEMA}\n",[33,1781,1782,1785],{"class":35,"line":912},[33,1783,1784],{"class":54},"    \"\"\"",[33,1786,498],{"class":132},[33,1788,1789],{"class":35,"line":918},[33,1790,74],{"emptyLinePlaceholder":73},[33,1792,1793],{"class":35,"line":965},[33,1794,1795],{"class":39},"    # Stage 3: decomposed — draft response (generation, no CoT)\n",[33,1797,1798,1801,1803,1805,1807,1809,1812,1814,1817,1819,1821],{"class":35,"line":970},[33,1799,1800],{"class":132},"    response ",[33,1802,476],{"class":50},[33,1804,560],{"class":50},[33,1806,479],{"class":132},[33,1808,482],{"class":50},[33,1810,1811],{"class":54},"\"Draft a response addressing these risks: ",[33,1813,413],{"class":46},[33,1815,1816],{"class":132},"risk_analysis",[33,1818,425],{"class":46},[33,1820,495],{"class":54},[33,1822,498],{"class":132},[33,1824,1825,1827,1829,1831,1833,1835,1838,1841],{"class":35,"line":976},[33,1826,404],{"class":50},[33,1828,580],{"class":132},[33,1830,588],{"class":54},[33,1832,591],{"class":132},[33,1834,941],{"class":54},[33,1836,1837],{"class":132},": risk_analysis, ",[33,1839,1840],{"class":54},"\"response\"",[33,1842,1843],{"class":132},": response}\n",[14,1845,1847],{"id":1846},"tips-tricks","💡 Tips & Tricks",[19,1849,1851],{"filename":1850,"language":22},"tips.py",[24,1852,1854],{"className":26,"code":1853,"language":22,"meta":28,"style":28},"# [Idiom] Name each stage by its SINGLE responsibility. If you can't name it\n# in one clause, it's two stages. \"extract-and-summarize\" → split into \"extract\"\n# and \"summarize\" — even if you merge them for latency, the naming surfaces\n# hidden multi-tasking before it becomes a debugging problem.\n\n# [Debug] Log EVERY intermediate step's input and output, not just the final\n# result. When a multi-step pipeline produces a bad answer, having the full\n# trace of intermediates is what makes it possible to localize the failure in\n# minutes instead of hours.\n\n# [Idiom] Put validation BETWEEN stages, not just at the end. A cheap structural\n# check (does the JSON have required fields? is severity a valid enum value?)\n# run after each stage catches a broken intermediate before it propagates\n# downstream and corrupts an otherwise-fine final output.\n\n# [Performance] Use a cheaper\u002Ffaster model for simple well-defined stages and\n# reserve your strongest model for the stage that actually needs deep reasoning.\n# A pipeline's total cost\u002Flatency is the sum of its stages — not every stage\n# needs your most expensive model.\n\n# [Idiom] Parallelize aggressively wherever dependencies genuinely allow it.\n# Before finalizing a design, explicitly draw the dependency graph between steps\n# (which steps need which prior outputs). Independent branches should run\n# concurrently — don't default to a sequential chain.\n",[30,1855,1856,1861,1866,1871,1876,1880,1885,1890,1895,1900,1904,1909,1914,1919,1924,1928,1933,1938,1943,1948,1952,1957,1962,1967],{"__ignoreMap":28},[33,1857,1858],{"class":35,"line":36},[33,1859,1860],{"class":39},"# [Idiom] Name each stage by its SINGLE responsibility. If you can't name it\n",[33,1862,1863],{"class":35,"line":43},[33,1864,1865],{"class":39},"# in one clause, it's two stages. \"extract-and-summarize\" → split into \"extract\"\n",[33,1867,1868],{"class":35,"line":58},[33,1869,1870],{"class":39},"# and \"summarize\" — even if you merge them for latency, the naming surfaces\n",[33,1872,1873],{"class":35,"line":64},[33,1874,1875],{"class":39},"# hidden multi-tasking before it becomes a debugging problem.\n",[33,1877,1878],{"class":35,"line":70},[33,1879,74],{"emptyLinePlaceholder":73},[33,1881,1882],{"class":35,"line":77},[33,1883,1884],{"class":39},"# [Debug] Log EVERY intermediate step's input and output, not just the final\n",[33,1886,1887],{"class":35,"line":83},[33,1888,1889],{"class":39},"# result. When a multi-step pipeline produces a bad answer, having the full\n",[33,1891,1892],{"class":35,"line":89},[33,1893,1894],{"class":39},"# trace of intermediates is what makes it possible to localize the failure in\n",[33,1896,1897],{"class":35,"line":95},[33,1898,1899],{"class":39},"# minutes instead of hours.\n",[33,1901,1902],{"class":35,"line":101},[33,1903,74],{"emptyLinePlaceholder":73},[33,1905,1906],{"class":35,"line":107},[33,1907,1908],{"class":39},"# [Idiom] Put validation BETWEEN stages, not just at the end. A cheap structural\n",[33,1910,1911],{"class":35,"line":113},[33,1912,1913],{"class":39},"# check (does the JSON have required fields? is severity a valid enum value?)\n",[33,1915,1916],{"class":35,"line":118},[33,1917,1918],{"class":39},"# run after each stage catches a broken intermediate before it propagates\n",[33,1920,1921],{"class":35,"line":124},[33,1922,1923],{"class":39},"# downstream and corrupts an otherwise-fine final output.\n",[33,1925,1926],{"class":35,"line":136},[33,1927,74],{"emptyLinePlaceholder":73},[33,1929,1930],{"class":35,"line":185},[33,1931,1932],{"class":39},"# [Performance] Use a cheaper\u002Ffaster model for simple well-defined stages and\n",[33,1934,1935],{"class":35,"line":226},[33,1936,1937],{"class":39},"# reserve your strongest model for the stage that actually needs deep reasoning.\n",[33,1939,1940],{"class":35,"line":266},[33,1941,1942],{"class":39},"# A pipeline's total cost\u002Flatency is the sum of its stages — not every stage\n",[33,1944,1945],{"class":35,"line":306},[33,1946,1947],{"class":39},"# needs your most expensive model.\n",[33,1949,1950],{"class":35,"line":312},[33,1951,74],{"emptyLinePlaceholder":73},[33,1953,1954],{"class":35,"line":318},[33,1955,1956],{"class":39},"# [Idiom] Parallelize aggressively wherever dependencies genuinely allow it.\n",[33,1958,1959],{"class":35,"line":324},[33,1960,1961],{"class":39},"# Before finalizing a design, explicitly draw the dependency graph between steps\n",[33,1963,1964],{"class":35,"line":614},[33,1965,1966],{"class":39},"# (which steps need which prior outputs). Independent branches should run\n",[33,1968,1969],{"class":35,"line":620},[33,1970,1971],{"class":39},"# concurrently — don't default to a sequential chain.\n",[14,1973,1975],{"id":1974},"️-edge-cases-gotchas","⚠️ Edge Cases & Gotchas",[19,1977,1979],{"filename":1978,"language":22},"edge_cases.py",[24,1980,1982],{"className":26,"code":1981,"language":22,"meta":28,"style":28},"# [Gotcha] Errors compound across stages if not handled explicitly. Four 95%\n# stages → 81.5% combined. Validate and retry\u002Ffall back at each stage, don't\n# assume \"each step usually works\" → \"the pipeline usually works.\"\n\n# [Gotcha] A later stage can't recover context that an earlier stage DISCARDED.\n# If extraction pulls only 3 fields and a later drafting stage needs a 4th piece\n# that was in the original document but never extracted, the pipeline has no way\n# to go back. Either pass original source material forward alongside extracted\n# summaries, or ensure the extraction schema anticipates everything downstream needs.\n\n# [Gotcha] Sequential latency is invisible until it's in production at real user\n# think-time. A 4-stage pipeline that took acceptable seconds in dev against a\n# fast, lightly-loaded API can feel unacceptably slow under production latency\n# and rate-limiting. Measure end-to-end under realistic conditions.\n\n# [Gotcha] Conditional branches rarely exercised in testing can harbor silent\n# bugs for months. A branch handling an uncommon category might go months without\n# a real example, and when one arrives, the branch's prompt was written against a\n# stale assumption about the schema flowing into it. Include at least one test\n# case per branch, even for rare branches (Chapter 9).\n\n# [Gotcha] Passing an entire prior step's raw output forward \"just in case\"\n# reintroduces the context-bloat problem decomposition was meant to solve. If\n# every stage defensively forwards everything, the final stages end up with as\n# much irrelevant context as the monolithic prompt you were trying to avoid.\n",[30,1983,1984,1989,1994,1999,2003,2008,2013,2018,2023,2028,2032,2037,2042,2047,2052,2056,2061,2066,2071,2076,2081,2085,2090,2095,2100],{"__ignoreMap":28},[33,1985,1986],{"class":35,"line":36},[33,1987,1988],{"class":39},"# [Gotcha] Errors compound across stages if not handled explicitly. Four 95%\n",[33,1990,1991],{"class":35,"line":43},[33,1992,1993],{"class":39},"# stages → 81.5% combined. Validate and retry\u002Ffall back at each stage, don't\n",[33,1995,1996],{"class":35,"line":58},[33,1997,1998],{"class":39},"# assume \"each step usually works\" → \"the pipeline usually works.\"\n",[33,2000,2001],{"class":35,"line":64},[33,2002,74],{"emptyLinePlaceholder":73},[33,2004,2005],{"class":35,"line":70},[33,2006,2007],{"class":39},"# [Gotcha] A later stage can't recover context that an earlier stage DISCARDED.\n",[33,2009,2010],{"class":35,"line":77},[33,2011,2012],{"class":39},"# If extraction pulls only 3 fields and a later drafting stage needs a 4th piece\n",[33,2014,2015],{"class":35,"line":83},[33,2016,2017],{"class":39},"# that was in the original document but never extracted, the pipeline has no way\n",[33,2019,2020],{"class":35,"line":89},[33,2021,2022],{"class":39},"# to go back. Either pass original source material forward alongside extracted\n",[33,2024,2025],{"class":35,"line":95},[33,2026,2027],{"class":39},"# summaries, or ensure the extraction schema anticipates everything downstream needs.\n",[33,2029,2030],{"class":35,"line":101},[33,2031,74],{"emptyLinePlaceholder":73},[33,2033,2034],{"class":35,"line":107},[33,2035,2036],{"class":39},"# [Gotcha] Sequential latency is invisible until it's in production at real user\n",[33,2038,2039],{"class":35,"line":113},[33,2040,2041],{"class":39},"# think-time. A 4-stage pipeline that took acceptable seconds in dev against a\n",[33,2043,2044],{"class":35,"line":118},[33,2045,2046],{"class":39},"# fast, lightly-loaded API can feel unacceptably slow under production latency\n",[33,2048,2049],{"class":35,"line":124},[33,2050,2051],{"class":39},"# and rate-limiting. Measure end-to-end under realistic conditions.\n",[33,2053,2054],{"class":35,"line":136},[33,2055,74],{"emptyLinePlaceholder":73},[33,2057,2058],{"class":35,"line":185},[33,2059,2060],{"class":39},"# [Gotcha] Conditional branches rarely exercised in testing can harbor silent\n",[33,2062,2063],{"class":35,"line":226},[33,2064,2065],{"class":39},"# bugs for months. A branch handling an uncommon category might go months without\n",[33,2067,2068],{"class":35,"line":266},[33,2069,2070],{"class":39},"# a real example, and when one arrives, the branch's prompt was written against a\n",[33,2072,2073],{"class":35,"line":306},[33,2074,2075],{"class":39},"# stale assumption about the schema flowing into it. Include at least one test\n",[33,2077,2078],{"class":35,"line":312},[33,2079,2080],{"class":39},"# case per branch, even for rare branches (Chapter 9).\n",[33,2082,2083],{"class":35,"line":318},[33,2084,74],{"emptyLinePlaceholder":73},[33,2086,2087],{"class":35,"line":324},[33,2088,2089],{"class":39},"# [Gotcha] Passing an entire prior step's raw output forward \"just in case\"\n",[33,2091,2092],{"class":35,"line":614},[33,2093,2094],{"class":39},"# reintroduces the context-bloat problem decomposition was meant to solve. If\n",[33,2096,2097],{"class":35,"line":620},[33,2098,2099],{"class":39},"# every stage defensively forwards everything, the final stages end up with as\n",[33,2101,2102],{"class":35,"line":865},[33,2103,2104],{"class":39},"# much irrelevant context as the monolithic prompt you were trying to avoid.\n",[14,2106,2108],{"id":2107},"spot-the-bug","🧠 Spot the Bug",[2110,2111,2112],"p",{},"A three-stage moderation pipeline: Stage 1 classifies as SAFE\u002FBORDERLINE\u002FUNSAFE. Stage 2 (only runs if BORDERLINE\u002FUNSAFE) extracts the violation category. Stage 3 (only runs if Stage 2 ran) drafts the user-facing explanation. A genuinely UNSAFE post written in heavily sarcastic, indirect style gets classified as SAFE at Stage 1. Because Stages 2 and 3 only run conditionally, the post sails through with no further checks. What's the structural flaw?",[2114,2115,2116,2120,2132,2135],"details",{},[2117,2118,2119],"summary",{},"Answer",[2110,2121,2122,2123,2127,2128,2131],{},"The pipeline's conditional branching means every downstream stage's ",[2124,2125,2126],"em",{},"entire existence"," depends on Stage 1 being correct — there's no independent check that could catch a Stage 1 error, because Stages 2 and 3 are architecturally incapable of running once Stage 1 says SAFE. This is the \"errors compound across stages\" risk taken to its extreme: instead of degrading a later stage's input, a single early misclassification ",[2124,2129,2130],{},"terminates the entire pipeline"," with no downstream opportunity to catch it.",[2110,2133,2134],{},"A more robust design would decouple \"should this get flagged for closer review\" from a single classification call — for example, running a cheap independent secondary signal in parallel (a keyword\u002Fpattern check, or a second differently-prompted classification pass) that can force escalation to Stage 2 even when Stage 1 says SAFE, or routing a random sample of SAFE-classified posts to human review as an ongoing audit on Stage 1's accuracy.",[2110,2136,2137,2138,2142],{},"The lesson: when later stages only run conditionally on an early stage's output, that early stage becomes a ",[2139,2140,2141],"strong",{},"single point of failure"," for the entire pipeline. High-stakes conditional gating needs an independent corroborating signal or a sampling-based audit, not sole reliance on one classification call.",[14,2144,2146],{"id":2145},"key-takeaways","Key Takeaways",[19,2148,2150],{"filename":2149,"language":22},"key_takeaways.py",[24,2151,2153],{"className":26,"code":2152,"language":22,"meta":28,"style":28},"\"\"\"\nDecomposition & task breakdown — pipelines of focused prompts.\n\"\"\"\n\n# 1. One giant prompt dividing attention across N tasks → quality degrades on\n#    each. Decompose into focused single-purpose stages → each gets full attention.\n\n# 2. Decompose along GENUINE dependencies. Only serialize steps that need prior\n#    outputs. Independent steps → parallel (asyncio.gather). Dependency graph\n#    first, chain second.\n\n# 3. Structured handoffs between stages (JSON schema) let application code\n#    validate, filter, and branch reliably — far more robust than passing prose.\n\n# 4. Errors compound MULTIPLICATIVELY: 0.95^4 = 0.815, not 0.95. Validate at\n#    each stage, retry\u002Ffall back individually, measure end-to-end reliability.\n\n# 5. CoT (one call, internal reasoning) and decomposition (multiple calls,\n#    inspectable stages) solve different problems and COMBINE well: decompose\n#    across major stages, use CoT within any stage that benefits from it.\n",[30,2154,2155,2159,2164,2168,2172,2177,2182,2186,2191,2196,2201,2205,2210,2215,2219,2224,2229,2233,2238,2243],{"__ignoreMap":28},[33,2156,2157],{"class":35,"line":36},[33,2158,86],{"class":54},[33,2160,2161],{"class":35,"line":43},[33,2162,2163],{"class":54},"Decomposition & task breakdown — pipelines of focused prompts.\n",[33,2165,2166],{"class":35,"line":58},[33,2167,86],{"class":54},[33,2169,2170],{"class":35,"line":64},[33,2171,74],{"emptyLinePlaceholder":73},[33,2173,2174],{"class":35,"line":70},[33,2175,2176],{"class":39},"# 1. One giant prompt dividing attention across N tasks → quality degrades on\n",[33,2178,2179],{"class":35,"line":77},[33,2180,2181],{"class":39},"#    each. Decompose into focused single-purpose stages → each gets full attention.\n",[33,2183,2184],{"class":35,"line":83},[33,2185,74],{"emptyLinePlaceholder":73},[33,2187,2188],{"class":35,"line":89},[33,2189,2190],{"class":39},"# 2. Decompose along GENUINE dependencies. Only serialize steps that need prior\n",[33,2192,2193],{"class":35,"line":95},[33,2194,2195],{"class":39},"#    outputs. Independent steps → parallel (asyncio.gather). Dependency graph\n",[33,2197,2198],{"class":35,"line":101},[33,2199,2200],{"class":39},"#    first, chain second.\n",[33,2202,2203],{"class":35,"line":107},[33,2204,74],{"emptyLinePlaceholder":73},[33,2206,2207],{"class":35,"line":113},[33,2208,2209],{"class":39},"# 3. Structured handoffs between stages (JSON schema) let application code\n",[33,2211,2212],{"class":35,"line":118},[33,2213,2214],{"class":39},"#    validate, filter, and branch reliably — far more robust than passing prose.\n",[33,2216,2217],{"class":35,"line":124},[33,2218,74],{"emptyLinePlaceholder":73},[33,2220,2221],{"class":35,"line":136},[33,2222,2223],{"class":39},"# 4. Errors compound MULTIPLICATIVELY: 0.95^4 = 0.815, not 0.95. Validate at\n",[33,2225,2226],{"class":35,"line":185},[33,2227,2228],{"class":39},"#    each stage, retry\u002Ffall back individually, measure end-to-end reliability.\n",[33,2230,2231],{"class":35,"line":226},[33,2232,74],{"emptyLinePlaceholder":73},[33,2234,2235],{"class":35,"line":266},[33,2236,2237],{"class":39},"# 5. CoT (one call, internal reasoning) and decomposition (multiple calls,\n",[33,2239,2240],{"class":35,"line":306},[33,2241,2242],{"class":39},"#    inspectable stages) solve different problems and COMBINE well: decompose\n",[33,2244,2245],{"class":35,"line":312},[33,2246,2247],{"class":39},"#    across major stages, use CoT within any stage that benefits from it.\n",[2249,2250,2251],"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 .sJ6F3, html code.shiki .sJ6F3{--shiki-default:#032F62;--shiki-github-dark:#9ECBFF}html pre.shiki code .ssxIu, html code.shiki .ssxIu{--shiki-default:#24292E;--shiki-github-dark:#E1E4E8}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}",{"title":28,"searchDepth":43,"depth":43,"links":2253},[2254,2255,2256,2257,2258,2259,2260,2261,2262,2263],{"id":16,"depth":43,"text":17},{"id":330,"depth":43,"text":331},{"id":626,"depth":43,"text":627},{"id":1050,"depth":43,"text":1051},{"id":1288,"depth":43,"text":1289},{"id":1583,"depth":43,"text":1584},{"id":1846,"depth":43,"text":1847},{"id":1974,"depth":43,"text":1975},{"id":2107,"depth":43,"text":2108},{"id":2145,"depth":43,"text":2146},"Splitting complex tasks into pipelines of focused single-purpose prompts — sequential vs parallel decomposition, structured handoffs, conditional branching, and error compounding. Code-first reference for mid-to-senior engineers.","md",{},"\u002Fprompt-engineering\u002F10-decomposition-and-task-breakdown",{"title":5,"description":2264},"prompt-engineering\u002F10-decomposition-and-task-breakdown","FbocwF-y7iKbwUFunHrk4k73nng6TfucRuV7Wck8d_c",1789924650955]