How Autonomous Coding Agents Work: The Agent Loop and the Philosophy of Subtraction

    Autonomous coding agents are often assumed to depend on elaborate orchestration systems, but in practice many of the strongest systems are built around a simple loop and increasingly capable models. This article explains how the agent main loop works, what tool-call requests and results look like, and why the “subtraction philosophy” can work better than heavy engineering. It also covers the conditions under which this approach succeeds, common failure modes, security boundaries, and practical guidance for building reliable coding agents.

    1. Why Did Coding Agents Suddenly Become Much Stronger?

    Over the past year, coding agents have repeatedly refreshed developers’ expectations. A question has therefore come up again and again: how do autonomous coding agents actually work? Is there a highly complex orchestration system behind them?

    The answer is usually the opposite. When you look closely at today’s mainstream coding agents, what drives them is often a very simple loop plus a continuously improving model.

    This article explains three things:

    1. How the agent main loop, also called the agent loop, actually works.
    2. What a tool-call request and its result look like.
    3. Under what conditions the “subtraction philosophy” holds, and when it starts to fail.

    2. From Copy-Paste to an Autonomous Loop: Four Stages of Coding Agents

    Stage 1: Conversational Copy-Paste

    In the early conversational AI workflow, developers described requirements in a chat interface, copied the generated code, pasted it into an editor, and returned to the chat when errors appeared. The “copy, paste, error, copy again” cycle was the biggest efficiency bottleneck at the time.

    Stage 2: In-Editor Command-Style Generation

    The next stage arrived in the form of editor plugins. Developers could generate code at the cursor with a keyboard shortcut, significantly reducing friction. However, it was still fundamentally single-shot generation and did not carry ongoing context understanding.

    Stage 3: Interactive Conversational Agents

    This stage introduced multi-turn conversation mechanisms that allowed back-and-forth communication. Agents began to have some degree of context awareness and could collaborate around a goal across multiple turns.

    Stage 4: The Autonomous Coding Era

    In this stage, an agent can complete a loop on its own: explore, code, test, and fix. Headless workflows became possible.

    It is important to clarify the boundary: what is being automated at this stage is line-by-line manual coding, not human judgment. Code review, change merging, and approval of high-risk operations still need to be handled by people.

    3. Why Now? The Inflection Point Comes from Crossing Capability Thresholds

    Autonomous coding agents are not a new concept. Several years ago, people had already tried similar systems, but the results were generally poor: agents got lost in long tasks, or became trapped in infinite loops because the orchestration was too rigid.

    What changed is that model capabilities crossed several important thresholds:

    • Long-range reasoning: the model can maintain a “reason-act-observe” loop across dozens of steps without drifting.
    • Instruction following: the model can reliably produce structured tool calls in the expected output format.
    • Repository-level understanding: the model can locate the real root cause across a large set of files instead of only patching the line that threw an error.
    • Tool calling: the model has become significantly more accurate at selecting and combining multiple tools across multiple turns.
    • Context window: the model can hold the intermediate state required for a medium-sized refactoring task.

    There are two verifiable reference points. One is SWE-bench Verified, released by OpenAI in August 2024, which contains 500 human-verified real-world GitHub issues and made autonomous bug fixing measurable for the first time. The other is Anthropic’s engineering blog post “Building Effective Agents”, published in December 2024, which explicitly states that most successful production implementations rely on simple, composable patterns and warns against starting with overly complex frameworks.

    In other words, earlier systems relied on hand-written orchestration to compensate for model weaknesses. Now those weaknesses are no longer fatal, so a simple loop can finally work.

    4. How Does the Agent Main Loop Actually Work?

    The control flow can be described in one sentence:

    On every turn, let the model reason first. If the output contains tool calls, execute them, write the results back into the context, and continue to the next turn. If there are no tool calls, treat the task as finished, produce the final answer, and stop.

    1. MAX_STEPS = 30 # Step limit to catch infinite loops
    2. MAX_TOKENS = 2_000_000 # Total budget limit
    3. context = [system_prompt, user_task]
    4. for step in range(MAX_STEPS):
    5. response = model(context) # 1. Reason first on every step; do not preset the workflow
    6. context.append(response)
    7. if response.has_tool_calls(): # 2. If there are calls: execute them and append results
    8. for call in response.tool_calls:
    9. if call.requires_approval: # 3. Suspend dangerous operations and wait for human approval
    10. wait_for_human(call)
    11. result, err = execute_with_retry(call) # Limited retries with backoff
    12. context.append(err or result) # 4. Return errors as-is so the model can fix them
    13. maybe_compress(context) # 5. Compress early reasoning when limits are exceeded; keep the task list
    14. continue
    15. return response.text # 6. No calls: return the final answer and exit
    16. # Fallback exit: when steps or budget are exhausted, leave a checkpoint and progress report for human decision-making
    17. return checkpoint_report()

    There are three easily overlooked but essential elements:

    • Tool exceptions should be returned to the model as structured errors, not thrown to the outer process.
    • When the context exceeds its limit, compress history while preserving the task list and recent observations.
    • Human approval nodes should be able to suspend and resume within the loop.

    Simple does not mean uncontrolled. A flat loop removes unnecessary branching logic, not robustness. Retry logic, timeouts, budgets, rollback points, and approvals are still required.

    What Does a Tool Call Look Like?

    Here is an example of a model-initiated request using the read-only read_file tool:

    1. { "tool": "read_file",
    2. "arguments": { "path": "src/parser.py", "start_line": 120, "end_line": 180 } }

    On success, the execution result is written back into the context:

    1. { "tool_call_id": "call_8f2", "status": "ok",
    2. "output": "def parse(src):\n if not src:\n raise ValueError('empty input')" }

    On failure, the error is also written back so the model can correct the parameters or try another path:

    1. { "tool_call_id": "call_8f2", "status": "error", "exit_code": 1,
    2. "output": "ModuleNotFoundError: No module named 'yaml'" }

    This detail—returning errors instead of hiding them—is key to why a flat loop can self-correct. The model’s ability to fix mistakes can only be exercised if the error information is actually fed back to it.

    Above this skeleton, there is no DAG orchestration, no thousand-line classification prompt set, and no meticulously designed state machine. The engineering principle behind this approach comes from The Zen of Python (PEP 20): simple is better than complex, complex is better than complicated, and flat is better than nested.

    5. When the Model Gets Better, Why Does Adding Layers Make Things Worse?

    A common failure mode looks like this: early on, to make the agent “more reliable,” a team wraps a fixed state machine around the loop. The agent must always produce a plan first, must wait for human confirmation for every file change, and must retry the same code location along a predefined branch after a test failure.

    In the era of weaker models, this kind of constraint did help fill gaps. But once a model is capable enough to reason that “this failure is a missing dependency rather than a logic error,” hard-coded branches can conflict with its correct judgment. The result is often repeated retries at the same failure point, or dozens of steps spent going in circles.

    This is a pattern repeatedly observed across agent products, not a conclusion drawn from a single benchmark. The engineering judgment is:

    Do not over-engineer to compensate for model limitations.

    When the underlying model keeps improving, cumbersome orchestration becomes a double burden: it increases maintenance cost and also narrows the space in which the model can operate.

    That judgment is conditional. It holds when three prerequisites are met:

    • Tool feedback is reliable.
    • Context is controlled.
    • Permission boundaries are clear.

    If any one of these is missing, simplifying too aggressively leaves the system running without protection.

    6. Complex Orchestration or Simple Loop? How to Choose

    Subtraction does not mean “write nothing.” It means deciding what to subtract and how to subtract it.

    • Remove unnecessary orchestration layers. Start with the minimal loop. Only add a constraint for a specific decision point when observability data shows that the model consistently gets that decision wrong, and document why the constraint was added.
    • Remove hard-coded branching logic. Put policy into tool descriptions and system prompts—for example, “If parameters are missing, first use read_file to gather the needed information”—instead of encoding it as if-else branches.
    • Remove reliance on prompt tricks. Instead of piling on patch-like prompts, describe the problem clearly and make tools atomic so the model can compose them correctly on its own.

    7. Common Pitfalls When Building Your Own Coding Agent

    Symptom Root Cause Prevention / Handling
    Wrong tool selection or invalid parameters Vague tool descriptions, overlapping responsibilities Improve tool descriptions and parameter schemas; one tool, one responsibility; define required fields and enumerations clearly
    Infinite loop or budget exhaustion No termination conditions Set a step limit, per-step timeout, and total budget; when exhausted, save a checkpoint and hand control back to a human
    Long tasks lose direction Context is filled with intermediate reasoning Compress context by summarizing early reasoning and preserving the task list; also maintain an explicit task list file
    Tests keep failing Only conclusions are available, with no reproducible information Return full error messages and failing commands; preserve rollback checkpoints
    Permission overreach The loop can directly touch production systems Sandbox execution, approval for dangerous operations, and hard blocking of irreversible operations

    8. Engineering Practice: Putting the Subtraction Philosophy into Implementation

    1. Implement the minimal viable agent loop first. Get “tool call → result feedback → continue reasoning” working before considering complex orchestration.
    2. Design clear, atomic tools. Accurate descriptions and minimal parameters help the model choose and combine tools correctly.
    3. Build complete observability. Record every tool call and reasoning trace so you can diagnose hangs, misuse, and anomalies.
    4. Design context management and termination conditions for long tasks. Preserve key human confirmation points.
    5. Keep the model replaceable. Avoid tightly coupling the architecture to one specific model, so model upgrades can directly translate into capability improvements.

    Security requirements must be written into the design from the beginning, not added afterward:

    • Prohibit irreversible operations such as rm -rf, git push --force, database deletion, and database writes without human confirmation.
    • Isolate execution environments with least-privilege sandboxes. Mount only necessary directories and open only necessary network access.
    • Inject credentials into tools through the environment, never into the model context. What the model cannot see cannot leak through it.
    • Keep audit records for high-risk operations: who approved which command, and when.

    The same minimal-necessary principle applies to deployment: containerized isolation, queue-based decoupling of asynchronous tasks, and archiving artifacts to object storage are all ways to release autonomy while keeping the system controllable and auditable.

    9. The Boundaries of the Subtraction Philosophy, and Its Real Value

    It is necessary to acknowledge the scope of this philosophy. For extremely long tasks, large-scale cross-repository refactors, or scenarios requiring parallel exploration of multiple approaches, a single flat loop will not hold up. In those cases, you need context compression and checkpoint rollback to fight drift, sub-agents to isolate exploration costs, and stronger permission governance to constrain parallel writes.

    It is also worth being honest: decision chains maintained through internal model reasoning are usually less explainable than explicit state machines. In scenarios with high audit requirements, the process needs to be recorded through external logs rather than relying on the architecture to prove itself.

    The rise of coding agents may look like a tool competition, but at its core it is a return to an engineering philosophy: when the model is strong enough, the best architecture is often the one most willing to subtract.

    Understanding the simplicity of the agent loop, understanding the restraint of “give the model tools, then step back,” and remembering the three prerequisites of that restraint—reliable tool feedback, controlled context, and clear permission boundaries—is what truly captures the technical core of this generation of intelligent programming tools.