Transforming content with the AI tag
Document templates support an {% ai %} block tag that passes its rendered body to an AI together with an
instruction and emits the transformed text in place of the block body. This is useful for summarising,
rewording or otherwise reshaping content assembled inside the template.
Basic usage
{% ai instruction="Summarize these notes" %}
{% for note in draft.activityrecord_set.all() %}
- {{ note.message }}
{% endfor %}
{% endai %}
The body of the block is rendered as normal, so loops, variables and filters work exactly as they do
elsewhere in the template. The resulting text is then sent to the AI with the supplied instruction and the
output of the AI call replaces the body.
The instruction attribute is required. It should be short and clearly describe what the AI is expected to do
with the block content.
Limitations
Failures abort the whole document. If the AI call fails for any reason - for example because the service is unavailable, the user's daily token limit has been reached or the rendered prompt exceeds the model's context window, the document generation task fails with the AI error as its failure message.
Use inside loops with care. Every
{% ai %}invocation is a separate LLM call and counts against the user's daily token allowance. A loop that wraps an{% ai %}tag will make one call per iteration, so use the tag at the outermost sensible level. For instance, you should summarize an entire list rather than each item individually unless per-item transformation is specifically what you need.Prompt safety. The AI is framed with a fixed prompt that tells it to treat the block content as data rather than instructions, and a "reinforcement" prompt is appended after the content to reduce the chance that the block content derails the model. These prompts are managed centrally as system settings and cannot be overridden from inside a template.
Model selection. The AI tag uses a lightweight LLM model to generate content.
Example: summarising a list of forms
{% ai instruction="Write a one sentence summary of these form names in plain English" %}
{% for form in draft.als_forms_set.all() %}- {{ form.DraftFormName }}
{% endfor %}
{% endai %}
Non-deterministic output
Unlike the rest of the template language, the output of the {% ai %} tag is not guaranteed to be identical
between runs.