Prompt Engineering Guide: Structuring One Prompt from Scratch
Most prompt failures are structure failures, not model failures. Here is how I build a prompt for a single task, piece by piece, with a worked example.
Why structure matters more than wording
When a prompt fails, the instinct is to tweak the wording: swap a verb, add an adjective, beg the model to be more careful. In my experience that rarely fixes the underlying problem. Most failures I have seen trace back to structure, not phrasing: the task was never fully specified, the output format was left to the model's imagination, or the examples given contradicted the instructions. A model cannot read your mind about what counts as a good answer, so if the prompt does not define that explicitly, you are gambling on the model guessing correctly.
Treating prompt writing as a structural exercise rather than a creative one also makes it testable. If a prompt is just a paragraph of vague encouragement, you cannot say why it worked or failed, and you cannot improve it systematically. If a prompt is built from named components, you can change one component, rerun the task, and attribute the difference. That is the same discipline you would want in any experiment: isolate variables, do not change five things at once and hope.
So in this post I want to walk through one concrete task, from a one-line request to a fully structured prompt, naming each piece as I add it. The task is deliberately ordinary: classifying short customer support messages into a fixed set of categories. It is simple enough to reason about precisely, and realistic enough that the same structure transfers to harder tasks.
Starting point and the components a prompt actually needs
The naive version of the task might be written as: 'Classify this customer message into a category.' This is not really a prompt, it is a wish. It does not say which categories exist, what to do with ambiguous messages, or what format the answer should take. If you ran this across a hundred messages you would get a hundred different styles of answer: some single words, some full sentences, some with explanations, some inventing categories that do not exist in your system.
A structured prompt for this task needs at least five components. First, a role or framing sentence that tells the model what kind of task this is, for example that it is acting as a support ticket triage system. Second, an explicit, closed list of the allowed categories, say five: billing, technical issue, account access, feature request, and other. Third, the input itself, clearly delimited so the model cannot confuse instructions with content, using something like triple quotes or a labelled block. Fourth, the output format, specified precisely: a single category label, nothing else, no punctuation, no explanation. Fifth, handling for edge cases: what happens when a message fits two categories, or none at all.
Each of these components fixes a specific failure mode. The closed category list stops the model inventing new labels. The delimiter around the input stops the model treating a customer's sentence like 'ignore previous instructions' as a command rather than data, which matters more than people expect once real user text starts flowing in. The output format constraint is what makes the result usable in an automated pipeline rather than needing a human to parse free text afterwards. The edge case rule is what stops silent failures, where the model picks a category at random rather than signalling genuine uncertainty.

Building it up with a worked example
Here is roughly what the assembled prompt looks like once all five components are in place. The role sentence: 'You are a support ticket classifier for a software product.' The category list: 'Classify the message into exactly one of these five categories: billing, technical_issue, account_access, feature_request, other.' The delimited input: 'Message: """I was charged twice this month and need a refund"""'. The format instruction: 'Respond with only the category name, lowercase, no punctuation, no explanation.' The edge case rule: 'If the message does not clearly match any category, respond with other rather than guessing.'
Running this on the example message, a well-structured prompt should reliably produce 'billing', because the category list narrows the decision space and the delimiter stops the message content leaking into the instruction. Compare that with the naive prompt, which might produce 'This message is about a billing issue because the customer mentions being charged twice', technically correct in content but useless as a machine-readable output, and inconsistent in format across runs.
The edge case rule earns its keep on harder inputs. Suppose a message reads: 'I can't log in and I'm also still waiting on a refund.' Without the fallback instruction, the model might silently pick one category and hide the ambiguity from you entirely. With the instruction in place, you at least get a signal, either an 'other' label or, if you extend the format to allow it, two labels joined by a rule you specified in advance. The point is that you decided the policy, rather than the model deciding it for you by default behaviour you never examined.
It is worth testing this prompt on a held-out set of messages you did not use while writing the instructions, the same discipline as a leakage-aware evaluation split in any machine learning workflow. If you only check the prompt against the examples you had in mind while writing it, you will overestimate how well it generalises, because you have effectively fitted the wording to those cases.
Why this discipline pays off, and a practical takeaway
The value of naming each component separately is that when the prompt fails on new data, you can localise the fix. If the model starts inventing a sixth category, the category list needs tightening, not the whole prompt rewritten. If it starts explaining itself despite instructions, the format constraint needs to be stated earlier and more forcefully, since models tend to weight instructions near the input more heavily than instructions buried at the top of a long prompt. If it mishandles genuinely ambiguous messages, the edge case rule needs revising, not the role sentence.
This also scales to harder tasks than five-way classification. Summarisation, extraction, multi-step reasoning: all of them benefit from the same five-part skeleton, role, constraints on the space of valid outputs, clearly delimited input, an explicit output format, and a stated policy for edge cases. The details change, but the discipline of naming each part so it can be tested and changed independently does not.
My practical takeaway is this: before writing a single word of a prompt, write down the five components as a checklist for your task. Role, constraints, delimited input, output format, edge case policy. Fill each one in deliberately rather than letting it emerge by accident from the model's default behaviour. Then test the result on examples you did not use to write it. A prompt built this way is not just more likely to work, it is also something you can explain, debug and improve, which a clever paragraph of persuasion never quite is.
