Write Code Like a Human Will Maintain It: Avoiding the AI Feedback Loop
The AI Maintenance Trap: Why "It Works" Isn't Enough
Using Large Language Models (LLMs) to generate code can create a deceptive sense of efficiency. When an AI can quickly produce working code that passes tests, developers are often tempted to ignore traditional best practices like DRY (Don't Repeat Yourself) or modular abstraction, assuming the AI will handle future updates across multiple files. However, this approach creates a dangerous technical debt cycle: LLMs do not write in a vacuum; they use your existing codebase as a signal for style and pattern.
When shortcuts—such as duplicated logic or "god functions"—are merged into a repository, they become part of the context the LLM uses for future prompts. Consequently, the AI stops starting from first principles and begins replicating the bad patterns already present in the code. This transforms a one-off shortcut into an established project style, making it increasingly difficult to prompt the AI out of the mess without significant manual refactoring.
The Risk of Divergent Logic
Beyond simple duplication, relying on LLMs to maintain repeated code often leads to "logic drift." Because the AI may implement the same logic slightly differently across various files, business rules can silently diverge. For example, a file upload check might be restricted to PDFs in one endpoint, while another endpoint accidentally allows PDFs and DOCX files because the AI generated a slightly different version of the same check.
Strategies for Maintaining Code Quality with AI
To prevent the "heat death" of a codebase driven by agents, developers can implement several technical guardrails:
1. Implement Automated Review Loops
Rather than relying on a single prompt, create structured review processes. Some developers use dedicated review files (e.g., .claude/commands/review.md) containing a checklist of maintainability standards that the agent must verify before finalizing code. Key checks include:
- Ensuring new code does not duplicate existing logic.
- Verifying that components adhere to the principle of separation of concerns.
- Confirming that tests actually fail if the code breaks.
2. Enforce Mechanical Baselines
LLM judgment should be layered on top of, not replace, static analysis. Using linters and static code analyzers (such as Credo for Ruby) provides a mechanical baseline that catches code smells regardless of the AI's tendencies. Some developers have gone further by writing custom linter rules ("cops") to force the AI to adhere to specific formatting and architectural preferences.
3. Establish Rigid Organizational Standards
Organizations that maintain strict software standards see higher success rates with LLMs. Effective standards include:
- Defined software layers and maximum allowed depth.
- A corporate code formatter for every language.
- A shared business vocabulary and data dictionary integrated into database schemas.
Community Perspectives and Counterpoints
While the consensus leans toward maintaining human-centric standards, there are diverging views on the future of AI-driven development:
- The "AI-Native" Approach: Some argue that human-centric practices like DRY were designed to solve human limitations (like limited memory and cognitive load). They suggest we should explore if there are "weird optimizations" or more verbose patterns that are actually better for LLMs to maintain.
- The Case for Manual Coding: A significant portion of the engineering community argues that delegating the entire typing process to agents is a mistake. They suggest using LLMs for exploration and review, but writing the actual implementation by hand to maintain a strong mental model of the system.
- The Reality of Deadlines: Some contributors note that most human-written code is already full of duplication due to tight deadlines and budget constraints; LLMs are simply reflecting the reality of the training data they were fed.
"The most frustrating part: I thought I was outsourcing maintenance to the LLM, but the slippery slope I found myself on was actually training it to have ever-worsening habits."
Ultimately, the goal remains the same as the classic industry adage: write code as if the next person to maintain it is a homicidal maniac who knows where you live—and in the modern era, that "person" is often an LLM that will repeat your mistakes a thousand times over.
Sources
Related
- Dispatch
- Dispatch
- Dispatch
- Dispatch
- Dispatch