Building Complex Systems in the Age of AI

The Rising Value of Human Judgment

Adapted from a 25-minute talk and the audience Q&A that followed, AI/ML Conversations meetup, April 7th 2026, NYC, @ CapitalOne. April 2026


My name’s Kostiantyn and I use AI to write AI - I’m a solo developer, founder of HyperDraw, CEO, whatever title you want; it’s very easy to collect titles when the company is one person.

Agentic Coding: it works, except when it doesn’t

Open the internet and it’s AI everywhere. You’ll be replaced in twelve months. Buy Claude Code. Buy more tokens. No - buy fewer tokens. Use OpenClaw, NanoClaw, whatever shipped this morning.

And here’s the annoying part: the thing works. We all know it works. We’ve seen it.

So let me report a real number. In the last two months I merged a hundred PRs - two-thirds from cloud agents, one-third from a local agent, zero fully manual. That sounds like a triumph.

And yet. Not all of that output is equal.

Every time I reach for anything that isn’t Claude Opus, I end up crawling back to Opus. And even with Opus, some PRs land in one shot - clean, merge, done, happy. Others I have to pull down, fix by hand, call good enough. And some I just close, because they went completely sideways. Why? Why does something that looks hard take less time, and something supposedly trivial refuse to work?

The honest answer is statistics: regression to the mean. These models read the entire internet - some genuinely beautiful code, and a great deal of code written by people who, let’s say gently, might have found more joy in another line of work. All of it is in there. Trigger the model toward the bad half of that distribution and the bad half is exactly what you get. The models are scary good - Claude 4.5 was already frightening, 4.6 is a beast that will write any language you name. But you have to push it toward the good half. It won’t wander there on its own.

The tool is not your moat. You are.

Everybody in this room has superpowers now. So do our competitors. So do the thirty-odd million people who installed the Claude Code extension last quarter. Everyone has the same wand.

So if you remember one thing from this: the tool is not your moat. You are your moat. The same model produces brilliant work for one person and useless sludge for the next, and the only variable that changed is who was driving. You get better, you stay in this industry. You don’t get better - the robots replace us, cheerfully.

Speed comes with its own drag

Go faster and the environment pushes back - call it drag, if you want the physics. Every feature you add is new surface area for bugs and a new thing you have to test. And while you’re coding one feature, you are by definition not coding another.

A man is cutting a piece of butter with the heavy duty chainsaw
Can it cut butter? You bet!

Ai art: a man cutting a stick of butter with a running chainsaw. He is doing it very efficiently. That’s the point. The chainsaw works. It cuts the butter beautifully. The fact that you can do something is not the same as the fact that you should.

Complexity did not go away - it never does. Software is a fractal: the deeper you zoom, the more of it there is, and it grows exponentially as you go. You want a website? Easy. With infinite scroll? Sure. High-performance infinite scroll over a million items that also remembers your scroll position when you come back? Now make it 3D. Each clause was one innocent sentence, and each one doubled the work underneath.

This is where the old dead scientists start whispering.

Turing says you cannot know how long a program will run until you run it - not in the general case. LLMs are function approximators; that’s just code. Which means you genuinely cannot know how long Claude will grind on your ticket. You can cap it - max tokens, max time, max dollars - but a cap only guarantees the agent stops, not that it finished.

The formal version. Impose a budget - tokens, time, iterations, dollars - and the only guarantee is that the agent halts. If the stopping condition is semantic (tests pass, bug fixed, feature implemented, proof found, code accepted), then predicting whether the agent reaches it before the budget runs out is generally not decidable for sufficiently expressive tasks.

Darwin says survival of the fittest, and he’s rude about it. My startup ships PRs at an astonishing rate and has, at time of writing, zero customers and a negative bank balance. More code is not product-market fit. Producing more doesn’t mean producing something anyone will pay for. Competition doesn’t evaporate because implementation got cheap.

Dunning and Kruger hang around the door: the moment people feel the new power, they feel like experts. That feeling arrives well before the competence does.

Amdahl is the one that stings. Everyone wants agent swarms - four agents, why not a thousand, a legion, my own army of robots to dominate the world. Fine: point that army at a single task - “write me an algorithmic trading bot, take it to Wall Street, make me rich.” Silence. Nobody even laughs, because everybody in the room already knows it won’t work. When many agents touch the same codebase, merging the text is the least of it - they conflict at the level of intent. One picks a color, another picks a different one; one reaches for a different language or paradigm entirely. Reconciling that requires serialization, and serialization is the hard ceiling on any parallel system.

