Prompt Engineering Guide: 10 Techniques That Actually Work


Disclosure: This article may contain affiliate links. We only recommend products we believe in. See how we make money.

These techniques apply in any chat box or API. For wiring Claude specifically, use the Claude API tutorial. For catching invented APIs after a prompt lands, see how to reduce AI hallucinations in code generation. Day-to-day pairing habits live in the AI pair-programming workflow.

The same model that shrugs at “fix this” will produce usable code from a prompt that names the runtime, the output shape, and what not to invent. That is prompt engineering: specifying the job. It is not a personality transplant.

Model choice still matters — ChatGPT vs Claude vs Gemini is the comparison — but swapping models will not save a vague prompt.

1. Specify the artifact, not the topic

Weak: “Write about Python decorators.”

Usable: “Write a technical tutorial on Python decorators for someone who already writes functions. Include three examples: a timing decorator, a decorator with arguments, and functools.wraps. Each example needs inline comments. Do not cover metaclasses.”

Name the genre (tutorial, review comment, migration plan), the audience, the length, and the sections. The model will fill a shape you did not ask for if you do not give one.

2. Give a role and the constraints of that role

“You are a senior backend engineer” is flavor text unless you also say what that engineer is allowed to do.

You are reviewing a pull request for a production API.
Check only: authz, input validation, and missing tests.
Do not suggest a rewrite. Do not comment on formatting.
If you are unsure, say "needs a human" instead of guessing.

That is the difference between a code-review bot and a chatbot that wants to redesign the service. For editor-native review, Cursor vs Copilot is the tool layer; the prompt is still yours.

3. Chain of thought — when it is worth the tokens

Adding “think through this step by step” helps on multi-hop reasoning (a gnarly regex, a race, a tax of edge cases). It is wasted tokens on “rename this symbol.”

For APIs, prefer a hidden scratchpad the product already supports (Claude’s thinking modes, a scratch field you discard) over a user-visible essay. You want the answer to be short even if the work was long.

Wei et al.’s chain-of-thought prompting is the usual citation. Treat it as “show intermediate work on hard problems,” not as a magic suffix.

4. Few-shot the shape, not the entire job

Two or three input/output pairs beat a paragraph of adjectives. The model pattern-matches the format.

Input: "The API returned a 429 error"
Classification: rate_limit
Severity: medium
Action: retry with Retry-After

Input: "Database connection pool exhausted"
Classification: infrastructure
Severity: critical
Action: page on-call

Input: "User reported slow page loads on mobile"
Classification:

This is also how you keep rate-limit and incident labels consistent across a team. Put the examples in the system prompt so every user turn inherits them.

5. Constrain the output so another program can read it

“Respond in JSON with keys summary, severity, recommendation.” “List exactly five items.” “No markdown fences.”

If a script will parse the answer — a CI reviewer, an agent tool — the constraint is the interface. Ask for a schema. Reject and retry when the parse fails. Do not “be flexible” in the parser.

6. Say what to omit

Negative instructions work when they are specific:

  • “Do not invent functions that are not in this file.”
  • “Do not add a try/except that swallows the error.”
  • “Do not include a motivational intro.”

“Don’t be generic” does nothing. Name the failure you have already seen.

7. Iterate on the artifact, not the universe

One-shot perfection is a bad bet. Generate a skeleton, then point at a section:

  1. “Outline a migration from Express routes to Hono. No code yet.”
  2. “Write only the auth middleware from that outline.”
  3. “Now add tests for a missing Authorization header.”

This is the same loop as pair programming: you hold the spec, the model holds the typing.

8. Temperature is an API knob, not a vibe

Provider docs agree on the direction even when defaults differ:

  • Low (0–0.3) for code, extracts, classifications, anything you will parse.
  • Higher (around 0.7+) for brainstorming names or copy.

If you need two ideas, ask for two ideas at low temperature. Do not crank creativity and then complain the JSON is invalid. The Claude Messages API exposes temperature on the same messages.create call as system and max_tokens.

9. System prompt for the rules, user prompt for the work

Lives in systemLives in user
Role, language, output schemaToday’s diff, stack trace, or question
”Never commit secrets”The file that might contain one
Few-shot labelsThe next unlabeled input

Stable rules in system keep a chat or a batch job consistent. Variable work in user keeps the cache and the logs readable. Hosted free-tier chats hide this split; APIs do not — use it.

10. Ask for a critique of this answer

“Review your own response. List any invented APIs, missing edge cases, or tests you skipped. Then output a corrected version.”

Self-critique is cheap compared with a production incident. It is not a substitute for running the code. After the model revises, compile, test, and check imports.

A worked coding prompt

Put this in system (or the first message of a chat UI):

You write TypeScript for Node 22.
Output a single .ts file. No markdown fences.
Use the node:test runner. No extra dependencies.
If a library API is not in the prompt, do not invent it — say UNKNOWN_API.

Then the user turn:

Write a function `parseRetryAfter(header: string): number | null` that
reads an HTTP Retry-After value (delta-seconds or HTTP-date).
Include tests for: "30", an RFC 7231 date in the future, and "".

That prompt names the runtime, the output, the test runner, and the failure mode (invented APIs). It is longer than “write a parser.” It is also something you can reuse in CI.

When prompting is the wrong lever

  • Missing context. A better adjective will not replace the file the model cannot see. Attach the file, or retrieve it — see vector databases.
  • Wrong model for the job. A cheap, small model will not become Claude because you said “you are an expert.”
  • Unverified code. Prompts do not run tests. AI unit-testing does.

If you only change one habit: stop sending bare verbs (“refactor,” “optimize,” “make it production-ready”). Send the artifact, the constraints, and the definition of done.