Output Caging Lab: Constrained Decoding for AI Agents
This is a hands-on lab about caging what a model can say, and being honest about what the cage cannot do. A grammar or JSON Schema enforced at decoding time guarantees the shape of an agent’s output: the right keys, enumerated tool names, bounded strings, no link syntax where you forbid it. It does not make the content true or safe. You make 12 scored calls for a fictional support agent, from choosing the constraint to the layers that cover what it cannot stop.
It follows OWASP’s guidance on improper output handling and the vendor and project documentation for structured output, and quotes no benchmark numbers. For testing single injection probes see the Prompt Injection Tester.
You are Marta Okonkwo, security lead at Northgate Freight. The support agent Dispatch reads customer emails (untrusted text) and returns a structured action that your orchestrator runs: look up an order, draft a reply, open a ticket, request a refund. Today it is asked nicely, in the prompt, to answer in JSON. Your engineering team wants to cage the output at decoding time with a grammar or JSON Schema. Over 12 scored decisions you choose what to cage, what a grammar cannot stop, and which layers sit around it. The honest rule to keep in mind: a grammar limits syntax, not meaning. Nothing here is an attack recipe, every host is a placeholder and every name is invented. Each call scores 0 to 10 with the source behind the feedback.
Make it yours
Replace the sample names so the scenario and the debrief you export are about your organisation.
TL;DRWhat this is
5 points
- A scenario lab about constraining what a model can emit. Constrained decoding (a grammar or a JSON Schema enforced token by token) guarantees the shape of an output. It does not guarantee the meaning. You act as security lead at a fictional freight company whose support agent returns structured actions for an orchestrator to run.
- You make 12 scored decisions: what a decoding constraint really promises, which constraint to pick, enumerating tool names, bounding strings, caging the free-text channel, then the cases a grammar cannot stop (a valid field carrying exfiltrating content, a wrong-but-legal tool choice) and the layers around it: post-decode validation, identifiers instead of URLs, rendering that does not auto-fetch, destination allow-lists, human approval, testing and what you tell leadership.
- It draws on OWASP LLM05 (Improper Output Handling) and LLM01, the OpenAI Structured Outputs guide, the llama.cpp GBNF guide and the abstracts of the Outlines and XGrammar papers. We quote no benchmark figures, and we say where only an abstract was read.
- Free to play, no account needed. Every organisation, host and agent is fictional and no attack text appears.
- Defensive and educational only.
How this differs from our other agent labs
The Insecure Output Lab traces model output into a downstream sink (a page, a query, a shell) and picks the mitigation for that sink. This lab works one step earlier, at the decoder: what you can stop the model from emitting at all, and what you cannot. The Agent Egress Containment Lab contains where a code executor can connect; here the question is the content of the agent’s own structured reply.
The Prompt Injection Tester builds probes for your own app, and the AI Prompt Injection Incident Lab is the response after a leak. For slow, multi-turn steering see the Crescendo Attack Lab, and for who may approve a risky action see the Agent Step-Up Approval Lab.
Frequently asked questions
What is constrained decoding?
It is a way of making a language model produce only outputs that fit a grammar or schema. At each step the runtime masks the tokens that would break the rules, so the result parses. The Outlines paper describes guiding generation with regular expressions and context-free grammars, and the llama.cpp guide describes GBNF grammars used to force valid JSON. It is a statement about structure, not about whether the content is right.
Does a JSON Schema or grammar stop prompt injection?
No. It limits which strings and shapes can be produced, so it can remove some channels, such as link or markdown syntax in a field that forbids those characters. It cannot tell that a well-formed recipient address is the wrong one, or that a legal tool choice is the wrong choice. OWASP LLM01 says it is unclear whether fool-proof prevention exists and recommends layered mitigations, including defined and validated output formats.
Is constrained output the same as OpenAI Structured Outputs or JSON mode?
Not exactly. OpenAI describes JSON mode as guaranteeing valid JSON and Structured Outputs as also guaranteeing adherence to a supplied JSON Schema. Its guide adds that Structured Outputs can still contain mistakes, that a safety refusal does not necessarily follow the schema, and that the supported schema subset has limits. Other engines, such as llama.cpp with GBNF, offer grammars with their own features.
What can a grammar never stop?
Anything that is valid under the rules. A syntactically correct field can carry sensitive data to an outside address, a plain-language instruction aimed at the reader, or a harmful value in the right type. A valid tool name can still be the wrong tool. Semantic abuse needs controls outside the model: policy checks in code, identifiers the server resolves, allow-lists, safe rendering and human approval for high-impact actions.
Why does the rendering policy matter if the output is constrained?
Because the output is displayed somewhere. OWASP LLM05 advises encoding model output for its context and using strict Content Security Policies, and warns about Markdown and JavaScript. A console that auto-fetches images or follows links from model text turns a harmless-looking string into an outbound request. Constrain the output, then render it as inert text.
Should I still validate outputs if I use a schema?
Yes. Validate in code against the same schema and against business rules, and treat refusals, empty or cut-off replies as failed steps. OWASP LLM05 advises treating the model like any other user and validating what it returns before it reaches backend functions.
How is the lab scored?
Each of the 12 decisions scores 0 to 10 and the result is your share of the maximum, with a short band that says what the score means. The debrief shows the source behind each rationale. Lines labelled PlayCISO practice are our reasoning, not a statement by a source.
Sources
All read on 4 November 2026. Lines in the feedback marked “PlayCISO practice” are our own reasoning, not a statement by any source. The scenarios are fictional. We cite primary sources, not vendor advisories, and say where a page could not be fully read.
- OWASP GenAI Security Project: LLM05:2025 Improper Output Handling (2025 list) Defines the risk as insufficient validation, sanitization and handling of model output before it reaches downstream components; advises treating the model as any other user.
- OWASP GenAI Security Project: LLM01:2025 Prompt Injection (2025 edition) Says it is unclear whether fool-proof prevention exists; lists mitigations including output validation, least privilege, human approval for high-risk actions and segregating external content.
- OpenAI API documentation: Structured model outputs (Documentation page read 4 Nov 2026) A vendor guide. It says Structured Outputs makes responses adhere to a supplied JSON Schema, and also that outputs can still contain mistakes and that a refusal need not follow the schema.
- llama.cpp project (ggml-org): GBNF Guide (Master branch on 4 Nov 2026) Project documentation for GBNF grammars that constrain model output in llama.cpp.
- Willard and Louf, arXiv: Efficient Guided Generation for Large Language Models (arXiv:2307.09702) (v4, 19 August 2023) Abstract page only. Describes guiding generation with regular expressions and context-free grammars through a finite-state-machine view.
- arXiv: XGrammar: Flexible and Efficient Structured Generation Engine for Large Language Models (arXiv:2411.15100) (arXiv 2411.15100) Abstract page only. Describes context-free-grammar constrained decoding with lower overhead.
- OWASP GenAI Security Project: LLM06:2025 Excessive Agency (2025 edition)
More security tools
The tools people use most on PlayCISO.
Catch injected instructions hiding in content your AI agent should only read.
Score your readiness against the first international standard for AI security threats.
Critical CVEs across 21 major vendors, month by month — and what the 2026 surge means.
Build an ordered ruleset, replay labelled packets and catch shadowed and any-to-any rules.
Self-assess all six Functions, from Govern to Recover, and see your weakest one.
Search 172 threat actors across Microsoft, CrowdStrike, Mandiant and community names.