System prompts
A system prompt is the first message in the list, with role system, that tells the model its job, its rules and the exact shape of the answer.
Last updated: 30 Sep, 2026 · groq 1.7 · gpt-oss-120b on Groq
The ticket sorter starts here: sort an online shop's support tickets into billing, shipping or other, with a priority, as JSON a program can read. A vague instruction goes first.
from groq import Groq
client = Groq()
MODEL = "openai/gpt-oss-120b"
def ask(messages, **settings):
response = client.chat.completions.create(model=MODEL, messages=messages, **settings)
return response.choices[0].message.contentSeven labelled tickets
tickets = [
("I was charged twice for one order", "billing"),
("My parcel has not arrived", "shipping"),
("Can I get a refund for the blue mug?", "billing"),
("How do I change my password?", "other"),
("The parcel arrived but the box was crushed", "shipping"),
("The courier asked me to pay a delivery fee at the door", "billing"),
("I want to cancel my order before it ships", "other"),
]Each ticket has the category a person chose. The last two are harder than they look: a fee asked for at the door is a charge, and cancelling an order is not about delivery.
A vague instruction
vague = "Sort this support ticket into billing, shipping or other and give it a priority."Sorting the tickets with the vague prompt
for text, expected in tickets:
answer = ask([{"role": "system", "content": vague}, {"role": "user", "content": text}])
print(f"{expected:9} {answer!r}")billing '**Category:** Billing \n**Priority:** High (duplicate charge requires prompt attention)' shipping '**Category:** Shipping \n**Priority:** High' billing '**Category:** Billing \n**Priority:** High' other '**Category:** Other \n**Priority:** High' shipping '**Category:** Shipping \n**Priority:** High (the package arrived damaged and may require replacement or refund)' billing '**Category:** Shipping \n**Priority:** High' other '**Category:** Shipping \n**Priority:** High (time‑sensitive request to cancel before the order ships)'
- No answer is JSON. The model chose its own shape, Markdown with bold labels, so a program cannot read it.
- Every priority is High, with no scale to measure against.
- The fee and the cancellation are filed as Shipping.
A structured prompt
structured = """You sort customer support tickets for an online shop.
Categories:
- billing: payments, charges, refunds
- shipping: parcels, delivery, damaged boxes
- other: anything else
Reply with one line of JSON and nothing else, like this:
{"category": "shipping", "priority": 3}
priority is 1 (can wait) to 5 (urgent)."""It says who the model is, defines each category, shows the exact output with one sample line, and gives the priority a scale. Triple quotes let a string run over several lines.
Sorting the tickets with the structured prompt
for text, expected in tickets:
answer = ask([{"role": "system", "content": structured}, {"role": "user", "content": text}])
print(f"{expected:9} {answer}")billing {"category": "billing", "priority": 5}
shipping {"category": "shipping", "priority": 3}
billing {"category": "billing", "priority": 4}
other {"category": "other", "priority": 2}
shipping {"category": "shipping", "priority": 3}
billing {"category": "shipping", "priority": 4}
other {"category": "shipping", "priority": 4}- Every answer is one line of JSON in the shape the prompt showed.
- Five of seven categories are right.
- The fee and the cancellation are still shipping. The prompt never said where a fee at the door or a cancellation belongs, so the model filed them by the word delivery and the word ships.
Vague vs structured prompt
| Vague | Structured | |
|---|---|---|
| Shape of the answer | Whatever the model chooses | One line of JSON |
| Categories defined | No | Yes, with examples of each |
| Priority scale | No | 1 to 5 |
| Readable by a program | No | Yes |
What to put in a system prompt
- The role: who the model is and what it is for.
- Definitions: what each category or field means, with the edge cases you know about.
- The output shape, with one sample the model can copy.
- Scales and limits, such as 1 to 5, or one sentence.
Related
- Previous: Chat messages and templates
- Next: Few-shot prompting
- Reference: OpenAI prompt engineering guide
- Remove the sample JSON line from
structuredand run it again. - Change the other line to
- other: account changes, cancelling an order, anything elseand sort the tickets again. - Move the category list from the system message into the user message.
Little by little, you're building something great.