[{"data":1,"prerenderedAt":238},["ShallowReactive",2],{"layout-chapters":3,"sidebar-chapters":34,"chapter-factor-5":65,"all-chapters":210},[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":48,"body":67,"chapterIndex":203,"description":198,"extension":204,"meta":205,"navigation":206,"path":207,"seo":208,"slug":17,"stem":17,"__hash__":209},"chapters\u002Ffactor-5.md",{"type":68,"value":69,"toc":197},"minimark",[70,75,79,87,90,107,110,123,137,140,149,152],[71,72,74],"h3",{"id":73},"_5-unify-execution-state-and-business-state","5. Unify execution state and business state",[76,77,78],"p",{},"Even outside the AI world, many infrastructure systems try to separate \"execution state\" from \"business state\". For AI apps, this might involve complex abstractions to track things like current step, next step, waiting status, retry counts, etc. This separation creates complexity that may be worthwhile, but may be overkill for your use case.",[76,80,81,82,86],{},"As always, it's up to you to decide what's right for your application. But don't think you ",[83,84,85],"em",{},"have"," to manage them separately.",[76,88,89],{},"More clearly:",[91,92,93,101],"ul",{},[94,95,96,100],"li",{},[97,98,99],"strong",{},"Execution state",": current step, next step, waiting status, retry counts, etc.",[94,102,103,106],{},[97,104,105],{},"Business state",": What's happened in the agent workflow so far (e.g. list of OpenAI messages, list of tool calls and results, etc.)",[76,108,109],{},"If possible, SIMPLIFY - unify these as much as possible.",[76,111,112],{},[113,114,118],"a",{"href":115,"rel":116},"https:\u002F\u002Fgithub.com\u002Fuser-attachments\u002Fassets\u002Fe5a851db-f58f-43d8-8b0c-1926c99fc68d",[117],"nofollow",[119,120],"img",{"alt":121,"src":122},"155-unify-state","https:\u002F\u002Fgithub.com\u002Fhumanlayer\u002F12-factor-agents\u002Fblob\u002Fmain\u002Fimg\u002F155-unify-state-animation.gif?raw=true",[124,125,126,133],"details",{},[127,128,129],"summary",{},[113,130,132],{"href":131},"https:\u002F\u002Fgithub.com\u002Fhumanlayer\u002F12-factor-agents\u002Fblob\u002Fmain\u002Fimg\u002F155-unify-state-animation.gif","GIF Version",[76,134,135],{},[119,136],{"alt":121,"src":122},[76,138,139],{},"In reality, you can engineer your application so that you can infer all execution state from the context window. In many cases, execution state (current step, waiting status, etc.) is just metadata about what has happened so far.",[76,141,142,143,148],{},"You may have things that can't go in the context window, like session ids, password contexts, etc, but your goal should be to minimize those things. By embracing ",[113,144,147],{"href":145,"rel":146},"https:\u002F\u002Fgithub.com\u002Fhumanlayer\u002F12-factor-agents\u002Fblob\u002Fmain\u002Fcontent\u002Ffactor-03-own-your-context-window.md",[117],"factor 3"," you can control what actually goes into the LLM",[76,150,151],{},"This approach has several benefits:",[153,154,155,161,167,173,179,185,191],"ol",{},[94,156,157,160],{},[97,158,159],{},"Simplicity",": One source of truth for all state",[94,162,163,166],{},[97,164,165],{},"Serialization",": The thread is trivially serializable\u002Fdeserializable",[94,168,169,172],{},[97,170,171],{},"Debugging",": The entire history is visible in one place",[94,174,175,178],{},[97,176,177],{},"Flexibility",": Easy to add new state by just adding new event types",[94,180,181,184],{},[97,182,183],{},"Recovery",": Can resume from any point by just loading the thread",[94,186,187,190],{},[97,188,189],{},"Forking",": Can fork the thread at any point by copying some subset of the thread into a new context \u002F state ID",[94,192,193,196],{},[97,194,195],{},"Human Interfaces and Observability",": Trivial to convert a thread into a human-readable markdown or a rich Web app UI",{"title":198,"searchDepth":199,"depth":199,"links":200},"",2,[201],{"id":73,"depth":202,"text":74},3,6,"md",{},true,"\u002Ffactor-5",{"title":48,"description":198},"ZzHDQZ5OmofGPSr-kArby3-ea6C0RtQXJGBuAuNfUo4",[211,213,215,216,217,219,221,222,224,226,228,230,232,234,236],{"slug":5,"title":36,"chapterIndex":212},0,{"slug":7,"title":38,"chapterIndex":214},1,{"slug":9,"title":40,"chapterIndex":199},{"slug":11,"title":42,"chapterIndex":202},{"slug":13,"title":44,"chapterIndex":218},4,{"slug":15,"title":46,"chapterIndex":220},5,{"slug":17,"title":48,"chapterIndex":203},{"slug":19,"title":50,"chapterIndex":223},7,{"slug":21,"title":52,"chapterIndex":225},8,{"slug":23,"title":54,"chapterIndex":227},9,{"slug":25,"title":56,"chapterIndex":229},10,{"slug":27,"title":58,"chapterIndex":231},11,{"slug":29,"title":60,"chapterIndex":233},12,{"slug":31,"title":62,"chapterIndex":235},13,{"slug":33,"title":64,"chapterIndex":237},14,1788741638421]