Guide
How to Prompt an AI Agent for a Refactor
Prompt an AI agent for a refactor by naming the public behavior that must stay the same, the files in scope, the reason for the change and the checks that prove nothing drifted. Avoid asking for a broad cleanup, and ask for one structural move at a time.

On this page
- What does a reviewable agent task look like?
- Can I adapt the prompt to my repo?
- How should a team run each agent task?
- What should you keep after the run?
- How do I refactor a large legacy codebase safely?
- Why is a refactor diff so hard to review?
- How big is too big for one refactor prompt?
- What do I do when the agent improves things I did not ask for?
What does a reviewable agent task look like?
Give the agent one named task, only the context it needs and a check you can rerun. A task shaped this way produces a diff small enough to review and a result you can repeat.
- Move
- Start with a bounded task
- Use this when
- You have a named owner, target files and a clear done state
- Proof to save
- Issue, files, checks and owner are named
- Move
- Give the agent context
- Use this when
- The repo has patterns the agent must follow
- Proof to save
- Prompt cites files, errors and constraints
- Move
- Review the diff
- Use this when
- The task changes production code
- Proof to save
- Changed files, test output and risks are visible
| Move | Use this when | Proof to save |
|---|---|---|
| Start with a bounded task | You have a named owner, target files and a clear done state | Issue, files, checks and owner are named |
| Give the agent context | The repo has patterns the agent must follow | Prompt cites files, errors and constraints |
| Review the diff | The task changes production code | Changed files, test output and risks are visible |
Each move leaves proof that a reviewer can check later.
Each move fails in its own way. Without a boundary, the agent edits files you never meant to open, and the diff becomes hard to read. Thin context fails more quietly: the code compiles and the tests pass, but the change ignores patterns the rest of the repo follows. Without a check you can rerun, you are taking the agent's word that the work is done.
Asking for a plan before the agent writes code is the easiest step to skip. It means a short wait while nothing visible happens, and the price of skipping it shows up later, in review.
If the plan names files you didn't expect, you learn that before any code exists. If it names the right files, you have a list to check the diff against. Once four hundred lines of diff are on screen, changing the approach means throwing that work away.
This is covered hands-on in Agent Mode Foundations — 6 short Units, free to read.
Rather do it than read about it? Run 11 interactive Cursor walkthroughs in a simulated editor. Free, no account needed.
Can I adapt the prompt to my repo?
Yes. Treat the frame below as a starting point. Fill in your own files, constraints and done state, and keep the plan step, so the agent commits to an approach before it writes code.
Task: [one outcome] Context: [files, errors, docs and examples] Boundary: [what not to touch] Done when: [test, typecheck, screenshot or review proof] Before editing, write a short plan with files, risk and checks.
Fill the Context line with things the agent can open: file paths, the exact error text and the doc or example to follow. Paste errors instead of paraphrasing them, because a paraphrase drops the detail the agent needs to trace the cause.
The Boundary line is easy to leave out, and in our view it does the most work. Without it, every file the agent can reach is fair game. You end up reviewing incidental edits to config, imports and helpers you had forgotten about, mixed in with the change you wanted. Naming what not to touch takes a few seconds, and reverting stray edits afterwards takes far longer.
"Done when" has to name something you can run or look at: a test name, a typecheck, a command whose output you can read, or a screenshot of one specific state. "Done when the bug is fixed" doesn't count. It hands the judgment back to the agent, and the agent will report that the work is finished either way.
How should a team run each agent task?
The habit that matters most for a team is leaving a trail the next reviewer can follow. The steps below keep the prompt and its proof attached to the change.
- 1Pick one real backlog item with a clear owner and expected result.
- 2Add only the context the agent needs: files, failing output, constraints and done state.
- 3Ask for a plan before code when the task touches more than one file.
- 4Run checks that match the risk: unit test, typecheck, visual pass or review checklist.
- 5Capture the prompt, diff, result and reviewer note so the workflow can be repeated.
Match the effort to the change. A one-file fix needs a clear done state and a typecheck, and a plan adds little. A change across several files is where a plan pays for itself, and where the check should include tests and a reviewer who knows that code.
What should you keep after the run?
Keep whatever lets someone rerun the work or pick it up later. A finished task is the merged code plus a short trail that shows how it got there.
- The prompt or plan that shaped the work.
- The files changed and the reason each file changed.
- The command, screenshot or review note that proved the result.
- The rule, checklist or template you would reuse next time.
The last item pays off over time. A rule or template saved from one good run means the next run starts from what already worked, not from a blank prompt.
How do I refactor a large legacy codebase safely?
Pin the behavior before you touch it. On a big, idiosyncratic repo, treat tests as guardrails: identify the current behavior, write tests that lock that current state, then make the minimal change while keeping inputs and outputs identical. A language migration works the same way. Moving legacy Java to something faster, such as Go, keeps the same inputs and outputs and gains speed and flexibility.
- 1Identify the current behavior you must not break.
- 2Write characterization tests that pin that current state.
- 3Make the smallest code change that meets the new goal.
- 4Keep input and output identical, and rerun the pinned tests.
The tests aren't there to prove the new design is clever. They are there to prove you changed nothing the caller can see.
identify the current state, write tests for that current state, and then do the minimal code changes... by maintaining the output of the current state.
The approach scales to large repos. In Cursor's QA workshop, the demo ran against Grafana: roughly 70K stars, about ten years old, more than 13K contributors and potentially gigabytes of files. Cursor's search docs describe Instant Grep, which builds and queries its index on your machine and outperforms ripgrep on large codebases, plus an Explore subagent for broad searches.
Why is a refactor diff so hard to review?
In a clean refactor, every line changes and the behavior does not. A reviewer usually reads a diff by asking what each line changes about the program's behavior. Here the answer is nothing, on every line, so the diff carries no signal. Pin the behavior in tests before you start, and let the tests do the reviewing.
Tests written afterward cannot do that job. They prove the new code agrees with itself, and the behavior they needed to capture is already gone.
A guardrail test you have never seen fail may not test anything. In Cursor's QA workshop, attendees described generated tests that log a failure with something like reporter.log instead of calling the framework's fail() method. Others wrapped the assertion in a try-catch that swallowed it. Make each guardrail go red for the reason you expect before you rely on it.
How big is too big for one refactor prompt?
Line count is a poor guide. What predicts a bad refactor run is how many judgment calls sit inside it. A rename across sixty files is large, but you can check it one grep at a time. A forty-line change to how a module gets its dependencies is small, and it can take an afternoon to be sure of.
So ask for one structural move per prompt, sized so you can describe it in a single sentence, such as "extract this into its own module" or "rename this concept everywhere it appears". If the description runs to a paragraph, you are looking at two moves under one name.
What do I do when the agent improves things I did not ask for?
Send the run back instead of reviewing it. A coding agent has a bias for action and will happily rewrite a module, so a mechanical move can come back with a rename you never asked for and a tidied import block. Now you cannot separate the move from the extra changes. The pinned tests will not flag them either, because they only check the behavior you pinned.
Prevent this in the Boundary line of the frame above. On a refactor, give the boundary more words than the task: name the files in scope, then name what is not part of this move.
It also helps to invite improvements as a separate follow-up. The suggestions are often good, and they belong in a diff of their own.
Frequently asked questions
Who is this guide for?
Developers using AI agents for refactors in production repos.
What should I do next?
Choose one structural move you can describe in a single sentence. Pin the current behavior with tests you have watched fail, and name what is out of scope before you prompt.
How do I stop an AI refactor from changing behavior?
Pin the behavior first. Identify what the code does now, write characterization tests that lock that state, make the smallest change and rerun the tests. Watch each test fail for the reason you expect before you rely on it, because a test you've never seen fail may not test anything.
How much should one refactor prompt ask for?
One structural move, small enough to describe in a single sentence, such as extracting a module or renaming a concept everywhere. Line count is a poor guide: a rename across sixty files is easy to check, while a forty-line change to how a module gets its dependencies can take an afternoon to verify.
Sources & last verified
- Cursor docs: prompting agents
- Cursor Learn: context
- Cursor Learn: working with agents
- Cursor agent best practices
- Cursor docs: Search (Instant Grep)
Cursor ships frequently. Facts verified against primary sources on October 28, 2026.