Most teams start using AI coding agents the same way they started using chatbots: they ask for one thing, inspect the answer, ask for a fix, inspect again, and keep going until the result looks usable. That works for a small task. It breaks down the moment the work becomes recursive.
A real engineering task is not a single prompt. It is a loop.
You describe a goal. The agent reads the codebase. It forms a plan. It edits files. It runs checks. It sees failures. It revises the plan. It asks for more context, or it keeps going. At the end, it either hands you a working change or a confident mess with passing tests that prove the wrong thing.
Loop engineering is the discipline of designing that cycle deliberately.
Prompt engineering asks, “What should I say to the model?” Loop engineering asks a more useful question: “What system of context, tools, checks, memory, budgets, and stop conditions will repeatedly push this agent toward correct work?”
That distinction matters because the quality of an AI agent is no longer determined only by the model. The model is one part of the machine. The loop around it decides whether the model is a useful teammate, an expensive autocomplete engine, or a runaway process burning tokens while mutating your repository.
What Loop Engineering Means
A loop is a repeatable cycle that moves an agent from an initial goal to a verified outcome.
In software engineering, a practical agent loop usually has seven parts:
- Trigger: what starts the loop.
- Goal: what the loop is trying to accomplish.
- Context: what the agent is allowed or required to inspect.
- Tools: what actions the agent can take.
- Verification: how the loop decides whether progress is real.
- Memory: what the loop carries forward between iterations.
- Stop rule: when the loop must stop, escalate, or declare failure.
The mistake is treating the model call as the product. The product is the loop.
Consider a bug-fix task. A weak loop looks like this:
User: Fix the failing checkout flow.
Agent: Makes a guess, edits code, says it is fixed.
Human: Manually checks. A stronger loop looks like this:
Trigger: A failing checkout E2E test or production error report.
Goal: Restore checkout completion without changing payment-provider semantics.
Context: The failing trace, relevant routes, payment adapter, recent commits, and runbook.
Tools: Read files, edit code, run targeted tests, inspect logs.
Verification: Reproduce failure, apply fix, pass targeted test, pass payment-adapter unit tests.
Memory: Record root cause and commands that proved the fix.
Stop rule: Stop after three failed hypotheses or any schema/payment-contract ambiguity. That is loop engineering. It is not about writing a prettier prompt. It is about shaping the environment in which the agent acts.
Why This Is Becoming a Core Engineering Skill
The early AI coding workflow was prompt-response. Ask for a component. Ask for a test. Ask for a refactor. The human stayed in the center and manually stitched each step together.
The newer workflow is agentic. Tools like Codex, Claude Code, Cursor agents, OpenCode, Aider, and custom internal systems can search, edit, test, summarize, and iterate. They can stay in the task longer. They can coordinate multiple files. Some can call browsers, databases, issue trackers, deployment APIs, and observability systems.
That power changes the failure mode.
When a chatbot misunderstands you, you get a bad answer. When an agent loop misunderstands you, it can produce a bad diff, add weak tests, update docs to match the bad behavior, and then tell you everything is green.
The industry is starting to formalize this. The LoopSpec paper frames loops as programmable objects with explicit state, actions, observations, and termination conditions. Another recent paper on infinite agentic loops studies what happens when autonomous agents keep generating actions without effective termination. You do not need to adopt either paper’s full framework to learn the practical lesson: loops need design.
The team that can design reliable loops will get more value from the same models than the team that only writes better prompts.
Prompt Engineering, Harness Engineering, and Loop Engineering
These terms overlap, but they are not the same job.
Prompt engineering is about instructions. You decide the role, tone, constraints, examples, output format, and refusal behavior.
Harness engineering is about the runtime. You wire the model to tools, schemas, retrieval, logs, permissions, storage, and user interfaces.
Loop engineering is about behavior over time. You define how the agent observes the world, chooses the next step, verifies progress, handles failure, remembers lessons, spends budget, and stops.
A prompt can say:
You are a senior engineer. Fix the bug and run tests. A harness can give the model a terminal, file editor, and test runner.
A loop decides:
- The agent must reproduce the bug before editing.
- The agent must state a hypothesis before each edit.
- The agent may run only targeted tests until a plausible fix exists.
- The agent must widen to broader checks before finalizing.
- The agent must stop and ask for human input if the failure moves across system boundaries.
- The final answer must include the root cause, changed files, and validation evidence.
That behavior is the difference between “AI helped me code” and “AI reliably executed part of my engineering process.”
The Anatomy of a Good Agent Loop
A good loop is not complicated. It is explicit.
1. A Sharp Trigger
Weak triggers create vague loops. “Improve the app” is not a trigger. “The /checkout E2E test fails after the provider redirect” is a trigger.
Good triggers include:
- A failing test name and error output.
- A specific production exception.
- A ticket with acceptance criteria.
- A dependency upgrade warning.
- A review finding with file and line references.
- A release checklist item.
The trigger should tell the agent where to begin. If the agent spends the first half of the loop guessing what problem it is solving, the loop is already leaking quality.
2. A Goal With Boundaries
Goals need both positive and negative space.
Bad:
Make onboarding better. Better:
Reduce onboarding drop-off by adding a guided first-project creation flow. Do not change billing, authentication, or workspace invitation behavior. The second version gives the agent a direction and a fence. The fence matters. Agents are eager refactorers. Without boundaries, they will often “improve” adjacent systems because those systems are visible in context.
3. Context Selection
Context is a budget and a risk.
Too little context makes the agent hallucinate architecture. Too much context makes it lose the task, overweight irrelevant files, or copy patterns from the wrong subsystem.
For coding loops, define context in layers:
- Required context: files, logs, docs, schemas, or traces the agent must inspect.
- Likely context: neighboring modules and tests.
- Forbidden context: secrets, unrelated generated files, vendor directories, or historical docs known to be stale.
- Escalation context: broader areas the agent may inspect only after a failed hypothesis.
This is where many teams underinvest. They write long prompts but give the agent no clear context policy. The result is an agent that reads too much, reads too little, or reads whatever file has the most familiar name.
4. Tool Policy
Tools are where an agent becomes operationally dangerous.
Reading files is low risk. Editing files is medium risk. Running tests is usually safe. Running migrations, deleting resources, deploying, sending emails, charging cards, or calling production APIs is high risk.
A loop should state which tools are allowed, when they are allowed, and what requires approval.
For example:
tools:
read:
allowed: always
edit:
allowed: after plan
tests:
allowed: targeted first, broad before final
network:
allowed: docs and package metadata only
deploy:
allowed: never in this loop
destructive_commands:
allowed: never without human approval This is not bureaucracy. It is how you let agents move fast inside a safe operating envelope.
5. Verification Ladder
Every loop needs a ladder of evidence. The agent should not jump from “I changed code” to “done.”
A practical verification ladder looks like this:
- Local reasoning: the change matches the stated hypothesis.
- Focused check: the failing test, type check, lint rule, or reproduction now passes.
- Neighbor check: nearby tests or related integration checks still pass.
- System check: broader build, end-to-end test, or smoke test.
- External signal: logs, metrics, user report, staging validation, or production canary.
Not every loop needs all five levels. A typo fix may need only a build. A payment bug needs the ladder.
The key is that verification should be designed before the agent edits code. If verification is invented after the diff exists, it tends to become a story that justifies the diff.
6. Memory That Helps, Not Memory That Pollutes
Agent memory is useful when it preserves hard-won facts:
- “This repo uses Supabase SSR cookies, not localStorage auth.”
- “The media worker has separate CORS rules from the API worker.”
- “This test fails in CI if the route path is not quoted in zsh.”
- “Provider webhooks are portal-managed; backoffice should show status, not create webhooks.”
Memory is harmful when it preserves stale guesses, personal preferences, or decisions that were true for one task but not the next.
Good loop memory should be:
- Short.
- Evidence-backed.
- Scoped to a repo, subsystem, or workflow.
- Easy to override when current code disagrees.
Treat memory as a cache, not a source of truth.
7. Stop Rules
This is the most ignored part of loop design.
An agent should not be allowed to iterate forever just because it can keep producing plausible next steps. Stop rules protect money, time, code quality, and trust.
Useful stop rules include:
- Stop after three failed hypotheses.
- Stop when the same test fails for two different reasons.
- Stop when the task crosses into an unapproved subsystem.
- Stop before any destructive command.
- Stop when the agent cannot reproduce the bug.
- Stop when required secrets, credentials, or product decisions are missing.
- Stop when the estimated cost exceeds the task budget.
The stop rule is not a sign of weakness. It is a control surface. A loop that cannot stop is not autonomous; it is unmanaged.
Five Practical Loop Patterns
Here are patterns worth turning into reusable workflows.
The Bug-Fix Loop
Purpose: move from a failure report to a verified fix.
Use this when you have an error message, failing test, broken route, regression, or production symptom.
Loop:
- Read the failing output and the nearest relevant code.
- Reproduce or explain why reproduction is impossible.
- State a hypothesis.
- Make the smallest change that tests the hypothesis.
- Run the focused check.
- If it fails, update the hypothesis.
- Before finalizing, run a neighboring check.
Stop when the agent cannot reproduce, cannot form a new hypothesis, or discovers the issue belongs to an external dependency or product decision.
The Code Review Loop
Purpose: find risks before merging.
Use this when reviewing a diff, PR, migration, or release branch.
Loop:
- Inspect the diff before the full files.
- Identify behavioral changes, not style changes first.
- Trace affected data flows.
- Look for missing tests around changed behavior.
- Rank findings by severity.
- Suggest focused fixes.
The review loop should not rewrite the code by default. Its output is judgment: bugs, regressions, security risks, test gaps, and questions.
The Refactor Loop
Purpose: improve structure without changing behavior.
Refactoring is where agents are both useful and risky. They can move fast, but they can also erase important constraints because the old code “looked messy.”
Loop:
- Define the invariant: what behavior must remain identical.
- Identify the smallest boundary to change.
- Add or confirm characterization tests.
- Move code in small steps.
- Run tests after each meaningful step.
- Stop if the refactor requires product or schema decisions.
A refactor loop without characterization tests is just a rewrite loop wearing nicer clothes.
The Research Loop
Purpose: answer a technical question with evidence.
Use this before adopting a library, changing architecture, choosing a model, or relying on a new API.
Loop:
- State the decision to be made.
- Search primary sources first: official docs, specs, papers, changelogs.
- Extract constraints that affect the codebase.
- Compare options against those constraints.
- Record the decision, assumptions, and freshness date.
The research loop should separate facts from inference. “The docs say X” and “therefore we should do Y” are different kinds of claims.
The Release-Readiness Loop
Purpose: decide whether a change is ready for users.
Loop:
- Read the release checklist or acceptance criteria.
- Identify user-facing paths touched by the change.
- Run checks at the right level: unit, integration, browser, smoke, or staging.
- Inspect logs or monitoring where available.
- List blockers, risks, and residual unknowns.
- Stop before deployment unless deployment is explicitly in scope.
This loop is less about writing code and more about refusing to confuse green local checks with production readiness.
A Reusable Loop Template
Here is a compact template you can adapt for any agent workflow:
name: bug-fix-loop
trigger:
type: failing-test | production-error | user-report | review-finding
required_input:
- exact error or failing behavior
- affected route/module/test when known
goal:
outcome: restore the expected behavior
non_goals:
- unrelated refactors
- dependency upgrades
- product behavior changes
context:
must_read:
- failing output
- nearest implementation file
- nearest test or spec
may_read:
- neighboring modules
- recent commits
- runbooks
avoid:
- generated files
- secrets
- unrelated vendor code
tools:
read_files: allowed
edit_files: allowed after hypothesis
run_tests: targeted first, broader before final
network: docs only
destructive_actions: require approval
iteration:
before_edit:
- state current hypothesis
- state expected verification
after_edit:
- run focused check
- compare result to hypothesis
- keep, revise, or revert the hypothesis
verification:
required:
- focused failing case passes
- related test or type check passes
final_report:
- root cause
- changed files
- commands run
- remaining risk
stop_rules:
- stop after three failed hypotheses
- stop if reproduction is impossible
- stop if fix requires product decision
- stop before destructive command The point is not to make every loop a YAML document. The point is to make the hidden operating procedure explicit enough that an agent can follow it and a human can audit it.
How to Start Without Overbuilding
You do not need a platform to practice loop engineering. Start with three small moves.
First, write an AGENTS.md file for your repository. Include how to run checks, which package manager to use, what patterns matter, what commands are dangerous, and what the agent should inspect before editing. This is the repo-level loop boundary.
Second, create two or three task-specific loops. A bug-fix loop, a review loop, and a release-readiness loop are enough for most teams. Keep them short. The goal is behavior, not documentation theater.
Third, measure the loop. Track how often the agent:
- Solves the task in one pass.
- Needs human correction.
- Runs the right checks.
- Touches unrelated files.
- Stops at the right time.
- Produces a final report that a reviewer can trust.
If you measure those outcomes, you will improve the loop faster than you improve the prompt.
The Hard Part Is Judgment
Loop engineering does not remove human judgment. It moves judgment earlier.
Instead of judging every token the model produces, you judge the loop:
- Did we give it the right trigger?
- Did we constrain the goal?
- Did we provide the right context?
- Did we allow the right tools?
- Did we define evidence before editing?
- Did we teach it when to stop?
That is a better use of senior engineering time.
The future of AI-assisted development will not belong to the teams with the longest prompts. It will belong to the teams with the best loops: tight enough to be safe, flexible enough to solve real problems, observable enough to debug, and honest enough to stop when the machine no longer knows what it is doing.
Prompting is how you talk to the model. Loop engineering is how you build a working relationship with it.