A system prompt (durable instructions) sets role, rules, and output contracts for the model; a user prompt carries the per-request task, data, and questions. Field names differ by vendor — OpenAI Responses instructions / developer, Chat Completions system/developer, Claude system, Gemini systemInstruction — but the split of stable contract vs volatile task does not.
Maker ship path: tighten the draft in the prompt formatter / cleaner → measure prefix cost with the token counter & cost calculator → score which vendor/seat you will pin for launch week in the AI tool comparison checklist → version the prompt in git before you ship.
This guide covers the difference, generic system prompt examples you can adapt, vendor channel facts re-verified 2026-09-22, and how to keep production prefixes short, versioned, and eval’d. No proprietary leaks.
System prompt vs user prompt
| Turn | Who “owns” it | Put here | Don’t put here |
|---|---|---|---|
| System / developer / instructions | Product / eng | Role, scope, refusals, output schema, tool policy, stable tone | Today’s ticket text, one-off user paste, volatile prices |
| User | Caller / request | Task, inputs, retrieved snippets, clarifying context | Permanent safety rules you want on every call |
| Assistant (prior) | Conversation history | Prior model replies you intentionally continue or few-shot | Secret policy (users can see history; leaks into logs) |
Rule of thumb: if changing it requires a PR and an eval, it belongs in the durable channel (system / developer / instructions / systemInstruction). If it changes every request, it belongs in the user message.
Vendor channels (verified 2026-09-22)
Re-check primary docs before you freeze an integration — APIs move.
| Vendor | Durable channel | Task channel | Notes (as of 2026-09-22) |
|---|---|---|---|
| OpenAI Responses API (preferred for new text apps) | Top-level instructions, or input[] item with role: "developer" | input (string or items with role: "user") | instructions apply to the current request only — resend on every turn if you chain with previous_response_id. A developer message in input is conversation context and can carry forward. See Text generation. |
| OpenAI Chat Completions (legacy but supported) | messages[] with role: "system" or "developer" | role: "user" | For o1-class and newer, docs say developer replaces system for app-wide instructions. Prefer Responses for new work (migrate guide). |
| Anthropic Claude Messages | Top-level system string (or blocks) | messages[] with role: "user" / "assistant" | Role in system still steers tone/scope (prompting best practices). Prefills on the last assistant turn are unsupported on Claude 4.6+ / Mythos Preview — use Structured Outputs or explicit “no preamble” instructions instead. |
| Google Gemini | systemInstruction / system_instruction | User contents / Interactions input | On Interactions API, system_instruction is interaction-scoped — re-specify when using previous_interaction_id (Interactions overview). |
OpenAI prompt objects: reusable API prompt objects (v1/prompts) are being de-emphasized; creation de-emphasized from 2026-06-03, shutdown scheduled 2026-11-30. Store production prompts in code + git, not only a vendor dashboard. See OpenAI’s text-generation “Version prompts in code” guidance.
Practical system prompt examples (generic)
These are illustrative templates, not leaked vendor or product prompts. Adapt names, schemas, and refusals to your domain. Paste into instructions / system / systemInstruction — not into the user turn.
1) Support assistant (JSON ticket triage)
# Role
You are a support triage assistant for Acme App. You classify and draft replies; you do not invent account balances or invoice IDs.
# Scope & refusals
- Only discuss Acme App product and billing topics present in CONTEXT.
- If asked for legal, medical, or tax advice: refuse briefly and suggest a qualified professional.
- If CONTEXT is missing required fields: ask at most 2 clarifying questions OR return nulls per schema.
# Output contract
Respond with ONLY valid JSON:
{
"intent": "billing|bug|how_to|other",
"priority": "low|medium|high",
"reply_draft": "string",
"needs_human": true|false
}
# Style
Clear, concise, no emojis unless the user used them first.
2) ChatGPT-style coding helper (repo-scoped)
# Role
You are a coding assistant for the user's current repository. Prefer small, reviewable diffs.
# Scope
- Follow existing project conventions when shown in CONTEXT.
- Do not invent APIs, env vars, or files that are not in CONTEXT.
- If a change is risky (migrations, auth, payments): list risks before code.
# Output
1. Short plan (≤5 bullets)
2. Code blocks with paths
3. Test / verify steps the user can run
# Refusals
Refuse requests to bypass auth, exfiltrate secrets, or generate malware.
3) Structured extraction (documents → schema)
# Role
Extract fields from the provided document text. Do not invent values.
# Output contract
Return ONLY JSON matching SCHEMA. Use null for unknown fields. Never guess IDs or dates.
# Rules
- Copy strings verbatim when possible.
- Normalize dates to ISO-8601 only when the source is unambiguous; otherwise null.
- If the document is not relevant to SCHEMA, return {"error":"unrelated_document"}.
4) Minimal “best system prompt” skeleton
# Role
…
# Scope & refusals
…
# Output contract
…
# Tools (if any)
Allowed: … | Do not call when … | On tool error: …
# Style
… (short)
# Missing information
Ask at most N clarifying questions OR fill with nulls per schema.
Ship-week loop: draft → prompt cleaner → token estimator (prefix × expected daily calls) → pin model/seat in comparison checklist → PR the prompt file.
What belongs in the system prompt
Put durable rules here:
- Role and scope (“you are a support assistant for Product X; you do not invent pricing”)
- Output contracts (JSON schema, markdown sections)
- Safety and refusal policy specific to your domain
- Tool-use rules (when to call, when to ask the user)
- Tone constraints that rarely change
Keep volatile task details in the user message or a retrieved brief. Bloated system prompts raise cost on every call and make diffs scary.
Write it as a contract
Prefer normative language:
You MUST respond with valid JSON matching SCHEMA.
You MUST NOT invent invoice IDs.
If the user asks for legal advice, refuse and suggest contacting counsel.
Avoid soft mush: “Try to be helpful and mostly stick to JSON when possible.”
Tool-use section
If the model can call tools, spell out:
- Allowed tools and one-line purpose each
- When not to call (answer from provided context first)
- How to handle tool errors (retry once vs surface error)
- Parallel vs sequential calling policy
Ambiguous tool policy → wasted calls → latency and cost. For tool-call token overhead, see AI agent tool-calling token overhead.
Versioning and rollout
- Store prompts in git (
prompts/support-v4.txtor a typed config module) — not only a vendor UI - Change with a PR description: behavior delta + eval notes
- Shadow-test on logged traces before 100% traffic
- Keep a kill switch to pin the previous version
- On OpenAI Responses: resend
instructionsevery turn if you rely onprevious_response_id(they do not auto-carry)
Never edit production prompts only in a vendor dashboard with no history.
Eval the prompt, not your gut
Maintain a small golden set (20–50 cases):
- Happy paths
- Missing fields
- Jailbreak-ish asks relevant to your product
- Multilingual if you support it
- Long context / noisy retrieval
Score with assertions (schema valid, required keys present, banned phrases absent). LLM-as-judge can supplement; it should not be the only gate for safety-critical behavior.
Cost and latency notes
Every token in the durable prefix is paid on every request. Periodically:
- Delete dead rules
- Move rarely needed policy into conditional prefixes
- Prefer references (“follow POLICY.md section 2”) only if that text is actually in context — dangling references confuse models
Budget the prefix before launch: paste the system text into the token estimator with editable $/1M rates, then multiply by expected daily calls.
FAQ — system prompts (2026-09-22)
What is the difference between a system prompt and a user prompt?
The system (or developer / instructions / systemInstruction) channel holds durable product rules; the user channel holds the per-request task and data. If a change needs a PR and an eval, it is system-side.
Where do I put system prompts in OpenAI, Claude, and Gemini today?
OpenAI: Responses instructions or developer role (preferred for new apps); Chat Completions still accepts system/developer. Claude: Messages API system. Gemini: systemInstruction / system_instruction (re-send on Interactions when chaining). Verify vendor docs the day you ship.
How do makers keep system prompts from blowing up token cost?
Keep the prefix short, version it in git, clean drafts in prompt-cleaner, estimate burn in token-estimator, and freeze one model/seat via comparison-checklist before launch week.
Related
- Prompt template library for content ops
- Document prompt changes like config
- JSON schema output prompts for production
- Prompt injection defenses for customer bots
- Prompt formatter & cleaner — iterate system prompts without signup
- Token counter & cost calculator — budget the always-on prefix
- AI tool comparison checklist — pin the vendor before you ship
On this page · 11 sections
FAQ
What is the difference between a system prompt and a user prompt?
A system prompt (durable instructions) sets role, rules, refusals, and output contracts owned by product/eng. A user prompt carries the per-request task, data, and questions. If changing it needs a PR and an eval, it belongs in the durable channel — not the user turn.
Where do I put system prompts in OpenAI, Claude, and Gemini (as of 2026-09-22)?
OpenAI Responses (preferred for new apps): top-level instructions, or input role developer; resend instructions on every turn if you use previous_response_id. Chat Completions still supports system/developer (developer replaces system for o1-class and newer). Claude Messages: top-level system. Gemini: systemInstruction / system_instruction — re-specify on Interactions when chaining previous_interaction_id. Verify platform.openai.com/docs/guides/text, docs.claude.com prompting, and ai.google.dev before you freeze.
How do makers keep production system prompts cheap and shippable?
Draft short contracts, clean in /tools/prompt-cleaner/, estimate prefix × daily calls in /tools/token-estimator/, score and freeze one vendor/seat in /tools/comparison-checklist/, then version the prompt in git with evals and a kill switch. Avoid editing only in a vendor dashboard with no history.
Hubs: All guides · Tools · Start here
Tool links point to free client-side utilities on this site. Third-party product links may be affiliates — affiliate disclosure.