Context engineering: your agent isn't dumb, it's drowning

Context engineering: your agent isn't dumb, it's drowning
30,000tokens: what a single test output can take up
5compaction stages, from 70% to 99% pressure
~15tokens: what's left of each masked observation
~15tool calls: when the system prompt starts to fade
Your AI agent isn't dumb, it's drowning in context: context engineering is the real product
I also tell the story in this eight-minute video on my channel Articulator EN.

The layer that matterslink

The starting point is a reading: the technical report on OpenDev, presented as the first complete write-up of an open-source coding agent that lives in the terminal. What stood out most wasn't the model or the tools, but the context engineering: the layer that decides what information the agent has in front of it on every turn.

OpenDev treats the context window as a finite resource that runs out, just like memory in an operating system.

The context window and RAM, two matching grids: a finite resource that fills up.
The context window, treated like the memory of an operating system.

That leads to the central idea: when an agent fails, most of the time it isn't bad reasoning, it's its context. These three symptoms probably sound familiar: the model forgot its instructions, the window filled up with endless command outputs, or the agent stopped following its system prompt after twenty tool calls.

Two buckets of red failure balls: the reasoning one is nearly empty, the context one is full.
A sketch, not data: the article only says "most".

For the author, this is the layer that separates a demo from something that holds up in production.

What an agent seeslink

The uncomfortable truth is this: a language model sees exactly what you put in front of it, and nothing more. And an agent reads files, searches and runs commands. All those results end up in the same fixed-size window.

Put numbers on it and it fills up fast. A single test run can return 30,000 tokens of output. Add a few large file reads and the context is already full.

A terminal with test output, 30,000 tokens and a full context bar.
A single test output can take up 30,000 tokens.

From then on, the agent stops being effective. Not because it got dumber: what matters has been buried under the noise.

A glowing gem, what matters, buried under a rain of stones and characters.
What matters, buried under the noise.

A budget, not a loglink

Cobus sums it up in one line: context is a budget, not a log. Tokens spent on a stale output are no longer available for the user's actual question.

A side note: the article credits that line to the paper, but what the paper says is "Treat context as a budget, not a buffer". Same idea; the wording with "log" is Cobus's.

Five stages instead of all or nothinglink

This is the centerpiece. The usual approach is all or nothing: when the context fills up, you run an emergency summary. OpenDev instead watches the pressure constantly and applies increasingly aggressive strategies: an adaptive compaction pipeline with five steps.

A context pressure gauge at 99% and five growing bars: 70, 80, 85, 90 and 99.
Each step kicks in at a pressure level.
  1. 70%, warning. Nothing gets touched yet. The system records the pressure and starts tracking the trend.
  2. 80%, observation masking. Earlier tool results get replaced with very compact reference pointers of about 15 tokens each, such as [output offloaded to scratch file]. The conversation keeps its structure but weighs far less.
  3. 85%, fast pruning. Old outputs beyond the recency window get deleted, without summarizing anything. That's why it's cheaper than asking the model for a summary.
  4. 90%, aggressive masking. The window of what's kept shrinks until only the most recent outputs remain.
  5. 99%, full compaction. According to the paper, it first saves the whole history to a file. Only now does the model summarize the middle of the conversation, and the latest part is kept word for word.
The conversation with old results turned into 15-token pointers, and free space below.
Stage two: each old observation becomes a pointer, and free space appears.
Fast pruning: old outputs get deleted and only the recent ones stay.
Stage three: pruning summarizes nothing, so it costs less.
Compaction: a conversation summary, the latest part word for word and the full history saved to a file.
Stage five: the history, safe in a file; the recent part, word for word.

One note if you go to the source: I use the article's numbering, 1 to 5. The paper numbers those same stages 1, 2, 2.5, 3 and 4.

The cheap stuff firstlink

Here's the key: cheap strategies often reclaim enough space. That saves you the cost of a summary and the information it always loses.

Masking and pruning reclaim enough space; the summary, which costs tokens and loses information, is crossed out.
If masking and pruning are enough, you skip the summary.

With stage two alone, each observation drops from thousands of tokens to about fifteen. And the article gives this result: sessions used to overflow at 15 to 20 turns; now they last 30 to 40, without compaction even kicking in.

A caveat from the paperlink

Here the article and its source don't say quite the same thing, so I went to check. The paper credits that jump in turns mainly to summarizing tool outputs and offloading the largest ones to files (those over 8,000 characters), not to the five-stage pipeline.

For the five stages it gives a different number: they cut the peak context used by observations by 54%. And these are data from their own experience, with no comparison against other agents, so read them with that in mind.

Two panels: the jump from 15-20 to 30-40 turns comes from summarizing and offloading to files; the five stages give −54%.
Two different numbers, with two different causes.

You'll also see "40+ turns" in the article's opening summary. In its body and in the paper, it's 30 to 40.

