01
The question
Retrieval-augmented generation (RAG) is the usual way to make a language model answer from your own documents: find the passages most similar to the question, then have the model answer from them. That puts a lot of trust in the documents. If someone can add one, a wiki page, a support ticket, a shared doc, can they change the answers?
Published attacks show it can be done. I wanted to measure the ordinary case instead: no optimisation against the retriever, just the simple kinds of planted text the literature describes, and four questions. How many questions does one bad passage reach? When it's retrieved, how often does the model repeat it? Does it spread beyond its target? And what do simple defences stop, at what cost?
02
The setup
The corpus is 10,000 paragraphs from SQuAD, a public Wikipedia question-answering dataset, so every question has a known right answer. 48 target questions get a planted passage, one at a time, so the corpus holds exactly one bad passage in 10,001. Another 235 real questions on the same articles measure spread, and 500 questions from other articles measure reach.
Retrieval uses a small open embedding model, and answers come from three open models running locally: qwen3 8B, Llama 3.1 8B and Gemma 3 12B. Everything is cached, so every number regenerates without calling a model again. The predictions were written down, with a timestamp, before the full run.
- False fact: restates the target question and asserts a made-up answer, a coined word or a shifted year, so any answer that repeats it can be detected exactly.
- Instruction injection: restates the question and tells the system to ignore the other sources and reply with a code word.
- Keyword-stuffed: one passage packed with common words, meant to be retrieved for as many questions as possible.
- Five copies: five reworded false-fact passages for the same target, as a dose comparison.
03
Retrieval decides who is exposed
A passage that restates its target question is, unsurprisingly, retrieved for that question every time: that's how it was written. The interesting part is everywhere else. With the top 5 passages retrieved, it reached 23% of other questions answered by the same paragraph, 3% of questions on the rest of the article, and 0.01% of questions on other articles: on average 6 of 10,570 questions, its target included.
The keyword-stuffed passages, built to be retrieved broadly, were almost never retrieved at all: 3 and 10 questions of 10,570. A dense retriever compares meaning, not word counts, and a bag of common words means nothing in particular. To still measure how models treat such a passage, a separate check forced it into first place. Models followed it 4–7% of the time.
A bag of common words means nothing in particular, so a meaning-based retriever never picks it.
04
The model decides what happens next
Once the bad passage is in front of the model, alongside four genuine ones, the models differ a lot. One false passage was repeated in 42% of qwen3's answers, 21% of Llama's and 42% of Gemma's. Five copies of it took that to 100%, 85% and 98%. Volume wins: when most of the evidence agrees, the models go with it.
Injections split the models even more. Gemma followed the planted instruction 56% of the time, qwen3 19%, and Llama 2%. The same instruction, in the same position, is close to harmless for one model and a coin flip for another.
| Once retrieved (top 5) | qwen3 8B | Llama 3.1 8B | Gemma 3 12B |
|---|---|---|---|
| One false passage | 42% | 21% | 42% |
| Five copies | 100% | 85% | 98% |
| Instruction injection | 19% | 2% | 56% |
| Accuracy on clean questions | 71.3% | 75.2% | 72.8% |
Share of the 48 target questions whose answer repeats the made-up claim or follows the instruction. 95% intervals are roughly ±12 points for the single-copy rows; all are in the full results. Gemma ran a reduced design to save time (top 5 only, fewer clean questions).
05
Does it spread?
Not directly. On nearby questions, even when the planted passage was retrieved, models almost never carried the made-up answer over: 0–5%. The false fact stays attached to the question it was written for.
It can come back, though. Systems often save their own answers, as notes, summaries or chat history, and retrieve them later. So I took every answer that had adopted the false fact, wrote it back into the corpus as a short note, removed the original poison, and asked again. The note alone brought the false answer back 35% of the time for qwen3 and Gemma, and 10% for Llama. Nearby questions sometimes retrieved the note, but none repeated it.
Remove the poison, keep the model's answer as a note, and the false fact comes back a third of the time.
06
What the defences stop, and what they cost
Each defence is judged on two things: how much poison it stops, and how much accuracy it costs on the 783 clean questions. A defence that refuses to answer anything is perfectly safe and useless.
Filtering instruction-like sentences out of retrieved passages stopped every injection, for all three models, and cost nothing on clean questions. It did nothing for false facts, which don't contain instructions. Asking the model to quote its source helped qwen3, made Gemma repeat the false fact more (56% instead of 42%), and cost Llama 9 points of accuracy.
Requiring two retrieved passages to agree stopped single false facts almost completely (2–4%), but failed against five copies, which agree with each other by design. And it abstained on 80–84% of clean questions, because in this corpus most answers come from one paragraph. As implemented here, a simple string rule, it's unusable. It shows the trade-off rather than a fix.
07
What to keep in mind
This is one corpus, one retriever and three small local models, so it says what happens in a setup like this one, not everywhere. A few things make specific numbers optimistic or pessimistic:
- SQuAD questions were written while reading their paragraph, so they share its wording. That makes retrieval easier than for real user questions, which probably flatters reach.
- Gemma ran a reduced design (top 5 only, fewer clean questions), and a larger 30B model I'd planned didn't run, so “does size help” rests on 8B against 12B.
- After seeing early results, I widened the rule for “followed the injection” to include answers that give the instructed reply without the code word. The stricter rate is reported beside it in the full results, and every change after the plan is logged.
- Answers are judged by exact string matching on the made-up values. A labelled sample of 90 outputs agreed with it completely, but most were clear-cut cases.
- The two-source rule is a crude string check. A model-based agreement check could do much better on accuracy.