engineering notes
Context contamination in tests
If the tester — human or LLM — knows how the system is built, the test is spoiled: a hint leaks into the check. The fix is full isolation of the test loop from knowledge of the implementation.
Executive summary. You can spoil an AI agent’s test without faking anything — it’s enough for the tester to know how the agent works inside. Then a hint quietly leaks into the check: the tester asks “conveniently”, senses the expected answer, skirts the weak spots. With humans this was long known; with the arrival of LLM testers it turned out the machine adapts the same way. The green report comes out “dirty” — it measures not the agent but its tester. The cure isn’t more tests but isolation: the tester must not know the internals.
There’s a quiet way to spoil a test where no one fakes anything. The tester is honest, the scenarios are real, the run is clean — and still the result doesn’t mean what it seems. The reason is that the tester knows how the system is built inside, and that knowledge leaks into the check. Call it context contamination: context the real user doesn’t have gets into the test, and it cues the agent’s answer.
If the tester knows how the system is built, they’re testing not the system but their knowledge of it.
Hypothesis: knowing the implementation contaminates the test — for humans and LLMs alike
When the tester knows the agent’s internals, they unconsciously run the dialog down the branch the agent handles best. They phrase the question in the terms the system expects. They don’t push where they’ve seen uncertainty. They accept an evasive answer as sufficient, because they know there’s a correct mechanism beneath it. Each such move is a hint that leaked from the tester’s head into the test. The real user won’t give those hints, because they don’t know the internals.
For a long time this was treated as a human problem: a developer can’t honestly test their own code, you need outside QA. With the arrival of LLM testers came the hope that a machine is free of this bias. The hope failed. If a description of the system, a reference answer, or even a hint at the “right” branch gets into the LLM tester’s context, it behaves exactly like an informed human: it senses the expected answer, adjusts its questions, stops pushing where it could have pressed harder. The machine is contaminated by knowledge too — the contamination just arrives through context rather than experience.
Problem: a contaminated green report is indistinguishable from an honest one
The danger of context contamination is that from outside it looks like a normal check. The report is green, the metrics good, the process followed. But it measures the pair “agent plus informed tester”, while in production the agent is left one-on-one with someone who knows nothing about it. The gap between these two situations is exactly the zone where the agent breaks for the customer after passing every test.
This is a direct continuation of the illusion of knowledge, only moved up to the level of tests. There the system confidently produced an answer with no basis under it; here the test confidently produces a green result with no honest check under it. In both cases the form is right and the substance is missing — and in both cases only someone who knows where to look can see it.
The window grows faster than the ability to use it: you can fit almost anything, but accuracy depends on what is put there and how. Window size is no substitute for context engineering.
This growth is a handy metaphor for contamination. The context window has grown tens of times over, and now it’s easy to fit everything into it: a description of the system, reference answers, the history of past runs, instructions on “how it should be”. But the more excess context rides along to the LLM tester, the harder it plays along — and the window’s size doesn’t undo the fact that knowledge the live user lacks got into the test. Fitting context is easy; not contaminating the check with it is separate engineering work.
Why the usual approaches don’t work
“Ask the tester to be objective” doesn’t work: contamination is unconscious, you can’t switch it off by willpower. A human who knows the system can’t ask as if they didn’t — and an LLM with the agent’s design in its context can’t “forget” that design for the duration of the run. Intent is beside the point; what matters is the presence of knowledge, not the wish to use it.
“Give the LLM tester more context so it checks better” does exactly the opposite. The more the system knows about the agent under test, the more precisely it finds the “right” branch and the less it resembles a real user. This is the same deficit as with context in general: what’s valuable isn’t the volume supplied but its cleanliness for the task — and the task of a test is precisely not to know.
“Run it once and lock it in” doesn’t save you for a different reason — non-determinism doesn’t care whether the test is contaminated; it just adds instability on top of a dirty check. The root is one: the check is run by a side into whose context knowledge of the implementation has leaked.
Engineering model: isolating the test loop
The fix isn’t cosmetic but architectural: the checking loop must have no access to the agent’s design. In practice that’s three boundaries. First, informational: the tester, human or LLM, sees the agent only as a black box — input and output, with no description of internals, no reference answers, no “right” branch in the context. The less it knows, the closer it is to a real user, and the real user is the standard of conditions.
The second boundary is role-based: the one who builds the agent and the one who checks it are different sides with different goals. The checker is interested not in green but in red; their context is filled not with knowledge of the system but with models of difficult behavior and real dialogs. A customer simulator must want to break the agent, not help it — and for that it must not be handed a map of its weak spots.
The third boundary is evaluative: the judge assesses the outcome by fact rather than matching the answer to a reference it could itself have cued. Did the dialog reach the goal or not — that’s a check for the result, not for knowing the right branch. The corpus of scenarios is drawn from live dialogs, because by definition they’re free of knowledge about the implementation — they were written by people who don’t care how the agent is built.
Practical takeaway for the business
Ask not only “who tested it” but “what did the tester know about the agent”. If the checker is a human from the development team, or an LLM with the system’s description placed in its context, you have a contaminated test even if the report is flawless. The cleanliness of a check is determined not by diligence but by the checker’s ignorance of the internals.
What to delegate. An isolated test loop is a separate function, like an independent audit: the checking side works with the agent blind, by input and output, on a corpus of real dialogs. That’s cheaper than figuring out after the fact why an agent with green tests broke for the customer.
What not to do. Don’t hand the checker — human or LLM — a map of the agent’s weak spots “to search better”: that’s exactly what turns a check into playing along. Don’t assume an LLM tester is automatically objective — it gets contaminated through context the way a human does through experience. And don’t accept a green report without establishing how blind the checker was to the implementation.
Check whether your tests are contaminated by knowledge of the system — .
Open questions
Whether the test loop can be isolated completely — in practice there’s always residual leakage through those who both build and check; the point is to minimize it and make it visible. Where the line is between “necessary task context” and “a contaminating hint” — it’s where context starts telling the checker the expected answer, not just the conditions. And the management question: who guarantees the blindness of the checking loop — that’s the quality owner’s role, and it must be assigned before the agent reaches customers.
If your tests are written and run by people who know the system from inside, the report is almost certainly contaminated, however good it looks. — let’s see what an isolated check of your agent shows, and where knowledge of the implementation is cuing its answers.