Giving Jarvis a Character 🎭
One extra argument turns a generic chatbot into your assistant. It is also where you set the rules that stop it confidently making things up.
Use the system prompt to set behaviour, tone and honesty rules, and keep it in a file you can edit.
about 20 minutesThe system prompt
Alongside messages there is a system argument. It is not part
of the conversation; it is standing instructions that apply to every turn.
response = client.messages.create(
model="claude-haiku-4-5",
max_tokens=1000,
system="You are Jarvis, a terse and slightly dry personal assistant. "
"Answer in at most three sentences unless asked for detail. "
"If you do not know something, say so plainly instead of guessing.",
messages=messages,
)
Add that to your chat loop and the character changes immediately. Same model, same code, different behaviour, because you told it what job it has.
What actually belongs in there
Beginners write "you are a helpful assistant" and stop, which does almost nothing. The useful contents are specific and testable:
- Who it is and who it is for. "You are Jarvis, a personal assistant running on your owner's own machine."
- How long answers should be. Genuinely the highest-impact line you can write. Models default to thorough; most personal use wants terse.
- What to do when unsure. "Say you do not know rather than guessing." This meaningfully reduces confident nonsense.
- Anything it must never claim. Especially once it has tools: "Never say you did something you were not able to do."
Vague instructions produce vague behaviour. "Be concise" is weaker than "at most three sentences unless asked for detail", because the second one is checkable.
Put the persona in a file
Hard-coding the personality means editing Python every time you want a different tone.
Put it in persona.txt instead, and read it at startup:
from pathlib import Path
DEFAULT_PERSONA = (
"You are Jarvis, a personal assistant running on your owner's own machine.\n"
"Be brief and concrete. Three sentences unless more is genuinely needed.\n"
"If you are unsure, say so rather than inventing an answer.\n"
"Never claim to have done something you were not able to do."
)
def load_persona(path="persona.txt"):
"""Read the system prompt from a file, falling back to the default.
Keeping the persona in a text file means you can edit how your
assistant behaves without touching code.
"""
p = Path(path)
if p.exists():
text = p.read_text(encoding="utf-8").strip()
if text:
return text
return DEFAULT_PERSONA
# no persona.txt in this folder yet, so we get the default
persona = load_persona("does-not-exist.txt")
print(persona.splitlines()[0])
print("lines:", len(persona.splitlines()))
You are Jarvis, a personal assistant running on your owner's own machine.
lines: 4
Now tuning your assistant is editing a text file. That matters more than it sounds: you will fiddle with this a lot, and the friction of opening a source file is enough to stop you bothering.
Telling it things it cannot know
A model has no idea what today's date is, what your name is, or which machine it is running on. It is not being coy; that information was simply never sent. If you want it to know, put it in the system prompt.
from datetime import date
def build_system_prompt(persona, user_name=None, today=None):
"""Persona plus a little live context the model cannot know on its own."""
parts = [persona]
if user_name:
parts.append(f"You are talking to {user_name}.")
if today:
parts.append(f"Today's date is {today.isoformat()}.")
return "\n\n".join(parts)
prompt = build_system_prompt(
"You are Jarvis, a terse assistant.",
user_name="Ada",
today=date(2026, 8, 17),
)
print(prompt)
You are Jarvis, a terse assistant.
You are talking to Ada.
Today's date is 2026-08-17.
This is the same principle as chapter 4, arriving from a different direction: everything it knows, you sent. Memory, personality and context are all just text you assemble before the call.
A warning about what this is not
The system prompt shapes behaviour. It is not a security boundary. Someone typing at your assistant can ask it to ignore its instructions, and it may partly comply. That is fine here, because it is your own assistant on your own machine and the only person you could fool is yourself.
It matters enormously in chapter 9, when we give it the ability to run code. The rule there is the one that actually holds: safety comes from what your Python code refuses to do, never from what the prompt asked the model not to do.
If it went wrong
- Nothing changed The
systemargument goes on the API call, not in themessageslist. It is a sibling ofmessages. - It ignores the length instruction Make it numeric and specific. "Three sentences" beats "concise" every time.
- It has forgotten the persona later in a long chat It has not; the system prompt is resent on every call. Long conversations simply dilute it. Restating the most important rule at the end of the persona helps.
Your assistant answers in the voice you specified, and editing persona.txt changes its behaviour on the next run without touching any Python.