AI made implementation cheap. It did not make intent, verification, coordination, or product taste cheap. If anything, it dragged those bottlenecks into the light.

The bottleneck has moved - to what, exactly?

Open any AI webinar, ask ChatGPT, read any thread: everyone repeats it like a mantra. The bottleneck has moved. And it has! The trouble is nobody finishes the sentence. It’s the underpants-gnomes plan from South Park:

  • step one: the bottleneck moves
  • step two: ???
  • step three: profit!

Nobody actually knows what step two is.

Here’s my best guess at the missing line. The bottleneck used to be “can we write the code?” It isn’t anymore. Now it’s: do we know what to build, do we know how to prove it works, and can we keep the whole thing coherent while it changes under us? Implementation went to zero; intent, verification, and architecture did not.

And one uncomfortable side effect: you can no longer hide inside a cozy niche as the lone developer who built the thing nobody else bothered to build. Google can go for the long tail now too. The moat made of “nobody else could be bothered” has evaporated.

That was a lot of darkness. Let me turn on a light.

A Formula One car racing through a muddy dirt road, wheels spinning up walls of mud
A Formula One car handed a dirt track: not a broken car, just the wrong road.

Build the highway before you race the car

So why does AI fail, when it fails? Not because the model is dumb. Because I didn’t build the road for it.

Picture a Formula One car up to its axles in a muddy field. That is not a broken car. That is a car I handed a dirt track and then blamed for not winning. Every time my repo was clean and the modules were honestly separated, the agent looked like magic. Every time it wasn’t, I got faster, more confident failure. Same model. Different road.

Our job in this new world is to lay down clean lanes - to design the high-speed roads our fast new robot overlords can drive without crashing into each other. Once you actually know which module is isolated and which one is independent, you can send several agents down parallel lanes and let them evolve without stepping on each other. And that buys back a little freedom from the tyranny of Amdahl.

Without tests, AI coding is just vandalism at speed

Everything you ever heard in an agile training, every TDD book you skimmed, every code-review ritual you rolled your eyes at - all of it matters more now, and it finally became affordable.

Google hit this wall early, purely because of scale: a hundred thousand engineers shoving code into one monorepo, a firehose of competing PRs. What Google had to solve with policy, all of us now get to solve by sheer volume of AI-generated artifacts. If you’re still not using version control, I genuinely don’t know what you’re doing.

And here’s why AI coding works for software while “AI for lawyers” and “AI for doctors” are still mostly slide decks: we can revert. We can test in isolation. We have fifty years of TDD and twenty years of containers sitting under our feet. That accumulated infrastructure is the road the race car has been waiting for.

Without tests, AI coding is just high-speed vandalism.

Because the AI will not remember what it built five minutes ago. It can’t - it isn’t the same instance. All those Claudes are not one person with shared memory; they’re strangers who each show up, focus hard on exactly the one thing you asked, and vanish. Ask one to do a thing, it does the thing. Ask the next one to do the second thing. The only way to preserve what the first one built is to wrap it in tests before the next stranger arrives.

I think of regression tests as a coral reef. A coral is a soft, living polyp - fragile on its own - that grows inside the hard calcified tube it secretes around itself. Tiny jelly, building rock, building islands. Our tests are the same trick: the AI writes the code, you try it, you like it, you tell it now cover this in tests, and you go get a coffee while it does. Come back and that behavior is fossilized - safe from the next well-meaning stranger. Layer by layer, an island of regression tests grows out of your past failures. Code that maintains itself.

Context is a real resource - and scarcer than it looks

192,000 tokens sounds like an ocean. Except roughly thirty percent is reserved for output, so you never had 192k to begin with. And then there’s the part nobody advertises: needle in a haystack is the easy case - what about needle in a needle-stack, when you need to find many things at once? If you actually probe how much a model recalls from its own context, it’s far from perfect. That’s not a defect; it’s what attention is. Give a human ten dense documents and demand instant recall of all of it - you’d strobe too.

Specs die on the same hill. Drop an 800-line spec into Claude and watch it struggle - every sentence is load-bearing, there’s no slack for it to skim. Here’s a little hack to borrow from ISO and W3C: number your sections. 3.6.7. Then you don’t say “go read the spec.” You say “read section 3.6.7 and write the entire test file for it” - twenty tests for that one section - and suddenly it works beautifully. Bounded, focused, tractable.

