Uncle Bob on AI Programming: Taming Agents with Deterministic Tools

Uncle Bob on taming AI agents with deterministic tools and why software fundamentals never change
Software legend Uncle Bob describes his methodology for AI programming: replace endless prompt engineering with deterministic constraints like CRAP scoring and mutation testing. He advocates multi-agent pipelines where specialized agents handle specification, coding, cleaning, and hardening in sequence, achieving 4-5x productivity while maintaining quality. Despite automation advances, he emphasizes that strategic skills like architecture design and organizing complexity remain irreplaceable human contributions.
Uncle Bob on AI Programming: Taming Agents with Deterministic Tools
Robert C. Martin (Uncle Bob) — a legendary figure in software engineering, author of Clean Code, and a programmer with over half a century of experience — recently shared his deep insights on the AI programming era in a live conversation. Starting in late 2024, this veteran who has championed "clean code" principles for decades began earnestly embracing AI agents and gradually developed a unique methodology. This article distills the core ideas from that conversation.
From "Cleaning Up After the Dog" to Deterministic Tools
Uncle Bob admits that his initial experience with early Grok agents writing code was far from ideal. "It wrote code, but always left a mess (dog doo), and I kept cleaning up after it." Worse still, as the code grew messier, the agent began to struggle: fixing one thing broke another, going in circles, and once it simply "gave up" on the task.
This made him realize a crucial fact: agents, like humans, are dragged down by messy code. "They may be fast and relatively smart, but they're constrained by messy code just like humans. The threshold may be different, but that threshold still exists."
The real turning point came when he recalled two innovations from around 2000 that were "good but impractical" at the time: CRAP scoring (combining code coverage with cyclomatic complexity to measure how "crappy" a function is) and mutation testing (flipping operators in code to verify whether the test suite is rigorous enough).
CRAP score (Change Risk Anti-Patterns) is a code quality metric proposed by Alberto Savoia in 2007, with a formula that combines cyclomatic complexity and test coverage. Cyclomatic complexity, introduced by Thomas J. McCabe in 1976, measures program logic complexity by counting independent paths — each additional if/else branch adds one to the complexity. When a function has high cyclomatic complexity but low test coverage, the CRAP score spikes, indicating the code is both complex and lacks test protection, making changes highly risky. Mutation testing is a technique for assessing test suite quality, with early theory dating back to Richard Lipton's student paper in 1971. The principle is to automatically inject small mutations into source code, such as changing > to >=, + to -, or true to false, then running the test suite. If the test suite detects these mutations (i.e., tests fail), the tests are effective; if tests still pass after mutation, it exposes blind spots in testing. Since each mutation requires a full test suite run, the computational cost for large projects is enormous.
These two techniques were too time-consuming for humans — mutation testing could run overnight. But agents are different: "They're fast and don't care how tedious the work is." So he had agents automatically run CRAP analysis and mutation testing, reactivating high-quality practices that were previously "impractical."

Reject "Steering," Embrace Deterministic Constraints
A core point of divergence in the conversation: when agents make mistakes, most people's approach is to keep stuffing rules into prompts (steering), while Uncle Bob chose deterministic checks.
He explained why steering fails — models exhibit "lost in the middle" phenomenon: as context windows expand, content at the beginning and end gets more attention, while middle content gets ignored. This phenomenon stems from the 2023 paper by Stanford's Nelson F. Liu et al., Lost in the Middle: How Language Models Use Long Contexts. The research found that when large language models need to retrieve key information from long contexts, if relevant information is at the beginning or end of the input, models perform best; but when information is buried in the middle, model performance drops significantly. This phenomenon shares similarities with the "serial position effect" in human cognitive psychology — humans also tend to better remember the beginning (primacy effect) and end (recency effect) of lists.
The longer the rules you write, the more likely important parts get squeezed into the middle and forgotten. "Models treat these rules like what they say in Pirates of the Caribbean — they're more like 'guidelines'."
Therefore his strategy is: compress the initial prompt to the absolute minimum, keep only the highest priority parts, then rely on deterministic tools afterward to ensure quality. The host analogized this to the context window's "smart zone" versus "dumb zone" — the first ~150K tokens where the model performs intelligently, after which attention relationships are severely diluted, "like every token is shouting in a crowded room, signal drowned in noise."
The beauty of deterministic tools: they don't consume context, can be layered indefinitely, locking the agent into a "straitjacket" that runs in a loop until the tools deem the code acceptable.

