PromptABCD
FeaturesLearnHow it worksUse casesFAQGuideBlogContext Blocks
Sign inGet started free
Sign inSign up
PromptABCD

A calm home for your best AI prompts. Save them once, find them in seconds, reuse them forever.

Product

  • Features
  • Chrome Extension
  • Free Courses
  • How it works
  • Use cases
  • Blog
  • Context Blocks
  • Export Anywhere
  • FAQ

Resources

  • User guide
  • Learn prompting
  • Sign in
  • Get started free

© 2026 PromptABCD. All rights reserved.

Privacy PolicyTerms and Conditions
Home/Blog/Agent Loop Engineering/Managing the Context Window Across Loop Iterations
Agent Loop Engineering

Managing the Context Window Across Loop Iterations

Why does your agent get slower and dumber the longer it runs? The agent loop context window is filling with junk. Here's a bloated loop, why it degrades, and how to keep context lean.

August 22, 2026·8 min read
ShareShare
⚡Featured Prompt— copy and use right now
messages = [system, user_goal]
for step in range(max_steps):
    reply = model.call(messages)          # sends EVERYTHING every time
    messages.append(reply.as_message())
    for call in reply.tool_calls:
        raw = tools[call.name](**call.args)
        messages.append(tool_result(call.id, str(raw)))   # full raw dump

Why does your agent get slower, pricier, and noticeably dumber the longer it runs? It starts sharp at step two and by step twelve it's forgetting instructions, repeating itself, and taking a full second longer per call. The culprit is almost always the agent loop context window quietly filling with junk — every raw tool result, every verbose thought, every stack trace, all re-sent on every single turn. The model isn't degrading. Its input is.

An agent's context window carries the entire transcript back to the model each iteration. Left unmanaged, that transcript grows without bound: step ten re-sends everything from steps one through nine, most of it no longer relevant. More tokens mean higher cost, higher latency, and — past a point — worse reasoning, because the signal the model needs is buried under accumulated noise. Let's tear a bloated loop apart.

Before: The Weak Prompt

Here's the loop, or rather the loop's context handling, in its naive form:

hljs python
messages = [system, user_goal]
,[object Object], step ,[object Object], ,[object Object],(max_steps):
    reply = model.call(messages)          ,[object Object],
    messages.append(reply.as_message())
    ,[object Object], call ,[object Object], reply.tool_calls:
        raw = tools[call.name](**call.args)
        messages.append(tool_result(call.,[object Object],, ,[object Object],(raw)))   ,[object Object],

What this does: appends every model reply and every raw tool result to a single ever-growing list that's re-sent in full on every call — so by late iterations the model is re-reading a mountain of stale detail each turn.

Run this for fifteen steps against tools that return large payloads and the final call carries tens of thousands of tokens, most of them results the agent already used and no longer needs.

And the growth isn't linear in the way you'd hope — it's closer to quadratic in effort. Each new turn adds to the transcript, and the whole fattened transcript is re-sent on the next turn, so you're not just paying for the new content, you're re-paying for all the old content every single step. A twenty-step run doesn't cost twenty units; it costs something closer to the sum of a growing series. That compounding is why an agent that felt cheap in testing on short tasks becomes alarming on the first long one — the cost curve was hiding in the steps you didn't run.

Why It Fails

The window fills with three kinds of junk, and each is avoidable.

First, raw tool payloads — a search tool returns a hundred results, the agent needed three, and the other ninety-seven ride along in context for the rest of the run. Second, verbose intermediate reasoning — every "let me think about this" thought preserved verbatim forever, though only its conclusion matters later. Third, resolved detours — a failed attempt, its error, and the recovery all kept in full even though only the outcome is relevant going forward.

The result isn't just cost and latency. Past a certain fill level, models genuinely reason worse — the instruction from step one gets diluted, and the model's attention scatters across pages of stale detail. A full context window degrades quality, not only economics. The teardown fix is to treat the window as a managed resource, not an append-only log.

This is the part that surprises people: managing the agent loop context window isn't primarily a cost optimization, it's a quality one. Teams reach for it to save money and discover the bigger win is accuracy — a lean window keeps the model's attention on the goal and the recent observations instead of forcing it to re-parse ninety-seven search results it already discarded. The savings are real, but the sharper reasoning is what actually moves your success rate.

⚠️ Common mistake: Assuming a bigger context window solves this. A larger window delays the wall but doesn't move it — you just pay to re-send more junk before quality drops, and it drops later but just as hard. The fix isn't more room for noise; it's less noise. Manage what goes in rather than buying space to ignore the problem. A bigger window is a bigger desk; it still gets buried if you never file anything away.

⚡ Pro tip: Log your context token count per iteration and plot it. A healthy managed loop stays roughly flat or grows slowly; a bloated one climbs linearly. That single line tells you instantly whether your loop manages context or just accumulates it.

After: The Improved Prompt

The fix is to curate context each turn: keep what future steps need, compress or drop what they don't.

