Home / Coding with AI APIs

Prompt engineering for engineers

System prompts, few-shot examples, structured output and reasoning, treated as code you version and test.

8 min read

Interviewers don't want prompt "tricks". They want to see that you treat prompts like code: clear specs, versioned, tested against an eval set.

Anatomy of a good prompt

  1. Role and context: who the model is acting as and for whom.
  2. Task: exactly what to do, in plain language.
  3. Constraints: what not to do, length, tone, what to do when unsure.
  4. Input data: clearly delimited, for example with XML-style tags such as <document>…</document>.
  5. Output format: a schema or template.
  6. Examples: a few input → output pairs covering edge cases.
System: You are a support assistant for Acme's billing product.
Answer only from the documents provided. If the answer is not in them,
say you don't know and suggest contacting support.

User:
<documents>
  <doc id="7">…</doc>
</documents>
<question>Can I change my billing date?</question>

Respond in at most 3 sentences and cite doc ids like [7].

Techniques that matter

  • Be specific and positive. "Respond in under 100 words as a bulleted list" beats "don't be verbose".
  • Few-shot examples fix format and edge-case behaviour better than long descriptions. Make examples diverse so the model doesn't copy one too closely.
  • Let the model reason before answering on multi-step problems, either by asking it to think step by step or by using a model's built-in extended reasoning. Separate reasoning from the final answer if you parse output.
  • Structured outputs via JSON schema or tool definitions, rather than asking nicely for JSON.
  • Decompose complex tasks into a chain of smaller prompts, each easier to test.
  • Give an out: explicitly allow "I don't know" to reduce hallucination.

Managing prompts in a codebase

  • Store templates in version control with IDs and versions; log the version with every request.
  • Separate static instructions (cacheable) from per-request data.
  • Never concatenate untrusted input into instructions without delimiters.
  • Change prompts only alongside an eval run, the same way you'd run tests for code.