Multi-Agent Pipeline: Five Steps from Spec to Quality
Uncle Bob is currently exploring a pipeline where multiple agents collaborate in series, each focused on a single task:
- Specifier: Converts human-written documents into Gherkin (given-when-then acceptance tests) and QA system test flows, verifying the system from a "human operating UI" perspective. Gherkin is a domain-specific language used in Behavior-Driven Development (BDD) frameworks, initially popularized by Aslak Hellesøy, founder of the Cucumber project, around 2008. It uses a three-part Given-When-Then structure to describe software behavior: Given describes the system's initial state, When describes the triggered action, Then describes the expected result. Its original intent was to make test cases readable to non-technical people, bridging the gap between business requirements and technical implementation.
- Coder: Writes unit tests and implementation code to make Gherkin pass. At this point, code is typically a mess.
- Cleaner: Runs CRAP analysis, performs code review, and cleans up the coder's mess.
- Hardener: Runs mutation testing, "no mercy," pursuing 100% coverage at every equals sign.
- QA agent: Converts QA documents into executable scripts that manipulate the system to produce deterministic results.
"If a task takes a single agent 5 minutes but results are questionable, this process takes about an hour — but still faster than humans, who might take half a day." He estimates overall productivity increases about 4-5x, with quality far exceeding manual human work.
Multi-agent advantages are twofold: first, they can run in parallel; second, focusing on single tasks controls context windows, mitigating "lost in the middle" issues, and allows agents to "spawn-do-die," with the next one entering with a clean context. The downside is high startup overhead (each agent takes 10-15 seconds to start and rebuild context).
The conversation also introduced a brilliant concept — context trajectory: once you steer an agent in a direction, all subsequent operations in the same session continue that trajectory; the only way to clear trajectory is to clear the context window. This also explains why agents focused on single tasks perform better.
Architecture and Module Design: The Core Lever That Can't Be Automated
Even with comprehensive testing and hardening processes, Uncle Bob emphasizes: good module design remains a huge lever, and this part still requires human intervention.
He had agents build an architecture viewer that pops up UML diagrams showing system module structure and dependency flow, with clickable modules that drill down layer by layer to code. He also wrote deterministic tools that use spec files to define expected dependency relationships between modules; once an agent violates rules, the checker forces it to fix (by inverting dependencies, inserting interfaces, or splitting modules).
"Inverting dependencies, inserting interfaces" directly corresponds to the Dependency Inversion Principle (DIP) from SOLID principles that Uncle Bob himself proposed. The principle states: high-level modules should not depend on low-level modules; both should depend on abstractions; abstractions should not depend on details, details should depend on abstractions. In practice, this means if module A directly depends on module B's concrete implementation, an interface should be inserted between them, with A depending on the interface and B implementing it, thus inverting the dependency direction. Uncle Bob systematized the five SOLID principles (Single Responsibility, Open-Closed, Liskov Substitution, Interface Segregation, Dependency Inversion) from the 1990s to 2000s, and in his book Clean Architecture further developed the "Clean Architecture" layered model, emphasizing that business rules should be at the architecture's center, independent of frameworks, databases, or UI and other peripheral details. The architecture viewer and dependency rule checker he built in the conversation essentially encode these architectural principles as deterministic constraints, forcing agents to respect module boundaries when auto-generating code.
"Anything well-partitioned with strict interface discipline that humans can grasp, models can too — because models are modeled after humans." He notes that agents pay attention to interface naming, structure, and tests to understand the system, thus not needing to read underlying code — this is both an advantage and a danger, provided the code remains consistent.

