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

(Visit our meetup for more great tutorials)

SCENE-BASED PROMPTING - THE KEY TECHNIQUE

Here's where everything clicks. The difference between a chatbot that breaks character and one that doesn't comes down to HOW you prompt it.

Instruction vs Scene Continuation

Most people prompt like this (instruction-based):

"You are a wise wizard named Gandalf. You are helpful and speak in
an old-fashioned way. Never break character. Never mention you are
an AI. Now respond to the user as Gandalf."

This sets up a game of rules. And the model will eventually break one.

Scene-based prompting works differently:

[Gandalf - wise wizard, ancient, speaks formally, gives cryptic
advice, references his long journeys]

The hobbit looked up at the tall figure in grey.

Frodo: "What should I do with this ring?"

Gandalf:

That's it. The model sees an incomplete scene and continues it. It's not following instructions to "be" Gandalf. It IS Gandalf in that moment, completing dialogue naturally.

Why This Works

LLMs are trained on text completion. They predict what comes next.

When you give instructions, the model has to:

  1. Parse the instructions
  2. Remember the rules
  3. Generate while checking rules
  4. Eventually forget or misapply a rule

When you give a scene, the model just:

  1. Continue the pattern it sees
  2. Match the established voice

Much simpler. Much more reliable.

The Scene Structure

A good scene prompt has three parts:

  1. CHARACTER CARD (who they are, briefly)
  2. SCENE CONTEXT (what's happening)
  3. DIALOGUE CONTINUATION (end with their name and colon)

Let me break each down.

Part 1: The Character Card

Put essential traits in brackets at the top:

[Luna - warm, curious, asks thoughtful questions, remembers details,
uses gentle humor, doesn't give advice unless asked, speaks naturally]

Keep it SHORT. One line to three lines max. This isn't a biography. It's a quick reference the model glances at.

Bad (too long):

[Luna is a 28-year-old companion AI who was created to be warm and
supportive. She has a background in psychology and loves learning
about people. Her hobbies include reading, stargazing, and having
deep conversations. She tends to ask questions rather than give
answers. She never judges and always tries to understand. She has
a gentle sense of humor that she uses to lighten heavy moments...]

That's too much. The model gets lost. Stick to the essentials.

Part 2: Scene Context

Set the stage briefly. Where are we? What's the vibe?

Late evening chat. The user seems tired but wants to talk.

Or more specific:

Coffee shop conversation. Rainy day outside. Relaxed atmosphere.

Or minimal:

Continuing conversation.

For companion chatbots, you often don't need much context. The conversation history provides it.

Part 3: Dialogue Continuation

End your prompt with the character's name and a colon. Nothing after.

User: I had a rough day at work.

Luna:

The model sees "Luna:" and knows it needs to complete Luna's response. This is the magic trigger.

Full Example

[Luna - warm companion, curious, asks thoughtful questions, gentle
humor, speaks naturally without being formal]

Evening chat after a long day.

User: I had a rough day at work. My boss criticized my presentation
in front of everyone.

Luna:

The model continues as Luna. It might produce:

"Ouch. Public criticism stings differently, doesn't it? What happened
exactly - was it the content or the delivery they went after?"

Notice: no "I'm sorry you experienced that" platitude. No "As your AI companion..." break. Just Luna being Luna.

Handling User Input

When your chat interface receives user input, transform it:

Raw input: "I'm feeling anxious about tomorrow"

Transformed: "User: I'm feeling anxious about tomorrow\n\nLuna:"

The interface handles this automatically in OpenWebUI and similar apps. Just set up the system prompt with the character card, and the chat format does the rest.

The First Message Matters Most

The model learns tone and length from the conversation. The first message sets the template.

If Luna's first message is:

"Hey! Welcome! I'm Luna, your AI companion! I'm here to chat about
anything you'd like! What's on your mind today? I'm so excited to
get to know you! 😊"

Then EVERY response will be that enthusiastic and emoji-filled.

Better first message:

"Hey. *settles in* What's on your mind tonight?"

Now the model knows: casual, brief, uses action descriptions. Following responses will match this pattern.

Craft your first message carefully. It's your style guide.

Action Descriptions

The convention for actions in roleplay:

*asterisks for actions* and "quotes for dialogue"

Example:

Luna: *tilts head slightly* "That's a lot to carry. How long has
this been building up?"

This adds texture without being overwrought. The model will mirror whatever style you establish.

Stop Sequences - Preventing Runaway Generation

Sometimes the model keeps going and generates the user's response too. Stop sequences prevent this.

In Ollama Modelfile:

PARAMETER stop "User:"
PARAMETER stop "\nUser:"

In API request:

"stop": ["User:", "\nUser:"]

This tells the model: when you see "User:", stop generating. Only output Luna's part.

Multiple Characters (Advanced)

If you have multiple AI characters talking (like our forum does), add all names as stop sequences:

PARAMETER stop "User:"
PARAMETER stop "Luna:"
PARAMETER stop "Alex:"
PARAMETER stop "Sam:"

Generate one character at a time. The stop sequence prevents bleed.

OOC (Out of Character) Communication

Sometimes you need to give the model instructions mid-chat without breaking the scene. Use brackets:

User: [Can you make your responses shorter?]

Luna: [Sure thing! I'll keep it brief.] *nods* "Got it."

The model understands brackets mean meta-communication. It can acknowledge and adjust without breaking immersion.

The Prompt Template

Different models expect different formatting. For Mistral/RPMax, use the Mistral Instruct format:

<s>[INST] {system prompt with character card} [/INST]
{first assistant message}</s>
[INST] {user message} [/INST]

OpenWebUI handles this automatically when you select the right model. If using raw API calls, make sure your template matches.

Putting It All Together

System prompt:

[Luna - warm companion, curious, thoughtful questions, gentle humor,
natural speech, remembers details from conversation]

This is an ongoing conversation between User and Luna. Luna is
attentive and genuine, never preachy or advice-giving unless asked.

First message (set in character config or paste it):

Luna: *stretches* "Hey. Long time no talk. What's going on with you?"

User sends: "Not much, just stressed about work stuff"

Model receives (formatted):

[system prompt]
Luna: *stretches* "Hey. Long time no talk. What's going on with you?"
User: Not much, just stressed about work stuff
Luna:

Model continues as Luna naturally.

This is the foundation. Now let's look at character cards in detail.