Code Generation and Refactoring: Beyond Autocomplete
Autocomplete finishes the line you’re typing. Large-scale AI-assisted refactoring rewrites a pattern across four hundred files, updates every caller consistently, and verifies each change compiles and passes tests — a task that used to require a dedicated engineer-week and a carefully hand-rolled codemod script. That difference in scope, not just in output quality, is what separates a coding assistant from an AI-native refactoring capability.
Three Tiers of Code Generation
| Tier | Example | What makes it hard |
|---|---|---|
| Line completion | Finishing a function signature or a loop | Minimal context needed, low risk |
| Function/file generation | Writing a new module from a spec | Needs to match existing conventions, covered in Context-Aware Code Intelligence |
| Cross-repository refactoring | Migrating from one API to another across the whole codebase | Needs a correct, complete understanding of every call site |
Most teams stop at tier two because tier three requires infrastructure most projects don’t have by default: a reliable way to find every affected call site, apply a consistent transformation, and verify nothing broke — at a scale too large for a human to review line by line.
What a Refactoring Agent Actually Needs
1. Complete call-site discovery. Before touching anything, the agent needs to enumerate every place the old pattern is used — via the symbol graph described in context-aware code intelligence, not a text search that misses aliased imports or dynamic dispatch.
2. A consistent transformation rule. The change applied to file 1 needs to be the same shape of change applied to file 400, even when the surrounding code differs — this is closer to a structural code transformation (an AST-based codemod) guided by the model than a fresh generation for every file.
3. Per-file verification. Each transformed file should compile and pass its local tests before the change is considered complete for that file — batching all 400 files into one untested commit turns a manageable refactor into an unreviewable one.
4. Staged rollout. Land the refactor in batches (by module or by risk level) rather than one giant PR, so a problem in batch 3 doesn’t block or complicate batches 1 and 2 that already merged cleanly.
Example: A Dependency Migration Workflow
Goal: migrate from requests to httpx across the codebase
1. Discover: find every import of `requests` and every call site (312 files)2. Classify: group by pattern — simple GET/POST calls vs. calls using requests-specific features (Session objects, custom adapters)3. Transform: apply the httpx-equivalent pattern per group, batch of 20 files at a time4. Verify: run each batch's tests; a batch with failures is paused for review, not silently skipped5. Escalate: files using requests-specific features with no clean httpx equivalent are flagged for human review instead of a risky automated guess6. Report: final PR summarizes what was migrated automatically vs. what needs manual attention, with links to each batchWhy This Needs the Rest of the Platform
Large-scale refactoring is where AI-native architecture pays for itself most visibly — it needs the agent runtime to execute safely at volume, the feedback loops to verify each batch, and governance to decide how large a change can land without explicit human sign-off. Refactoring at this scale isn’t really a code-generation problem — it’s a systems problem that code generation is one component of.
Starting Point
Don’t attempt full-repository refactors as a first project. Start with a bounded, well-understood transformation — renaming a widely-used function, or migrating one small dependency — and use it to validate your call-site discovery and per-batch verification before trusting the same pipeline with something riskier.