Est.

Ambiguous Delimiters and Format Collisions in Prompt Templates

Mismatched delimiters in prompts create security vulnerabilities attackers can exploit.

Columnist · · 12 min read
Cover illustration for “Ambiguous Delimiters and Format Collisions in Prompt Templates”
Prompt Failure Patterns · September 18, 2026 · 12 min read · 2,731 words

How format collisions happen in practice

Pick one delimiter style and use it everywhere in a prompt. XML tags, JSON, markdown headers, whatever the model was trained on. That's the rule that stops most of this, and it's almost embarrassingly simple. Mixing styles creates the ambiguity, and it's not a theoretical worry: smaller models getting confused when XML, JSON, and markdown all appear in the same prompt at once is a documented production pattern. That mixing problem occurs in production models today, not in some edge-case benchmark nobody will ever hit.

Providers have converged on different conventions, and breaking those conventions costs a prompt the exact structural signal the model was trained to recognize. Anthropic recommends <context>, <example>, and <thinking> tags for Claude Opus 4.7. Adding JSON blocks and markdown bullets to that same prompt disrupts the structural conventions the model was trained to follow. On the tool-call side, the provider-recommended path for a flagship model is a request-time schema, response_format={"type": "json_schema", "json_schema": {...}}, which gives the model a structured target to fill rather than a paragraph to interpret. Prose instructions work until they don't, and they fail exactly on the edge cases nobody bothered to test.

Three small, reasonable-looking edits break format contracts more often than any dramatic rewrite does. Placing user input right next to system policy with no boundary between them is the first: the model has no way to know the user's text is data rather than command, so untrusted content gets read as instruction. Renaming a variable like policy_excerpt without running it through eval coverage is the second. Nothing crashes. The compiled prompt just quietly loses its grounding context, and nobody notices until answers start drifting for reasons no one can name. Treating few-shot examples as harmless padding is the third, and it's the one teams underestimate most: examples set hidden format expectations, and an example formatted one way can override an explicit output rule stated later in the same prompt.

FutureAGI's 2026 pattern guide also flags a "lost in the middle" effect: hard rules buried in the center of a long prompt get dropped far more often than the same rules pinned to the top or the bottom. It's a format decision with a direct effect on whether the model follows the rule at all, and it costs nothing to fix once a team knows where to look.

Put those three edits together and ambiguous boundaries appear between sections of a prompt. Ambiguous boundaries used to be a quality risk. Now they're an opening.

Chat template injection: ambiguous delimiters as an attack surface

Agents lean on chat-template tokens, the structural markers that separate a system turn from a user turn from a tool result, to keep the serialized context coherent. When a tool's output or a retrieved document contains the same delimiter tokens the chat template itself uses, the model cannot reliably distinguish which one governs the current turn. That confusion is the exact mechanism behind ChatInject, an attack presented at ICLR 2026 by researchers at Chung-Ang University, and it's a sharper problem than most teams give it credit for.

ChatInject skips persuasive language entirely; it does not inject text that tries to talk a model into misbehaving. It forges structure instead. The attack formats a malicious payload to look like a native chat template, injecting tokens such as <|user|> and <|assistant|> to build a fabricated dialogue history, what the researchers call a "ghost history." That fake history triggers role confusion, and the model ends up convinced a conversation happened that never did.

The numbers make the gap between old-style injection and template-forging injection hard to wave away. On the AgentDojo benchmark, attack success rate rose from 5.18% for traditional prompt injection to 32.05% for ChatInject. On InjecAgent, it went from 15.13% to 45.90%, and a multi-turn variant of the attack hit a 52.33% average success rate on that same benchmark. Same agents, same tasks. The attacker mimicked the chat template's own structural markers.

A separate benchmark called ASPI, built by Scale AI and collaborators across 728 task-attack scenarios, found something worse: agents get far more vulnerable the moment they ask a clarifying question. The mechanism tracks. When an agent asks for more input to resolve ambiguity, it opens a channel it explicitly invited, and it expects that channel to carry task-relevant information. The line between instruction and data collapses right there, because the agent asked for it. Attack success rose from 1.8% to 34.0% for o3, from 2.2% to 35.7% for Gemini-3-Flash, and from 11.1% to 63.1% for Kimi K2.5, once the interaction moved from a fully specified task into a clarification loop. Robustness measured under clean, fully specified conditions tells you almost nothing about robustness under ambiguity, and standard execution-time security testing underestimates the real attack surface by a wide margin.

The instruction hierarchy defense proposed by Wallace and colleagues in 2024 tries to fix this by ranking trust across roles: system above user above tool output. ChatInject cuts underneath that defense. If an attacker can forge the role labels themselves, the hierarchy has nothing left to enforce. Most earlier injection research treated LLM input as plain text and missed this. Modern inputs are structured, role-tagged, and delimiter-dependent, and that structure is what an attacker can counterfeit.

