Your Agent Does Not Need a Bigger Context Window
TL;DR: Retrieval put untrusted text inside the same window as your instructions, and models have no architectural way to tell the two apart. Bigger windows make this worse, not better. What helps is tracking which content in a trajectory came from somewhere you do not control, and refusing consequential actions downstream of it when the stakes require a clean one.
The failure has a boring shape
An agent reads a document. The document contains a sentence addressed to the agent. The agent does what the sentence says.
That is the whole attack. It requires no exploit, no malformed input, no clever encoding. It requires an attacker who can put text somewhere your agent will read: a support ticket, a CV, a supplier invoice, a filing, a calendar invite, a web page, a code comment.
The reason it keeps working is architectural. In a language model there is no channel separation. Your system prompt, the user’s request, and the retrieved document are the same kind of thing by the time they reach the weights: tokens in a sequence. “Follow these instructions” and “process this data” are a distinction you hold in your head and the model does not.
Why more context makes it worse
The instinct when an agent behaves badly is to give it more information. More context, more examples, a longer system prompt restating that it must not follow instructions in documents.
Consider what that does. The system prompt is a fixed number of tokens near the front. The retrieved material grows. Every document added shifts the ratio further towards text you did not write, and towards text an attacker may have. You are increasing the attack surface and diluting the only defence you have, in one move.
Longer windows also change what an attacker can afford to do. In four thousand tokens an injected instruction has to be near the top and blunt. In a million, it can sit in the middle of a plausible document, phrased carefully, and nobody skimming will find it.
Filtering the input is worth doing and will not save you
Screen for known patterns. “Ignore previous instructions”, “reveal your system prompt”, roleplay triggers, unusual encodings. It raises the bar and it costs almost nothing.
It is not a control. Keyword filtering has a high false positive rate on legitimate documents, so you end up flagging rather than blocking, which means the content still reaches the model. And the space of ways to phrase an instruction in natural language is not enumerable. You are pattern-matching against a generative adversary.
Treat it as a speed bump. Speed bumps are useful. They are not gates.
The question worth asking instead
Stop trying to determine whether a document is malicious. You cannot, reliably, and every hour spent there is an hour not spent on the question that has an answer:
Which parts of this trajectory came from somewhere we do not control, and does the action about to happen require that they had not?
That is answerable. You know whether a document arrived from a customer upload or from your own curated store. You know whether an index was populated by your team or by a third party. The provenance is a fact about your architecture, not a judgement about content.
Once you track it, the interesting property falls out: taint propagates forward through a trajectory. If step 0 read an unverified document, step 4 is downstream of unverified content whether or not it looks like it. And now a policy becomes expressible in a way that does not depend on detecting anything:
This agent may summarise a document containing untrusted content. It may not initiate a payment in the same trajectory.
That is a real control. It does not need to know what the document said.
Not every action needs a clean context
The mistake in the other direction is treating all taint as fatal. Most of what agents do is fine downstream of untrusted content. Reading a customer’s email in order to answer it is the job, and refusing on those grounds is refusing to work.
The requirement belongs on the action, not on the agent. Summarising: fine. Drafting a reply for a human to send: fine. Moving money, changing a configuration, disclosing data, closing a case without review: these are the ones where the question “was anything in this trajectory written by someone else?” deserves an answer before rather than after.
Which means the interesting design work is deciding, per action, whether it needs a clean context. That is a conversation with the people who own the consequences, and it is a better conversation than the one about prompt engineering.
What the record needs to say
When an action is refused for this reason, three things have to be in the record or the refusal is not useful.
Which content was untrusted. The specific source, not a boolean on the trajectory.
Where it entered. The step index. An agent that read an unverified document at step 0 and one that picked up an untrusted index at step 6 are different incidents with different remedies.
Whether the decision downstream of it stood. This is the one teams forget. The value is not knowing that taint was present; it is knowing which decisions were allowed to proceed anyway, because that is the list you review when something turns out to have gone wrong.
Architecture beats detection, every time
The general lesson, and it is older than agents: when you cannot reliably detect a bad input, stop trying, and arrange things so that a bad input cannot reach the consequence.
Isolate the component that reads untrusted material from the component that acts. Give the reading component no authority to do anything irreversible. Make the handoff between them explicit and checkable. This is the same instinct that produced privilege separation and parameterised queries, and it works here for the same reason: it removes the class of failure rather than filtering instances of it.
Prompt injection is not solved and will not be solved by better prompts. It is bounded by better architecture.
The bottom line
You will not stop your agent from reading something an attacker wrote. You can stop it from doing anything expensive afterwards. That is a smaller, achievable goal, and it is the one worth building.