designing-loops
Designing loops
A loop is an agent repeating cycles of work until a stop condition is met. Every loop is a choice along two axes: what triggers the next cycle, and what stops it. Get both right and the loop runs unattended; get either wrong and it either stalls waiting on you or burns turns past the point of being useful.
Not all tasks need a loop. Start with a single turn — write the prompt, look at the result, write the next prompt — and reach for the shapes below only once that manual cycle itself becomes the bottleneck.
The four shapes
| Shape | Triggered by | Stops when | Fits |
|---|---|---|---|
| Turn-based | You, each prompt | The agent judges the task done, or needs more from you | Short, one-off tasks outside any regular process |
| Goal-based | You, once, in real time | The goal is met, or a turn cap is hit | Tasks with a verifiable exit condition |
| Time-based | A schedule (local interval or cloud cron) | You cancel it, or the underlying work runs out (queue empties, PR merges) | Recurring work, or watching an external system that changes on its own clock |
| Proactive | An event or schedule, no human watching | Each cycle's goal is met; the loop itself runs until switched off | A recurring stream of well-defined work — triage, migrations, upgrades |
Turn-based is the default — it's just talking to the agent. The other three trade a bit of setup for running unattended; pick the cheapest shape that still gets you a real stop condition.
Goal-based turns "keep going until this is good enough" into a bounded loop: define what done looks like, and an evaluator checks that condition each time the agent tries to stop, sending it back to work until the goal is met or the turn cap is reached. The turn cap is what keeps a fuzzy goal from running forever — always set one.