Patterns for Reducing Friction in AI-Assisted Development

The practices that make human pair programming effective—onboarding, structured design discussion, shared standards—apply equally to working with AI coding assistants. I propose five patterns that bring this collaborative scaffolding to AI-assisted development, shifting the experience from correcting a tool to collaborating with a capable teammate.

24 February 2026


Photo of Rahul Garg

Rahul is a Principal Engineer at Thoughtworks, based in Gurgaon, India. He is passionate about the craft of building maintainable software through DDD and Clean Architecture, and explores how AI can help teams achieve engineering excellence.


When I do pair programming with a colleague, certain rituals happen naturally. I walk them through the codebase before asking them to contribute. We sketch on a whiteboard before diving into implementation. I explain our conventions, our constraints, the reasoning behind past decisions. We review the work against team standards.

With AI coding assistants, I have noticed that most developers—myself included, initially—skip all of this. We type a prompt, expect aligned output, and then wonder why the result doesn't fit.

The promise of AI coding assistants was compelling: dramatically faster development, instant code generation, a tireless pair programmer available around the clock. The adoption has been remarkable—by most accounts, the majority of professional developers now use tools like GitHub Copilot, Cursor, or Claude in their daily work.

Yet a consistent frustration seems to be emerging. The time saved by AI-generated code is often consumed by the effort required to correct it. I have experienced—and heard others describe—a cycle I call the “Frustration Loop”: generate code, review it, find it doesn't fit the codebase, regenerate with corrections, review again, and eventually either accept heavily-modified output or abandon the attempt entirely.

The pattern is familiar enough that it warrants examination. My sense is that this is not a failure of AI capability—modern language models are remarkably sophisticated. The friction arises from how we collaborate with these systems.

The Frustration Loop

The typical interaction pattern looks something like this:

A developer asks the AI to create a service. The AI responds quickly with syntactically correct code that follows common patterns from its training data. However, it uses Express.js when the project uses Fastify. It places files in utils/ when the convention is lib/services/. It generates class-based code when the codebase is functional. Each correction requires another generation cycle, and with each cycle, the time advantage erodes.

Generate → Review → "Not quite right" → Regenerate → Review → "Still wrong" → Give up
      

This cycle persists because AI assistants, by default, draw from their training data—an aggregation of patterns from millions of repositories. They produce what might be called “the average of the internet” rather than code that fits a specific team's architecture and conventions.

Common symptoms include:

  • AI generates solutions that don't align with existing architecture
  • Developers spend significant time on post-generation editing
  • Context established early in a conversation is lost as the session lengthens
  • Quality varies depending on which team member is prompting

The Speed Trap

Part of the problem lies in how success is measured with these tools. Teams often track metrics like time to first output or lines of code generated. These metrics are easy to capture and show immediate results, but they obscure the actual cost.

If an AI generates 200 lines of code in seconds, but a developer spends 30 minutes reviewing, debugging, and refactoring to fit team patterns, the net productivity gain is questionable. The work has shifted from writing to fixing, but the total effort may not have decreased.

When I pair with a human colleague, I don't measure success by how fast they type. I care about whether their contribution fits the codebase, whether it solves the right problem, whether it will hold up in review. The same should apply to AI collaboration.

More useful metrics focus on what I might call “collaboration quality”:

Misleading MetricMore Useful Alternative
Time to first outputFirst-pass acceptance rate
Lines of code generatedIteration cycles per task
Tasks completedPost-merge rework required
Generation speedReview burden compared to manual writing

For teams tracking DORA metrics, first-pass acceptance serves as a leading indicator for change failure rate. Code that requires extensive correction before being usable is a signal of misalignment, and misaligned code that ships becomes technical debt.

The Tool-to-Teammate Shift

A useful reframe, I believe, is to stop treating AI as a tool and start treating it as a teammate—a distinction that sounds semantic but has practical implications.

AI assistants are like junior developers with infinite energy but zero context.

AI assistants are like junior developers with infinite energy but zero context. They can work faster than any human, they never tire, and they never complain. But they know nothing about a specific project's conventions, constraints, or history. Without the same scaffolding a team would provide a human collaborator, they default to generic patterns that may or may not fit.

Consider how I work with a new team member. I don't expect them to produce high-quality, architecture-aligned code on their first day without context. I onboard them. I walk through the codebase. I explain the patterns and the reasoning behind architectural decisions. I pair with them on initial work. I review their output against team standards.

The parallel to pair programming is instructive:

Human Pair ProgrammingAI Collaboration Equivalent
“Let me show the docs first”Sharing architectural context before requesting code
“Let's sketch this on the whiteboard”Structured design discussion before implementation
“Here's how reviews work here”Encoding standards into reusable prompts or commands
“Let me update the doc with the decision”Persisting decisions so they survive session boundaries
“What did that teach us?”Systematically capturing what worked and what didn't

The AI is fast—remarkably fast. But it needs the same things a human pair needs:

  • Onboarding — Context about the codebase before contributing
  • Whiteboarding — Structured design discussion before implementation
  • Guardrails — Standards and quality checks consistently applied

Five Patterns for AI Collaboration

The framework I propose consists of five complementary patterns. Each addresses a specific failure mode in AI collaboration—and each mirrors a practice that makes human collaboration effective.

Knowledge Priming

The human parallel: Onboarding a new hire

