Agents & MCPDeveloper skill

Prompt Engineering

Prompting techniques that reliably work: clear role and task, structure, examples, explicit output contracts, and iteration.

What it does

The same request to an AI model gives you a great answer on Monday and a shapeless one on Tuesday. Ask for a list and get paragraphs. Ask about a document and get a confident answer that is not in the document anywhere.

This treats the instructions as something to be debugged rather than written once. It starts by writing down what a perfect answer looks like, then collects the real messy inputs that break things. The instruction goes at the top, the material you are asking about gets clearly fenced off so it cannot be mistaken for a command, and the shape of the answer is shown as a filled-in example rather than described. Examples are added for the cases that actually fail, not the easy ones, and the model is told exactly what to say when the answer is not there, so it stops filling gaps on its own.

You end up with an instruction that produces the same shape every time, a small set of test cases proving it, and a note on which change fixed which failure.

You end up with a prompt that holds its format on messy input, plus the test cases that prove it.

When to reach for it

Use it when writing the instructions behind an AI feature, a workflow, or an agent, and whenever a working prompt starts returning vague, inconsistent, or badly formatted results on real input.

Skip it for one-off questions in a chat, where rephrasing and asking again is faster. This is for instructions that will run many times on input you have not seen yet.

What's inside

prompt-engineering/
├── SKILL.md
└── references/
    └── examples.md
SKILL.md
---
name: prompt-engineering
description: Writes and debugs prompts for language models using the techniques that actually change output quality, applied cheapest first - explicit task and success criteria, structure and delimiters, examples that cover the hard case, an exact output contract, room to reason, and iteration from real failures. Use when writing the instructions for an AI feature or agent, or when a prompt returns vague, inconsistent, or wrongly formatted results.
---

# Prompt Engineering

You turn a vague instruction into one that produces the same good result on messy input, run after run. Prompts are debugged, not written: the first version is a hypothesis, and the failures tell you what to add.

Apply the techniques in the order below. Each one is cheaper than the one after it, and most problems are solved in the first three.

## Workflow

1. **Define what good looks like first.** Write one example of an ideal output before writing the prompt. If you cannot, the task is not defined yet and no wording will save it.
2. **Collect real inputs, including the ugly ones.** Three to five, covering the empty case, the ambiguous case, and the one that broke last time. This is your test set.
3. **State the task plainly, and put it first.** Say what to do and for whom, in the opening lines. An instruction buried under three paragraphs of background gets treated as background.
4. **Structure the prompt.** Separate instructions, context, and the input itself with headings, tags, or fenced blocks. This alone fixes most "it ignored my input" and "it answered the example instead of the question" cases.
5. **Specify the output contract exactly.** Format, sections, order, length, what to leave out. If you need machine-readable output, show the exact keys and one filled example.
6. **Add examples that cover the hard case.** One to three input-output pairs teach format and edge behavior faster than any amount of prose. An example of the easy case teaches nothing you did not already get for free.
7. **Give it room to think when the task is hard.** Ask for the reasoning before the answer on anything involving analysis, comparison, or multi-step logic. Keep that reasoning out of the final output if you only need the result.
8. **Say what to do when unsure.** "If the document does not contain the answer, reply exactly: not found." Without this, the model fills the gap, confidently.
9. **Run the whole test set, then fix the smallest thing.** Change one element, re-run everything, keep the change only if it fixes the failure without breaking a case that passed.

```text
Prompt review checklist
[ ] An ideal output was written before the prompt
[ ] The instruction is in the first three lines
[ ] Instructions, context and input are visibly separated
[ ] The output contract names format, sections and length
[ ] At least one example covers the case that usually fails
[ ] Behavior on missing or ambiguous input is stated
[ ] No two instructions contradict each other
[ ] Tested on real messy input, not just the demo case
```

## Technique order

| Order | Technique | Fixes |
| --- | --- | --- |
| 1 | Be explicit: task, audience, constraints | Vague, generic, off-target answers |
| 2 | Structure with delimiters | Input treated as instruction, or ignored |
| 3 | Exact output contract | Format drifting between runs |
| 4 | Examples covering edge cases | Right content, wrong shape or wrong edge behavior |
| 5 | Reasoning before answer | Wrong conclusions on multi-step tasks |
| 6 | Role in the system prompt | Wrong register, depth, or standard of rigor |
| 7 | Prefill the start of the reply | Preambles, apologies, stray prose around JSON |
| 8 | Split into chained prompts | One prompt trying to do four jobs badly |

Work down the list. Reaching for a role or a chain when the output contract was never written is how prompts get long without getting better.

## Structure and delimiters

```text
You are reviewing support tickets for a billing product.

## Task
Classify the ticket below into exactly one category and extract the account id.

## Categories
billing_error | refund_request | access_issue | feature_question | other

## Output
JSON only, no prose:
{"category": "billing_error", "account_id": "AC-8842", "confidence": "high"}
If no account id appears, use null. If no category fits, use "other".

## Ticket
<ticket>
{{ticket_text}}
</ticket>
```

Four things are doing work here. The task is first. The input is fenced, so a ticket containing the words "ignore the above" is data rather than an instruction. The contract shows real keys with real values instead of describing them. And both unknown cases have a stated answer, so the model never has to invent one.