hljs python
[object Object], ,[object Object],(,[object Object],):
    system, goal = messages[,[object Object],], messages[,[object Object],]
    recent = messages[-keep_recent:]
    old = messages[,[object Object],:-keep_recent]
    summary = summarize_old(old) ,[object Object], old ,[object Object], ,[object Object],       ,[object Object],
    kept = [system, goal]
    ,[object Object], summary:
        kept.append(assistant_note(,[object Object],))
    ,[object Object], kept + recent

What this does: preserves the system prompt, the goal, and the most recent turns verbatim, while compressing the older middle of the transcript into a short progress summary — keeping continuity without re-sending every stale detail.

hljs python
[object Object], ,[object Object],(,[object Object],):
    trimmed = extract_relevant(raw, max_items=,[object Object],)         ,[object Object],
    messages.append(tool_result(call.,[object Object],, trimmed))
    archive[call.,[object Object],] = raw                               ,[object Object],

What this does: puts only the relevant slice of a tool result into context while archiving the full payload elsewhere, so the agent can fetch details on demand without carrying the whole payload every turn.

Breaking Down Each Element

Three moves keep the window lean.

Trimming at the source — storing only the relevant slice of each tool result — stops junk from entering the window in the first place, which beats cleaning it up later. Summarizing the middle — compressing older turns into a progress note — preserves continuity without the verbatim bulk. And archiving off-context — keeping full payloads retrievable but out of the window — means nothing is lost, only moved, so the agent can pull detail back if it genuinely needs it.

Together they hold the window roughly flat as the run grows. The agent keeps its recent working memory and a summary of its history, instead of dragging every raw byte forward forever.

The mental model that helps: treat the agent loop context window like a desk, not an archive. A desk holds what you're working on right now plus a note of where things stand; everything else goes in a drawer you can open when needed. An agent whose desk is buried under every document it has ever touched works exactly as badly as a person in the same situation — slowly, and with things constantly falling through the cracks. Curation keeps the desk clear.

⚡ Pro tip: Keep the most recent few turns verbatim and only summarize what's older. Recency matters — the agent's immediate next step depends on the last couple of observations in full detail, while step three's raw output can safely become one line of summary.

Variations for Different Contexts

Context strategy shifts with the work.

A research analyst's long-running agent leans hard on summarization, collapsing each explored source into a one-line finding and archiving the full text. A software engineer's coding agent keeps recent file states verbatim but summarizes older edits, since the current code matters far more than the history of how it got there. A customer-service agent handling long conversations keeps a running summary of resolved issues and only the active thread in full, so a forty-message chat stays as lean as a five-message one.

Same window, three curation policies — each keeping what its task needs live and compressing the rest.

⚡ Pro tip: Give the agent a

recall(id)
tool that pulls an archived full payload back into context on demand. Then you can trim aggressively without fear — if the agent turns out to need the ninety-seven search results after all, it can ask for them, and you've paid for that bulk only on the rare turn it's actually needed instead of every turn.

⚡ Pro tip: Trigger summarization by token threshold, not step count. A step that returns a huge payload should trigger compaction immediately, while ten tiny steps might not need it yet. Watch the actual fill level and compress when it crosses a line, not on a fixed schedule.

Save and Reuse This

Context management isn't task-specific plumbing you rebuild each time — it's the same trim-summarize-archive pattern with the knobs set differently. Swap what counts as "relevant," tune how much recent history stays verbatim, and the machinery carries over unchanged. The policy is task-specific; the plumbing is not. That split is exactly why it's worth building once properly: the hard part — trimming safely, summarizing without losing thread, archiving retrievably — is identical across agents, and only the "what counts as relevant" knob changes from one to the next.

I keep the

trim_context
and
store_result
helpers saved and versioned in PromptABCD next to the loop code, so every new agent manages its window from the first run — instead of shipping an append-only loop that runs great in the demo and turns slow and forgetful the moment a real task takes fifteen steps.

context windowagent loopmemorytokensai agentsoptimization

Continue Reading

How to Summarize History Mid-Loop Without Losing State
Agent Loop Engineering

How to Summarize History Mid-Loop Without Losing State

An agent summarized its own history mid-run and forgot it had already booked the flight — then booked it again. Good agent loop history summarization keeps state intact. Here's how.

August 22, 2026·8 min read
Context Compaction Between Agent Turns
Agent Loop Engineering

Context Compaction Between Agent Turns

Most advice on agent context compaction is backwards: it compresses on a timer and loses the wrong things. Here's how to compact by relevance, keep what matters, and do it safely.

August 22, 2026·8 min read
Tree of Thoughts Inside the Agent Loop
Agent Loop Engineering

Tree of Thoughts Inside the Agent Loop

A tree of thoughts agent explores several reasoning paths and keeps the best, instead of committing to the first. Here's a real case where branching turned a stuck agent into a solver.

August 22, 2026·8 min read

Save the prompts from this post

PromptABCD is a free prompt manager. Paste, organize, and reuse your best AI prompts — no more hunting through chat history.

Start free →
← PreviousTree of Thoughts Inside the Agent LoopNext →Context Compaction Between Agent Turns
Share this post:
ShareShare