Before asking AI to generate code, share curated context about the project: the tech stack with version numbers, directory structure, naming conventions, and examples of existing patterns. This practice is essentially manual RAG (Retrieval-Augmented Generation)—filling the context window with high-value, project-specific information that overrides generic training data.

Just as I would walk a new team member through the codebase before asking them to contribute, I prime the AI with the context it needs to produce aligned output.

The failure mode addressed: AI defaults to generic patterns because it lacks project-specific context.

Design-First Collaboration

The human parallel: Whiteboarding before coding

Rather than asking AI to immediately produce code, walk through progressive levels of design: capabilities, components, interactions, contracts, and only then implementation. This mirrors the whiteboarding that precedes coding in effective human collaboration.

When I pair with a colleague on a complex feature, we don't jump straight to the keyboard. We sketch. We align on approach. We catch misunderstandings before they become bugs. The same discipline applies to AI.

The failure mode addressed: AI jumps to implementation before understanding requirements, producing code that solves the wrong problem.

Sensible Defaults

The human parallel: What a senior developer does instinctively

Every team has senior developers who instinctively know when code is right—they spot architectural drift, security gaps, and convention violations that others miss. This intuition is invaluable, but it lives in their heads. It does not scale.

The solution is to make tacit knowledge explicit. Just as I would walk a new hire through our conventions, I make those defaults explicit and shareable for AI collaboration. When defaults exist as artifacts rather than intuition, they apply consistently regardless of who is prompting.

The failure mode addressed: AI generates technically correct code that violates team expectations, requiring extensive rework.

Context Anchoring

The human parallel: Updating the doc with decisions

Maintain a living document that captures decisions, constraints, and current state as a feature evolves. This document serves as external memory, anchoring context that would otherwise be lost as conversations grow longer or sessions end.

When pairing with humans, I naturally update shared documents as we make decisions. The same practice prevents AI from contradicting itself or forgetting earlier conclusions.

The failure mode addressed: AI forgets decisions made earlier in long conversations, leading to contradictions and inconsistency.

Feedback Flywheel

The human parallel: Retrospectives and continuous learning

Systematically harvest learnings from AI interactions to improve the other four patterns. When a prompt works particularly well, capture it. When AI consistently misunderstands something, add it to the priming context. When a failure pattern emerges, add a guardrail.

Just as teams learn from retrospectives and improve their collaboration over time, I build institutional knowledge about what makes AI collaboration effective.

The failure mode addressed: Teams make the same mistakes repeatedly without building institutional knowledge about effective AI collaboration.

The Shared Mental Model

These patterns work together to create what might be called a shared mental model between humans and AI. When both operate from the same vocabulary (through priming), the same architecture vision (through design-first discussion), the same quality standards (through codified commands), and the same decision history (through anchored documentation), the friction of translation diminishes.

The cognitive load shifts from constant vigilance and correction to expressing intent and refining output. This is the difference between struggling with a tool and collaborating with a capable partner.

I hypothesize that these patterns, when applied consistently, could yield meaningful improvements:

  • Higher first-pass acceptance rates (reducing the generate-fix-regenerate cycle)
  • Fewer iteration cycles per task
  • Less post-merge rework

These are not yet validated findings—this is a proposed framework based on reasoning about why friction occurs and what might address it. Early experiments in my own work have been encouraging, but more practice and observation is needed.

Trade-offs and Limitations

This approach is not without costs. Creating and maintaining priming documents requires effort. Design-first conversations take longer than immediately requesting code. The patterns require discipline to sustain.

For simple, one-off tasks, the overhead may not be justified. A quick utility function or a straightforward refactor may not warrant a full design discussion. The investment pays off primarily for non-trivial work, especially work that spans multiple sessions or involves team coordination.

There is also a learning curve. Teams accustomed to treating AI as a search engine or autocomplete system may find the transition to structured collaboration unfamiliar. The shift requires deliberate practice.

Where This Leads

I have outlined the problem of friction in AI-assisted development and introduced a framework for addressing it. Each of the five patterns merits deeper exploration:

  • Knowledge Priming: What to include, how to structure it, how to keep it current
  • Design-First Collaboration: The levels of design, handling AI that wants to skip ahead
  • Sensible Defaults: Making tacit knowledge explicit, scaling senior intuition across the team
  • Context Anchoring: Managing long conversations, surviving session boundaries
  • Feedback Flywheel: Systematic improvement, measuring what matters

Subsequent articles will explore each pattern in depth.

The underlying insight is straightforward: AI assistants are powerful but contextless. The techniques that make human collaboration effective—onboarding, structured discussion, shared standards, documented decisions, continuous learning—apply equally to AI collaboration. My belief is that developers who internalize this approach will experience AI as a force multiplier rather than a source of friction.


Acknowledgements

I'm grateful to several people who shaped this series. Jim Gumbley read early drafts and pushed on the layer beneath the practical advice—especially the connection to how attention and context work in transformer models. His feedback sharpened the thinking and sparked ideas for future work.

Vanya Seth has been a long-standing conversation partner on these ideas; she encouraged and guided me to draft articles for Martin's site.

I treat AI as a teammate, not a tool—the same philosophy behind this series. I anchored the base thought process: the ideas, structure, and voice. AI accelerated the drafting and complemented my thinking with quick iterations and alternative phrasings. Together we complemented each other; the writing process itself reflects the kind of collaboration these articles advocate.

Significant Revisions

24 February 2026: Knowledge Priming first published

24 February 2026: Patterns for Reducing Friction in AI-Assisted Development first published