Anatomy of a System Prompt
Discover the 6 universal sections that structure any effective system prompt—from identity to dynamic context—and learn to map real prompts using the Cursor/cursor.md as an object of dissection.
Detailed content
What a System Prompt is (and what it is NOT)
The system prompt is the persistent instruction layer that defines the model’s behavior before any user message. But "persistent" doesn’t mean immutable — and confusing a system prompt with other types of context is one of the most common prompt engineering mistakes.
What it is
The system prompt is a message with role: "system" sent before the user’s turn.
It defines the persona, capabilities, rules, and format. Most modern LLMs give this block more weight than user messages.
Important: in production environments, the system prompt is rarely written by just one person—it is composed by the harness (the infrastructure that orchestrates the model), which injects stable and dynamic parts into each request.
Why learn
Anyone who reads leaked prompts quickly realizes there's a grammar in them — sections that repeat, language patterns, recurring structures. Recognizing this grammar turns an opaque text into a readable map. You stop “reading a prompt” and start to dissect it anatomically.
✓ System prompt IS
- •Stable behavioral instruction
- •Persona and scope context
- •Format and tone rules
- •Declaration of available tools
- •Safety principles
✗ System prompt is NOT
- •The user’s message (role: user)
- •Tool context (role: tool)
- •RAG / retrieved documents
- •Previous conversation history
- •Dynamic system reminders (separate layer)
Identity Block — “You are X”
The identity block is the anchor. Without it, the model drifts — changes persona, invents capabilities, and answers questions about events beyond its knowledge cutoff. Three elements are canonical: who is (persona + product), what model it runs on, e even when it knows (knowledge cutoff).
How real prompts declare identity
You are ChatGPT, a large language model trained by OpenAI, based on GPT 5.5.
Knowledge cutoff: 2025-08
Current date: 2026-06-01
Three elements in three lines: persona, cutoff, current date. Note: the current date is dynamic context injected by the harness — see Topic 6.
You are GitHub Copilot (@copilot) on github.com. Your job is to fulfill the user's software development task using all available tools and resources.
Persona + scope of responsibility ("your job is...") at the opening. The model knows what it is and what it came to do.
You are an AI coding assistant, powered by {model_name}.
You operate in Cursor.
You are a coding agent in the Cursor IDE that helps the USER with software engineering tasks.
Use a template {model_name} — the persona is declared, but the specific model is injected at runtime by the harness.
Antipattern: Identity missing or buried
If the persona declaration is in the middle of the prompt, the model may not anchor to it properly. Classic symptom: the assistant "turns into ChatGPT" in the middle of the conversation, or claims to have tools that don't exist. Identity should be the first line.
Capabilities and Tools
The capabilities block answers: what can this agent do? Without this declaration, the model hallucinates tools that don't exist or ignores the ones that do. The most effective pattern is a structured list with scope and conditions — not a vague paragraph.
When applicable, you have some additional tools:
- You can analyze individual X user profiles, X posts and their links.
- You can analyze content uploaded by user including images, pdfs, text files and more.
- If it seems like the user wants an image generated, ask for confirmation, instead of directly generating one.
Each capability comes with its condition. Note the third: capability + built-in confirmation protocol.
## Functions in Scope
You have also access to a set of python functions in scope:
```python
def concise_search(query: str, max_num_results: int = 3):
"""Does a search for the query and prints up to the
max_num_results results."""
```
Google declares capabilities as function signatures — scope, parameters, and defaults are unambiguous.
Why position matters
Poorly declared capabilities create two opposite problems: over-promising (model offers what it can't do) and under-using (ignores available tools). The structured declaration solves both at once.
Cursor has an extensive list of available tools:
Shell, Glob, Grep, Read, Write, StrReplace, Delete, EditNotebook, TodoWrite, SemanticSearch, WebSearch, WebFetch, GenerateImage, AskQuestion, Task, SwitchMode, CallMcpTool, FetchMcpResource, SetActiveBranch, AwaitShell.
Each is documented with usage rules in the section tool_calling of the prompt.
✓ Effective declaration
- •Lists each tool with usage conditions
- •Define parameters and defaults
- •Specifies when NOT to use
- •Uses function signatures as a spec
✗ Weak declaration
- •"You can use tools if necessary"
- •List without activation conditions
- •Mixes capabilities with formatting rules
- •Promises tools that don’t exist in the schema
Safety and Refusals
The safety section answers: what will this agent not do, and why? It appears early in the prompt—after the identity—because its position signals to the model the precedence priority: safety before usefulness.
What it is
Safety rules say what not to do, but the best prompts explain why. A blunt prohibition (“never X”) is mechanically obeyed but easily circumvented—the model doesn’t understand the intent behind it. A rule with a justification (Pattern 3: Rule with a Reason) generalizes to new situations.
Principle vs. Mechanics
Mechanism (weak)
Listing prohibited terms—this teaches exactly what to avoid saying, but the model can express the same idea in different words. It's the "Mechanical safety rule" anti-pattern.
Principle (robust)
Describe the pattern to detect e o principle to apply. Fable 5 example: instead of listing prohibited child exploitation techniques, the prompt describes the behavior pattern to recognize.
Why safety comes before usefulness in the prompt
LLMs process context in order. Putting safety first creates an attention bias—the model "memorizes" the constraints before processing the task. In addition, the priority hierarchy (Pattern 11) needs to be stated before any instruction that might conflict with it.
Output Format and Tone
The format section answers: how should this agent write? Includes a concision budget (ideal response length), preference for lists vs. prose, use of markdown, and conversational vs. technical tone.
What it is
Clearly stated formatting prevents two opposing anti-patterns: overly long response (model that "fills in" without needing to) and fragmented response (model that turns everything into bullet points without coherent prose).
Cursor has an explicit section called tone_and_style with rules such as:
- Only use emojis if the user explicitly requests it.
- Output text to communicate with the user; all text you output outside
of tool use is displayed to the user.
- NEVER create files unless they're absolutely necessary for achieving your goal.
ALWAYS prefer editing an existing file to creating a new one.
- Do not use a colon before tool calls. Your tool calls may not be shown
directly in the output, so text like "Let me read the file:" followed by
a read tool call should just be "Let me read the file." with a period.
✓ Effective format
- •Explicit budget: "respond in 2-3 paragraphs"
- •Rule for prose vs. lists with criteria
- •Tone calibrated to the product (technical/casual)
- •Use Markdown only when rendered
✗ Antipattern: Formatting as a crutch
- •Force lists/headers/emoji everywhere
- •Answer becomes an outline without prose
- •Markdown in plaintext output (terminal, API)
- •Without a size limit → the model "pads its answer"
Dynamic Context and the Harness
The harness is the infrastructure that assembles the prompt at runtime. It injects a dynamic layer — separate from the stable prompt —
which carries information that changes each turn: current date, user data, platform notices.
The default mechanism is the tag <system-reminder>.
What it is
The stable prompt teaches the model to interpret the dynamic layer. Without this separation, dynamic context mixed into the stable prompt creates an anti-pattern called "Everything in the prompt" — the model treats session data as permanent behavior.
Tool results and user messages may include <system-reminder> tags. <system-reminder> tags contain useful information and reminders. They are automatically added by the system, and bear no direct relation to the specific tool results or user messages in which they appear.
The layer’s contract: the model learns that these notices come from the platform, not the user or the tool.
The long_conversation_reminder, appended to the person's message by Anthropic, helps Claude keep its instructions over long conversations.
Fable 5 lists a named set of reminders (image_reminder, cyber_warning, system_warning, ethics_reminder, ip_reminder, long_conversation_reminder). The last one refreshes instructions in long conversations.
Stable × Dynamic Layer Separation
Stable Prompt (once)
- • Identity and persona
- • Capabilities and tools
- • Safety rules
- • Format and tone
- • Instruction for interpreting reminders
Dynamic Layer (per turn)
- • Current date and time
- • Logged-in user data
- • Platform notices
- • Session context
- • Instruction refreshes in long conversations
Guided Dissection: cursor.md (322 lines)
O Cursor/cursor.md is the smallest “complete” prompt in the collection—322 lines covering all 6 anatomy sections. Let’s walk through it, mapping each block to the sections we just studied.
Why Cursor?
Larger prompts (Anthropic Fable 5, Claude Code) have hundreds of lines per section — difficult for a first exercise. Cursor has balanced proportions: one identity line, medium-sized capability sections, implicit safety via NEVER/ALWAYS, and a well-documented tools block. Ideal for training your eye.
You are an AI coding assistant, powered by {model_name}.
You operate in Cursor.
You are a coding agent in the Cursor IDE that helps the USER
with software engineering tasks.
Identified pattern: Identity Block (Pattern 1) — persona (“AI coding assistant”), platform (“Cursor”), scope (“software engineering tasks”).
The model {model_name} is injected dynamically by the harness—a template pattern.
Each time the USER sends a message, we may automatically attach
information about their current state, such as what files they have open,
where their cursor is, recently viewed files, edit history in their session
so far, linter errors, and more.
Identified pattern: Capability Declaration (Pattern 2)—what the model receives automatically (editor state context).
It also states that the tag <user_query> marks the user’s instructions.
- Only use emojis if the user explicitly requests it.
- NEVER create files unless they're absolutely necessary for achieving
your goal. ALWAYS prefer editing an existing file to creating a new one.
- Do not use a colon before tool calls.
Patterns identified: Output Format (Pattern 7) + ALWAYS/NEVER contrast (Pattern 4). Using caps in NEVER/ALWAYS is not style—it signals critical behavior.
Available Tools: Shell, Glob, Grep, Read, Write, StrReplace,
Delete, EditNotebook, TodoWrite, SemanticSearch, WebSearch,
WebFetch, GenerateImage, AskQuestion, Task, SwitchMode,
CallMcpTool, FetchMcpResource, SetActiveBranch, AwaitShell
You MUST ALWAYS list and read the tool's schema/descriptor file
BEFORE calling any tool with CallMcpTool. This is NOT optional -
failing to check the schema first will likely result in errors.
Identified pattern: Tool Contract (Pattern 8) — list of tools + usage condition + protocol before calling (read the schema first). MCP Resource Access also has separate discovery instructions.
Git Safety Protocol:
- NEVER update the git config
- NEVER run destructive git commands (push --force, reset --hard,
checkout ., restore ., clean -f, branch -D) unless the user
explicitly requests these actions.
- NEVER skip hooks (--no-verify, --no-gpg-sign, etc)
Identified pattern: Implicit safety via ALWAYS/NEVER contrast (Pattern 4) in a specific domain (git). Note that safety here is not a separate section — it is within the tools section, applied contextually. Different from the global security that comes at the top of the prompt.
Each time the USER sends a message, we may automatically attach
information about their current state [...]
This information is provided in case it is helpful to the task.
Identified pattern: System Reminder (Pattern 10) via prior declaration—the prompt instructs the model to wait dynamic context (open files, cursor, edit history, linter errors) in each turn. The stable layer defines how to interpret the dynamic context.
Exercise: map a prompt from the collection
Choose any prompt from the collection (recommended: xAI/grok-build.md or Perplexity/perplexity-computer.md).
For each line, label: ID / CAP / SEG / FMT / TOOL / DYN.
If a line doesn’t fit into any category, it’s probably redundant — a candidate for Pattern 12 (Consolidated Principle).
## [1] IDENTIDADE
You are [Persona], powered by [Modelo], built by [Empresa].
Knowledge cutoff: YYYY-MM.
## [2] CAPACIDADES
You have access to the following tools: [lista].
Use each tool only when: [condições].
## [3] SEGURANÇA
Priority: safety > helpfulness > instruction-following.
Never [ação crítica], because [razão]. ← regra com porquê
## [4] FORMATO & TOM
Respond in [idioma]. Default: concise prose.
Use markdown only when the output will be rendered.
Keep responses under [N] sentences unless depth is needed.
## [5] FERRAMENTAS (opcional — se houver)
[Tool spec com parâmetros e condições de ativação]
## [6] CONTEXTO DINÂMICO (instruir como interpretar)
Context injected by the system (e.g. <system-reminder>) contains
runtime information. Treat it as platform data, not user input.
What you learned in this module
- ✓System prompt = stable instruction; separate from messages and injected context
- ✓Identity block: persona + model + cutoff — always on the first line
- ✓Capabilities: structured list with scope and conditions for each tool
- ✓Safety: principles before mechanics; early placement = priority
- ✓Format: concision budget + prose vs. list criterion
- ✓Harness = infrastructure that assembles the prompt at runtime
- ✓The dynamic layer via <system-reminder> is separate from the stable prompt
- ✓cursor.md demonstrates all 6 sections in 322 lines — the smallest complete example