Don't Impose "Human Discipline" on Agents
Regarding whether his classic works need updating, Uncle Bob offered two insights:
First, thresholds need adjustment. Agents have enormous and precise short-term memory, handling higher complexity than humans. Therefore he relaxed the CRAP score threshold for functions from the human standard of 4 to 6, even trying to push it to 8.
Second, discipline shouldn't be copied wholesale. He's a staunch advocate of Test-Driven Development (TDD), but explicitly states he wouldn't force agents to follow TDD's strict rhythm of "write one line of test, write one line of code." "TDD is human discipline because humans have limited short-term memory. It doesn't make sense for agents."
Test-Driven Development (TDD) was systematized by Kent Beck in 1999 within Extreme Programming (XP) practices, with the core "red-green-refactor" cycle: first write a failing test (red), then write minimal code to make the test pass (green), finally refactor code to eliminate duplication and improve design. TDD's essence is a cognitive aid for humans — by breaking large problems into tiny steps, helping programmers maintain control over code within limited working memory. John Ousterhout in his book A Philosophy of Software Design criticized TDD, arguing it encourages developers to focus excessively on tactical small steps while neglecting overall system design and abstraction. Ousterhout advocates first thinking through interfaces and abstractions, then writing complete implementation code, and finally adding tests. Uncle Bob's perspective here is thought-provoking — as one of TDD's most famous evangelists, he acknowledges that for AI agents with enormous "working memory," TDD's step-by-step rhythm loses meaning; agents naturally gravitate toward Ousterhout-style complete implementation first.
Even if you command them to do TDD, they eventually always revert to the Ousterhout approach of "write function first, test later."
His summary is incisive: "Imposing human values on agents is fine, but imposing human discipline and behavioral patterns on them is unwise."
Specs Are Ephemeral: Return to Agile Thinking
In today's "spec-driven development" zeitgeist, Uncle Bob's stance is quite counter-current. He's done extensive upfront planning experiments, with results "always disastrous" — agents write gorgeous detailed plans, but they all collapse during execution because you can't think of everything, and they're not as smart as you.
"This is the same temptation we experienced in the '70s, which led to the waterfall model." The Waterfall Model concept traces back to Winston W. Royce's 1970 paper, dividing software development into strictly sequential phases: requirements analysis, system design, coding, testing, deployment, etc. Ironically, Royce in his original paper was actually critiquing the flaws of this linear process, but the industry adopted it as a standard model for decades. By the late 1990s, the software industry widely recognized the waterfall model's fragility in handling changing requirements. In 2001, 17 software developers including Uncle Bob signed the Agile Manifesto at the Snowbird ski resort in Utah, officially launching the agile movement. Agile's core philosophy is embracing change, short iteration cycles, and continuous delivery of working software.
Uncle Bob believes the answer is still agile: do one or two stories, look at the architecture, manually organize, do a few more, organize again.

