12 Factor Agents Developer Dex introduces the 12 Factor Agents methodology, a set of engineering principles for building reliable and maintainable AI agents, drawing from his experience with various agent frameworks and conversations with founders. The open-source guide emphasizes deterministic code with LLM steps rather than fully autonomous agents, aiming to improve scalability and reliability of LLM-powered software. In the spirit of 12 Factor Apps . The source for this project is public at https://github.com/humanlayer/12-factor-agents https://github.com/humanlayer/12-factor-agents , and I welcome your feedback and contributions. Let's figure this out together Tip Missed the AI Engineer World's Fair? Catch the talk here https://www.youtube.com/watch?v=8kMaTybvDUw Looking for Context Engineering? Jump straight to factor 3 https://github.com/humanlayer/12-factor-agents/blob/main/content/factor-03-own-your-context-window.md Want to contribute to npx/uvx create-12-factor-agent - check out the discussion thread https://github.com/humanlayer/12-factor-agents/discussions/61 Hi, I'm Dex. I've been hacking https://youtu.be/8bIHcttkOTE on AI agents https://theouterloop.substack.com for a while https://humanlayer.dev . I've tried every agent framework out there , from the plug-and-play crew/langchains to the "minimalist" smolagents of the world to the "production grade" langraph, griptape, etc. I've talked to a lot of really strong founders , in and out of YC, who are all building really impressive things with AI. Most of them are rolling the stack themselves. I don't see a lot of frameworks in production customer-facing agents. I've been surprised to find that most of the products out there billing themselves as "AI Agents" are not all that agentic. A lot of them are mostly deterministic code, with LLM steps sprinkled in at just the right points to make the experience truly magical. Agents, at least the good ones, don't follow the "here's your prompt, here's a bag of tools, loop until you hit the goal" https://www.anthropic.com/engineering/building-effective-agents agents pattern. Rather, they are comprised of mostly just software. So, I set out to answer: Welcome to 12-factor agents. As every Chicago mayor since Daley has consistently plastered all over the city's major airports, we're glad you're here. Special thanks to @iantbutler01, @tnm, @hellovai, @stantonk, @balanceiskey, @AdjectiveAllison, @pfbyjy, @a-churchill, and the SF MLOps community for early feedback on this guide. Even if LLMs continue to get exponentially more powerful https://github.com/humanlayer/12-factor-agents/blob/main/content/factor-10-small-focused-agents.md what-if-llms-get-smarter , there will be core engineering techniques that make LLM-powered software more reliable, more scalable, and easier to maintain. How We Got Here: A Brief History of Software https://github.com/humanlayer/12-factor-agents/blob/main/content/brief-history-of-software.md Factor 1: Natural Language to Tool Calls https://github.com/humanlayer/12-factor-agents/blob/main/content/factor-01-natural-language-to-tool-calls.md Factor 2: Own your prompts https://github.com/humanlayer/12-factor-agents/blob/main/content/factor-02-own-your-prompts.md Factor 3: Own your context window https://github.com/humanlayer/12-factor-agents/blob/main/content/factor-03-own-your-context-window.md Factor 4: Tools are just structured outputs https://github.com/humanlayer/12-factor-agents/blob/main/content/factor-04-tools-are-structured-outputs.md Factor 5: Unify execution state and business state https://github.com/humanlayer/12-factor-agents/blob/main/content/factor-05-unify-execution-state.md Factor 6: Launch/Pause/Resume with simple APIs https://github.com/humanlayer/12-factor-agents/blob/main/content/factor-06-launch-pause-resume.md Factor 7: Contact humans with tool calls https://github.com/humanlayer/12-factor-agents/blob/main/content/factor-07-contact-humans-with-tools.md Factor 8: Own your control flow https://github.com/humanlayer/12-factor-agents/blob/main/content/factor-08-own-your-control-flow.md Factor 9: Compact Errors into Context Window https://github.com/humanlayer/12-factor-agents/blob/main/content/factor-09-compact-errors.md Factor 10: Small, Focused Agents https://github.com/humanlayer/12-factor-agents/blob/main/content/factor-10-small-focused-agents.md Factor 11: Trigger from anywhere, meet users where they are https://github.com/humanlayer/12-factor-agents/blob/main/content/factor-11-trigger-from-anywhere.md Factor 12: Make your agent a stateless reducer https://github.com/humanlayer/12-factor-agents/blob/main/content/factor-12-stateless-reducer.md For a deeper dive on my agent journey and what led us here, check out A Brief History of Software https://github.com/humanlayer/12-factor-agents/blob/main/content/brief-history-of-software.md - a quick summary here: We're gonna talk a lot about Directed Graphs DGs and their Acyclic friends, DAGs. I'll start by pointing out that...well...software is a directed graph. There's a reason we used to represent programs as flow charts. Around 20 years ago, we started to see DAG orchestrators become popular. We're talking classics like Airflow https://airflow.apache.org/ , Prefect https://www.prefect.io/ , some predecessors, and some newer ones like dagster https://dagster.io/ , inggest https://www.inngest.com/ , windmill https://www.windmill.dev/ . These followed the same graph pattern, with the added benefit of observability, modularity, retries, administration, etc. I'm not the first person to say this https://youtu.be/Dc99-zTMyMg?si=bcT0hIwWij2mR-40&t=73 , but my biggest takeaway when I started learning about agents, was that you get to throw the DAG away. Instead of software engineers coding each step and edge case, you can give the agent a goal and a set of transitions: And let the LLM make decisions in real time to figure out the path The promise here is that you write less software, you just give the LLM the "edges" of the graph and let it figure out the nodes. You can recover from errors, you can write less code, and you may find that LLMs find novel solutions to problems. As we'll see later, it turns out this doesn't quite work. Let's dive one step deeper - with agents you've got this loop consisting of 3 steps: - LLM determines the next step in the workflow, outputting structured json "tool calling" - Deterministic code executes the tool call - The result is appended to the context window - Repeat until the next step is determined to be "done" initial event = {"message": "..."} context = initial event while True: next step = await llm.determine next step context context.append next step if next step.intent === "done" : return next step.final answer result = await execute step next step context.append result Our initial context is just the starting event maybe a user message, maybe a cron fired, maybe a webhook, etc , and we ask the llm to choose the next step tool or to determine that we're done. Here's a multi-step example: 027-agent-loop-animation.mp4 At the end of the day, this approach just doesn't work as well as we want it to. In building HumanLayer, I've talked to at least 100 SaaS builders mostly technical founders looking to make their existing product more agentic. The journey usually goes something like: - Decide you want to build an agent - Product design, UX mapping, what problems to solve - Want to move fast, so grab $FRAMEWORK and get to building - Get to 70-80% quality bar - Realize that 80% isn't good enough for most customer-facing features - Realize that getting past 80% requires reverse-engineering the framework, prompts, flow, etc. - Start over from scratch Random Disclaimers DISCLAIMER : I'm not sure the exact right place to say this, but here seems as good as any: this in BY NO MEANS meant to be a dig on either the many frameworks out there, or the pretty dang smart people who work on them . They enable incredible things and have accelerated the AI ecosystem. I hope that one outcome of this post is that agent framework builders can learn from the journeys of myself and others, and make frameworks even better. Especially for builders who want to move fast but need deep control. DISCLAIMER 2 : I'm not going to talk about MCP. I'm sure you can see where it fits in. DISCLAIMER 3 : I'm using mostly typescript, for reasons https://www.linkedin.com/posts/dexterihorthy llms-typescript-aiagents-activity-7290858296679313408-Lh9e?utm source=share&utm medium=member desktop&rcm=ACoAAA4oHTkByAiD-wZjnGsMBUL JT6nyyhOh30 but all this stuff works in python or any other language you prefer. Anyways back to the thing... After digging through hundreds of AI libriaries and working with dozens of founders, my instinct is this: - There are some core things that make agents great - Going all in on a framework and building what is essentially a greenfield rewrite may be counter-productive - There are some core principles that make agents great, and you will get most/all of them if you pull in a framework - BUT, the fastest way I've seen for builders to get high-quality AI software in the hands of customers is to take small, modular concepts from agent building, and incorporate them into their existing product - These modular concepts from agents can be defined and applied by most skilled software engineers, even if they don't have an AI background How We Got Here: A Brief History of Software https://github.com/humanlayer/12-factor-agents/blob/main/content/brief-history-of-software.md Factor 1: Natural Language to Tool Calls https://github.com/humanlayer/12-factor-agents/blob/main/content/factor-01-natural-language-to-tool-calls.md Factor 2: Own your prompts https://github.com/humanlayer/12-factor-agents/blob/main/content/factor-02-own-your-prompts.md Factor 3: Own your context window https://github.com/humanlayer/12-factor-agents/blob/main/content/factor-03-own-your-context-window.md Factor 4: Tools are just structured outputs https://github.com/humanlayer/12-factor-agents/blob/main/content/factor-04-tools-are-structured-outputs.md Factor 5: Unify execution state and business state https://github.com/humanlayer/12-factor-agents/blob/main/content/factor-05-unify-execution-state.md Factor 6: Launch/Pause/Resume with simple APIs https://github.com/humanlayer/12-factor-agents/blob/main/content/factor-06-launch-pause-resume.md Factor 7: Contact humans with tool calls https://github.com/humanlayer/12-factor-agents/blob/main/content/factor-07-contact-humans-with-tools.md Factor 8: Own your control flow https://github.com/humanlayer/12-factor-agents/blob/main/content/factor-08-own-your-control-flow.md Factor 9: Compact Errors into Context Window https://github.com/humanlayer/12-factor-agents/blob/main/content/factor-09-compact-errors.md Factor 10: Small, Focused Agents https://github.com/humanlayer/12-factor-agents/blob/main/content/factor-10-small-focused-agents.md Factor 11: Trigger from anywhere, meet users where they are https://github.com/humanlayer/12-factor-agents/blob/main/content/factor-11-trigger-from-anywhere.md Factor 12: Make your agent a stateless reducer https://github.com/humanlayer/12-factor-agents/blob/main/content/factor-12-stateless-reducer.md - Contribute to this guide here https://github.com/humanlayer/12-factor-agents I talked about a lot of this on an episode of the Tool Use podcast https://youtu.be/8bIHcttkOTE in March 2025- I write about some of this stuff at The Outer Loop https://theouterloop.substack.com - I do webinars about Maximizing LLM Performance https://github.com/hellovai/ai-that-works/tree/main with @hellovai https://github.com/hellovai - We build OSS agents with this methodology under got-agents/agents https://github.com/got-agents/agents - We ignored all our own advice and built a framework for running distributed agents in kubernetes https://github.com/humanlayer/kubechain - Other links from this guide: 12 Factor Apps https://12factor.net Building Effective Agents Anthropic https://www.anthropic.com/engineering/building-effective-agents agents Prompts are Functions https://thedataexchange.media/baml-revolution-in-ai-engineering/ Library patterns: Why frameworks are evil https://tomasp.net/blog/2015/library-frameworks/ The Wrong Abstraction https://sandimetz.com/blog/2016/1/20/the-wrong-abstraction Mailcrew Agent https://github.com/dexhorthy/mailcrew Mailcrew Demo Video https://www.youtube.com/watch?v=f cKnoPC Oo Chainlit Demo https://x.com/chainlit io/status/1858613325921480922 TypeScript for LLMs https://www.linkedin.com/posts/dexterihorthy llms-typescript-aiagents-activity-7290858296679313408-Lh9e Schema Aligned Parsing https://www.boundaryml.com/blog/schema-aligned-parsing Function Calling vs Structured Outputs vs JSON Mode https://www.vellum.ai/blog/when-should-i-use-function-calling-structured-outputs-or-json-mode BAML on GitHub https://github.com/boundaryml/baml OpenAI JSON vs Function Calling https://docs.llamaindex.ai/en/stable/examples/llm/openai json vs function calling/ Outer Loop Agents https://theouterloop.substack.com/p/openais-realtime-api-is-a-step-towards Airflow https://airflow.apache.org/ Prefect https://www.prefect.io/ Dagster https://dagster.io/ Inngest https://www.inngest.com/ Windmill https://www.windmill.dev/ The AI Agent Index MIT https://aiagentindex.mit.edu/ NotebookLM on Finding Model Capability Boundaries https://open.substack.com/pub/swyx/p/notebooklm?selection=08e1187c-cfee-4c63-93c9-71216640a5f8 Thanks to everyone who has contributed to 12-factor agents All content and images are licensed under a CC BY-SA 4.0 License https://creativecommons.org/licenses/by-sa/4.0/ Code is licensed under the Apache 2.0 License https://www.apache.org/licenses/LICENSE-2.0