How to Make AI Consolidate Code—Without Micromanagement
Source: Dev.to
The Problem
When you say “refactor this,” AI defaults to responsibility separation.
"Refactor this namespace"
↓
AI splits by responsibility
↓
More files, clearer boundaries
↓
Context size increases
↓
Worse than before
I hit this directly. A namespace was growing too large, so I asked AI to refactor it. The result was more files, more indirection, and an even larger context window.
To force DRY consolidation, I had to micromanage:
- specify exact files
- point to specific lines
- explain which patterns were “the same”
That doesn’t scale.
First Attempt: Policy Declaration
My first idea was to declare a refactoring policy upfront:
Refactoring Policy:
- Priority: DRY (consolidate duplicates)
- Prefer integration into existing files
- Minimize responsibility separation
- Do not increase file count
AI understood the policy, then asked:
“Which files and which duplicates do you want to consolidate?”
Back to micromanagement. The policy told AI how to refactor—but not what to look for.
The Missing Piece: Phases
The breakthrough was realizing this:
AI needs explicit permission—and a workflow—to discover refactoring targets on its own.
- Policies define direction.
- Phases define agency.
Without phases, AI waits for human‑specified targets. With phases, AI can take initiative safely.
The DRY‑First Refactoring Protocol
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━─
DRY-First Refactoring Protocol
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━─
【Phase 1】Discovery
List the following:
- Files with similar processing
- Duplicate code patterns
- Consolidation candidates
【Phase 2】Proposal
For each discovered duplicate:
- Where to consolidate
- How to integrate
(Do not implement yet)
【Phase 3】Implementation
After "approved", implement.
【Priority】
1. DRY (consolidate duplicates)
2. Integration into existing files
3. Responsibility separation (minimum necessary)
The Result
Phase 1: Discovery
Similar processing:
SelectBuilder.cs,ProjectionBuilder.cs,HavingBuilder.cs– common: SQL operator mapping, constant stringificationJoinBuilder.cs,GroupByBuilder.cs,HavingBuilder.cs– common: Lambda / MemberExpression extraction
Consolidation candidates:
GetSqlOperatorandVisitConstant→ unify- Lambda extraction → consolidate in
BuilderUtil
Phase 2: Proposal
Consolidate operator and constant processing
Target: BuilderUtil.cs
- Add
GetSqlOperator(ExpressionType) - Add
FormatConstant(ConstantExpression) - Replace implementations in Select/Projection/Having builders
Consolidate Lambda/Member extraction
Target: BuilderUtil.cs
- Add
ExtractLambda(Expression) - Add
UnwrapLambdaBody(Expression) - Replace custom implementations across builders
Reply “approved” to proceed to Phase 3.
I replied: approved. AI implemented the consolidation—no micromanagement required.
Phase 3: Implementation
(Implemented as described above.)
Measured Impact
| Metric | Before | After | Change |
|---|---|---|---|
| Files | 7 | 7 | 0 |
| Lines | 1559 | 1479 | -5.1% |
The goal wasn’t dramatic reduction; it was consolidation without expansion. That goal was met.
Why This Works
| Element | Effect |
|---|---|
| Explicit phases | Prevents premature implementation |
| Discovery first | AI finds targets autonomously |
| Proposal gate | Human reviews intent, not code |
| “Approved” trigger | Clear responsibility handoff |
Key insight: AI can discover duplication patterns—if you explicitly ask it to. Without discovery, AI waits; with it, AI acts.
Before and After
Before (no protocol):
"Refactor this"
→ AI separates by responsibility
→ File count increases
→ Human intervenes with specific instructions
→ Micromanagement
After (with protocol):
"Refactor this" + protocol
→ AI lists duplicates
→ AI proposes consolidation
→ Human approves
→ AI implements
→ No micromanagement
When to Use This Protocol
Use it when:
- A namespace or module is growing too large
- You sense duplication but don’t want to enumerate it
- Previous refactoring increased complexity
- Context size is becoming a bottleneck
Don’t use it when:
- Responsibility separation is the actual goal
- The codebase is small enough for direct instruction
- You already know exactly what to consolidate
The Deeper Lesson
AI’s default behavior isn’t wrong—responsibility separation is a valid refactoring strategy. The problem is implicit defaults. When you don’t specify direction, AI chooses one.
This protocol makes intent explicit:
- What to look for (duplication)
- When to stop (proposal before implementation)
- How to prioritize (DRY over separation)
It isn’t about controlling AI; it’s about aligning AI’s initiative with your goals.
Summary
| Problem | Structural Fix |
|---|---|
| AI defaults to separation | Declare DRY priority |
| Policy alone causes questions | Add discovery phase |
| Risk of unwanted changes | Add proposal gate |
| Micromanagement burden | Let AI discover first |
Three phases. One approval. No micromanagement.
This article is part of the “Beyond Prompt Engineering” series, exploring structural—not ad‑hoc—approaches to AI‑assisted development.