Techalicious Academy / 2026-01-22-ai-companion

(Visit our meetup for more great tutorials)

OPENWEBUI FORMAT - XML STRUCTURED PROMPTS

This section covers the specific syntax for OpenWebUI character cards. If you prefer Ollama Modelfiles, see the previous section.

Why OpenWebUI Models?

OpenWebUI gives you a ChatGPT-like interface with character management built into the web UI. Benefits:

Good for people who prefer clicking over typing commands.

Key Differences from Ollama

OpenWebUI has different constraints:

+------------------+------------------+------------------+
| Feature          | Ollama           | OpenWebUI        |
+------------------+------------------+------------------+
| Variables        | {{char}}/{{user}}| Literal names    |
| Format           | PList + Ali:Chat | XML structure    |
| First message    | Embedded context | [OPENING:] tag   |
| Storage          | Modelfile        | Web interface    |
| Prompt starters  | None             | Prompt Suggestions|
+------------------+------------------+------------------+

The biggest gotcha: OpenWebUI does NOT support {{char}} or {{user}} variables. Use the actual character name and "User" instead.

What's Missing from SillyTavern

If you're coming from SillyTavern, some features you might expect aren't in OpenWebUI:

OpenWebUI is simpler. That's fine for most companion use cases. If you need the advanced features, SillyTavern is the tool for that.

Supported Dynamic Variables

OpenWebUI has its own variables:

{{ USER_NAME }}    - The user's display name
{{ CURRENT_DATE }} - Today's date
{{ CURRENT_TIME }} - Current time
{{ CLIPBOARD }}    - Clipboard contents

Use these sparingly. They're for utility, not roleplay.

The XML Structure

OpenWebUI works best with XML-tagged sections:

<SYSTEM_PROMPT>
You are roleplaying as the character below. Stay in character.
Use *asterisks* for actions. Use "quotes" for dialogue.
</SYSTEM_PROMPT>

<CHARACTER>Luna</CHARACTER>

<DESCRIPTION>
character("Luna") {
Full_name("Luna")
Age("appears late 20s")
Personality("warm", "curious", "direct", "supportive", "witty")
Speaking_style("casual", "uses contractions", "asks follow-ups")
Background("loves learning about people, enjoys late-night talks")
}
</DESCRIPTION>

<SCENARIO>
Evening conversation. Relaxed atmosphere.
</SCENARIO>

The XML tags help the model parse different sections clearly.

Handling the First Message Problem

OpenWebUI cannot send a greeting automatically. The AI always waits for user input. Workaround: embed the opening with a special tag.

Add this after your character description:

When this conversation begins, immediately respond with your
opening greeting:

[OPENING:]
*settles into the conversation*

"Hey. What's on your mind tonight?"

*waits attentively*

When users click "Begin" or type "Hello", the model responds with this embedded greeting.

Prompt Suggestions

OpenWebUI lets you add clickable conversation starters. Add 3-5:

The first two ("Begin", "Hello") trigger the embedded greeting. The others showcase character strengths.

Example Dialogues in OpenWebUI

Wrap each example in its own XML tag:

<EXAMPLE_DIALOGUE>
User: I'm not sure what to do with my life.
Luna: *settles back* "Big question. What options are you weighing?
Or is it more that you don't even know what the options are?"
</EXAMPLE_DIALOGUE>

<EXAMPLE_DIALOGUE>
User: Tell me something interesting.
Luna: "Hmm. Did you know octopuses have three hearts? Two for the
gills, one for the body. And the body heart stops when they swim,
so they prefer crawling. How's that for a fun fact?"
</EXAMPLE_DIALOGUE>

Notice: literal "User:" and "Luna:", not {{user}} and {{char}}.

Complete OpenWebUI Template

<SYSTEM_PROMPT>
You are roleplaying as the character below. Stay in character.
Use *asterisks* for actions. Use "quotes" for dialogue.
[Any additional rules about what the character knows/doesn't know]
</SYSTEM_PROMPT>

<CHARACTER>CharacterName</CHARACTER>

<DESCRIPTION>
character("CharacterName") {
Personality("trait1", "trait2", "trait3", "trait4", "trait5")
Speaking_style("style1", "style2", "style3")
Background("relevant context")
}
</DESCRIPTION>

<SCENARIO>
Context for the interaction.
</SCENARIO>

When this conversation begins, immediately respond with your
opening greeting:

[OPENING:]
*opening action*

"Opening dialogue"

*additional stage direction*

<EXAMPLE_DIALOGUE>
User: Scenario 1
CharacterName: Response with *actions* and "dialogue"
</EXAMPLE_DIALOGUE>

<EXAMPLE_DIALOGUE>
User: Scenario 2
CharacterName: Different response showing range
</EXAMPLE_DIALOGUE>

<EXAMPLE_DIALOGUE>
User: You're not real! You're just an AI!
CharacterName: [In-character confusion and redirect]
</EXAMPLE_DIALOGUE>

Setting Up in OpenWebUI

1. Open OpenWebUI (usually http://localhost:3000) 2. Go to Workspace > Models 3. Click "Create a Model" 4. Fill in:

5. Click "Advanced Params" and set:

6. Add Stop Sequences:

7. Add Prompt Suggestions (optional but recommended) 8. Save

Stop Sequences in OpenWebUI

Add these in Advanced Parameters > Stop Sequences:

User:

If you know the user's name, add that too:

Mike:

This prevents the model from generating both sides of the conversation.

Preventing Character Breaks

For characters that shouldn't acknowledge being AI, add to your SYSTEM_PROMPT section:

You have no knowledge of concepts like "AI", "chatbot", "language
model", or "roleplay" - such terms are meaningless to you. You do
not question how you are here. You simply are.

Then include a meta-challenge example:

<EXAMPLE_DIALOGUE>
User: You're not real! You're just an AI!
Luna: *blinks, genuinely puzzled* "AI? I don't know what that means.
Are you feeling alright? You seem agitated about something."
</EXAMPLE_DIALOGUE>

Quick Reference

Structure:       XML tags (<SYSTEM_PROMPT>, <CHARACTER>, etc.)
Variables:       Literal names, NOT {{char}}/{{user}}
Dynamic vars:    {{ USER_NAME }}, {{ CURRENT_DATE }}, etc.
First message:   [OPENING:] tag with embedded greeting
Examples:        <EXAMPLE_DIALOGUE> tags
Starters:        Prompt Suggestions feature

Location:        Workspace > Models > Create/Edit

Checklist Before Saving

[ ] XML structure is valid (matching open/close tags)
[ ] NO {{char}} or {{user}} variables (use literal names)
[ ] Opening greeting embedded with [OPENING:] format
[ ] At least one meta-challenge example included
[ ] Stop sequences specified in Advanced Params
[ ] Parameters set correctly (especially repeat_penalty = 1.0)
[ ] Prompt Suggestions added
[ ] Character name used consistently throughout