The system prompt fadeslink

This is the part that surprised the author most. After about 15 tool calls, the model stops following its system prompt, and it happens again and again. The instructions are still there in the window. It just no longer pays attention to them.

The paper's example: you tell it to always run the tests after editing. At first it does. But after about twenty calls, it quietly stops.

Cobus explains it as a distance problem: the system prompt sits at position zero, and the model's attention has moved to the recent messages, past position 50,000. Those two positions come from the article; they aren't in the paper.

A strip of messages with the spotlight of the model's attention on the latest ones, at position 50,000 or more.
The model's attention is on what's recent, far from the system prompt.

User-role reminderslink

How do you fix it? With event-driven reminders: short messages injected right at the decision point, where the agent would go wrong. According to the paper, it has eight event detectors; for example, when a tool fails and there's no retry, or after five reads in a row with no progress. And counters limit how many times each reminder fires.

And here's the trick: they aren't sent as system messages, but with role: user. After forty turns, one more system message blends into the background the model has half forgotten. What the user writes, on the other hand, appears as the most recent thing of all, and the model treats it as something that demands a response.

The spotlight of the model's attention points at the user-role reminder, at the end of the conversation.
With the user role, the reminder is the most recent thing and demands a response.

Three lessonslink

Of all the lessons in the paper, the author picks three:

1. A budget, not a log

Every message competes for finite space. Adding is spending, not recording. Watch what's consuming it and whether it still pays off.

2. Steer at decisions, not at startup

A long system prompt fades. A short reminder, right before deciding, sticks.

3. Cap whatever grows

Undo history, concurrent calls, behavioral nudges. Without a limit, long sessions end up failing.

Sketch of influence on the model: the system prompt fades over time and the reminder, right before deciding, sticks.
A sketch, not a measurement: the prompt fades and the reminder sticks.
Three bars stopped by a cap, and a session with no cap that ends up failing.
Everything that grows with the session needs a cap.

In shortlink

Treat context as a budget, compress the cheap stuff first, remind it of the rules right when they're needed and cap whatever grows.

In one line

Your agent is as good as its context.

What eats up the most memory in your agent?

Sourceslink

Continue reading

Last posts -->

Have you seen these projects?

Gymnasia

Gymnasia Gymnasia
Expo
React Native
TypeScript
OpenAI
Anthropic

Fitness app with two agents that run entirely on the device, with no backend, so the user's data never leaves the phone. A BYOK conversational coach with local tools and a remote system prompt with offline fallback, plus a food estimator that pulls macronutrients out of a photo of the plate, with barcode scanning against OpenFoodFacts.

LangGraph Deep Researcher

LangGraph Deep Researcher LangGraph Deep Researcher
Python
LangGraph
FastAPI
React
TypeScript
Docker

Multi-agent research system built with LangGraph. A supervisor breaks your question down into topics and launches search sub-agents in parallel; each one compresses its findings before handing them to a writer agent that produces the final sourced markdown report. Live streaming over WebSockets, a configurable model per role and bring-your-own API keys that are never persisted server-side.

Tau

Tau Tau
Python
LangChain

Multi-agent tutoring system for secondary school students, with one agent per subject and course material written and validated by a team of teachers. It was used with real students at a private school in Spain and at a secondary school in Colombia.

View all projects -->
>_ Available for projects

Do you have an AI project?

Let's talk.

maximofn@gmail.com

Machine Learning and AI specialist. I develop solutions with generative AI, intelligent agents and custom models.

Do you want to watch any talk?

Last talks -->

Do you want to improve with these tips?

Last tips -->

Use this locally

Hugging Face spaces allow us to run models with very simple demos, but what if the demo breaks? Or if the user deletes it? That's why I've created docker containers with some interesting spaces, to be able to use them locally, whatever happens. In fact, if you click on any project view button, it may take you to a space that doesn't work.

Flow edit

Flow edit Flow edit

FLUX.1-RealismLora

FLUX.1-RealismLora FLUX.1-RealismLora
View all containers -->
>_ Available for projects

Do you have an AI project?

Let's talk.

maximofn@gmail.com

Machine Learning and AI specialist. I develop solutions with generative AI, intelligent agents and custom models.

Do you want to train your model with these datasets?

short-jokes-dataset

HuggingFace

Dataset with jokes in English

Use: Fine-tuning text generation models for humor

231K rows 2 columns 45 MB
View on HuggingFace →

opus100

HuggingFace

Dataset with translations from English to Spanish

Use: Training English-Spanish translation models

1M rows 2 columns 210 MB
View on HuggingFace →

netflix_titles

HuggingFace

Dataset with Netflix movies and series

Use: Netflix catalog analysis and recommendation systems

8.8K rows 12 columns 3.5 MB
View on HuggingFace →
View more datasets -->