The Importance of Being Idempotent

ecto1 pts0 comments

The Importance of Being Idempotent - Cam Pedersen

"The truth is rarely pure and never simple."<br>Algernon, The Importance of Being Earnest

I've been building agentic apps for friends lately. I keep running into the same problems, and there isn't shared vocabulary for them yet, so here's what I've been thinking about.

A while-loop that calls a model, reads the output, runs a tool, and loops is an agent. It works in a demo and breaks in production, and it breaks in the same handful of ways regardless of the model or the stack. Six of them, below. About half have names in the literature; for the rest I'll propose some.

(Naming something you only half-discovered invites an argument. The alternative is everyone hitting it separately forever, so: names.)

1. The agent forgets what you asked

Give an agent a bug to fix. It opens the relevant file, notices the logger is ugly, refactors the logger, notices the tests are slow, and some number of tool calls later it is reorganizing imports in a file unrelated to the original task. Asked for status, it reports progress, because by its current frame it is making progress. The original task is untouched.

This has a name: goal drift. A technical report defines it operationally: measurable deviation from the original objective under context length and competing sub-goals (arXiv:2505.02709). Later work reframes it as machine akrasia (arXiv:2512.05449). The model is not confused. The original instruction is one message competing against a growing pile of more recent, more specific tokens, and recency wins.

Give it a long enough transcript and a plausible local sub-goal and it will quietly redefine "done" to mean "the thing I am currently doing." The drift is gradual and each individual step looks reasonable, which is why it is hard to catch by reading the trace. It is Bunburying: the agent invents a more agreeable task as a pretext to avoid the one it was given.

Watch it happen:

Spinning up the agent...

The perturbations are real inputs: an offhand aside several turns back, a large file that dominates the context by sheer token mass, the model adopting a wrong direction because agreement reads as cooperative. The meter is the distance between the stated objective and current behavior. The gold lines are the objective being re-pinned, which is the next section.

2. Intent-pinning

The mitigation is the recurring correction in that demo (the gold lines), and as far as I can find it has no agreed name. So: intent-pinning.

Re-inject the original objective on a schedule, as a fresh recent message rather than relying on the system prompt. The system prompt already holds the goal and is already losing the recency fight; re-injection puts the objective back where recency now works in its favor. The nearest prior work is ReCAP's "structured re-injection" of plan context across hierarchy levels (arXiv:2510.23822), framed there as a prompting technique.

Treating it as a control loop is what justifies a separate name. Setpoint: the pinned objective. Error: measured drift, computable as semantic distance between current trajectory and the objective. Actuator: re-inject; if re-injection stops reducing error, replan; if replanning stops working, halt and escalate to a human. Each gold line in the demo is the actuator firing. The open question is gain: re-inject too rarely and drift has already happened, too often and the context window is spent restating the objective to a model that already has it. There is a usable setting in between, and most systems never find it because the error signal was never instrumented.

Mitigations, weak to strong:

Intent-pinning: re-inject the objective on a schedule. The cheap end. Static text gets pattern-matched, and longer context can reduce drift while making that pattern-matching worse (arXiv:2505.02709).

Recitation: have the agent restate the objective at the tail of its own context each turn.

Agent-rewritten plan file: a todo.md the agent keeps editing, so reciting the plan is the work (Manus, Claude Code).

Decomposition into fresh-context subtasks: each subgoal runs in a clean window (ReCAP, arXiv:2510.23822; Context-Folding, arXiv:2510.11967).

Orchestrator with workers: the lead holds the goal, workers return only results (Anthropic's multi-agent setup; though Cognition reports this coordination breaks down on write-heavy tasks).

Closed control loop: measure drift and replan or escalate when re-injection stops bringing it down (Reflexion, arXiv:2303.11366).

3. Context rot

Past some context length, output quality degrades: the agent cites files that don't exist and treats its own earlier guesses as established fact. The decline is not abrupt and tends to be worst for information in the middle of a long context.

This is named and measured. Lost in the middle is the canonical result (arXiv:2307.03172). The broader degradation under accumulated context has been measured and called "context rot" (Chroma Research). Anthropic's...

context agent objective arxiv drift model

Related Articles