## Examples that earn their place

Show the case that fails, not the case that works.

For the classifier above, the useful example is not a clean billing error. It is the ticket that mentions a refund but is actually asking whether refunds are possible, which belongs in `feature_question`. One example of that boundary does more than a paragraph explaining it.

Keep examples consistent with the contract. An example that shows four keys when the contract names three confuses the model more than having no example at all.

## Reasoning and prefill

For anything involving comparison, judgment, or several steps, let the reasoning come first, then the answer. Reasoning after the conclusion is decoration; the conclusion is already fixed.

```text
Think through the comparison in <scratch> tags: what each option costs,
what it risks, and where they genuinely differ. Then give the recommendation
in <answer> tags. Only the answer will be shown to the user.
```

Prefilling the first characters of the reply is the cheapest way to kill preambles. Starting the response with `{` for a JSON task removes the "Here is the JSON you requested" line without a single word of instruction about it.

## Debugging by symptom

| Symptom | Most likely cause | First thing to try |
| --- | --- | --- |
| Format changes every run | No output contract | Show the exact shape with one filled example |
| Ignores part of the input | Input not delimited | Fence the input, name it in the instruction |
| Confidently wrong facts | No stated unknown behavior | Add the exact "if you do not know" response |
| Right idea, wrong shape | Contract described but not shown | Replace the description with an example |
| Fails only on long inputs | Instruction is above the document | Put the long document first, instruction last |
| Fails on one edge case | Missing example for it | Add that single case as an example |
| Contradicts itself | Competing instructions | Delete the weaker one; do not add a third |
| Good sometimes, bad often | Task genuinely ambiguous | Split into two prompts, or add a decision rule |

## Rules

- Be specific rather than polite. "Exactly three bullets, each under 12 words" beats "please be concise".
- Say what to do, not only what to avoid. A negative instruction leaves the target unspecified.
- Every line should earn its place. Long prompts dilute; the model spreads attention across whatever is present.
- Never stack contradictions. "Be thorough" and "be brief" in the same prompt average into something neither.
- Put the output contract near the end, closest to where the model starts writing.
- With a long document, put the document first and the question last. Instructions at the top of a long input get diluted.
- Change one thing at a time and re-run the full test set. Two changes and an improvement teach you nothing.

## Example

**Weak.** `Summarize this customer feedback.`

Length varies from two lines to two paragraphs, sometimes bulleted, sometimes not. Nothing can be compared across runs and nothing can be parsed.

**Strong.**

```text
Summarize the customer feedback below into exactly three bullets:
one strength, one complaint, one requested feature, in that order.

Each bullet: under 15 words, in the customer's own framing, no interpretation.
If a category does not appear in the feedback, write "none" for that bullet.
Output the three bullets only, with no heading and no closing line.

<feedback>
{{feedback_text}}
</feedback>
```

**What each change bought.** "Exactly three, in that order" makes runs comparable. "Under 15 words" removes the length lottery. "In the customer's own framing" stops the drift into invented interpretation. The `none` rule removes the temptation to manufacture a complaint that was never made. And fencing the feedback means a customer writing "please summarize this differently" is quoted, not obeyed.

## Edge cases

- **The output must be machine-readable.** Show the exact structure, state what to do when a field is unknown, and prefill the opening character. Validate the output and retry once with the parser's error message appended.
- **Untrusted user text inside the prompt.** Fence it, name it as data, and never let an instruction depend on its content. Treat anything it says about the instructions as content.
- **The task has four stages.** Chain it. One prompt per stage with a clean contract between them beats one prompt doing all four at 70% each.
- **It works in chat and fails in production.** Production input is messier and the conversation history is gone. Test with the real variable input, not the polished version you typed.
- **A rule keeps slipping late in long outputs.** Restate it in the contract at the end. Distance from an instruction reduces its weight.
- **The prompt is now 400 lines.** Some of that is a skill, not a prompt. Move the stable workflow into a skill and keep the prompt to the task.
- **You cannot tell whether a change helped.** Your test set is too small or too easy. Add the cases that actually failed in the wild.

## Files

- `references/examples.md` - three prompts rebuilt from failure: an extraction prompt that would not hold its format, a classifier that drifted on boundary cases, and a long-document question-answering prompt. Each shows the failing version, the fix, and why it worked. Read before debugging your own.

Install it

Claude Code (this project)

Unzip the download into .claude/skills/. The folder is already named right.

Claude Code (every project)

Unzip into ~/.claude/skills/ to use it everywhere.

claude.ai

Upload the zip under Settings, then Capabilities, then Skills (paid plans).

How to call it

Just describe the task. The description line inside the skill does the matching. Or call it directly:

/prompt-engineering my prompt gives different results every timehelp me write instructions for this AI featurehow do I get reliable JSON out of the modelit keeps ignoring my formatthe model makes things up instead of saying it does not know

Works beyond Claude

Skills use the open Agent Skills format. The exact same folder works in OpenAI Codex, Gemini CLI, Cursor, GitHub Copilot and other tools that read the format.

Using a plain chat app? Paste SKILL.md into ChatGPT or Gemini as instructions. You lose auto-triggering, but the method still works.

agentskills.io

Pattern credit: Anthropic — Prompt engineering overview

Related skills