The attacker running ChatInject and the engineer who renamed a variable without eval coverage are exploiting the identical weakness: the model has no ground truth about which section of the prompt it's actually reading. Neither failure gets fixed by making the model smarter. Both get fixed in the harness, and nowhere else.

Why the failure stays hidden: fluent output masking structural misparse

Format-collision failures don't announce themselves. The model still returns something coherent, so a human skimming the output, or a pass/fail test checking for a crash, sees nothing wrong. That's what makes this failure class hard to catch: the visible surface is clean, while the structure itself produces the damage.

The symptoms that trace back to format problems look like ordinary bugs on the surface. Invalid JSON where the prompt promised a schema. Tool calls carrying the wrong argument shape. Answers that flatly ignore retrieved context, a groundedness failure that reads like the model just didn't bother reading the document. Instruction text leaking into the visible response. The same request producing noticeably different answers for different users even though nothing about the underlying prompt should differ between them.

In a multi-step agent, the damage compounds quietly. A misparse at the planner stage doesn't fail loudly right there, it sends the wrong objective downstream, and the failure only becomes visible several steps later, once an action stops making sense given everything that came before it. A case study on AgenTracer-8B, cited in a survey out of TU Munich, traced a failure back to Step 2 of an agent run, where a Web Surfer sub-agent retrieved the wrong file. Nobody could actually see the problem until Step 11, nine steps later, once the evidence finally piled up enough to be legible. The error started early and hid behind a run of intermediate outputs that all looked fine on their own.

Attribution mistakes compound this in production monitoring, too, and this is where teams get lazy. A two-year postmortem at a major retailer found a persistent attribution error rate hovering around 10%, where the model blamed a given technology simply because it happened to get mentioned somewhere in the incident thread rather than because it caused anything. Guilt by association, baked into an automated postmortem pipeline, running at scale, unnoticed for two years.

Testing only the final response misses all of this. Planner failures and tool-selection failures happen upstream of that final answer, and if eval coverage stops at the last message in the transcript, none of it gets caught before shipping. Catching this failure class means looking at the compiled prompt at every layer, comparing prompt versions against the same trace cohort, and treating parser telemetry, retries, and repair attempts as real signals instead of background noise to filter out.

Diagram: Template-Forging vs. Traditional Injection: Attack Success Rates. Visualizes: Show the dramatic jump in attack success rates when moving from traditional prompt injection to ChatInject (template-forging injection) across two benchmarks.

Signals that surface format collisions in production traces

Retries, fallback responses, and repair prompts are usually the first hint that something's wrong with the format contract, well before anyone notices a drop in output quality. The What Is LLM Prompt Format? FutureAGI Guide (2026) treats these as format-failure indicators specifically, and that distinction changes how a team triages an incident.

One diagnostic separates format defects from model defects cleanly: compare prompt versions against the same cohort. If version 14 of a prompt fails across every model it's tested on, and version 13 passes on that identical cohort, the format itself changed the contract, full stop. If both versions fail only on the longest retrieved contexts, the problem sits somewhere else entirely, most likely context-window pressure or weak retrieval, and rewriting the prompt's layout won't touch it.

A handful of trace-level metrics do most of the diagnostic work. Prompt adherence checks whether the model actually followed the role, tone, and constraints encoded in the prompt. Schema validation failure rate catches the case where a schema was promised and the response can't be parsed against it. Parse-error and retry rate exposes how much downstream code is quietly compensating for ambiguous output instructions. Token count at the prompt level flags bloated formats and duplicated examples before the resulting cost or latency creep shows up at scale. Eval-fail-rate broken out by prompt version lets a team run the same labeled dataset against two different formats and see, directly, which one caused the regression.

Automated diagnosis has its own blind spot. A framework called Continual Search found that as execution logs grow longer, LLM judges settle on a plausible-sounding root cause well before they've worked through all the evidence. The fix is successive-turn probing, which forces the judge to keep digging instead of anchoring on the first explanation that fits. Left alone, the judge picks a convenient answer and stops.

Calibration benchmarks exist now for teams that want a reference point instead of a guess. TRAIL, TELBench, AgentRx, Who&When, and Who&When Pro together cover large numbers of labeled trajectories across different agent frameworks, with Who&When Pro alone comprising more than 12,000, giving teams something to measure their own attribution tooling against instead of trusting it blind. Separately, ICSE 2025 research on code-augmented root cause localization found a 28.3% improvement in localization accuracy over prior leading methods, simply by incorporating code knowledge alongside the trace. Giving the diagnosis tool the code's own vocabulary makes it much better at pointing to the right layer.

Attributing the failure to the right harness layer

Knowing a run failed tells you nothing useful. Identifying which layer of the harness caused the failure determines the fix, because the harness is several distinct layers stacked on top of each other, and each one can independently produce the exact same visible symptom.

