Skip to content

Agent Loops ​

A coding agent that runs once produces a draft. What makes the result trustworthy is the loop around the agent: what checks the work, what goes back to the agent when the check fails, and who decides the work is done.

In Dagu that loop is part of the workflow, not part of the prompt. harness.run runs the agent. A check that the agent cannot edit decides whether it runs again. A human.task brings in a person where the decision needs judgment. The run is durable throughout: it survives restarts, waits for people without holding a process, and records every attempt.

A coding agent runs its own tool loop inside a harness.run step. Around it, an inner loop sends the agent's changes to a check, such as tests, and sends failures back until the check passes. Around that, an outer loop sends work that passed to a person in a human.task step, who completes it or pushes it back with feedback. Completed work moves on.

Four Terms, Two Questions ​

The four terms answer two different questions about a loop.

Does the result go back to the agent?

  • Open loop. The agent runs and its result is used as it is. Nothing the result reveals reaches the agent again. A nightly digest, a draft that a person edits, and a triage report are open loops.
  • Closed loop. A check measures each result, and a failure goes back to the agent, with what the check found, for another attempt. The loop ends when the check passes or a limit is reached.

Repetition is not feedback. An agent that runs every night, or reruns after a crash, is still in an open loop if nothing looks at what it produced and tells it.

Where does the loop sit, and what closes it?

  • Inner loop. The fastest loop around one piece of work. The agent changes something, a command checks it, and failures go straight back. Each turn takes seconds to minutes, and no person is involved.
  • Outer loop. A loop that contains inner loops and crosses a boundary such as a person's review, a schedule, a pull request, or production. Each turn takes hours to days.

Inner and outer are relative: every loop is inner to the loop around it. The innermost loop runs inside the agent itself, as Claude Code or Codex calls tools until it decides to stop. Dagu does not see inside that loop. It starts the agent, and it owns every loop above it.

The two questions are independent, but useful workflows tend to land in the same place: a closed inner loop that a command closes, nested in a closed outer loop that a person closes.

LoopClosed byBuilt withTurn timeGuide
Agent loopThe agent's own judgmentThe agent CLI inside harness.runSecondsHarness
Open loopNothing reaches the agentharness.run, artifacts, an optional gateOne runOpen Loops
Inner loopA commandrepeat_policy on harness.run or dag.runMinutesInner Loops
Outer loopA personhuman.task with push_backHoursOuter Loops
Background loopA schedule or an eventschedule, webhooks, watch, parallelDaysBackground Loops

Gates and Loops ​

A check that can only stop bad work is a gate. A check that sends work back is a loop.

  • A step that runs the tests after the agent and fails the run is a gate. Put it inside a repeat_policy and it becomes a loop.
  • A human.task without with.push_back is a gate: the person completes it, or stops the run. With push_back, it closes a loop: the person's feedback reruns the agent.

Gates are still useful. An open loop with a gate is the right shape when a person reads the result anyway and fixing it by hand is cheaper than explaining the fix.

Who Decides the Work Is Done ​

In a bare agent loop, the agent decides. It stops when the work looks done to it. The Claude Code documentation puts the consequence plainly: without a check that comes back pass or fail, "that makes you the test suite."

A Dagu loop moves that decision out of the agent:

  • An inner loop ends when a command exits 0, not when the agent says it has finished.
  • An outer loop ends when a person completes the task, not when the agent stops asking.
  • Every loop has a limit, and running out of attempts is an outcome the workflow handles: the run fails, or a person takes over.

Choosing a Loop ​

text
Can a command decide whether the work is right?
├─ yes → inner loop, closed by that command
│        Must a person still judge the work before it ships?
│        ├─ yes → nest it in an outer loop: human.task with push_back
│        └─ no  → ship on pass; fail or escalate when attempts run out
└─ no  → Will a person judge the result?
         ├─ yes, and send it back with feedback → outer loop
         ├─ yes, but only accept it or stop    → open loop with a gate
         └─ no                                 → open loop; keep the result as an artifact

When the order of steps itself depends on what the agent finds, rather than a fixed check-and-retry shape, use an Agent DAG instead: a model chooses the next action until declared goals are met.

Design Rules ​

These rules follow from published results on self-correction, verifier-driven code generation, and the ways coding agents fail. Each guide shows the fields that apply them.

  1. End the loop on a command, not on the agent's claim. Models that review their own work without outside feedback do not reliably improve it, and often make it worse (Huang et al.). The same models improve when the feedback comes from running the code (Chen et al., Gou et al.).
  2. Keep the check out of the agent's reach. Under pressure, agents edit tests or special-case them, and Anthropic reports that this "typically emerges after multiple failed attempts" (Claude 3.7 Sonnet system card). Run the check as a step the agent does not write, and fail when test files change.
  3. Send back what failed, not "try again". Specific feedback outperforms generic feedback (Madaan et al.). Pass the failing output to the next attempt.
  4. Allow a few attempts, then escalate. Most of the gain arrives in the first two or three rounds (Gou et al., Li et al.), and agents "succeed quickly and fail slowly" (Yang et al.). A limit of 3 to 5 is a sound default; past it, hand the work to a person instead of raising the limit.
  5. Start each attempt fresh and keep state in files. Long sessions degrade. Each repeat of a harness.run step starts a new agent process, so the plan, progress notes, and check output belong in files the next attempt reads.
  6. Review with a different model. Model judges favour output from their own model (Zheng et al., Panickssery et al.). Give the reviewer a different provider, and give it the check results.
  7. Put people at the plan and the merge, not in every turn. A reviewed plan has more leverage than reviewed code, and passing tests does not make a change mergeable: maintainers would not merge about half of the benchmark pull requests that an automated grader passed (METR).
  8. Give the agent a way to ask for help. An explicit "needs a person" exit cut test cheating from 54% to 9% for one frontier model (Zhong et al.). Outer Loops shows the wiring.

In This Section ​

  • Open Loops: run an agent once, keep its result reviewable, and gate what ships.
  • Inner Loops: run an agent until a command passes, with the failure fed back each time.
  • Outer Loops: let a person send work back with feedback, review plans, and take over when the agent runs out of attempts.
  • Background Loops: run loops on a schedule or an event, fan them out over many items, and review the results later.

Further Reading ​

Dagu is open source under the GNU General Public License v3.0.