Skip to the content
Software Made Clear Diagrams that show the mechanism About

12-factor agents: actions, saved progress and retries

Learn the twelve agent-design principles through a pull request that times out: what the model proposes, what the program allows and how work resumes.

6 min read Updated September 24, 2026 Last verified September 22, 2026
ANSWER

The 12-factor agents guide explains how to build software around AI models. You keep control of the instructions, allowed actions and saved progress instead of asking a model to keep trying until it says it is done.

IN PLAIN TERMS

An agent asks to open a pull request, but the connection drops. Before trying again, the program checks whether the request already created one. It saves what it finds so another worker can continue the same task without opening a duplicate.

An agent tries to create a pull request. The API call times out. It now has a practical problem: creating another pull request could duplicate the first one, but reporting success would be a guess. The program needs a way to check what happened.

Asking for an action is not performing it#

When a model calls a tool, it first produces a request: an operation name and its arguments. Application code then decides whether to perform it. That code can check the repository, validate the arguments and confirm that this action is allowed. Well-formed JSON is not permission to run the request.

Dex Horthy’s 12-factor agents guide sets out principles for this kind of software. Rather than put the entire process inside an open-ended agent loop, it makes the developer’s choices about prompts, information and execution explicit. The name does not mean that a system needs twelve agents.

What to do when the response is lost#

In this illustrative workflow, task U-17 fixes an upload boundary. Its branch is ready for review, and creating a pull request is permitted. The application sends that request, but the connection times out before it receives the result.

A lost response leaves the result unknown—not undone.

The same work identity follows this proposed pull request through every step.

  1. Proposed

    Model requests a PR for task U-17, branch upload-fix.

    No external write yet.

  2. Authorised

    Application validates repository, branch and permitted action.

    Allowed to attempt; not yet completed.

  3. Attempted

    Create request is sent; the response times out.

    The service may already have created the PR.

  4. Reconcile

    Look up the work identity and verify the matching branch.

    Confirm the existing PR before considering another write.

  5. Recorded

    Store the confirmed PR reference with task U-17.

    Resume from the real result, not from the missing response.

No conclusive lookup result?Keep the outcome uncertain and follow the API's safe-retry policy. A single empty search is not proof that no write occurred.

Hypothetical execution trace. The workflow, not the model's closing message, records which external effect was confirmed.

The server may have created the pull request even though the client saw a timeout. Before retrying, the application looks for the corresponding pull request and checks its repository and branch. If it cannot establish the result, it records that uncertainty and stops for investigation. It does not turn “no response” into either “failed” or “succeeded”.

The same distinction matters for tests. Asking to run a test does not show that it ran. Save the command’s actual result and the code version it tested. When a command never starts because a dependency is unavailable, report that rather than inventing a test result.

The twelve principles in plain language#

This is a brief paraphrase of the twelve factors, in their original order. The linked guide explains the reasoning behind them.

  1. Turn requests in ordinary language into named, proposed actions.
  2. Keep the prompts under your control.
  3. Choose the information included in each model call.
  4. Keep a tool request separate from the code that executes it.
  5. Avoid separate, conflicting records of the task and its progress.
  6. Make starting, pausing and resuming work straightforward.
  7. Let the agent request a person’s input through a tool.
  8. Keep control over which step runs next.
  9. Give the model useful, compact error details.
  10. Give agents focused jobs.
  11. Allow work to start through the channels people use.
  12. Pass the saved task state into a worker rather than relying on its memory.

These principles are useful when they change what the program can do. For U-17, a replacement worker should be able to find the task and its branch. The program should distinguish an approved request from a confirmed result. Counting twelve headings in a design document would not demonstrate either behaviour.

Save the question and the approved answer#

Earlier in U-17, the agent might need to ask whether the upload limit counts the file alone or the complete request. Save that question with the task, the reason it blocks progress and who is allowed to answer. After a reply arrives, save the decision before continuing.

A message saying “approved” is not enough when two proposals are waiting. Record which proposal and action the person approved. Approval to create a pull request is not approval to merge it, and approval of an earlier version may not cover a materially changed version.

Check who sent the reply and which pending question it answers. A repeated or late message must not start the next step twice. The stop-and-ask guide shows how a task can wait without depending on one chat session staying open.

Let another worker continue the same task#

When a worker starts, give it the current task, the code version and the decisions already made. Include the actions already attempted and the next action it may take. It should not need to remember an earlier process in order to continue correctly.

This is what stateless worker means in this design: the information needed to continue is supplied as input. The workflow still stores state. Clearing a conversation does not erase the branch, undo file edits or stop a process that is still running.

Check the workspace before resuming. Keep full logs available without sending all of them to the model, and keep secrets out of model input. Passing saved work between agents explains what the next worker should receive.

Handle duplicate requests and interrupted writes#

A lost response is not a new problem created by language models. AWS’s guidance on safe retries explains the use of stable request identifiers and idempotent operations. An idempotent operation can be repeated without producing an additional effect of the kind the API promises to prevent.

Use the guarantees of the actual API. A search that returns no result may be delayed or incomplete. A made-up request identifier does not prevent duplicate writes unless the receiving system or your own coordination code uses it for that purpose.

Consider two workers trying to claim the same task. The claim must be recorded as one indivisible operation, or both can believe they own it. Likewise, review must identify the code it inspected, because the branch may change before acceptance. A program that writes to an external service and then crashes needs to check that service before repeating the write.

These are implementation requirements. Adding another model called “supervisor” does not make them hold.

Use the principle that addresses your failure#

If a task loses a person’s approval after a restart, improve the saved decision record. If the model misses the relevant error among thousands of log lines, improve the information it receives. If a write happens before approval, fix the code that permits that action.

Your existing tools may already provide the missing feature. Orchestrator or pipeline helps decide when a separate workflow system is useful. For the agent’s immediate workspace and tools, continue with the harness guide.

IF YOU REMEMBER ONE THING

Record what was requested, what was allowed and what actually happened. After an interruption, the next worker needs those records—not a confident guess from the previous conversation.

Questions people also ask

3 QUESTIONS
Must I implement all twelve factors before using an agent?

No. They are design advice, not a certification. A helper that only reads documents does not need the same approval and retry rules as a worker that changes an external system. Start with the problems your workflow actually has.

Does owning control flow mean avoiding frameworks?

No. It means you can determine which actions run, pause before actions that need approval, and resume after an interruption. A framework can provide those features. You do not need to rebuild them just to avoid using a framework.

Does structured output make an operation safe?

No. It makes the model's request easier for a program to read. A correctly formatted request can still target the wrong repository or ask for an action the user did not approve. The program must check those things before running it.

The library Browse all articles