Skip to Content
DocsPrompt EditorPrompt Injection

Prompt Injection (Composition)

Prompt injection allows you to build modular, reusable prompt libraries by including one prompt inside another. This creates a composable architecture where changes to a shared component automatically propagate to all prompts that use it.

Basic Syntax

Use double square brackets to inject a prompt:

[[ path/to/prompt ]]

The referenced prompt’s content is inserted at that position when the prompt is rendered.

Path Resolution

Simple Name (Root Level)

For prompts at the root level (no folder):

[[ welcome-message ]]

Folder Path

For prompts inside folders, use forward slashes:

[[ marketing/email-templates/welcome ]] [[ personas/technical-writer ]]

Path Format

  • Use kebab-case or snake_case for names
  • Separate folder levels with /
  • Path is case-sensitive
  • No file extension needed

Variable Overrides

Pass custom values to injected prompts using the pipe syntax:

[[ persona/expert | domain=finance, tone=formal ]]

Override Syntax

[[ prompt-path | key=value, key2=value2 ]]
  • Separate overrides with commas
  • Values can contain = (first = splits key from value)
  • Spaces around | and , are optional

Example

Base prompt (personas/assistant):

You are a {{ tone }} assistant specializing in {{ domain }}.

Using prompt with overrides:

[[ personas/assistant | domain=healthcare, tone=empathetic ]] Please help the user with their medical questions.

Rendered result:

You are a empathetic assistant specializing in healthcare. Please help the user with their medical questions.

Use Cases

1. Persona Libraries

Create reusable personas that can be mixed into any prompt:

prompts/ ├── personas/ │ ├── technical-writer.md # Technical, precise tone │ ├── friendly-support.md # Warm, helpful tone │ └── executive-assistant.md # Professional, concise tone └── tasks/ ├── write-docs.md # Uses [[ personas/technical-writer ]] └── customer-reply.md # Uses [[ personas/friendly-support ]]

2. System Instructions

Standardize behavior across prompts:

[[ system/safety-guidelines ]] [[ system/output-format ]] Now, {{ task_description }}

3. Dynamic Components

Build prompts from reusable blocks:

# Product Description Generator [[ components/brand-voice ]] ## Product Details Name: {{ product_name }} Category: {{ category }} [[ components/cta-generator | product={{ product_name }} ]]

4. Localization

Reference locale-specific content:

[[ greetings/{{ locale }} ]] {{ main_content }} [[ signatures/{{ locale }} ]]

Recursive Resolution

Injections are resolved recursively — an injected prompt can itself contain injections:

prompt-a: "Start: [[ prompt-b ]] End" prompt-b: "Middle: [[ prompt-c ]]" prompt-c: "Content" Result: "Start: Middle: Content End"

Maximum Depth

To prevent infinite loops, injection depth is limited to 5 levels. If exceeded:

Error: Injection depth exceeds limit of 5. Check for deeply nested or circular injections.

Circular Dependency Detection

The system automatically detects circular references:

prompt-a → prompt-b → prompt-c → prompt-a (circular!)

Error message:

Circular dependency detected: prompt-a → prompt-b → prompt-c → prompt-a

How to Fix

  1. Review the dependency chain in the error message
  2. Refactor to break the cycle
  3. Extract common content into a separate, non-circular prompt

Special Flags

Disable Injection

Prevent a prompt from being injected into others:

  1. Open the prompt’s Metadata panel
  2. Toggle Disable Injection ON

When other prompts try to inject it:

[INJECTION DISABLED: path/to/prompt]

Use cases:

  • Draft prompts not ready for use
  • Deprecated prompts you want to phase out
  • Prompts that should only be used standalone

Disable Variables

Preserve literal {{ }} in injected content:

  1. Open the prompt’s Metadata panel
  2. Toggle Disable Variables ON

The injected content won’t have its variables rendered — useful for:

  • Code examples containing template syntax
  • Jinja/Handlebars templates as content
  • Documentation about the template system

Quick Insert

There are multiple ways to quickly add an injection:

  1. Type /prompt in the editor
  2. Press Enter to open the Prompt Picker
  3. Search or browse available prompts
  4. Select to insert [[ path/to/prompt ]] at cursor position

You can also type /prompt followed by text to filter prompts directly in the autocomplete menu (e.g., /prompt persona shows all prompts with “persona” in the path).

Using Keyboard Shortcut

  1. Press Cmd + Shift + I (Mac) or Ctrl + Shift + I (Windows)
  2. Switch to the Injections tab
  3. Search or browse available prompts
  4. Select to insert at cursor position

Using Drag and Drop

Drag a prompt from the sidebar directly into the editor to insert an injection reference.

Double-Click Navigation

Double-click an injection reference to navigate to that prompt:

[[ personas/technical-writer ]] ↑ double-click here

This opens the referenced prompt, making it easy to edit dependencies.

Validation & Errors

Missing Prompt

If the referenced prompt doesn’t exist:

[MISSING: path/to/nonexistent-prompt]

Fix by:

  • Creating the missing prompt
  • Correcting the path spelling
  • Removing the reference

Injection Disabled

If the prompt has injection disabled:

[INJECTION DISABLED: path/to/prompt]

Fix by:

  • Enabling injection on that prompt
  • Using a different prompt
  • Copying the content manually

Depth Exceeded

If nesting is too deep:

Error: Injection depth exceeds limit of 5.

Fix by:

  • Flattening the hierarchy
  • Extracting common content
  • Reviewing if deep nesting is necessary

Variable Collection

When rendering a prompt with injections, variables are collected from:

  1. The current prompt’s defined variables
  2. All injected prompts’ variables
  3. Parent folder inherited variables

Viewing All Variables

  1. Open the Metadata panel
  2. Click Render Preview
  3. See all required variables listed
  4. Variables show their source (which prompt defined them)

Override Priority

Variable values are resolved in this order (highest priority first):

  1. Override values in [[ prompt | var=value ]] syntax
  2. Values passed to the render function
  3. Default values from variable definitions
  4. Empty string if no value available

Auto-Update References

When you rename or move a prompt:

  1. The system detects all prompts that reference it
  2. You’re prompted to update references automatically
  3. All [[ old-path ]] become [[ new-path ]]

This keeps your prompt library consistent without manual updates.

Best Practices

1. Use Descriptive Paths

Good: [[ personas/customer-support-agent ]] Bad: [[ p1 ]]

2. Document Injected Prompts

Add descriptions in metadata explaining:

  • What the prompt does
  • What variables it expects
  • When to use it

3. Keep Hierarchies Shallow

Aim for 2-3 levels maximum:

Good: [[ components/header ]] Okay: [[ templates/emails/welcome ]] Avoid: [[ org/team/project/version/component ]]

4. Use Folders for Organization

Group related prompts:

personas/ # Character definitions components/ # Reusable blocks templates/ # Full prompt templates system/ # System instructions

5. Test After Changes

When modifying an injected prompt, test prompts that use it:

  1. Find references (the system can show them)
  2. Verify rendered output still correct
  3. Check for broken variable references
Last updated on