Architecture is what makes the model look like magic

Architecture is still the king. The whole game is keeping the model’s attention pointed at the one thing you’re solving today - spend the entire force of that context window on this single bug, this single refactor, this single feature. Not all three at once, whispering “and also, while you’re in there…” The shape of your codebase is exactly what lets you aim the model like a rifle instead of broadcasting to the whole building.

Feedback latency dominates AI coding productivity. Small, isolated, revertible changes aren’t just tidy hygiene - they’re the thing that makes agent-assisted development possible at all.

The method I actually use

Here’s my secret sauce. It may expire in a couple of months, but this is genuinely what I do.

  1. Define the intent - yourself. Before you invoke a single agent, you have to know what you’re building. Talk to ChatGPT, talk to humans, do the research. You are the only creature in this loop who knows what the AI should write. Keep that agency on you and nowhere else.

  2. Make the model draft the spec. Don’t hand-write it from a cold start. Tell it what you want and make it hand the spec back to you - articulated, structured, in its own words.

  3. Read the spec yourself. Does it match the thing in your head, or did it go completely bananas and misunderstand you? This is your one cheap chance to catch the expensive mistake before it’s expensive.

  4. Run a gap analysis. Once you’re happy with the spec, fire a cloud agent at your own codebase - don’t even watch it - and ask: “given this spec and the current state of the repo, how far are we?” Sometimes you get a lovely surprise because you’re already close. Sometimes you get the cold bucket of “oh, that’s a lot of work.” Both are gifts.

  5. Write the failing tests first. Fundamentalist, by-the-book TDD - the test before the code. For a human that’s soul-crushing. But the AI doesn’t feel pain, so you don’t have to feel it for it.

  6. Implement against the tests. Let it write code until the tests go green. Constrained implementation is dramatically cleaner than open-ended “go build it.”

  7. Verify the neighborhood. The feature works - but what about everything living next to it? I build a drawing app, and adding one thing to the Free Transform tool has a lovely habit of quietly breaking a different tool three streets over. Go find those. Then hand them back to the AI to fix.

  8. Let it cool down. Don’t stack a major refactor on top of something you shipped an hour ago and are still nervous about. Let the important stuff sit and settle. When it stops scaring you, reopen the track and pile on again.

New tools have always made human judgment more valuable

This movie has played before. Five hundred years ago people fretted that peasants might learn to read - and heaven forbid, write. What on earth would they write?

I’m from Ukraine, so here’s the trivia I can’t resist. Ivan Fedorov ran the first printing press in Moscow. Could’ve been the local hero. Instead the scribes - the men whose whole living was copying books by hand - wanted him on a literal stake. So he ran, to what later became Ukraine, and became the first Ukrainian book printer. The people whose skill the new medium threatened didn’t debate him. They reached for the fire.

So let’s not join the crowd insisting we must still type every line by hand because “the AI is wrong.” Every new medium makes some old skill invisible and makes a deeper one priceless. The typewriter is gone; your brain matters more than it ever has. AI may kill the value of typing code from scratch - it raises the value of knowing what good software feels like, how systems fail, and how to say precisely what you mean.

And to get the model to perform, you have to speak the language it was trained on. This is method acting. When I debug WebGL - which I do not truly know - I speak fluent 3D lingo anyway, catch-me-if-you-can style, and the model lights up: “oh, this neighborhood, I know this street.” Or I’ll say “think in C++, just write it in JavaScript for simplicity,” and it reaches back into every good systems book it ever read. Either you become the expert and use the jargon, or you hand the tool to the real experts and become their infrastructure. The tool is a multiplier - and multipliers amplify whatever’s already there. Feed it a negative and it multiplies the negative.

The problems didn’t disappear. AI just lets you reach the harder ones. And I’d genuinely like to know: what are you seeing out there? Because we are all learning this at the same time.



Selected Q&A

What is the right unit of version control - code or prompts?

Question: We used to version-control assembler, then we trusted compilers and started version-controlling higher-level code. Are we transitioning from version-controlling code to version-controlling prompts?

