Skip to content

The Pattern That Works: Human Judgment Plus AI Execution

The Problem

When I first started using AI for coding, I asked it questions like “what should I do?” or “how should I structure this?” The AI would respond with options, possibilities, and vague suggestions. It felt like spinning in place.

Here’s what a typical interaction looked like:

Me: "How should I handle the threading model for this epoll system?"
AI: "There are several approaches you could take:
1. One epoll per thread with thread-local storage
2. Shared epoll with mutex locking
3. Event-driven architecture with a central dispatcher
Each has pros and cons..."

This was frustrating. I wanted answers, not a textbook. I had working code to ship, not philosophy papers to write.

Then I noticed something. When I gave the AI precise direction instead of asking for options, it executed flawlessly. The difference was in how I framed my requests.

The Solution: Direction, Not Questions

The effective pattern I discovered is simple but powerful:

Human discovers problem → Human defines constraint → AI executes changes → Human reviews results

Let me show you what this looks like in practice.

Example 1: Thread-local epoll

I was working on an NGINX-like server where each thread needed its own epoll instance. The existing code passed epoll file descriptors around everywhere, creating complexity.

Instead of asking “how should I handle this?”, I told the AI:

Me: "Each thread has exactly one epoll. The epoll should be thread-local storage.
Remove the fd parameter from all epoll-related functions."

That one sentence—each thread has exactly one epoll—gave the AI everything it needed. The AI:

  1. Created thread-local storage for epoll
  2. Rewrote all epoll interfaces to use thread-local instead of parameters
  3. Found and updated every call site across 10+ scattered locations
  4. Removed the fd parameter from every function signature

Zero compilation warnings. All references updated. Consistent patterns throughout.

A human might miss one of those 20 changes. AI won’t. But the prerequisite was that I gave it an accurate judgment.

Example 2: Architectural Refactoring

Later, I noticed a field in the conn structure that didn’t belong there:

Me: "This field shouldn't be in conn. It belongs to a new concept called http_peer.
Create the new struct, move the field, update all references."

The AI:

  1. Created a new http_peer struct
  2. Moved the field with correct type and initialization
  3. Found all 20+ references across 6 files
  4. Updated each reference to use the new struct
  5. Maintained all existing behavior

Again, zero missed references. Clean refactoring. The constraint “belongs to http_peer” gave the AI architectural direction, and it derived all specific changes.

Why This Pattern Works

AI Without Direction Spins in Place

When I ask AI “what should I do?”, it can’t make decisions. It lists options because it lacks context about my goals, constraints, and architecture. This is a feature, not a bug—the AI is being appropriately cautious.

But when I give a constraint like “this layer shouldn’t know about the layer above”, the AI has direction. It can derive specific changes from that principle without asking for permission at each step.

The Constraint → Execution Flow

BAD APPROACH:
Question: "How should I refactor this?"
Result: Options, possibilities, no decision made
Human: Still has to decide and specify every change
GOOD APPROACH:
Constraint: "This layer shouldn't know about the layer above"
Result: AI derives all specific changes
Human: Reviews the output, corrects if needed

The leverage is massive. One accurate judgment propagates across dozens of files through AI execution.

Wrong Direction Propagates Errors

But there’s a catch. Wrong direction efficiently propagates errors across your entire project.

I learned this the hard way when I told the AI to “make all functions static by default”. It did exactly that—breaking a dozen tests that relied on internal functions being accessible for mocking. The AI executed my constraint perfectly. The constraint was wrong.

This is why review matters. You’re not reviewing code for syntax errors. You’re reviewing whether your direction was correct.

The Full Workflow in Practice

Here’s the complete workflow I use:

1. DISCOVER: Human notices architecture problem
Example: "fetch creates a new epoll for each call—that's pseudo-async"
2. DIRECTION: Human defines the constraint
Example: "Global event loop + pending Promise architecture"
3. EXECUTE: AI makes all specific changes
- Modifies 9 files
- Updates all async interfaces
- Maintains consistency across codebase
4. REVIEW: Human validates results
- Tests pass ✓
- Performance improved ✓
- Architecture cleaner ✓
5. CORRECT: If needed, refine direction and loop

