Put approval between choosing a tool and running it
A model can propose an action before your software decides whether to execute it. The control-flow chapter of 12-Factor Agents describes pausing between tool selection and invocation so a person can review the proposed call. For engineers connecting models to consequential tools, this gives an architecture review a concrete starting point: where can execution stop, and what state survives the pause?
The repository is a guide to engineering LLM applications. Its README advocates incorporating small, modular agent concepts into existing products. Read it when deciding how your application should control context and execution. The reviewed chapters leave application functions, storage and integrations for you to implement.
What happened when we ran it
Our sandbox installed the Python contributor project in 11 seconds, recording 35 dependencies and 38 MB on disk. Build succeeded with a recorded duration of 0 seconds. Tests were skipped because no script or target was found. The run targeted ./hack/contributors_markdown/ at commit d20c728 on 2026-11-08. It did not run an agent assembled from the guide.
The configured sandbox had 3 CPUs, 8 GB RAM and image label ghcr.io/astral-sh/uv:python3.12-bookworm. That label cannot establish the actual Python version or operating system. The checkout contained 499 files, approximately 12,816 source lines and 47.1 MB. Our scan detected no CI workflow files, Dockerfile or tests directory. Those scan results do not assess the reliability of an application built from the guide.
pip-audit reported 0 known vulnerabilities. The harness recorded 34 packages scanned, 35 reported and one skipped. This result covers the recorded audit, not the security of an application you later build. Neither the utility build nor skipped tests establish model quality, successful tool execution or correct approval handling.
Choose what the model sees
Factor 3 explains that applications can construct context rather than use only a standard message layout. Its examples combine an initiating message, tool requests and results into an event history.
Use that distinction when reviewing a poor next-step choice. Did the request include the relevant tool result? Did resolved errors remain visible? Should sensitive data have been excluded? These are design questions drawn from the chapter, not improvements measured in our run.
The chapter excludes training your own models and fine-tuning existing models. It also acknowledges uncertainty about the best context format. Its XML-style events are one representation to consider; the supplied evidence does not establish that they outperform standard messages. Compare representations against cases from your own application before choosing one.
The control-flow example needs implementation work
Factor 8 separates immediate tool results from work that pauses for a person. Its example appends events, requests approval, saves a thread and breaks the loop while awaiting a later response. The useful design question is whether your application can pause after tool selection and before invocation.
The introductory list describes fetching Git tags and deploying a backend, while the code branches fetch open issues and request approval for creating an issue. The snippet also uses await inside a function declared with def, mixes next_step with nextStep, and depends on undefined application functions and storage. It illustrates control flow but is not a complete Python program. Our sandbox run did not execute it.
Before implementing this pattern, name an operation that needs approval and specify where its proposed arguments will be stored. Then explain how a later response finds that operation and resumes the workflow. The chapter motivates that boundary; your implementation must preserve and enforce it.
Reading the guide does not require its contributor utility
The contributor utility manifest names a separate Python project and requires Python 3.13 or newer. Reading the chapters does not require a Python environment. The README also says its principles can be applied in Python or another language.
The utility's measured 38 MB footprint is no estimate of an agent application's dependencies. A model client, tool integrations and persistent state require separate implementation choices. The repository’s code uses Apache 2.0 licensing, while its content and images use CC BY-SA 4.0. Check which material you intend to reuse.
Choose a runtime separately
LangGraph describes itself as a low-level orchestration framework for building, managing, and deploying long-running, stateful agents. Its README lists durable execution and human oversight of agent state. Evaluate it when you need runtime infrastructure for a workflow that persists or pauses.
Pydantic AI describes itself as a Python AI SDK with a typed, extensible agent loop. Evaluate it when you need an executable Python library with typed agent interfaces. These are implementation options, not measured competitors to a guide. Neither alternative was run as part of this sandbox result.
Documentation earns 4/5 on this editorial rubric: 1 means core explanations are missing; 2 means substantial gaps prevent practical use; 3 means useful guidance with material gaps; 4 means detailed architectural examples with identifiable implementation defects; 5 requires examples independently checked across the reviewed paths. The context and control-flow chapters support the 4, while the mismatched operations, syntax and naming issues prevent a 5. This score assesses the reviewed documentation, not application reliability. Community responsiveness and application maturity remain unassessed.
Start with the chapter covering your next consequential tool call. Specify the state your application must preserve before that call runs, then verify the implementation separately.