He uses a brilliant analogy to explain why he abandons heavy upfront planning: if modifying a house costs just $1, would you spend thousands hiring an architect for a perfect plan? Or just iterate directly with contractors? "The cost of change has plummeted to near zero, why do expensive upfront planning?"
Therefore he doesn't persist spec documents in repositories — "specs are ephemeral." In the past, source code was the ultimate specification written by humans; now source code is no longer written by humans. His current approach is actually to treat the final result as the specification, and he advises people not to download his tools, but to have their agents reference them and then customize their own version.
Strategic Programming and Fundamentals: How Newcomers Grow in the AI Era
Borrowing John Ousterhout's framework, Uncle Bob distinguishes tactical programming (sergeants on the ground) from strategic programming (generals commanding the war). Agents excel at tactics but not strategy.
So in an AI era where agents eat all tactical work, how do newcomers learn strategic programming? His advice is quite vivid:
- Write code first, for a year, to understand what agents are dealing with.
- Get treated like an agent after joining — have your supervisor assign tasks and apply the same deterministic tool constraints as if you were an agent, "painfully unproductive for months, but learn a ton."
- Complete the full abstraction chain from binary to assembly, C, Python. He reiterates advice from ten years ago: spend a weekend writing assembly language to understand what's really happening behind the scenes.
He also recommends reading those "old books nobody reads" — works by Tom DeMarco and Ed Yourdon, as well as The Pragmatic Programmer, filtering out dated content to extract high-level strategic thinking. Tom DeMarco and Ed Yourdon were pioneers of structured analysis and design methods; their 1970s-80s works (like DeMarco's Peopleware and Yourdon's Structured Analysis) laid theoretical foundations for software engineering management and system design, with many core ideas — like focusing on human factors, modular decomposition, information hiding — still guiding AI programming today.
Why Fundamentals Never Go Out of Style
The conversation concludes with the value of software fundamentals. Uncle Bob quotes Dijkstra: software is the most complex thing humans have ever attempted.
Edsger W. Dijkstra (1930-2002) was one of computer science's founders, 1972 Turing Award recipient. His best-known contributions include Dijkstra's algorithm for shortest paths, advocacy for structured programming, and famous critique of goto statements (1968's Go To Statement Considered Harmful). Dijkstra had profound insights into software complexity, writing: "The art of programming is the art of organizing complexity," noting that human intellectual limitations are the fundamental constraint software engineering must face. In his EWD manuscript series, he repeatedly emphasized that program correctness shouldn't rely on testing ("testing can only prove the presence of bugs, not their absence") but should be guaranteed through rigorous mathematical reasoning.
"Therefore fundamentals are how we organize complexity into understandable forms — not just understandable by humans, but also by our models, since models are modeled after humans."
He analogizes this abstraction leap to history: from binary to assembly, assembly to compilers, each step had people below shouting "this will ruin everything," but the same rules always applied. "The rules you discard, you'll pick up off the ground a year later, dust them off, and remember why you needed them in the first place."
For those who think fundamentals no longer matter, his prophecy is unsparing: "They'll learn the lesson, and they'll learn it the hard way — won't take long. I've watched agents hit that wall, I know that wall is there."
What's most moving about this conversation: a veteran who's upheld "clean code" for decades hasn't rigidly stuck to dogma, but used his lifetime of accumulated engineering wisdom to recalibrate methods for the AI agent era — tools have changed, speed has changed, but the fundamentals of organizing complexity have never changed.
Key Takeaways
- Use deterministic tools (CRAP scoring, mutation testing) rather than endlessly expanding prompts to constrain agents
- Build multi-agent pipelines where each agent handles a single focused task: specification, coding, cleaning, hardening, QA
- Good module design and architecture remain irreplaceable human contributions that provide massive leverage
- Don't impose human discipline (like strict TDD rhythm) on agents; impose human values instead
- Specs are ephemeral; embrace agile iteration rather than heavy upfront planning
- Software fundamentals — organizing complexity — remain essential even as tools evolve
- Newcomers should learn by writing code, being treated like agents under constraints, and studying the full abstraction chain
Related articles

Intent.md Reshapes AI Development: Anthropic's New Paradigm for Agent Collaboration
Anthropic releases an AI-native SDLC handbook using Intent.md to restructure human-AI collaboration across the full development lifecycle, from requirements to maintenance.

EcoFlow River Gen4 Review: Are the 256Wh/512Wh Portable Power Stations Worth It?
In-depth analysis of EcoFlow's River Gen4 portable power stations — covering the River 260 Gen4 (256Wh) and River 520 Gen4 (512Wh) in capacity, energy density, portability, and use cases.

OpenAI's Staggering $38.5 Billion Loss: The Financial Truth and Capital Game Before Its IPO
OpenAI faces a reported $38.5B loss before its IPO. This deep dive analyzes compute costs, strategic logic, IPO timing, and what it means for the generative AI industry.