Skip to main content
Prompt files use Liquid.js for dynamic content. Instead of hardcoding values, you insert variables that get filled in when the prompt runs.
generate_summary@v1.prompt
When you call generateText({ prompt: 'generate_summary@v1', variables: { max_paragraphs: 2, company_data: '...' } }), Liquid replaces {{ max_paragraphs }} with 2 and {{ company_data }} with your content before the prompt is sent to the LLM. Templates render before YAML parsing, so you can template the frontmatter too — useful for dynamic model selection or configuration. The rendered body is then parsed as either plain instructions or role-tagged messages. A template that emits plain text first selects instruction mode; one that emits a tag first selects message mode. Text generation APIs require message mode, while generateImage requires instruction mode.

Variables

The double-brace syntax {{ variableName }} renders values from the variables object you pass to the generate function.
For nested objects, use dot notation:
Undefined variables and unknown filters throw a non-retryable FatalError at render time (strictVariables / strictFilters). Pass every variable the template references, and only use known Liquid filters. Validate inputs in your step before calling the LLM.

Variables containing markup

Output automatically XML-escapes body interpolations before it identifies message blocks, then decodes the value inside the resulting message or instructions. A variable containing <system>example</system> therefore remains data and cannot inject a new message:
Do not add Liquid’s escape filter for this safety behavior; it would escape a value that Output already protects. Use {% raw %}...{% endraw %} when the authored template itself must contain literal Liquid delimiters such as {{ example }}. In message mode, authored examples of the surrounding role tag must still be escaped. For example, write &lt;user&gt;example&lt;/user&gt; inside a <user> block. See Prompt Body Modes.

Conditionals

Use {% if %} to include content only when a condition is true:
With include_competitors: true, the competitor instruction is included. With false or undefined, it’s omitted entirely. Add {% else %} for alternate content:
Use {% unless %} for the inverse — it renders when the condition is falsy:

Loops

Iterate over arrays with {% for %}:
forloop.index gives you the 1-based position (1, 2, 3…). Use forloop.index0 for 0-based indexing. For arrays of objects:

Filters

Filters transform values using the pipe syntax {{ value | filter }}. Text transformations:
Arrays:
Default values:
If tone is undefined or empty, it renders as “professional”. Chaining filters:
For the full filter reference, see the Liquid.js documentation.

Templating Frontmatter

Variables work in the YAML frontmatter too. This lets you dynamically configure model settings:
Use this pattern when you need to switch models based on task complexity or cost.

Common Patterns

Optional sections based on input:
Building structured instructions from an array of rules:
Conditional system behavior:

Cheatsheet

Quick reference for the most common Liquid.js syntax.

Output

Tags

Operators

Loop Variables

String Filters

Array Filters

Other Filters

Number Filters