The system prompt is the job description your AI agent reads before every conversation. It decides what the agent does when a request is unclear, when two rules collide, and when it should stop and ask a person. Most agents that misbehave in production don't have a model problem; they have a system prompt that is vague, contradictory or overloaded. This guide distills what Anthropic and OpenAI now publish about writing system prompts for agents, turns it into a practical template, and includes a tested Python linter that catches the most common mistakes before your users do.
What changed in 2026: from prompt tricks to context engineering
Early prompt engineering was about magic phrases. Today's guidance is calmer. Anthropic describes the system prompt as one part of context engineering: choosing the smallest set of useful information the model sees at each step, alongside tool definitions, examples, conversation history and retrieved data. Its advice is to aim for "the minimal set of information that fully outlines your expected behavior". Minimal doesn't mean short. It means every line earns its place.
Anthropic also warns about two failure modes. One is hardcoding brittle, if-this-then-that logic for every case, which breaks the moment reality doesn't match. The other is vague, high-level guidance that assumes the model shares context it doesn't have. The target is the "right altitude" between them: specific enough to guide behavior, flexible enough to let the model use judgment. (New to prompting in general? Start with our guide to writing better prompts.)
The anatomy of a good agent system prompt
Both vendors recommend clear sections. Anthropic suggests XML tags or Markdown headings so the model can tell instructions, background and data apart. A structure that works for most business agents has six parts:
- Role: one or two sentences on who the agent is and what it is for. "You book appointments for a dental clinic" beats "You are a helpful assistant".
- Context: the facts the agent needs and can't guess: business hours, languages, who the users are, what a good outcome looks like.
- Tools: when to use each tool and when not to. Anthropic notes that if a human engineer can't say which tool fits a situation, the agent can't either, so keep tools few and non-overlapping. (More in our guide to reliable tool calling.)
- Rules: the constraints, with the reason behind each one, and an explicit order for when they conflict.
- Escalation: exactly when the agent stops and hands over to a person.
- Output: the format, length and language of replies, described positively.
Seven rules from the vendors' own guides
1. Write for a smart colleague with no context
Anthropic's test: if you showed the prompt to a capable colleague who knows nothing about your project, would they know what to do? If they'd have questions, so will the model. Spell out the audience, the goal and what "done" means.
2. Explain why, not just what
A rule with a reason generalizes; a bare rule doesn't. Anthropic's own example: instead of only forbidding ellipses, tell the model its reply will be read aloud by a text-to-speech engine that can't pronounce them. The model then avoids other things a speech engine would stumble on too, without being told.
3. Remove contradictions, and rank what's left
This is the costliest mistake. OpenAI's GPT-5 prompting guide warns that contradictory or vague instructions can hurt its newer reasoning models more than older ones, because the model spends effort trying to reconcile rules that can't both be true. Its example is a healthcare scheduling prompt that says never to book without explicit patient consent, and elsewhere to auto-assign the earliest same-day slot for urgent cases. The fix wasn't a smarter model; it was rewriting the rules so one clearly takes priority, with the exception spelled out.
4. Calm down the capital letters
"CRITICAL: You MUST…" was a workaround for older models that missed instructions. Anthropic's current guidance says newer models follow the system prompt closely, and shouting now tends to make them overreact, applying a rule in places it was never meant for. Use normal language and a reason instead.
5. Say what to do, not only what to avoid
"Reply in two or three short sentences in the patient's language" works better than "Don't write long messages". Positive instructions give the model a target; negative ones only fence off one wrong answer among many.
6. Show a few good examples
Anthropic recommends three to five diverse, canonical examples wrapped in their own tags, rather than a long list of edge cases. Make them different from each other, or the model will copy the one pattern they share.
7. Decide how independent the agent should be
Agents need explicit guidance about when to act and when to ask. Anthropic's docs suggest telling the model to take local, reversible actions freely but to confirm before anything hard to undo, such as deleting data, sending messages or spending money. OpenAI's guide goes further for eagerness: you can set a budget on tool calls, define when the agent should stop searching, and ask for a short preamble that tells the user what it's about to do.
Where to put long documents
If your agent works with long material (contracts, manuals, knowledge-base pages), put that material near the top of the context and your instructions and question at the end. Anthropic reports this can improve response quality by up to 30% in its tests with complex, multi-document inputs. Wrap each document in its own tags with its source, so the agent can quote and cite the right one. (For when to retrieve instead of stuffing everything in, see RAG vs long context.)
Long-running agents: the prompt isn't enough
For tasks that run for hours or across many context windows, Anthropic's guidance adds three techniques: compaction (summarizing the conversation and starting fresh with the summary), structured note-taking (the agent keeps a progress file outside the context window, for example a JSON status file plus git commits as checkpoints), and sub-agents that do focused work and return a short summary. The system prompt should tell the agent these exist and when to use them. (Our guide to AI agent memory covers this in depth.)
What never belongs in a system prompt
- Secrets. API keys, passwords and tokens belong in your server's configuration, where the tool code uses them. Anything in the prompt can leak through a clever question or a log file.
- Your only line of defense. A prompt can be argued with; code can't. Limits on spending, permissions and dangerous actions should be enforced in the tool layer too, as our guide to agent security and prompt injection explains.
- Stale facts. Prices, stock levels and schedules change. Let the agent fetch them with a tool instead of hardcoding them.
A tested demo: a system prompt linter
You can catch several of these problems automatically. The script below needs no API key. It checks a prompt for the six sections, looks for "always" and "never" rules that talk about the same thing, counts all-caps commands, and flags anything that looks like an API key. It runs on two versions of a dental clinic booking prompt: the first has the same kind of conflict as OpenAI's healthcare example, and the second is a rewrite that follows the rules above. The key in the first prompt is a fake placeholder.
"""A system-prompt linter (no API key needed).
It flags the problems that vendor prompting guides warn about most often:
missing sections, contradictory rules, shouting, and secrets pasted into the prompt.
"""
import re
SECTIONS = ["role", "context", "tools", "rules", "escalation", "output"]
SHOUTING = re.compile(r"\b(CRITICAL|IMPORTANT|MUST|NEVER|ALWAYS)\b")
SECRET = re.compile(r"\bsk-[A-Za-z0-9-]{16,}|\beyJ[A-Za-z0-9_-]{20,}")
STOP = {"with", "without", "that", "this", "then", "them", "they", "your", "from",
"for", "the", "and", "only", "after", "before", "about", "when", "cases"}
def words(sentence):
return {w for w in re.findall(r"[a-z]{4,}", sentence.lower()) if w not in STOP}
def lint(prompt):
issues = []
for name in SECTIONS:
if not re.search(rf"<{name}[ >]|^#+\s*{name}", prompt, re.I | re.M):
issues.append(f"missing section: {name}")
sentences = re.split(r"(?<=[.!?])\s+|\n", prompt)
always = [s for s in sentences if re.search(r"\balways\b", s, re.I)]
never = [s for s in sentences if re.search(r"\bnever\b", s, re.I)]
for a in always:
for n in never:
shared = (words(a) & words(n)) - {"always", "never"}
if len(shared) >= 2:
issues.append(f"possible conflict on {sorted(shared)}:\n"
f" ALWAYS: {a.strip()}\n NEVER: {n.strip()}")
loud = SHOUTING.findall(prompt)
if loud:
issues.append(f"shouting ({len(loud)}x: {', '.join(sorted(set(loud)))}); "
"newer models may overreact, explain the reason instead")
if SECRET.search(prompt):
issues.append("looks like an API key or token; keep secrets out of prompts")
return issues, len(prompt) // 4 # rough estimate: ~4 characters per token
BEFORE = """You are a helpful assistant for a dental clinic.
CRITICAL: You MUST be helpful and NEVER refuse a patient.
Never book an appointment without the patient's explicit consent.
For urgent cases, always book the earliest same-day appointment automatically.
Calendar API key: sk-EXAMPLE-not-a-real-key-0000
"""
AFTER = """<role>You book appointments for a dental clinic by chat.</role>
<context>Patients write in English or Arabic. Opening hours: Sun-Thu, 9:00-17:00.</context>
<tools>find_slots(date) lists free slots. book(slot, patient_id) creates a booking.
The calendar connection is configured outside this prompt.</tools>
<rules>Book only after the patient confirms the exact slot, because a wrong booking
blocks a chair another patient needed. For urgent pain, offer the earliest same-day
slot first and book it once the patient agrees.</rules>
<escalation>Hand over to the front desk for bleeding, swelling or fever,
and whenever the patient asks for a person.</escalation>
<output>Short replies in the patient's language. End with the booked date and time.</output>
"""
for label, prompt in [("BEFORE", BEFORE), ("AFTER", AFTER)]:
issues, tokens = lint(prompt)
print(f"{label}: ~{tokens} tokens, {len(issues)} issue(s)")
for issue in issues:
print(" -", issue)
Output, run on 2026-10-07:
BEFORE: ~75 tokens, 9 issue(s)
- missing section: role
- missing section: context
- missing section: tools
- missing section: rules
- missing section: escalation
- missing section: output
- possible conflict on ['appointment', 'book']:
ALWAYS: For urgent cases, always book the earliest same-day appointment automatically.
NEVER: Never book an appointment without the patient's explicit consent.
- shouting (3x: CRITICAL, MUST, NEVER); newer models may overreact, explain the reason instead
- looks like an API key or token; keep secrets out of prompts
AFTER: ~188 tokens, 0 issue(s)
What the rewrite changed:
- The conflict is gone. Instead of "never without consent" plus "always automatically", there is one rule: book after the patient confirms, and for urgent pain, offer the earliest slot first. The reason (a wrong booking blocks a chair someone else needed) tells the agent what matters.
- No shouting. The rewrite uses normal sentences, and the urgent case gets a concrete action instead of a capitalized warning.
- The key is out. The calendar connection lives in the server's configuration, not in text the model can repeat.
- Escalation is explicit. Bleeding, swelling or fever, or a request for a person, goes to the front desk.
- It got longer, and that's fine. About 190 tokens instead of 75, but every added line answers a question the agent would otherwise guess at.
A linter like this is a cheap first filter, not proof of quality. Its contradiction check is deliberately simple and will miss conflicts phrased differently. The real test is running the agent on realistic conversations and grading the results, as our guide to AI agent evals describes.
A checklist before you ship
- Could a smart new colleague do the job from this prompt alone?
- Does each rule come with its reason?
- If two rules can collide, does the prompt say which one wins?
- Are instructions written as what to do, in calm language?
- Are there three to five varied examples, if the format matters?
- Does the agent know which actions it may take alone and which need a person?
- Are secrets, prices and other changing facts kept out of the prompt?
- Have you tested it on real conversations, including awkward ones?
The takeaway
A good system prompt reads like a clear brief for a capable new hire: who they are, what they need to know, which tools to use, which rules matter and why, when to ask for help, and what the answer should look like. Write it calmly, remove contradictions, keep secrets and hard limits in code, and test it on real conversations. When the agent misbehaves, fix the brief before you blame the model.
Sources: Anthropic, "Effective context engineering for AI agents" (September 2025, updated January 2026); Anthropic, Claude prompting best practices documentation; OpenAI, GPT-5 prompting guide. Checked October 2026; vendor guidance evolves with each model generation.