Real Performance Results

After applying this workflow to the fetch concurrency problem:

Before: fetch creates new epoll per call → 905ms for concurrent operations
After: global event loop + pending Promise → 302ms for concurrent operations

The performance improvement came from my architectural judgment (global event loop), not from AI magic. The AI just executed that judgment across 9 files without missing anything.

Common Mistakes I See

Mistake 1: Asking Instead of Telling

WRONG: "What's the best way to handle threading?"
BETTER: "Use thread-local storage for the connection pool. Each thread has its own pool."

The first question produces discussion. The second constraint produces code.

Mistake 2: Micromanaging Implementation

WRONG: "On line 45, change the variable name to connectionPool. Then on line 52..."
BETTER: "Rename this variable to reflect that it's a pool, not a single connection."

When I micromanage, I limit the AI’s ability to find better solutions. Constraints give direction; implementation details emerge from that direction.

Mistake 3: Skipping Review

Just because AI is smart doesn’t mean I can skip review. I review for:

  1. Direction correctness: Did I give the right constraint?
  2. Scope creep: Did AI make changes I didn’t ask for?
  3. Test coverage: Did AI update tests along with code?
  4. Edge cases: Did AI handle error paths correctly?

Mistake 4: Using Weak Models for Architecture Changes

For simple refactoring, any model works. For architectural changes that require understanding context across multiple files, I use the strongest model available.

The difference is huge. Weak models miss context and make inconsistent changes. Strong models understand that changing one struct affects 20 files and handle all of them correctly.

Practical Tips From Experience

Build Judgment Through Practice

The leverage of this pattern depends on the quality of my judgment. Judgment comes from:

  • Reading professional code
  • Working with experts who explain their reasoning
  • Making mistakes and learning from them
  • Understanding system architecture at a deep level

AI cannot substitute for this. It amplifies good judgment and bad judgment equally.

Review Tests, Not Just Test Results

When AI makes changes, I don’t just run tests. I review the tests themselves. Did AI update tests to match the new architecture? Did it add tests for new code paths? Tests are code too, and they need to reflect architectural changes.

Use Code Review as Learning

After AI executes my constraint, I review the diff. I learn from how AI solved problems I might have approached differently. This improves my future constraints.

Keep Constraints Atomic

One constraint per request works better than multiple constraints. If I need to make two architectural changes, I do them in sequence:

Step 1: "Create http_peer struct and move relevant fields from conn"
Step 2: "Add connection pooling to http_peer with max 10 connections per peer"

Each step gets reviewed before the next. This catches direction errors early.

When to Use This Pattern

This pattern works best when:

  • I understand the architecture and can give accurate constraints
  • The change affects multiple files or locations
  • I know what the result should look like but not every implementation detail

It works less well when:

  • I’m exploring what architecture to use
  • I need the AI to suggest options for a complex tradeoff
  • The problem domain is new to me and I need education

For exploration, I use a different approach: conversation and prototyping. For execution, I use constraints.

Summary

In this post, I showed the effective pattern for AI-assisted development: human discovers problem, thinks through direction, gives AI precise constraints, reviews results, corrects if needed.

The key insight is that AI excels at execution when given clear architectural direction. One sentence like “each thread has exactly one epoll” enabled AI to correctly modify 10+ scattered locations with zero warnings. But wrong direction efficiently propagates errors across the entire project.

The future of programming isn’t writing code—it’s making judgments. One accurate judgment, amplified by AI, can touch dozens of files. But judgment must come from human experience, reading code, and working with experts.

Next steps:

  1. Next time you use AI for coding, try giving constraints instead of asking questions
  2. Review AI output for direction correctness, not just code correctness
  3. Build your judgment muscle by reading professional code and working with experts
  4. Use stronger models for architectural changes that require context understanding

Final Words + More Resources

My intention with this article was to help others share my knowledge and experience. If you want to contact me, you can contact by email: Email me

Here are also the most important links from this article along with some further resources that will help you in this scope:

Oh, and if you found these resources useful, don’t forget to support me by starring the repo on GitHub!

Comments