How it works
The explanation, with examples you can run.
Start from success criteria
Before writing the prompt, write down how you will judge the output. "Summaries are good" is not a criterion; "summary is under 80 words, mentions every action item, invents nothing, and uses the customer's name" is. Collect 10 to 30 realistic inputs, including awkward ones (empty, very long, wrong language, hostile). These become your first evaluation set, and every prompt change is measured against them.
System and user messages
Most chat APIs separate a system prompt (sometimes called developer or instructions) from user and assistant turns.
- The system prompt holds what stays the same: the role, the audience, rules, tone, output format, and refusal or fallback behaviour.
- The user message holds this request's input. Wrap documents and user-supplied text in clear delimiters (XML-style tags work well with several providers) and say in the instructions that the content inside them is data.
- Previous assistant turns are part of the input too. If an earlier answer was wrong, the model may repeat it; you can edit or drop history your code sends.
SYSTEMYou write replies for Acme's support team. Audience: customers, plain English.Rules:- Use only facts from <ticket> and <policy>. If they do not answer the question, say you will pass it to a colleague. Never promise refunds.- Under 120 words. No headings. Sign off as "Acme Support". USER<policy>...refund policy text...</policy><ticket>...the customer's message...</ticket>Write the reply.Examples beat adjectives
Telling a model "concise, friendly, professional" leaves a lot open. Showing it two or three short examples of input and ideal output (few-shot prompting) pins down format, length and tone. Make examples varied, so it does not copy one surface pattern, and make sure they obey your own rules, because the model will imitate them closely, including their mistakes.
Give it room to work, then a clean answer
For tasks that need several steps (comparisons, maths, multi-part decisions), results often improve if the model works through the problem before committing to an answer. Many current models do this internally when you enable a reasoning or "thinking" option; with others you can ask for the working in a separate tagged section and show users only the final part. Either way, parse the answer from a predictable place rather than from free text.
Prompts are code
- Keep prompts in version control next to the code that uses them, not pasted into a dashboard nobody reviews.
- Change one thing at a time and re-run the evaluation set; prompt changes often have side effects on cases you did not look at.
- Template carefully: build prompts from parts with clear boundaries instead of string-concatenating user input into your instructions.
- Re-test when you change model or model version. A prompt tuned for one model is not guaranteed to behave the same on another.
# Placeholder client. The prompt lives in a file under version control.SYSTEM = open("prompts/support_reply.v3.txt").read() def draft_reply(ticket_text: str, policy_text: str) -> str: user = f"<policy>\n{policy_text}\n</policy>\n<ticket>\n{ticket_text}\n</ticket>\nWrite the reply." res = llm.generate(model=MODEL, system=SYSTEM, messages=[{"role": "user", "content": user}], max_output_tokens=400) return res.textCheck yourself
3 questions. Get them all right to finish this topic.
0 of 3 right so far. Get all three to finish this topic.