Best Practices for AI-Assisted Development
Two developers get the same AI assistant and the same ticket: “add team invitations to the dashboard.” One pastes the ticket, accepts a 400-line diff, and spends the afternoon debugging why invites silently fail for existing users. The other ships it in an hour with passing tests and a clean diff. Same model, same task. The difference is workflow, not prompting.
Using an AI assistant well is less about clever wording and more about a repeatable loop: feed it the right context, plan before you execute, and verify continuously. This guide covers the core practices, grounded in a real feature, and points you to deeper articles for each.
What You’ll Walk Away With
Section titled “What You’ll Walk Away With”- The context inputs that actually move output quality (precise
@-mentions and a persistent rules file) - A concrete Plan-Execute-Verify loop applied to a real Next.js + Drizzle feature
- Copy-paste prompts for the plan, execute, and verify phases
- How each phase maps to Cursor, Claude Code, and Codex mechanics
- The failure modes that quietly erode AI-assisted work, and how to catch them
1. Context Is King
Section titled “1. Context Is King”The biggest lever on output quality is the quality of context you provide. Two inputs do most of the work.
Precise @-mentions. Reference the exact files and symbols the task touches rather than letting the AI guess. For our invitations feature: @src/db/schema.ts @app/api/teams/route.ts. Pointing at the schema and the route is worth more than ten sentences of description.
A persistent rules file. Encode your stack and conventions once so you don’t repeat them every prompt. A short CLAUDE.md (also read by Codex) or .cursor/rules/*.mdc file like:
- DB access goes through Drizzle in src/db; never write raw SQL in route handlers.- API routes return typed JSON via the `apiResponse()` helper in lib/api.ts.- All new tables need a migration in drizzle/ and a matching zod schema.2. Adopt a Structured Workflow: Plan, Execute, Verify
Section titled “2. Adopt a Structured Workflow: Plan, Execute, Verify”The reliable pattern is three phases with a human checkpoint between each. Here it is applied to adding team invitations.
-
Plan first (read-only). Work in a read-only mode so the AI proposes without editing. Have it produce a TODO plan that names the files each step touches.
-
Execute incrementally. Switch to an execution mode and do one TODO item at a time, reviewing each diff. Working in small steps keeps every change reviewable.
-
Verify continuously (TDD). Use automated feedback loops. Test-Driven Development is especially powerful here: have the AI write failing tests first, confirm they fail, then implement until green.
Each Phase, Per Tool
Section titled “Each Phase, Per Tool”The Plan-Execute-Verify spine maps onto distinct mechanics in each tool. The discipline is identical; the controls differ.
Plan in the Ask mode (mode dropdown, read-only). Execute by switching to Agent, accepting diffs per hunk; Cursor writes a checkpoint before each edit so you can roll back a bad step. Verify by having Agent run your test command and fix failures, reviewing each change before accepting.
Plan in plan mode (claude --permission-mode plan, or Shift+Tab to cycle into it). Execute in default mode (approve commands) or accept-edits mode for auto-applied edits. Verify with a PostToolUse hook that runs your test suite after each edit, so a failing change can’t accumulate unnoticed.
Plan with codex --sandbox read-only. Execute with --full-auto (sets on-request approvals and a workspace-write sandbox), ideally in a worktree to isolate changes. Verify by letting Codex run tests and then opening a GitHub PR, so your normal CI and reviewers gate the merge.
3. Treat the AI as a Junior Developer
Section titled “3. Treat the AI as a Junior Developer”The AI is fast, broadly knowledgeable, and occasionally naive. Direct it like a talented junior: give it one well-scoped task at a time (the execution prompt above), review its output line by line rather than trusting green tests, and give corrective feedback instead of starting over. The conversational loop is a strength — a precise “the 409 case isn’t handled; add it and re-run the tests” is faster than rewriting the prompt from scratch.
When This Breaks
Section titled “When This Breaks”- Context overload. Twenty
@-mentioned files produce worse answers than three. Trim to what the task touches. - Plan drift. Long sessions wander from the approved plan. Re-paste the numbered TODO and ask which step you’re on before continuing.
- Rubber-stamped reviews. After several correct diffs you stop reading; that’s when the bug ships. Keep diffs small and lean on automated gates (hooks, CI) that don’t fatigue.
- Tautological tests. AI-written tests can pass against broken code. Confirm a test actually fails when you break the implementation.
What’s Next
Section titled “What’s Next”Go deeper on each practice: