# 12-Factor Agents: Patterns of Reliable LLM Applications

Dex Horthy, HumanLayer | AI Engineer World's Fair 2025 | 17:06

Source: https://www.youtube.com/watch?v=8kMaTybvDUw
Channel: AI Engineer (https://www.youtube.com/@aiDotEngineer). Summarised by AIE Talks.
Page: https://aietalks.com/talks/12-factor-agents-patterns-of-reliable-llm-applications
Published: 2025-07-03
Tags: context-engineering, reliability, tool-use, workflows

## TL;DR
- Reliable agents are mostly ordinary software with carefully chosen LLM steps inside deterministic workflows.
- Tools are structured JSON passed to code, so engineers should own the prompts, context window, state, and control flow around them.
- Small focused agents can handle bounded tasks while humans enter the workflow through natural language and familiar channels such as Slack or email.

## Summary
Dex Horthy argues that production agents rarely follow the simple pattern of a prompt, a bag of tools, and a loop. In practice, the strongest systems he saw were mostly deterministic software with LLM steps placed where they added value. He presents the 12 factors as software engineering patterns for making those systems reliable. The main ideas are to turn natural language into structured outputs, write and test prompts directly, control the context window, model tools as JSON plus ordinary code, and own execution and business state. Agents should pause and resume through simple APIs, contact humans when needed, run in small focused loops, and accept triggers from channels such as Slack, email, Discord, or SMS. Horthy is honest that longer autonomous loops often degrade as context grows. His recommendation is to start with deterministic workflows, add bounded agents at their edges, and let models take on larger tasks only as the surrounding system makes them reliable.

## Key ideas
### Most production agents are mostly software
[01:31](https://www.youtube.com/watch?v=8kMaTybvDUw&t=91s)
After speaking with more than 100 founders, builders, and engineers, Dex Horthy noticed that most production agents were not very agentic. They were mostly ordinary software with LLM steps placed at selected points. Teams were applying small, modular concepts to existing code instead of rewriting everything around an agent framework. He compares this with the way cloud applications were built before the term "cloud native" became common. The 12 factors are presented as a practical set of patterns and as a wish list for frameworks that need to support builders who want high reliability while moving quickly.

### Natural language to JSON is the useful model capability
[03:47](https://www.youtube.com/watch?v=8kMaTybvDUw&t=227s)
Horthy says the most magical thing an LLM can do is turn a sentence into JSON. The JSON can then enter ordinary application code, regardless of whether that code is a loop, a switch statement, or a larger workflow. This is his first factor, natural language to tool calls. The point is to isolate the model's strength in interpreting language and selecting an action from the deterministic code that executes the action. The rest of the system can then be designed and tested as software.

### Tools are structured outputs followed by deterministic code
[04:04](https://www.youtube.com/watch?v=8kMaTybvDUw&t=244s)
Horthy calls tool use harmful as an abstraction, while clarifying that giving an agent access to the world is useful. The difficulty comes from treating tool use as something mysterious. The model outputs JSON, deterministic code does something with it, and the result may be added to the next model input. If an output can generate a normal program structure, it can feed a loop or a switch statement. There is no special execution category called a tool once the model output and the code are separated.

### Owning control flow keeps long workflows manageable
[05:09](https://www.youtube.com/watch?v=8kMaTybvDUw&t=309s)
The naive agent is a loop that sends an event into a prompt, executes the model's next step, adds the result to the context window, and repeats until the model says it is done. Horthy says this breaks down especially in longer workflows, where large context windows reduce the quality and reliability of results. An engineered agent has a prompt for selecting the next step, a switch that handles the model's JSON, explicit context construction, and a loop that controls when and why execution exits. Owning that flow allows the application to break, switch, summarize, or use a model as a judge.

### Execution state and business state should be managed together
[07:20](https://www.youtube.com/watch?v=8kMaTybvDUw&t=440s)
Agent systems have execution state such as the current step, next step, and retry count. They also have business state, including messages, data shown to users, and pending approvals. Horthy wants both managed through ordinary APIs that can launch, pause, and resume work. A long-running call can interrupt the workflow, serialize the context window into a database, and return a state ID. When the operation finishes, the application loads the state, appends the result, and sends it back to the model. The agent does not need to know that the work happened in the background.

### Prompt and context construction need direct ownership
[08:39](https://www.youtube.com/watch?v=8kMaTybvDUw&t=519s)
Horthy says prompt abstractions can produce a strong starting point, but teams that need to pass a quality threshold eventually write every token by hand. His reasoning is that the model maps input tokens to output tokens, so reliability depends on the input tokens the application supplies. Engineers should be able to test different prompt instructions and context layouts. Context includes prompts, memory, retrieval data, and history. They can use standard message formats or stringify their event and thread state in another structure. The goal is to improve the clarity and density of the information reaching the model.

### Errors should be compressed before returning to the model
[10:40](https://www.youtube.com/watch?v=8kMaTybvDUw&t=640s)
When a model calls an API incorrectly or an API is down, the application can put the call and error into the context and ask the model to try again. Horthy warns that blindly accumulating errors can make an agent spin, lose context, or get stuck. The application should remove pending errors after a valid tool call, summarize what went wrong, and avoid putting an entire stack trace into the context. This is an example of why context ownership matters. Error handling is part of deciding what the model needs to see, rather than an automatic replay of everything that happened.

### Small agents fit inside deterministic workflows
[12:34](https://www.youtube.com/watch?v=8kMaTybvDUw&t=754s)
Horthy recommends micro-agents with loops of roughly three to ten steps inside mostly deterministic directed workflows. At HumanLayer, a deployment bot uses deterministic CI/CD code until a merged pull request has passing development tests. A model then proposes the deployment order, a human can change that order, and the workflow executes the approved deployment. Once deployment finishes, deterministic code runs end-to-end tests against production. If those fail, a small rollback agent handles the bounded recovery task. This structure gives each agent a limited context and a clear responsibility.

### Stateless agents should reduce explicitly owned state
[14:25](https://www.youtube.com/watch?v=8kMaTybvDUw&t=865s)
Horthy describes agents as stateless reducers, then corrects the term to transducers because the process has multiple steps. The practical point is that the application should own state and manage it in whatever representation fits the product. The model handles the next transformation from the supplied context, while the surrounding software stores execution and business data. He connects this approach to his preference for scaffolding that gives developers code they can own, rather than a wrapper around hidden framework behavior.

## Notable quotes
- "Not every problem needs an agent." (01:30)
- "There's nothing special about tools. It's just JSON and code." (04:53)
- "Everything in making agents good is context engineering." (10:09)
- "Agents are just software, so let's build software." (08:07)
- "My tech agents are better with people." (15:27)

## Tools & references mentioned
- HumanLayer
- 12-factor agents GitHub repository
- Hacker News
- CrewAI
- LangChain
- smolagents
- LangGraph
- Griptape
- Airflow
- Prefect
- Gemini
- NotebookLM
- MCP
- Slack
- Discord
- SMS
- A2 protocol
- shadcn
- RubyConf
- "Goto Considered Harmful" paper

## Who should watch
- You have an agent that works at a demo quality level, but debugging its prompts, tools, or hidden framework behavior has become difficult.
- Your product needs long-running workflows, approvals, retries, or background operations that must pause and resume cleanly.
- You are deciding whether to use a large autonomous loop or place smaller model-driven steps inside a workflow you already control.

## Related talks

- [Building Enterprise LLM Agents That Work](https://aietalks.com/talks/building-enterprise-llm-agents-that-work) (Shaan Desai, Cohere, 18:29)
- [Architecting and Testing Controllable Agents](https://aietalks.com/talks/architecting-and-testing-controllable-agents) (Lance Martin, LangChain, 2:21:54)
- [The LLM Triangle: Engineering Principles for Robust AI Applications](https://aietalks.com/talks/the-llm-triangle-engineering-principles-for-robust-ai-applications) (Almog Baku, 26:19)
- [Ship Real Agents: Hands-On Evals for Agentic Applications](https://aietalks.com/talks/ship-real-agents-hands-on-evals-for-agentic-applications) (Laurie Voss, Arize AI, 2:04:18)
- [Effective agent design patterns in production](https://aietalks.com/talks/effective-agent-design-patterns-in-production) (Laurie Voss, LlamaIndex, 15:38)
