Three levels of assistance
| Level | What it does | What you must supply |
|---|---|---|
| Completion | Finishes the line or block you're typing | Direction, constantly |
| Conversation | You describe a change, it returns code you paste | Context and judgement |
| Agent | It reads files, edits them, runs commands, iterates | A precise goal and a real review |
Moving down the table increases leverage and increases the cost of an unnoticed mistake. Completion errors are visible immediately. An agent working for twenty minutes can produce a large, confident, plausible change that is wrong in a way you'll only find in production.
What to delegate
The reliable division: delegate work where the correct answer is well known and the tedium is in the typing. Keep work where the difficulty is in deciding what correct means.
- Delegate, boilerplate, tests for existing behaviour, format conversions, regex, config files, repetitive refactors, first drafts of documentation
- Delegate carefully, a new feature in a well-established pattern, in a codebase it can read
- Keep, data models, security boundaries, anything touching money, and any decision that will be expensive to reverse
Writing a request that works
Most poor output is a poor request. The difference between the two versions below is the difference between something you rewrite and something you keep.
Weak: "Write a function to validate emails" Strong: "In this TypeScript file, add a function that checks whether a string is a plausible email address. Return a discriminated union { ok: true } | { ok: false, reason: string }. Don't add dependencies. Don't try to be exhaustive about the RFC, we send a confirmation email anyway. Match the existing style in this file."- Say where the code goes and what's around it
- Say what the output shape must be
- Say what not to do, new dependencies are the most common unwanted addition
- Say what the code is for, so it can make the right trade-off
Reviewing what comes back
Generated code arrives looking finished. It has consistent naming, comments, and error handling, and it reads like a competent colleague wrote it. That surface quality is uncorrelated with whether it's correct, and it makes review harder than reviewing a human's rough draft.
- Read the edges firstEmpty input, missing values, failed network calls. The happy path is nearly always fine; the edges are where confident guessing shows.
- Check every import and API call is realPlausible-but-nonexistent methods are a signature failure of this workflow.
- Check it fits your codebase, not the average codebaseIt may have introduced a second way of doing something you already do one way.
- Run it against a case you choseNot the case it suggested. Its example was chosen to succeed.
Common mistakes
- Accepting code you don't understand because it runs
- Asking for a large feature in one request instead of several reviewable steps
- Letting it add a dependency to solve a ten-line problem
- Reviewing generated code less carefully than a colleague's, because it looks tidier
- Using it to learn a subject and never verifying what you learned
Key takeaways
- Completion, conversation, and agents trade leverage against review cost
- Delegate the well-trodden; keep the decisions that are expensive to reverse
- Precise requests with constraints produce usable code; vague ones produce average code
- Review edges, imports, and fit, not the happy path
Try it yourself
Take a small function you wrote yourself and ask a model to write it from your description. Compare them line by line. The differences show you both what the tool assumes and where your description was ambiguous.
CHECK YOUR UNDERSTANDING
Pass the quiz below to unlock this.