Here’s the test: when did we stop checking in assembler and start checking in C? Only once the compiler became a deterministic, high-quality machine - once we trusted that regenerating the low-level artifact would give us something at least as good, every time. The moment that trust exists, the low-level artifact stops mattering. So today - save the prompt “Claude, write me a clone of Airbnb” and run it again tomorrow. Same result? Not a chance. So the code - Software 1.0 - is still the unit we version. Will that change? Gradually, and eventually, yes.

One observation: prompts are a one-dimensional, sequential, textual language - structurally that’s every other programming language we’ve ever had. I expect prompts to drift toward formal code over time. Should you version them? Sure, why not. Read a lawyer’s contract - it’s English, supposedly, but it’s a very special, very constrained kind of English.

Specs as the new code

Question: The spec becomes the new code if it’s written precisely enough. My friend, the creator of the Kotlin language, is now developing a language called Codespeak - a reliable spec you can version and generate predictable code from.

This is the right direction. The gap right now is that natural language is ambiguous by design. Math and code have exact resolution; English doesn’t. Every spec you write, no matter how carefully, still has room for interpretation underneath it. But as those tools tighten, the spec becomes the real artifact.

“All models are wrong, but some are useful.” Earth can be modeled as a sphere. Then a squashed sphere. Then there are mountains. The more you explore, the more detail there is to the actual shape. Declarative and imperative blur together at the edges - people used to joke that “HTML is not a language,” but it’s declarative.

Careful review versus the pressure to ship fast

Question: You said to review the plan before deploying. How does that survive the modern pressure to deliver at speed? We keep seeing cloud-provider incidents attributed to AI-generated code that someone shipped without stopping to read.

I learned to drive about two years ago, so this metaphor is fresh. As a pedestrian you can do whatever you want - stop dead in the middle of the street, cross on red, weave through people. No license, no rules, nobody dies. Then you get in a car. Faster, heavier, and suddenly the licensing gets serious - because now you can hurt people.

AI is the same. You built a billing system in one hour? Amazing. But the next morning your money is my money - is that still amazing? Maybe you want to talk to some humans first, sleep on it a night, and make sure your money stays your money. Speed is only an advantage if verification keeps up with it. Managerial culture will take a while to catch up. The principle doesn’t move: if you can, doesn’t mean you should.

Are LLM-generated diagrams reliable?

Question: I’ve been asking Claude to draw diagrams so I can see how it understood a design, and it’s often wrong.

Claude has been quite solid with diagrams for at least the past year - mermaid, UML, even ASCII art, pretty decent. Use it. And when it’s wrong, it’s often my prompt that was wrong, not the model. It works both ways too: scribble something on a whiteboard or a napkin, show it to Claude, and it reads your sketch and runs with it. Diagrams are one of the better bidirectional interfaces we’ve got.

Can you make the model talk faster - “caveman” prompting?

Question: Any first-hand experience getting it to use fewer words to save tokens?

The caveman-language joke - make the AI grunt in one-word sentences to save tokens - is real to a point. Same joke gets told about Mandarin, shorter words and all. But the actual cheat isn’t fewer words, it’s symbols. A symbol is a token so heavy it teleports the model straight into the right basin - the exact region where the knowledge you need actually lives. That’s the WebGL-lingo trick, the “think in C++” trick. One loaded word from the right domain drops the model into the right neighborhood faster than a paragraph of careful hedging ever could.

Which old principles still matter most?

Question: Which past engineering principles help build this highway where AI can operate faster?

All of them. SOLID helps. TDD genuinely helps. Small, revertible PRs help. CI/CD is crucial. Everything that was considered best practice is best practice - and now we can actually afford to do it properly. If writing tests took two weeks for code no one uses, a reasonable human wouldn’t bother. AI can cover a PR with tests in half an hour. The argument against rigor was always time. That argument got weaker.

Will AI shrink the job market?

The job market is changing - that’s not up for debate. There will be layoffs. There already are. And there will be bad managers who dress up their own incompetence, or plain embezzlement, as “we let people go because of AI.”

But think about what kind of human chooses to become a programmer in the first place. It’s a very specific wiring: the patience to sit and check every edge case; the nagging dread that it seems to work but you’re not sure; the bug you’re still turning over at the family dinner table. That person isn’t going anywhere. The problems didn’t disappear - AI just lets you reach the harder ones. When everything easy is solved, only the hard tasks are left, and hard tasks stay hard.

My guess: we end up with a billion programmers. People will write software that exists for an hour - “program my coffee machine, with my voice” - and nobody will blink. The field expands long before it contracts.