Prompts are API calls
Treat every prompt like a function signature: inputs, expected output, constraints, error handling. Vague prompts produce vague code. Senior engineers write specs, not wishes.
Bad: "Add error handling to this function"
Good: "Add try/catch to `processPayment()` in payment.ts. Catch StripeError
and PaymentTimeout separately. Log with structured JSON (level: error,
fields: orderId, stripeCode). Re-throw timeout; return 402 for card
errors. Match existing pattern in refund.ts lines 45-60. Add unit test."
The prompt anatomy for code
| Section | Purpose | Example |
|---|---|---|
| Role | Sets expertise level | "You are a senior TypeScript engineer on our payments team" |
| Task | One clear objective | "Implement retry logic for the webhook handler" |
| Context | Relevant code, errors, logs | Paste the file, stack trace, or failing test |
| Constraints | What NOT to do | "Don't modify the database schema; no new dependencies" |
| Output format | How to respond | "Return only the changed function; explain changes in 3 bullets" |
| Examples | Few-shot patterns | "Follow the pattern in refund.ts" |
Anthropic recommends XML tags (<task>, <context>, <constraints>) for Claude. OpenAI's guide emphasizes explicit instructions over implicit assumptions. Both agree: specificity beats cleverness.
Patterns that work for code
1. Chain of verification
Generate → "Now review your output against these constraints: [list]" → Fix
Cheaper than one-shot perfection; catches most obvious errors.
2. Diff-style requests Ask for changes, not rewrites: "Show only the modified lines with enough context to apply as a patch."
3. Test-first prompting "Write the test cases first, then implement. Tests must fail before your code, pass after."
4. Adversarial review "Find three bugs or edge cases in this implementation" — then fix them in a follow-up.
5. Constrained output Use JSON mode, structured outputs, or tool schemas when you need parseable results. Free-form prose is for exploration, not pipelines.
Few-shot: when and how
Few-shot examples teach format and style, not logic:
- Use when output format is non-obvious (custom DSL, internal API patterns)
- Use when you have 1-2 canonical examples in your codebase
- Skip when the task is well-defined and the model knows the language
- Danger: stale examples teach stale patterns — keep them current
Anti-patterns
| Anti-pattern | Why it fails |
|---|---|
| "Be careful" / "Don't hallucinate" | No actionable constraint |
| Mega-prompts (50 instructions) | Model loses early instructions (primacy/recency bias) |
| Asking for architecture + implementation + tests in one call | Context exhaustion; quality drops on later parts |
| Copy-pasting Stack Overflow as context | Conflicts with your codebase conventions |
Temperature and model selection for code
- Code generation: temperature 0–0.2, capable model (don't cheap out on architecture tasks)
- Exploration/brainstorming: temperature 0.7+, can use faster/cheaper model
- Review/analysis: low temperature, strong model — you want precision, not creativity
Interview framing
"I write prompts like function specs: explicit inputs, constraints, expected output format, and verification criteria. For production workflows, I use structured outputs and test-first prompting rather than hoping the model gets it right in one shot."
Senior signal: Show a before/after prompt diff. Explain why each addition reduces ambiguity. Mention that you version prompts in git alongside the code they affect.
Further Reading
Hands-On Tasks (Optional)
Practical exercises — prompt drills, local MCP servers, or workflow design on paper. The goal is professional fluency, not model training.
- Rewrite a vague prompt into a spec25m
Take a real prompt you've used ('fix this bug'). Rewrite it with: goal, constraints, files in scope, test criteria, and output format. Compare outputs side-by-side.