Imported from zubayr-ahmad/best-practices-skills (
Prompt-Best-Practices/SKILL.md). Install upstream withnpx skills add zubayr-ahmad/best-practices-skills --skill Prompt-Best-Practices. Copyright stays with the author.
Prompt Best Practices
A prompt is a behavior specification, not a changelog. The two ways prompts fail are opposite: written too vaguely to steer anything, or patched so many times that the rules now contradict each other and nobody will touch the file.
Write for a capable new colleague who has no memory of previous conversations: they need the goal, the constraints, and enough context to make the judgment calls you didn't anticipate.
1. Anatomy of a Prompt
Include these in this order, omitting what a simple task doesn't need. Each piece appears exactly once.
- Role and objective - who the model is acting as and what a good outcome is.
- Context - what the model needs to make sensible judgments: who the reader is, where the output goes, what the surrounding system does.
- Rules and constraints - the standing behavior, ordered from most to least important.
- Process - the steps or decision order, when the task has a required sequence.
- Output format - shape, length, structure. Keep this together at the end, separate from content rules.
- Examples - one to three, if the format or judgment is hard to describe.
Keep related instructions together. A rule about tone in three separate places is three places to update and three chances to contradict yourself.
2. Writing Rules That Work
Be specific about what you want, not just what you forbid. "Don't be verbose" gives no target. "Answer in under 150 words, leading with the recommendation" does. Every negative rule should carry the positive alternative beside it.
State the principle, then the instance. This is the difference between a rule that generalizes and one that only fires on the exact case you saw. Write the rule at the level of the behavior you actually want, and let the specific case be an illustration under it:
Weak (overfit to one incident):
If the user asks about pricing for the enterprise plan, don't guess the number.
Better (principle, with the case as illustration):
Never state a figure you can't source from the provided documents - say what
you'd need instead. (Pricing is the common case: plan prices change often and
are not in your context.)
The overfit version leaves the model guessing on the next twenty variants. The general version covers them.
Say why the rule exists when the reason isn't obvious. A model that understands the intent applies the rule correctly to cases you never listed; a model given a bare directive applies it literally and breaks on the edge. One clause is usually enough: "…because the downstream parser rejects trailing commentary."
Aim at the right altitude. Too generic ("be helpful and professional") steers nothing. Too specific ("if the message contains the word 'refund', respond with…") produces brittle keyword matching. The target is a rule a competent person could apply to a situation you didn't foresee and get right.
One rule, one place, one voice. Don't restate the same requirement in three sections for emphasis - repetition reads as three separate rules and creates drift when one copy is later edited.
Prefer a short rule with a clear boundary over a long hedge. Hedged instructions ("generally try to usually prefer…") give the model permission to do anything.
Order by importance. Attention concentrates at the beginning and end of a long prompt and thins in the middle. Non-negotiable constraints go early; format goes at the end; the least critical detail goes in the middle.
Use structure the reader can scan - short headed sections, one rule per line. Use XML or markdown tags when the prompt carries distinct blocks (documents, examples, user data) so the boundaries are unambiguous. Don't tag a three-line prompt.
Examples are strong medicine. Models copy examples closely, including incidental details you didn't intend - the length, the tone, the hedging, the structure. Make every example exactly the behavior you want. Two consistent examples beat six sloppy ones. Cover the tricky case, not the easy one.
3. System Message vs User Message
The split is stable-versus-per-request, and it is the whole rule.
| Goes in the system message | Goes in the user message |
|---|---|
| Role, objective, and domain context | The actual task or question this time |
| Standing rules that apply to every request | The data: document, code, ticket, transcript |
| Tone, style, and formatting policy | Per-request constraints ("keep this one short") |
| Tool-use policy and safety boundaries | Anything that differs between calls |
| Output schema and structure | Retrieved context for this specific query |
Why it matters beyond tidiness:
- Steerability. When standing rules and per-request data are mixed in one blob, the model has to guess each time which sentence is a policy and which is input. It guesses right most of the time and wrong exactly on the edge cases you cared about.
- Caching and cost. Caching matches on a stable prefix. Anything that changes per request - a timestamp, an ID, the user's document - invalidates everything after it if it sits in the system message.
- Injection safety. Untrusted content (user files, web pages, tool output) goes in the user turn, clearly delimited, and is labelled as data to be processed rather than instructions to obey. Never paste external text into the system message.
Practical tests: If this sentence would be identical on every call, it belongs in system. If I'd have to edit it per request, it belongs in user.
For agent and rule files (CLAUDE.md, AGENTS.md, skill bodies), the same logic applies - standing behavior in the file, task specifics in the request.
4. Modifying an Existing Prompt
Most prompt damage happens here. Each edit is reasonable alone; twenty of them turn a specification into sediment. Follow this order.
Step 1: Diagnose before writing anything
A wrong behavior has four different causes and they need four different fixes:
| Cause | Fix |
|---|---|
| No rule covers this | Add a rule - in the right section |
| A rule covers it but is ambiguous | Sharpen the existing rule; do not add a second one |
| Another rule contradicts it | Resolve the conflict; adding a third rule makes it worse |
| The rule exists and is clear, but is buried | Move it, shorten the surroundings, or raise its priority |
Only the first calls for new text. Adding a rule when an existing one is ambiguous is the single most common mistake - you now have two overlapping rules and the model picks unpredictably.
Step 2: Read the whole prompt before editing it
Search for the topic first. Find every place the behavior is already mentioned. If the prompt already says something related, the change belongs there, not at the bottom.
Step 3: Place the change where it belongs
New text goes inside the section that owns that topic, at the position its importance warrants. Appending to the end because that's where the cursor is, is how prompts lose their shape. If the rule genuinely belongs to no existing section, that is a signal the prompt's structure needs a new section, not an orphan line.
Step 4: Match the surrounding voice exactly
The edit must be indistinguishable from the original text. Match: person and mood (imperative vs descriptive), formatting (bullets vs prose, heading depth), sentence length, terminology (if the prompt says "the user", don't write "the customer"), and the level of detail the neighboring rules use. A correct rule in the wrong register still reads as a patch and invites the next person to append another one.
Step 5: Generalize rather than accumulate
Before adding a sibling rule, ask whether the existing rule can absorb this case by being stated one level more generally. Three specific rules that share a principle should be one rule with the principle stated and the cases named. A prompt grows in precision over time; growing in length is a symptom.
Step 6: Check for conflict and redundancy
Re-read the new rule against the whole prompt. Does anything contradict it? Does anything now become dead - a clause that only existed to handle the case you just covered better? Remove what the change made obsolete. Every edit is an opportunity to delete something.
Step 7: Verify the rest still holds
Confirm the change didn't quietly break neighboring behaviors. Keep a handful of representative cases - the ones that motivated earlier rules - and check them, not just the new case. Without this, each fix silently trades one failure for another.
5. Never Write These
- Changelog language. "Remember not to…", "As mentioned before…", "Don't do what you did last time…", "IMPORTANT UPDATE:". These date the prompt, reference context the model doesn't have, and signal the file is being used as an incident log.
- Escalating emphasis. ALL CAPS, "CRITICAL!!!", bolding every third rule. When everything is urgent, nothing is. If a rule is being ignored, it is misplaced, contradicted, or unclear - shouting doesn't fix any of those.
- Exceptions to exceptions. "Always X, except when Y, unless Z, but if W then X again." Restate the rule as the decision that's actually being made.
- Orphan appendices. A "Additional notes" or "Extra rules" section at the bottom is where structure goes to die.
- Restating a rule for emphasis in a second location.
- Dead scaffolding. Instructions for a tool that was removed, a format no longer consumed, a model quirk that no longer exists.
6. When to Restructure Instead of Patch
Stop patching and rewrite the affected area when any of these is true:
- The same behavior has been patched more than about five times - the underlying rule is wrong, not incomplete.
- Two instructions genuinely conflict and you're about to add a third to arbitrate.
- The prompt has grown several times its original size with no structural review.
- You can't say what a section is for, or whether a clause is still load-bearing.
- New rules have nowhere natural to live.
- You are afraid to edit it - fragility means it's doing too much in one block.
How to restructure without losing behavior:
- Inventory every clause and label it: role, standing rule, edge case, format, dead.
- Note which clause exists for which real failure. Anything with no identifiable cause is a deletion candidate.
- Rebuild around the Section 1 anatomy: merge duplicates, resolve contradictions explicitly, promote repeated edge cases into the general rule that covers them.
- Move genuinely request-specific edge cases out of the system prompt and into the per-request context that needs them.
- Verify against your saved cases before replacing the original, and keep the old version until the new one has proven itself.
7. Length and Placement
- A prompt should be as long as its rules require and no longer. Long prompts aren't wrong; padded prompts are. Every sentence either changes behavior or is removable.
- Instruction dilution is real: the longer the prompt, the less weight any individual clause carries. Adding a rule slightly weakens every other rule - which is the honest argument for deleting as you add.
- Keep format instructions consolidated and near the end; keep content rules together and earlier. Interleaving them makes both fragile.
- If the prompt is straining to cover many unrelated modes, that's an architecture signal: route to different prompts rather than growing one that handles everything with conditionals.
8. Before Delivering
- The prompt has one clear objective, and every rule serves it
- Each rule appears exactly once, in the section that owns the topic
- Rules state the principle, with specific cases as illustrations - not the reverse
- Negative rules name the positive alternative; non-obvious rules say why
- Nothing contradicts anything else; overlapping rules were merged
- Standing behavior is in the system message; per-request data in the user message
- Untrusted content is delimited and marked as data, never as instructions
- Format instructions are consolidated and separate from content rules
- Examples demonstrate exactly the wanted behavior, including its tone and length
- For an edit: voice, formatting, and terminology are indistinguishable from the surrounding text
- For an edit: whatever the change made redundant was deleted
- Representative earlier cases were re-checked, not just the new one
- No changelog phrasing, no shouting, no orphan "extra rules" section