The prompts that survive contact with production do not read like poetry. They read like typed function signatures with pre- and post-conditions. Cleverness is a liability because it hides intent from the next engineer — and from the model.
The principle
A prompt is a contract between your system and a stochastic function. The contract has an input schema, an output schema, and a set of error paths. Anything else is decoration.
The contract shape
SYSTEM:
You are a citation extractor.
INPUT (JSON):
{ "doc": string, "max_citations": int }
OUTPUT (JSON, strict):
{ "citations": [{ "quote": string, "page": int }],
"confidence": number,
"error": null | "no_source" | "ambiguous" }
RULES:
- Never invent quotes not present verbatim in "doc".
- If unsure, set error and return [].Error paths
Give the model a way to say “I don't know.” A prompt without an error slot forces hallucination — the model has no legal way to abstain.
caveat
Every prompt in production should have an error field in its output schema. Downstream code that treats abstention as a valid response is dramatically more reliable than one that assumes success.Testing prompts
- Snapshot tests on the JSON schema — any drift fails CI.
- A small golden set of 20-50 cases, graded deterministically.
- Adversarial cases: empty doc, contradictory doc, prompt-injection doc.
Ship the prompt like you ship any other function: typed, tested, versioned, monitored.