Skip to content

Effective Prompting Techniques

You ask for “a user authentication system with email verification,” the model picks a session strategy you’d never ship, hardcodes a mailer you don’t use, and you spend the next twenty minutes un-picking choices it made because you never made them. The model wasn’t wrong — it was unguided. The gap between a frustrating session and a great one is almost never the model. It’s how you frame the request.

These are the prompting patterns that consistently produce accurate, well-architected code across Cursor, Claude Code, and Codex.

  • A clarification-first prompt pattern you can append to any complex request
  • A plan-then-execute loop that stops the model rushing into a flawed implementation
  • Few-shot and persona prompts that lock the model to your codebase’s conventions
  • A per-tool troubleshooting table for when output quality drops

This works because it forces the model to expose its assumptions while they’re still cheap to change. Use the same pattern across the lifecycle:

  • PRDs: “Ask for everything you need to prepare the best PRD”
  • Planning: “Ask for everything you need to prepare the best plan”
  • Implementation: “Ask for any clarifications before starting”
  • Debugging: “Ask for any additional context that would help diagnose this issue”

The more constraints you supply, the less the model improvises. Vague requests get generic code; specific requests get code you can ship.

  • Don’t say: “Add a database connection.”
  • Do say: “Add a connection to our PostgreSQL database using the pg library. Load the connection string from DATABASE_URL. Include retry logic with exponential backoff and a typed health-check function.”

Naming the library, the env var, and the error behavior upfront steers the model to the right implementation in one pass instead of three.

For anything bigger than a one-line change, force the model to think before it codes.

  1. Ask for a plan first — and forbid code.

    I need a feature that lets users upload a profile picture. First,
    produce a detailed, step-by-step plan: list the files you'll create
    or modify and the order of changes. Do NOT write any code yet.
  2. Review and refine the plan. The model returns an outline (“1. Add /api/upload-avatar. 2. Add a file input to ProfilePage…”). Correct it before any code exists: “Use a separate AvatarUpload component instead of editing ProfilePage directly.”

  3. Execute the approved plan.

    The plan looks good. Implement step 1 only, then stop so I can review
    the diff before we continue.

This two-phase loop catches architectural mistakes when they cost a sentence to fix, not a 30-file diff. For the full discipline, see PRD to Plan to Todo.

To make the model match your codebase’s conventions, show it an existing file rather than describing the convention in prose.

  • Don’t say: “Create a service class with a constructor, a private logger, and JSDoc on public methods.”
  • Do say: “Create a PaymentService class that follows the exact pattern and structure of @/services/AuthService.ts.”

Models are excellent at pattern-matching. A concrete example is a tighter spec than any description.

Priming the model with a role focuses it on the right domain of knowledge.

Security Expert

“You are an expert security engineer. Review this code for XSS, CSRF, and SQL injection. List every issue with a concrete fix.”

Performance Guru

“You are a senior performance engineer. Find bottlenecks in this function and suggest optimizations that reduce allocations and time complexity.”

Treat the session as a dialogue, not a single shot. Steer the first attempt toward what you actually want:

  • “Good start, but you didn’t handle the unauthenticated case. Add that check.”
  • “This works but reads poorly — refactor the nested ifs into a switch.”
  • “Add a comprehensive unit-test suite for the function you just wrote.”

When This Breaks: Per-Tool Troubleshooting

Section titled “When This Breaks: Per-Tool Troubleshooting”

When output quality drops, the cause is almost always context or configuration — not the model. The fixes differ per tool, so this is where the three diverge most.

  • Model doesn’t understand the codebase: create a rule via the New Cursor Rule command (Cursor Settings > Rules, Commands), or generate one from chat. Rules persist project conventions into every request.
  • Model recreates existing code: @-mention the source — @auth.ts extend the login logic — so it edits rather than reinvents.
  • Confused about a library: add the Context7 MCP (“use Context7 for docs”) so current library docs are pulled into context.
  • Poor quality on hard tasks: confirm you’ve selected a top model in the picker (Claude Fable 5, Opus 4.8, or Sonnet 4.6) and enable MAX mode for large-context work. Fable 5 is the strongest option for the hardest refactors and complex multi-file work; see model comparison for the full tier and pricing breakdown.
  1. Set up context. Maintain project rules / CLAUDE.md / AGENTS.md; refresh as the codebase changes.

  2. Use the right capability. Pick a top model; on Claude Code raise the effort level for architecture work; in Cursor enable MAX mode for large context.

  3. Be explicit. Reference specific files with @-mentions and show example patterns.

  4. Request clarification. End prompts asking what the model needs; use the PRD to Plan to Todo loop for control.

  5. Configure documentation access. Add the Context7 MCP, or instruct a web search for current library docs.