Why your agent loops — and the structural fixes.
Most agent loops are a symptom of bad memory contracts, not bad prompts. A short taxonomy and the four interventions that actually help.
Every team I’ve consulted with on agentic systems has a “the agent gets stuck in a loop” complaint. And every time, the first instinct is to rewrite the prompt.
It almost never helps. Loops are a structural failure, not a prompting one. They happen when the agent’s memory of what it has already tried is incomplete, ambiguous, or invisible to the next step.
The four loop types I see most
- The amnesia loop. The agent re-tries the same tool call with the same arguments because the previous result wasn’t carried into the next step’s context.
- The disagreement loop. Two agents (or two roles in one agent) cycle between conflicting recommendations, neither acknowledging the other’s prior turn.
- The optimism loop. The agent keeps trying a strategy that’s failing because the failure signal is too soft (“hmm, that didn’t quite work”).
- The ungrounded loop. The agent generates plausible next steps from its prior, ignoring tool outputs entirely.
Different roots, different fixes. None of them are “be more clever in the system prompt.”
Fix one — explicit memory contracts
Stop writing free-form summaries between agent steps. Write a typed object.
type StepMemory = {
step: number;
action: { tool: string; args: unknown };
outcome: 'success' | 'partial' | 'failure';
artifacts: string[]; // paths/IDs the next step can read
blocked_by?: string; // what would unblock progress
};
Now the next step has something to reason about that isn’t a paragraph of vibes.
Fix two — load failure into the context
When a step fails, the failure has to be louder in the next step’s context than the success would have been. Tag it. Put it in a ## Failed attempts section the agent can’t ignore.
Fix three — bound the search
Most “loops” are loops because there’s no termination condition. Cap turns, cap retries per tool, and write the cap into the prompt: “You have 3 attempts remaining for this subgoal.”
Fix four — disagreement requires arbitration
If you have a planner and a critic, the critic doesn’t just say “try again.” The critic produces a constraint the planner has to satisfy. Loops collapse the moment one agent can produce binding output for the other.
What this looks like in practice
The Voyager system I wrote about elsewhere had a loop problem in week two. Four agents, all looping. The fix wasn’t prompt engineering — it was three things, in this order:
- Make the planner emit a typed plan object the others must conform to.
- Make tool failures appear as first-class items in subsequent contexts.
- Cap retries and make the agent declare a stopping condition before starting.
After those three, the loop rate fell to under 1% of runs. We never touched the system prompts.