[{"data":1,"prerenderedAt":528},["ShallowReactive",2],{"layout-chapters":3,"sidebar-chapters":34,"chapter-factor-2":65,"all-chapters":511},[4,6,8,10,12,14,16,18,20,22,24,26,28,30,32],{"slug":5},"intro",{"slug":7},"brief-history",{"slug":9},"factor-1",{"slug":11},"factor-2",{"slug":13},"factor-3",{"slug":15},"factor-4",{"slug":17},"factor-5",{"slug":19},"factor-6",{"slug":21},"factor-7",{"slug":23},"factor-8",{"slug":25},"factor-9",{"slug":27},"factor-10",{"slug":29},"factor-11",{"slug":31},"factor-12",{"slug":33},"appendix",[35,37,39,41,43,45,47,49,51,53,55,57,59,61,63],{"slug":5,"title":36},"Introduction",{"slug":7,"title":38},"A Brief History of Software",{"slug":9,"title":40},"Factor 1: Natural Language to Tool Calls",{"slug":11,"title":42},"Factor 2: Own Your Prompts",{"slug":13,"title":44},"Factor 3: Own Your Context Window",{"slug":15,"title":46},"Factor 4: Tools Are Structured Outputs",{"slug":17,"title":48},"Factor 5: Unify Execution State",{"slug":19,"title":50},"Factor 6: Launch\u002FPause\u002FResume",{"slug":21,"title":52},"Factor 7: Contact Humans with Tools",{"slug":23,"title":54},"Factor 8: Own Your Control Flow",{"slug":25,"title":56},"Factor 9: Compact Errors into Context",{"slug":27,"title":58},"Factor 10: Small, Focused Agents",{"slug":29,"title":60},"Factor 11: Trigger from Anywhere",{"slug":31,"title":62},"Factor 12: Stateless Reducer",{"slug":33,"title":64},"Appendix: Pre-Fetch Context",{"id":66,"title":42,"body":67,"chapterIndex":131,"description":111,"extension":506,"meta":507,"navigation":158,"path":508,"seo":509,"slug":11,"stem":11,"__hash__":510},"chapters\u002Ffactor-2.md",{"type":68,"value":69,"toc":503},"minimark",[70,75,79,86,96,102,105,194,197,200,374,383,391,452,455,490,493,496,499],[71,72,74],"h3",{"id":73},"_2-own-your-prompts","2. Own your prompts",[76,77,78],"p",{},"Don't outsource your prompt engineering to a framework.",[76,80,81],{},[82,83],"img",{"alt":84,"src":85},"120-own-your-prompts","https:\u002F\u002Fgithub.com\u002Fhumanlayer\u002F12-factor-agents\u002Fblob\u002Fmain\u002Fimg\u002F120-own-your-prompts.png?raw=true",[76,87,88,89],{},"By the way, ",[90,91,95],"a",{"href":92,"rel":93},"https:\u002F\u002Fhamel.dev\u002Fblog\u002Fposts\u002Fprompt\u002F",[94],"nofollow","this is far from novel advice:",[76,97,98],{},[82,99],{"alt":100,"src":101},"image","https:\u002F\u002Fgithub.com\u002Fuser-attachments\u002Fassets\u002F575bab37-0f96-49fb-9ce3-9a883cdd420b?raw=true",[76,103,104],{},"Some frameworks provide a \"black box\" approach like this:",[106,107,112],"pre",{"className":108,"code":109,"language":110,"meta":111,"style":111},"language-python shiki shiki-themes github-light github-dark","agent = Agent(\n  role=\"...\",\n  goal=\"...\",\n  personality=\"...\",\n  tools=[tool1, tool2, tool3]\n)\n\ntask = Task(\n  instructions=\"...\",\n  expected_output=OutputModel\n)\n\nresult = agent.run(task)\n","python","",[113,114,115,123,129,135,141,147,153,160,166,172,178,183,188],"code",{"__ignoreMap":111},[116,117,120],"span",{"class":118,"line":119},"line",1,[116,121,122],{},"agent = Agent(\n",[116,124,126],{"class":118,"line":125},2,[116,127,128],{},"  role=\"...\",\n",[116,130,132],{"class":118,"line":131},3,[116,133,134],{},"  goal=\"...\",\n",[116,136,138],{"class":118,"line":137},4,[116,139,140],{},"  personality=\"...\",\n",[116,142,144],{"class":118,"line":143},5,[116,145,146],{},"  tools=[tool1, tool2, tool3]\n",[116,148,150],{"class":118,"line":149},6,[116,151,152],{},")\n",[116,154,156],{"class":118,"line":155},7,[116,157,159],{"emptyLinePlaceholder":158},true,"\n",[116,161,163],{"class":118,"line":162},8,[116,164,165],{},"task = Task(\n",[116,167,169],{"class":118,"line":168},9,[116,170,171],{},"  instructions=\"...\",\n",[116,173,175],{"class":118,"line":174},10,[116,176,177],{},"  expected_output=OutputModel\n",[116,179,181],{"class":118,"line":180},11,[116,182,152],{},[116,184,186],{"class":118,"line":185},12,[116,187,159],{"emptyLinePlaceholder":158},[116,189,191],{"class":118,"line":190},13,[116,192,193],{},"result = agent.run(task)\n",[76,195,196],{},"This is great for pulling in some TOP NOTCH prompt engineering to get you started, but it is often difficult to tune and\u002For reverse engineer to get exactly the right tokens into your model.",[76,198,199],{},"Instead, own your prompts and treat them as first-class code:",[106,201,205],{"className":202,"code":203,"language":204,"meta":111,"style":111},"language-rust shiki shiki-themes github-light github-dark","function DetermineNextStep(thread: string) -> DoneForNow | ListGitTags | DeployBackend | DeployFrontend | RequestMoreInformation {\n  prompt #\"\n    {{ _.role(\"system\") }}\n    \n    You are a helpful assistant that manages deployments for frontend and backend systems.\n    You work diligently to ensure safe and successful deployments by following best practices\n    and proper deployment procedures.\n    \n    Before deploying any system, you should check:\n    - The deployment environment (staging vs production)\n    - The correct tag\u002Fversion to deploy\n    - The current system status\n    \n    You can use tools like deploy_backend, deploy_frontend, and check_deployment_status\n    to manage deployments. For sensitive deployments, use request_approval to get\n    human verification.\n    \n    Always think about what to do first, like:\n    - Check current deployment status\n    - Verify the deployment tag exists\n    - Request approval if needed\n    - Deploy to staging before production\n    - Monitor deployment progress\n    \n    {{ _.role(\"user\") }}\n\n    {{ thread }}\n    \n    What should the next step be?\n  \"#\n}\n","rust",[113,206,207,212,217,222,227,232,237,242,246,251,256,261,266,270,276,282,288,293,299,305,311,317,323,329,334,340,345,351,356,362,368],{"__ignoreMap":111},[116,208,209],{"class":118,"line":119},[116,210,211],{},"function DetermineNextStep(thread: string) -> DoneForNow | ListGitTags | DeployBackend | DeployFrontend | RequestMoreInformation {\n",[116,213,214],{"class":118,"line":125},[116,215,216],{},"  prompt #\"\n",[116,218,219],{"class":118,"line":131},[116,220,221],{},"    {{ _.role(\"system\") }}\n",[116,223,224],{"class":118,"line":137},[116,225,226],{},"    \n",[116,228,229],{"class":118,"line":143},[116,230,231],{},"    You are a helpful assistant that manages deployments for frontend and backend systems.\n",[116,233,234],{"class":118,"line":149},[116,235,236],{},"    You work diligently to ensure safe and successful deployments by following best practices\n",[116,238,239],{"class":118,"line":155},[116,240,241],{},"    and proper deployment procedures.\n",[116,243,244],{"class":118,"line":162},[116,245,226],{},[116,247,248],{"class":118,"line":168},[116,249,250],{},"    Before deploying any system, you should check:\n",[116,252,253],{"class":118,"line":174},[116,254,255],{},"    - The deployment environment (staging vs production)\n",[116,257,258],{"class":118,"line":180},[116,259,260],{},"    - The correct tag\u002Fversion to deploy\n",[116,262,263],{"class":118,"line":185},[116,264,265],{},"    - The current system status\n",[116,267,268],{"class":118,"line":190},[116,269,226],{},[116,271,273],{"class":118,"line":272},14,[116,274,275],{},"    You can use tools like deploy_backend, deploy_frontend, and check_deployment_status\n",[116,277,279],{"class":118,"line":278},15,[116,280,281],{},"    to manage deployments. For sensitive deployments, use request_approval to get\n",[116,283,285],{"class":118,"line":284},16,[116,286,287],{},"    human verification.\n",[116,289,291],{"class":118,"line":290},17,[116,292,226],{},[116,294,296],{"class":118,"line":295},18,[116,297,298],{},"    Always think about what to do first, like:\n",[116,300,302],{"class":118,"line":301},19,[116,303,304],{},"    - Check current deployment status\n",[116,306,308],{"class":118,"line":307},20,[116,309,310],{},"    - Verify the deployment tag exists\n",[116,312,314],{"class":118,"line":313},21,[116,315,316],{},"    - Request approval if needed\n",[116,318,320],{"class":118,"line":319},22,[116,321,322],{},"    - Deploy to staging before production\n",[116,324,326],{"class":118,"line":325},23,[116,327,328],{},"    - Monitor deployment progress\n",[116,330,332],{"class":118,"line":331},24,[116,333,226],{},[116,335,337],{"class":118,"line":336},25,[116,338,339],{},"    {{ _.role(\"user\") }}\n",[116,341,343],{"class":118,"line":342},26,[116,344,159],{"emptyLinePlaceholder":158},[116,346,348],{"class":118,"line":347},27,[116,349,350],{},"    {{ thread }}\n",[116,352,354],{"class":118,"line":353},28,[116,355,226],{},[116,357,359],{"class":118,"line":358},29,[116,360,361],{},"    What should the next step be?\n",[116,363,365],{"class":118,"line":364},30,[116,366,367],{},"  \"#\n",[116,369,371],{"class":118,"line":370},31,[116,372,373],{},"}\n",[76,375,376,377,382],{},"(the above example uses ",[90,378,381],{"href":379,"rel":380},"https:\u002F\u002Fgithub.com\u002Fboundaryml\u002Fbaml",[94],"BAML"," to generate the prompt, but you can do this with any prompt engineering tool you want, or even just template it manually)",[76,384,385,386],{},"If the signature looks a little funny, we'll get to that in ",[90,387,390],{"href":388,"rel":389},"https:\u002F\u002Fgithub.com\u002Fhumanlayer\u002F12-factor-agents\u002Fblob\u002Fmain\u002Fcontent\u002Ffactor-04-tools-are-structured-outputs.md",[94],"factor 4 - tools are just structured outputs",[106,392,395],{"className":393,"code":211,"language":394,"meta":111,"style":111},"language-typescript shiki shiki-themes github-light github-dark","typescript",[113,396,397],{"__ignoreMap":111},[116,398,399,403,407,411,415,418,422,425,428,431,434,436,439,441,444,446,449],{"class":118,"line":119},[116,400,402],{"class":401},"szBVR","function",[116,404,406],{"class":405},"sScJk"," DetermineNextStep",[116,408,410],{"class":409},"sVt8B","(",[116,412,414],{"class":413},"s4XuR","thread",[116,416,417],{"class":401},":",[116,419,421],{"class":420},"sj4cs"," string",[116,423,424],{"class":409},") -> ",[116,426,427],{"class":405},"DoneForNow",[116,429,430],{"class":409}," | ",[116,432,433],{"class":405},"ListGitTags",[116,435,430],{"class":409},[116,437,438],{"class":405},"DeployBackend",[116,440,430],{"class":409},[116,442,443],{"class":405},"DeployFrontend",[116,445,430],{"class":409},[116,447,448],{"class":405},"RequestMoreInformation",[116,450,451],{"class":409}," {\n",[76,453,454],{},"Key benefits of owning your prompts:",[456,457,458,466,472,478,484],"ol",{},[459,460,461,465],"li",{},[462,463,464],"strong",{},"Full Control",": Write exactly the instructions your agent needs, no black box abstractions",[459,467,468,471],{},[462,469,470],{},"Testing and Evals",": Build tests and evals for your prompts just like you would for any other code",[459,473,474,477],{},[462,475,476],{},"Iteration",": Quickly modify prompts based on real-world performance",[459,479,480,483],{},[462,481,482],{},"Transparency",": Know exactly what instructions your agent is working with",[459,485,486,489],{},[462,487,488],{},"Role Hacking",": take advantage of APIs that support nonstandard usage of user\u002Fassistant roles - for example, the now-deprecated non-chat flavor of OpenAI \"completions\" API. This includes some so-called \"model gaslighting\" techniques",[76,491,492],{},"Remember: Your prompts are the primary interface between your application logic and the LLM.",[76,494,495],{},"Having full control over your prompts gives you the flexibility and prompt control you need for production-grade agents.",[76,497,498],{},"I don't know what's the best prompt, but I know you want the flexibility to be able to try EVERYTHING.",[500,501,502],"style",{},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .s4XuR, html code.shiki .s4XuR{--shiki-default:#E36209;--shiki-dark:#FFAB70}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}",{"title":111,"searchDepth":125,"depth":125,"links":504},[505],{"id":73,"depth":131,"text":74},"md",{},"\u002Ffactor-2",{"title":42,"description":111},"IvYbP27r4juKN1VGIU9cnZMjJqDK6Eg_ZVGWSGi98ic",[512,514,515,516,517,518,519,520,521,522,523,524,525,526,527],{"slug":5,"title":36,"chapterIndex":513},0,{"slug":7,"title":38,"chapterIndex":119},{"slug":9,"title":40,"chapterIndex":125},{"slug":11,"title":42,"chapterIndex":131},{"slug":13,"title":44,"chapterIndex":137},{"slug":15,"title":46,"chapterIndex":143},{"slug":17,"title":48,"chapterIndex":149},{"slug":19,"title":50,"chapterIndex":155},{"slug":21,"title":52,"chapterIndex":162},{"slug":23,"title":54,"chapterIndex":168},{"slug":25,"title":56,"chapterIndex":174},{"slug":27,"title":58,"chapterIndex":180},{"slug":29,"title":60,"chapterIndex":185},{"slug":31,"title":62,"chapterIndex":190},{"slug":33,"title":64,"chapterIndex":272},1788741638420]