---
title: "Managing prompt snippets"
manual: "TYPO3 LLM Extension"
version: "0.35"
permalink: "https://docs.typo3.org/permalink/netresearch/nr-llm:administration-snippets@0.35"
source: "Administration/PromptSnippets.rst"
modified: "2026-09-16T22:09:16+00:00"
---

# Managing prompt snippets

Prompt snippets are small named prompt *fragments* —
personas, tones of voice, target audiences, image
styles, layouts — that editors manage centrally.
Consuming extensions (for example `nr_repurpose`)
query snippets by tag and compose them into their
prompts.

Snippets are deliberately **not** prompt templates:
a [prompt template](https://docs.typo3.org/permalink/netresearch/nr-llm:adr-031@0.35) is a complete,
versioned prompt with model parameters, while a
snippet is a reusable building block without any
model binding.

## Adding a snippet

1.  Navigate to **AI > Authoring >
    Snippets**.
1.  Click **New Snippet**.
1.  Fill in the fields:

    -   ****Identifier****

        Unique technical identifier (e.g.,
        `persona-friendly-expert`).

    -   ****Name****

        Display name (e.g., `Friendly Expert`).

    -   ****Tags****

        Comma-separated tags consuming extensions
        search for (see below).

    -   ****Snippet text****

        The prompt fragment itself.

    -   ****Metadata (JSON)****

        Optional JSON object with extra settings.
1.  Click **Save**.

## Tag convention

Tags are free-form, comma-separated strings. There
is no fixed vocabulary — consuming extensions agree
on tags with the editors. Matching is exact per tag
and case-insensitive: the tag `style` does *not*
match a snippet tagged `lifestyle`.

Established tags so far:

| Tag | Used for |
| --- | --- |
| `audience` | Target audience descriptions |
| `tone_of_voice` | Tone-of-voice instructions |
| `persona` | Writing/speaking personas |
| `layout` | Layout instructions (e.g. for slides) |
| `style` | Image / visual style descriptions |

Persona snippets may carry a voice hint in their
metadata so speech features can pick a matching
text-to-speech voice:

**Metadata of a persona snippet**

```json
{"voice": "nova"}
```

## Attaching snippets to a configuration

A configuration can select snippets by tag. Every
request made with that configuration then carries
them — chat, single-prompt completion, streaming and
agent runs alike — without any extension code.

1.  Navigate to **AI > Setup >
    Configurations** and edit a configuration.
1.  Open the **Parameters** tab.
1.  Tick the wanted tags under **Prompt
    snippet tags**. The list offers the tags the
    snippet records actually carry.
1.  Click **Save**.

The active snippets carrying any ticked tag are
appended to the configuration's
**System Prompt**, each as a `NAME:` block
separated by a blank line, in the order the tags are
listed. A snippet carrying two ticked tags is added
once. A tag no snippet carries adds nothing — there
is no error, matching the free-tag model above.

**Effective system prompt of a configuration with the tags `persona` and `tone_of_voice`**

```text
You are a helpful assistant.

Nova persona:
You are Nova, a friendly expert.

Formal tone:
Use a formal, professional tone of voice.
```

Two limits are worth knowing:

-   Only **active** snippets are composed; hiding a
    snippet removes it from every configuration that
    selects its tag.
-   A caller that supplies its own system message
    replaces the configuration's system prompt for
    that call, and with it the snippet block. This is
    the documented per-call precedence and predates
    this field.

## Using snippets from an extension

Query snippets by tag through the public
`PromptSnippetRepository` and compose the
selected fragments with the
`PromptSnippetComposer`:

**Composing snippets into a prompt**

```php
$audiences = $this->promptSnippetRepository
    ->findActiveByTag('audience');
$tones = $this->promptSnippetRepository
    ->findActiveByTag('tone_of_voice');

$sections = $this->promptSnippetComposer->composeSections([
    'TARGET AUDIENCE' => $audiences[0] ?? null,
    'TONE OF VOICE' => $tones[0] ?? null,
]);
```

`composeSections()` renders each non-null
snippet as a `LABEL:` block followed by the
snippet text, joined by blank lines. Null entries
and empty snippets are skipped.

`findActiveByTag()` filters on `is_active`
only — like every repository here it ignores the
enable fields, so **hidden** records are part of
its result. Configurations drop them when they
compose their prompt; an extension that queries
directly has to skip `isHidden()` snippets
itself if it wants the same behaviour.

See [ADR-031](https://docs.typo3.org/permalink/netresearch/nr-llm:adr-031@0.35) for the design
rationale.
