Designing agents that prompt injection can't steer: CaMeL and the six patterns

Two 2025 papers argue that prompt injection is better contained by how an agent is built than by filtering what it reads. One proposes CaMeL; the other catalogues six patterns. Here is each, and its cost.

The short answer

The most reliable defences against prompt injection in 2025 research don’t try to spot malicious text. They change the agent’s structure so that untrusted text can’t choose its actions. A June 2025 paper by researchers from several labs states the principle: once an agent has ingested untrusted input, it must be constrained so that input cannot trigger consequential actions. It then describes six patterns that do this.2

The best-known concrete design is CaMeL, from a March 2025 paper. A privileged model writes a plan from the user’s request alone; a quarantined model reads untrusted data but has no tools; an interpreter runs the plan and checks a security policy before every tool call. On the AgentDojo benchmark it solved 77% of tasks with “provable security”, against 84% for an undefended system.1 The cost is real, and the authors say plainly that prompt injection is not fully solved.

Every MCP tool call goes through your rules first. Here a delete that doesn’t say which rows is stopped before it reaches the database. These are the rules deedglass init starts with; the call is made up.

The principle

Filtering asks: “is this text an attack?” An attacker only needs one phrasing the filter misses. Benchmarks such as AgentDojo show detectors reduce attack success, but not to zero.3

Design asks a different question: “if this text were an attack, what could it make the agent do?” If the answer is “nothing consequential”, the filter’s misses stop mattering. That’s the approach both papers take.

It also lines up with the “lethal trifecta” framing: private data, untrusted content, and a way to communicate externally.4 Each pattern below removes or constrains one leg.

The six patterns

From the June 2025 paper, in its own terms:2

Pattern How it works Untrusted data can…
Action-selector The model maps a request to predefined tool calls; results never feed back Nothing; it never reaches the model’s decisions
Plan-then-execute A fixed plan is made before untrusted data is read Change inputs to planned actions, not which actions run
LLM map-reduce Isolated sub-agents each process one piece of untrusted data; a separate step combines results Affect only its own piece’s output
Dual LLM A privileged model with tools never sees untrusted data; a quarantined model sees it but has no tools Shape the quarantined model’s output only
Code-then-execute The model writes a program that calls tools and unprivileged models; the program runs Flow as data through the program, not change it
Context-minimization The user’s prompt is removed from context once it has shaped the actions Not be combined with the original request later

The column on the right is the useful one. In each pattern, the attacker’s text is still read, but its reach is bounded by the structure.

CaMeL in more detail

CaMeL combines the dual-LLM and code-then-execute ideas with security policies.1

  1. The privileged model sees only the user’s query. It writes code, in a restricted Python subset, that expresses the plan.
  2. The quarantined model parses untrusted data, an email or a document, into a fixed schema. It has no tool access.
  3. The interpreter runs the plan, tracking where every value came from and who may read it, its capabilities.
  4. Before each tool call, a policy function takes the tool name and arguments and returns allowed or denied with a reason.

So when an email says “forward this to attacker@example.com”, the quarantined model may extract that address as data. But the plan, written before the email was read, decides whether a send happens, and the policy decides whether a value whose provenance is “an untrusted email” may be used as a recipient. Untrusted data can never change the program flow.1

The authors list the limits: side channels through exceptions and timing; the burden on users of writing and maintaining policies; lower utility on tasks with poorly documented APIs; much higher token use than ordinary tool calling; and the statement that prompt injection attacks are not fully solved.1

What each pattern costs

The second paper’s main contribution is being honest about trade-offs between utility and security.2 A rough guide:

Pattern Good for Gives up
Action-selector Menus of fixed actions Any reasoning over tool results
Plan-then-execute Tasks whose steps are known upfront Adapting the plan to what it finds
LLM map-reduce Processing many independent documents Reasoning across documents
Dual LLM Tasks that need both tools and untrusted reading Simplicity; two models to coordinate
Code-then-execute Complex multi-step tasks Needs a safe interpreter; more tokens
Context-minimization Stopping late-stage manipulation Follow-up questions that need the original request

CaMeL’s own numbers show the overall shape: some tasks become impossible under a strict design (77% versus 84% solved), and in return the ones it does solve come with a design-level assurance that injected text didn’t steer them.1

Picking one for a real agent

Three questions get you most of the way:

  1. Can the task’s actions be decided before reading untrusted data? If yes, plan-then-execute or action-selector. A support bot that can only look up an order and open a ticket fits.
  2. Does the agent need to read many untrusted items and summarise? Map-reduce, with no tools in the per-item step.
  3. Does it need to act based on what it reads? That’s the hard case: dual LLM or a CaMeL-style design, plus policies on the arguments of every consequential call.

Most production agents today are none of these: one model, all tools, everything in one context. If that’s yours, the cheapest improvement is to split reading from acting, even crudely, and to put rules on what the acting part may do.

Where policies come in

Notice that CaMeL, the strongest design here, still ends with a policy check before each tool call: a function of the tool name and its arguments that says yes or no.1 Patterns bound what untrusted text can reach; policies decide what reaches the outside world. CaMeL needs both, and its authors note that writing policies is a burden users carry.

That check is what a tool-call policy is, enforced at the point where a call leaves for a real system. It’s useful on its own in an agent that follows none of these patterns, and it’s still needed in one that follows them all. For how injection gets in to begin with, see indirect prompt injection research and tool poisoning; for how defences are measured, AgentDojo and InjecAgent. To see a policy refuse a call on a real database in your browser, try the playground; to grade what an agent can reach on your machine, run npx deedglass scan (the grade, explained).

Written with AI assistance and checked against our claims register.

The takeaway

CaMeL kept untrusted data out of the plan and solved 77% of AgentDojo tasks with what its authors call provable security, against 84% undefended.

Read nextAgentDojo and InjecAgent: how prompt injection is measured in tool-using agents Try it: install in 7 s

Related on this site

More posts

Sources

  1. 1Debenedetti et al. Defeating Prompt Injections by Design (arXiv 2503.18813) · arxiv.org · checked 26 October 2026
  2. 2Beurer-Kellner et al. Design Patterns for Securing LLM Agents against Prompt Injections (arXiv 2506.08837) · arxiv.org · checked 26 October 2026
  3. 3Debenedetti et al. AgentDojo (arXiv 2406.13352) · arxiv.org · checked 26 October 2026
  4. 4Simon Willison: The lethal trifecta for AI agents · simonwillison.net · checked 26 October 2026

Published 26 October 2026, sources last checked 26 October 2026. If something here is out of date, write to hello@deedglass.com.

Try it on your own setup

npx deedglass scan

Grades only your own setup. Nothing is uploaded.

Pricing