Skip to main content

Placeholders

A placeholder is a switch inside your prompt: one named slot, a few named blocks of instructions, and the caller picks which block goes there.

Placeholders let one prompt behave differently for different customers, roles or workflows without copying it. The instruction blocks live in Genum, are versioned with the prompt, and are tested like the rest of it. The caller only picks one by name.

Placeholders replace Context Memory. If you used memory keys, see Migrating from Memory.


How a Placeholder Works

Put {{key}} anywhere in the prompt text:

# Role
You are a support assistant for our online store.

{{tone}}

# Task
Answer the customer's question about their order.

Then define the placeholder in the prompt's Placeholders tab:

PartExampleNotes
KeytoneLetters, digits and underscores, up to 64 characters. It is exactly what goes between {{ and }}.
Description"How formal the answer is"Optional note for authors. Never sent to the model.
Valuesformal, friendlyEach value has a name and a content block, the text that replaces {{tone}}. The content may be empty.
DefaultformalOptional. At most one value per placeholder can be the default.

A caller never sends the text of a block, only the name of a value. Everything the model reads stays in Genum, where it is committed and tested.


How the Value Is Chosen

At run time, Genum fills each {{key}} in the text as follows:

  1. It uses the value the caller selected by name.
  2. If nothing was selected, it uses the default value.
  3. If there is no default either, it replaces {{key}} with nothing.

A few rules follow from this:

  • Every occurrence of {{key}} is replaced, not only the first.
  • Substitution is positional. A block is inserted only where its {{key}} appears. If you remove {{tone}} from the text, selecting a tone value has no effect.
  • A {{key}} that no placeholder defines is left in the text as written, so the model sees the literal {{key}}. Genum flags it so you can define it.
  • A selection for a key that does not appear in the text, or naming a value that does not exist, is ignored and reported back to the caller. An unknown value name falls back to the default.

In the Playground

  • The Placeholders tab lists the prompt's placeholders. Select one to see and edit its values, each with its own editor for the instruction block.
  • Under the prompt editor, every placeholder found in the text is shown as a chip. Use it to choose the value the next Playground run uses.

Versioning

Placeholders are part of a prompt version. Committing a prompt saves its placeholders and their values together with the text. Productive runs, the default for API calls, use the committed placeholders, not the ones you are currently editing.

Editing an instruction block therefore reaches production only after you commit, exactly like editing the prompt text. The version history shows the placeholders each version was committed with.

See more on versioning


Testing

A test case stores the value it uses for each placeholder and always runs with exactly those values, so every variant of a prompt can have its own regression tests. The test case table shows each test case's selection in the Placeholders column.

Test cases created from a log keep the placeholder values of that run.

Deleting a placeholder or one of its values removes that selection from the test cases that used it. The test cases themselves are kept.

See more on testing


Using Placeholders Through the API

Select values by name when you run a prompt:

{
"id": 123,
"question": "Where is my order?",
"placeholders": { "tone": "friendly" }
}

The response tells you what was applied:

"placeholders": {
"resolved": { "tone": "friendly" },
"ignored": []
}
  • resolved maps every key found in the text to the name of the value that was used, or null if none was.
  • ignored lists the keys you sent that were not applied.

The API can also:

  • Render a prompt, returning the final instruction with placeholders filled in, without running it.
  • Create a prompt together with its placeholders and values.

Both are described in the Native API Integration guide.


Migrating from Memory

Context Memory has been replaced by placeholders, and existing memory keys were converted automatically:

  • Every prompt that had memory keys now has a placeholder named memory_key. Each former memory key is one of its values: the key became the value name, and the memory text became its content.
  • No value is marked as default, so a run that selects nothing adds nothing, as before.
  • Test cases that used a memory key now use the matching memory_key value.
  • Memory was always appended at the end of the prompt. To keep that behaviour, {{memory_key}} was added at the end of each affected prompt's draft, and the prompt was marked as uncommitted. You can move it anywhere in the text.
Commit affected prompts

Committed versions were not changed. Until you commit the updated draft, productive runs of an affected prompt use its previous version, which contains no {{memory_key}}, so no memory block is added to them. Review the draft, run your tests and commit it to restore the memory behaviour in production.

The API still accepts memoryKey on a run. It is deprecated and equivalent to "placeholders": { "memory_key": "..." }. If a request sends both, placeholders.memory_key wins.


Integration Options

Placeholders can be used with Genum's integration options:

  • Native API Integration: select values with placeholders, render and create prompts
  • n8n Custom Nodes: select a value of the memory_key placeholder with the node's memoryKey field
  • OpenTelemetry: record which values your own agent used, so a replay uses the same ones