Skip to content
Back to AI Coding

Structured Prompt Engineering Patterns

Repeatable patterns for prompts that produce consistent, reviewable code: role, context, constraints, output format.

Prompt EngineeringIntermediate

Why

GitHub's 2024 survey found 92% of US respondents use AI coding tools to generate test cases, and 73% of open source respondents use AI tools for coding or documentation. Ad hoc prompts yield inconsistent output.

Structured patterns (role + context + constraints + format + examples) make output deterministic enough to review and iterate on. This is the difference between 'sometimes good' and 'reliably good' AI code, and it lets you version prompts alongside code.

When

Use structured prompts when you repeat the same kind of AI task (write a unit test, add a REST route), when multiple teammates use AI and you want consistent output, or when AI output must match a strict format (JSON schema, specific file template). Skip it for one-off exploratory questions.

How

1. Pick a pattern. The five-block pattern works for most code tasks: [ROLE] [CONTEXT] [CONSTRAINTS] [OUTPUT FORMAT] [EXAMPLES] 2. ROLE: who the AI acts as. Be specific. "You are a senior TypeScript engineer who writes strict, null-safe code." 3. CONTEXT: only what is needed, with file references. "Project: Astro 7 + zod. Relevant files: @src/api/router.ts @src/data/books.ts" 4. CONSTRAINTS: hard rules the output must obey. - Use named exports only. - Validate all inputs with zod. - Do not add new dependencies. - Match the existing error-handling pattern in router.ts. 5. OUTPUT FORMAT: the exact shape you want back. "Return only the new file content, no markdown fences, no explanation." 6. EXAMPLES: one or two input/output pairs (few-shot). This is the highest-leverage block. Paste a known-good route handler and say "follow this shape". 7. Store the prompt as a reusable file (prompts/add-route.md) and version it in git. Iterate when output drifts; treat prompts like code with reviews.

Example

Reusable prompt file: prompts/add-route.md ## ROLE You are a senior TypeScript engineer on an Astro 7 + zod project. ## CONTEXT - Router: @src/api/router.ts (Hono-style handlers) - Data layer: @src/data/books.ts (CRUD on Books table) - Existing route to mirror: @src/api/routes/health.ts ## CONSTRAINTS - Validate request body with a zod schema; infer the type. - Return 201 on create, 400 on validation error, 500 on DB error. - Named exports only; no new dependencies. ## OUTPUT FORMAT A single TS file, no markdown fences, no prose. ## EXAMPLE (contents of health.ts pasted here as the shape to follow) Usage in Cursor: @prompts/add-route.md "add POST /api/books"

Common Problems

  • ⚠Error: Model returns "I cannot help with that" → rephrase to remove restricted phrasing; narrow scope and provide explicit allowed examples.
  • ⚠JSON parse error on model output → wrap with a fenced ```json block and add "respond with valid JSON only" to the system prompt.
  • ⚠Error: Token limit exceeded (400 Bad Request) → split the prompt, summarize prior context, or switch to a larger context model.
  • ⚠Error: Model returns "I cannot help with that" → rephrase to remove restricted phrasing; narrow scope and provide explicit allowed examples.

Best Practices

  • ✓Keep prompts under ~2000 tokens. Long prompts dilute attention on the actual task.
  • ✓Put constraints as bullet negatives ('do not add deps') — models follow negatives better when explicit.
  • ✓Version prompts in git and review prompt diffs in PRs just like code.
  • ✓A/B test prompt variants on the same task; keep the one with fewer review corrections.
  • ✓Reuse one canonical prompt per task type across the team to guarantee consistent output.

FAQ

What is the five-block prompt pattern?

Role + Context + Constraints + Output Format + Examples. Role sets expertise, context scopes files, constraints set hard rules, format fixes the shape, and examples (few-shot) anchor it. Together they make output deterministic enough to review.

Why do I need few-shot examples in prompts?

Zero-shot prompts drift across model versions and produce inconsistent shapes. One input/output example anchors the exact format you want and is the highest-leverage block. Without it, the same prompt can yield different structures on different days.

How long should a structured prompt be?

Keep it under ~2000 tokens. Over-stuffing context (pasting 10 files) dilutes attention on the actual task. Include only the files the output depends on, plus one example. Long prompts cost more and perform worse.

Should I version prompts in git?

Yes. Store reusable prompts as files (e.g., prompts/add-route.md) and commit them. Review prompt diffs in PRs like code, and A/B test variants on the same task. Unversioned prompts in chat history are lost and can't be iterated as a team.

How do I stop the AI from wrapping code in markdown fences?

Add an explicit output-format block: 'Return only the new file content, no markdown fences, no explanation.' Without it, models default to wrapping code in fences and adding prose you must strip.