Write Your First System Prompt — Practical Prompt Engineering, Part 2
- Contributor
- 5 days ago
- 3 min read
Updated: 2 hours ago
Practical Prompt Engineering · Part 2
A system prompt sets the model's behavior for the conversation. Done well, it dramatically improves output quality. This tutorial walks through writing one.
What You'll Build
A system prompt for a specific task that produces consistent, useful outputs.
Step 1: Pick a Specific Task (5 min)
Don't write a general-purpose prompt. Pick one task:
Summarize customer support tickets
Classify incoming emails
Generate product descriptions
Answer questions about your documentation
Specific tasks produce specific prompts.
Step 2: The Anatomy (5 min)
A working system prompt has:
1. Role: who the model is
2. Task: what it does
3. Inputs: what it'll receive
4. Output format: what it produces
5. Constraints: what it shouldn't do
6. Examples: 1-3 demonstrations (optional but powerful)
Step 3: Draft v1 (10 min)
For summarizing support tickets:
You are a customer support analyst. You summarize support tickets
into a 2-sentence summary that captures: (1) the customer's issue
and (2) any action items.
You will receive a ticket transcript. Output only the summary; no
preamble or formatting.
Do not invent details. If the ticket is unclear, say so in the
summary.
Simple. Specific. Bounded.
Step 4: Test It (10 min)
Try on 3-5 sample tickets:
ticket = """
Customer: My order hasn't arrived. Order number 12345. It's been
2 weeks.
Agent: Let me look that up. I see it was shipped via standard
shipping; ETA was 7-10 business days. I'll check the carrier.
Agent: Looks like the carrier had a delay. New ETA is tomorrow.
Customer: Okay thanks.
"""
response = client.messages.create(
model="claude-sonnet-4-6",
system=system_prompt,
messages=[{"role": "user", "content": ticket}]
)
Read the output. Is it what you wanted?
Step 5: Iterate (15-30 min)
Common issues and fixes:
Output too long? Add to prompt: "Maximum 30 words."
Output too short? Add: "Include the key issue and resolution status."
Inconsistent format? Add explicit format: "Format: 'Issue: ... Action: ...'"
Hallucinations? Add: "Only use information from the ticket. Do not infer beyond what's stated."
Each iteration teaches you what works.
Step 6: Add Examples (15 min)
Few-shot examples dramatically improve consistency:
You are a customer support analyst. You summarize support tickets...
Here are examples:
Input: [example ticket 1]
Output: Issue: Order #X delayed beyond ETA. Action: Carrier issue
identified; new ETA tomorrow.
Input: [example ticket 2]
Output: Issue: Customer received wrong item. Action: Replacement
shipped; return label provided.
Now summarize:
[actual ticket]
The model patterns its output after the examples. Powerful for consistency.
Step 7: Handle Edge Cases (15 min)
What if the ticket is empty? Malformed? Off-topic?
Add to the prompt:
Special cases:
- If the ticket is empty or has no customer issue: respond "No
customer issue identified."
- If the ticket contains content unrelated to a support issue:
respond "Out of scope."
- If you're uncertain about the action status: say so explicitly.
Edge cases handled in the prompt prevent surprises.
Step 8: Constrain Tone (10 min)
If tone matters:
Tone: professional and neutral. Do not use phrases like "Great
question!" or "Thanks for reaching out."
Voice: third person; no first-person ("I see that...").
Generic prompts produce generic tones. Specific constraints produce specific tones.
Step 9: Test on Your Eval Set (15 min)
The eval cases from Part 1:
def evaluate_prompt(system_prompt, eval_cases):
for case in eval_cases:
output = client.messages.create(
model="claude-sonnet-4-6",
system=system_prompt,
messages=[{"role": "user", "content": case["input"]}]
).content[0].text
# Manual or automated check
pass_check = case["expected_topic"] in output.lower()
print(f"{'PASS' if pass_check else 'FAIL'}: {output[:100]}")
Without eval, you don't know if changes improve. With it, you do.
Step 10: Version and Store (10 min)
Save the working prompt:
prompts/
ticket_summary_v1.txt # First draft
ticket_summary_v2.txt # With examples
ticket_summary_v3.txt # Current production version
Each new version is a separate file. You can compare across versions, revert, A/B test.
What You Just Did
You wrote a system prompt that:
Has a clear role
Specifies the task
Bounds the output
Provides examples
Handles edge cases
Has a consistent tone
It produces consistent outputs that you can rely on.
Common Failure Modes
Vague role. "You are a helpful assistant." Doesn't steer toward your specific task.
No format specified. Output structure varies; downstream code breaks.
Asking too much. One prompt tries to do 5 things. Break into multiple.
No examples. For complex tasks, examples are the highest-leverage addition.
Untested. Prompt works on one example; fails on others.
Continue the Practical Prompt Engineering path
Part of the Practical Prompt Engineering learning path.


