Skip to content

CONCEPT Cited by 2 sources

Opaque output-format fencing

Definition

Opaque output-format fencing is the prompt-engineering primitive of instructing the LLM to wrap its entire response in a pair of opaque delimiter tags — strings unlikely to appear in the output content itself — so a downstream parser can unambiguously locate the payload by find-last- delimiter / regex. The LLM may still emit prose, apologies, or explanation around the fence; the fence's contract lets the pipeline ignore everything outside.

The primitive

## System prompt constraint

You MUST return just the transformed file inside the
<updatedContent> tag like:
<updatedContent>transformed-file</updatedContent>
without any additional data.

(Zalando system prompt verbatim, sources/2025-02-19-zalando-llm-powered-migration-of-ui-component-libraries)

Slack's Enzyme-to-RTL codemod uses the same primitive with <code></code>:

"evaluate your output and make sure your converted code is between <code></code> tags." (Source: sources/2024-06-19-slack-ai-powered-conversion-from-enzyme-to-react-testing-library)

Two independent industry instances converging on the same shape.

Why "opaque" delimiters

The word opaque is load-bearing: the delimiter should be a string the target language doesn't emit. In both examples above, the tag looks like HTML but isn't valid markup in the target language (JavaScript / TypeScript don't use <updatedContent> or <code> as valid syntax), so the delimiter can't be confused with real output content.

Contrast with using Markdown code fences (```) as the delimiter: Markdown code fences commonly appear inside LLM-emitted explanation text, making the outer fence ambiguous with inner code samples.

Why it beats JSON-mode structured output

  • No schema friction. JSON-mode requires a schema and breaks on malformed JSON; a single trailing comma kills the output. Fence tags survive arbitrary inner content.
  • Output is already the target language. Returning transformed code as a JSON string field requires re-escaping newlines, quotes, and backslashes; the downstream parser has to unescape. A bare-text fence doesn't.
  • Robust to model chatter. The LLM can explain itself before / after the fence ("I've migrated the file as follows: <updatedContent>…</updatedContent> Let me know if you'd like changes!") and the parser takes the payload regardless.

Why it beats plain "return only the code"

"Return only the transformed code, no other output" doesn't survive contact with the LLM's trained tendency to emit preamble ("Here's the migrated component:"). Temperature=0 (see concepts/temperature-zero-for-deterministic-codegen) mitigates but doesn't eliminate this. The fence gives the parser a contract that doesn't depend on the model perfectly following the "no other output" instruction.

Tradeoffs

  • Token cost. The fence costs a few tokens per request; negligible.
  • Not a substitute for schema when schema is needed. If the output is structured data (lists, objects, enums), JSON-mode remains the right choice. Fencing is for single-payload outputs: one transformed file, one generated SQL query, one extracted attribute value.
  • Multi-payload outputs need multiple fences. If a single call needs to return N files, either use N fences (<file1>…</file1>, <file2>…</file2>) or switch to JSON-mode with a typed schema.

Zalando-specific context

The fence is the last line of Zalando's system prompt, following the role assertion ("You are an expert frontend software developer…") and the task description. Downstream, the parser strips the fence and writes the file. The pipeline's truncation-recovery loop ("continue" prompt; see concepts/continue-prompt-for-truncated-output) is aware of the fence: if the closing </updatedContent> is missing, the response is truncated; send "continue" and concatenate.

Seen in

Last updated · 501 distilled / 1,218 read