The prompt layer covers mixed delimiter styles, instructions given out of order, hard rules buried where the model is statistically likely to drop them, and few-shot examples quietly overriding a schema stated later. The tool layer covers something adjacent but different: tool descriptions carrying embedded instructions of their own (a tool-poisoning pattern), tool output that happens to contain the same delimiter tokens as the chat template, or schema drift, where a third-party API changed shape and the CI test mock kept returning the old format anyway. The workflow layer is where planner prompts fail to separate a user's actual goal from tool policy, so downstream steps inherit the wrong objective, or where artifacts loop between agents with no cycle detector to catch it. The memory layer covers context injected at invocation time overwriting the delimiter structure the base prompt relies on, since working memory, episodic memory, and long-term memory often get folded into the same system prompt, and any one of them can collide with conventions the others assume.

Recovery strategy depends on getting this attribution right, and most teams get it backward: they patch the visible symptom and call the incident closed. Decoupled self-correction patches the failure surface, a retry here, a JSON fixer there, without any grounded diagnosis of where the error actually started. It works fine when the error really is local. It fails, reliably and repeatedly, when the true cause sits several steps upstream, because the patch never touches the thing that's actually broken. Closed-loop recovery grounds the repair in an attributed root cause instead, and closed-loop recovery has been shown to repair substantially more failed tasks in a single rerun compared to decoupled self-correction baselines. That gap is not marginal, and it's why attribution has to come before repair, not after.

Teams that only patch the output layer, adding a repair prompt or a retry loop without ever tracing back to whichever layer actually broke, are running decoupled self-correction whether they call it that or not. They're shipping blind. The layered harness model terramosaic.org makes the requirement explicit: teams can usually tell whether a break lives in the prompt, the context, the skill, the harness, or the loop, but only when those layers stay structurally separate and observable in the trace. Collapse the layers together and attribution stops being solvable by inspection.

Fixing format collisions at the harness level before shipping

The single highest-leverage fix is the consistency rule from earlier, applied without exception: one delimiter style, end to end, for a given model. XML for Claude Opus 4.7, a JSON schema for GPT-5 tool calls, markdown for everything that doesn't need machine parsing. Mixing styles is what creates the ambiguity in the first place, so the fix is simple, just consistent, and the teams that skip it because it sounds too obvious are the ones debugging it three months later at 2am.

Explicit schemas beat prose descriptions every time an edge case shows up. Telling a model in a sentence to "respond in JSON" works most of the time and fails exactly when it matters most. A request-time JSON schema is a hard contract the model has to satisfy, not a polite suggestion buried in a paragraph, and every major provider now recommends the schema-first path for that reason.

Constraint placement is a fix, not just a diagnostic. Hard rules belong at the top of the prompt or in the system message, never buried in the middle, because mid-prompt placement measurably raises the rate at which a model drops the rule. That's a structural decision, and it costs nothing to implement once a team knows to check for it.

Boundary enforcement around untrusted content does double duty. Keeping user input and tool output behind clear, unambiguous delimiters is a quality fix, since it stops the model from confusing data for instruction, and it's also the primary defense against ChatInject-style attacks, since a forged role tag has nowhere to hide if the real boundaries are unambiguous to begin with.

A Determinism-Faithfulness Assurance Harness, or DFAH, gives teams a way to verify a fix actually holds before it ships. A Task Runner executes the flow under controlled randomness and records the full transcript. A Trajectory Store persists every tool call, argument, and result so the run can be replayed later. A Grader Suite then applies code-based graders (schema validation, tool call verification), model-based graders (faithfulness checks), and human audit sampling on top of that. Replay is what turns "it seemed to work" into something a team can actually stand behind under scrutiny.

Version comparison decides whether a fix ships. Running the repaired format against the same labeled cohort that surfaced the original failure decides the outcome: if the new version pushes the JSON failure rate above an explicit threshold (FutureAGI's own guide uses 2% as the block point), the team stops the release and goes back into the schema rather than ship something that regresses quietly. That threshold discipline is the same rigor code review and regression testing apply to application logic, aimed here at a prompt's layout contract instead.

None of this holds together without tooling that keeps prompt version labels attached to trace data, so a team can pull up v13 next to v14 against the same cohort and see the difference directly, instead of guessing from memory. Platforms built to ingest production traces and attribute a given failure to a specific harness layer, prompt, tool, workflow, or memory, before recommending a fix, are what turns this from a manual forensic exercise into something closer to a repeatable engineering discipline.

Sources

  1. What Is LLM Prompt Format? FutureAGI Guide (2026)
  2. ASPI: Seeking Ambiguity Clarification Amplifies Prompt Injection Vulnerability in LLM Agents
  3. LLM Prompt Format 2026: 9 Patterns for GPT-5, Claude, Gemini
  4. ChatInject: Abusing Chat Templates for Prompt Injection in LLM Agents
  5. augmentcode.com
  6. lilianweng.github.io

More in Prompt Failure Patterns