Prompt Engineering Patterns for Code Refactoring Agents
Explicit prompts on intent, scope, and verification make refactoring agents far more reliable.

Code refactoring agents depend less on model strength than on how their prompts define intent, scope, and verification. The most useful prompt engineering patterns make those obligations explicit before editing begins. Naming the operation, constraining context, separating planning from action, and defining completion account for much of the reliability difference. More complex architectures extend those patterns.
Why refactoring agents fail more often than they should
Refactoring asks for a structural improvement without a change in external behavior, but that definition leaves much unresolved. It does not tell an agent which structure is wrong, which transformation applies, or which dependencies must remain intact. Liu et al. found that agents identify the correct refactoring at a very low rate without an explicit refactoring type, but reach the high eighties when it is supplied. That gap makes underspecified intent a more actionable problem than model selection. An agent cannot reliably preserve a developer’s intent when the prompt requires it to guess what that intent is.
Each guess creates an opportunity for behavioral drift, scope creep, or a change that breaks downstream code. In Python, keeping behavior unchanged is especially hard because dynamic typing, runtime name resolution, and dynamic dispatch can hide changes in behavior even when a transformation seems to work. Oliveira et al. found 13 distinct bugs across seven refactoring types in Rope implementations, with 12 accepted by the respective developers. That finding concerns refactoring implementations themselves. It shows why a tool that seems to work still needs a clear account of what must stay unchanged.
What makes a refactoring prompt structurally sound
A sound prompt covers intent, scope, and verification. Intent states what should improve and why that improvement is needed. Scope identifies the files and methods that may change and the boundaries the agent must preserve. Verification sets a machine-checkable condition for when the work is done, so the agent has no need to judge success for itself. These dimensions serve different purposes, so precision in one does not compensate for silence in another.
For example, even with a clear structural goal, the agent can edit too much if the prompt leaves open which code it may change. Supplying an entire repository does not resolve that problem, because available context and permitted scope are not the same thing. Context can instead be divided into critical material, helpful material, and background to ignore unless needed. That division separates obligations from information the agent may consult. Verification then closes the remaining gap between a change that looks complete and one that meets the task’s stated requirements.
Naming the refactoring type explicitly and why vague instructions collapse
The highest-return change is to replace a vague improvement request with a named operation, a target location, and a rationale. Liu et al.’s jump from a very low identification rate to the high eighties shows how much it helps to tell the agent which operation to use. A request to “make this class cleaner” asks the agent both to diagnose the design and to choose among possible transformations. Naming Extract Method or Move Method removes that first layer of ambiguity. The agent can then work on a defined transformation rather than invent its own interpretation of improvement.
A concrete instruction can say to extract lines 42–67 of PaymentProcessor into a private method named calculateFee because the method currently violates single-responsibility. This gives the agent an operation, a location, a destination, and a reason. Specifying the target method signature, its containing class, and the behavioral contract narrows the task further. These details are not decorative formalism, because each eliminates a choice the agent would otherwise make. Although writing them requires upfront work, the relevant comparison is the cost of a precise instruction against the cost of repeated correction.
Separating planning from acting to prevent scope drift
Even a correctly named operation can go wrong when the agent edits before it understands dependencies. Plan-before-act separates that understanding from execution and gives the developer a chance to reject an unsafe scope before a diff exists. The first step produces a plan, writes no code, modifies no files, and states assumptions and risks. The second step begins only after the developer reviews the plan. This is a prompt-level boundary.
Anthropic’s Explore, Plan, Implement, Commit workflow for Claude Code makes the same separation explicit. Its Explore phase is read-only and builds understanding. A brief planning instruction can ask the agent to read the relevant directory, explain the concern, identify key files and request flow, and state assumptions without changing code. For larger refactors, the plan also needs dependencies, safe intermediate states, tests, rollout steps, rollback strategy, and stopping criteria. Those checkpoints make the proposed sequence reviewable before the agent commits to it.
Stripe constrained Minions to narrow tasks with clear inputs and explicit success criteria after early unconstrained agentic attempts broke CI. Its blueprint architecture alternates deterministic steps with agentic steps, placing boundaries around work that would otherwise remain open-ended. That approach makes the additional review round trip preferable to a multi-file diff that fails review and must be reverted.
Output contracts: telling the agent what done looks like before it starts
SmellBench shows why passing tests alone is not enough to establish refactoring quality. Architectural quality can degrade while functional checks still pass, so test-passing behavior is an incomplete objective. An output contract defines what the result must contain, what it must not change, and what evidence establishes completion. It turns verification from an afterthought into part of the task. Without that contract, the agent can satisfy a narrow functional check while missing the structural purpose of the refactor.
A useful contract calls for replacement code, the files that changed, the key changes, and any compatibility risks. It also names protected boundaries, including public APIs, behavioral contracts, and external interfaces. Completion evidence can include a passing test suite, a clean build, and a diff with no unintended file touches. Architectural criteria must sit beside those checks, since functional correctness does not establish that the requested design improvement occurred.
Failure Mode Declaration tells the agent to say what is missing, keep to known facts, give the smallest useful partial answer, and name the input it needs next. The Decision Ledger records key assumptions, trade-offs, why an option is safest, and what could go wrong. Together, they make incomplete work honest and completed work auditable. That matters when several reviewers must assess the same AI-generated change without reconstructing its unstated assumptions.
Each guess creates an opportunity for behavioral drift, scope creep, or a change that breaks downstream code.
Few-shot examples and the context budget in practice
A weak class design paired with an improved version shows what clearer responsibilities mean in practice. Unlike a general request for clean code, the pair gives the agent a concrete standard for naming, style, and granularity. Anthropic documents referencing an existing example file as a way to anchor style without describing it at length. For refactoring, that reference helps connect the requested operation to the codebase’s own conventions.
Examples still need a disciplined context budget. The critical tier contains the target file or method, the tests that must keep passing, and the output contract. The helpful tier has nearby files that the refactoring may touch and the interface definitions that matter to the task. Configuration files, unrelated modules, and project history belong in the ignore-unless-needed tier. These priorities tell the agent which material governs the task and which material supplies background only.
Anthropic notes that context degrades as it fills, which makes this distinction more than a cost-control measure. Pasting the whole repository draws attention to code outside the task and can make the work slower, more costly, and less consistent. Even with a large context window, the context still needs to be chosen with care. Where dependency implications are non-obvious, staged reasoning about those dependencies can supplement the examples. The purpose remains a bounded structural decision.
Where simple prompt patterns reach their limits: compound and repository-scale refactoring
These patterns help with many failures on atomic refactorings, but in compound work, transformations depend on one another. Each step’s output becomes the next step’s input, so an edit that looks right on its own may not fit the planned sequence. Research on LLM-driven refactoring finds a sharp drop from atomic to compound tasks. Greater prompt precision remains useful, but it cannot by itself remove the difficulty of coordinating tightly constrained changes. This is the point at which the unit of work matters as much as the instruction.
SWE Refactor Bench, released on arXiv on August 24, 2026, tested full-repository technology stack migrations across multiple runs of frontier models. Only a small share passed every stage of evaluation. SWE-Bench ProMax also exposes a scope difference, with a large share of instances changing many files and hundreds of lines, while the vast majority of SWE-bench Verified instances modify a single file. Its question about benchmark validity matters just as much, because higher scores alone cannot show how well a model handles software engineering as a whole. Tasks that span files or a whole repository need more than prompts built for single edits, especially since passing tests tells only part of the story of architectural quality.
Multi-agent and loop architectures for refactoring at scale
Multi-agent systems extend prompt patterns by assigning separate stages to bounded sub-agents. MANTRA, from Concordia University in 2025, divides work into planning, generation, compilation, testing, and self-reflection. It combines Context-Aware Retrieval-Augmented Generation, coordinated multi-agent collaboration, and Verbal Reinforcement Learning. Its refactorings are perceived to be as readable and reusable as human-written code. That result supports the approach without establishing that every refactor needs its orchestration overhead.
SWE-Refactor makes the complexity trade-off clearer. Multi-agent, RAG, and simple prompting do about as well as each other on straightforward Extract Method tasks. On Move Method and Extract+Move tasks, the multi-agent workflow finishes far more cases. The extra architecture is therefore justified by harder coordination problems. Simple constrained prompts remain the appropriate baseline for well-scoped work.
Stripe and Spotify illustrate contrasting operational priorities. Stripe’s Minions emphasizes narrow, well-defined tasks without multi-agent orchestration overhead. Spotify’s Jo Kelly-Fenton and Aleksandar Mitic described Honk at QCon London 2026 as a coding agent for migrations across Spotify’s codebase. Honk addressed complexities that traditional scripts could not handle and reduced migration timelines, while edge cases and standardizing code for review remained challenges.
Lulla et al.’s JAWs@ASE 2026 paper describes loop engineering as building systems that prompt agents in place of a person guiding each run interactively. The emerging framing uses machine-checkable stop conditions, persistent state files, verifier sub-agents, token budgets, and escalation points. Its impact claims rest almost entirely on anecdotes and self-reported productivity numbers, so it is not yet an established best practice. The study found autonomous loops in the majority of matched repositories, but almost none committed the prescribed state files. Teams are taking up the architecture faster than the tools that make it reliable, and every run still needs the earlier prompt patterns.
Putting the patterns together: a decision framework for choosing prompt structure
Choose the structure by asking whether the operation is atomic or compound and whether it touches one file or many. For atomic, single-file work, use an explicit refactoring type, an output contract, and a reference-pattern example. Plan-before-act is optional but low-cost at this level, and multi-agent orchestration is unnecessary. For compound work within one file, make planning mandatory and use structural examples to clarify how the operations interact. Add a Decision Ledger so reviewers can assess the assumptions behind the sequence.
For multi-file refactoring, use staged planning with dependencies, safe intermediate states, tests, rollout steps, rollback strategy, and stopping criteria. Enforce the context budget strictly, add a build gate and an architectural review criterion, and consider whether a loop is warranted. For full-repository technology stack migration, use a loop or multi-agent architecture, with Stripe and Spotify as contrasting reference points. Machine-checkable stop conditions must govern repository-scale execution rather than leaving completion to an agent’s narrative. At every level, Failure Mode Declaration requires the agent to expose missing inputs.
The highest-leverage implementation detail is to make these constraints persistent. Claude Code, Cursor, and GitHub Copilot support the prompt patterns through their respective working contexts. Teams can encode output contracts and context budgets in CLAUDE.md, .cursor/rules/ as a directory of .mdc files, and .github/copilot-instructions.md. That avoids restating the same boundaries in every session. Reliable refactoring then starts from a specification that stays in place, with less riding on how carefully someone words the next request.
Sources
- Detecting Behavioral Changes in Python Refactoring Implementations with Foundation Models
Provided the finding about 13 distinct bugs across seven refactoring types in Rope implementations, used to illustrate why behavioral preservation needs explicit specification.
- Loop Engineering: Building Blocks, Adoption, and Impact
Provided the loop engineering framing — building systems that prompt agents in place of a person — along with findings on autonomous loops, state file adoption, and impact claims based on anecdotes.
- Do Prompt Patterns Affect Code Quality? A First Empirical Assessment of ChatGPT-Generated Code
Provided the empirical data on identification rates for refactoring types, showing the jump from very low rates without an explicit type to the high eighties when it is supplied.