Skip to content

dev_top10

Architecture

One might think that AI code generators, having trained on millions (billions?) of lines of code, are experts at application architecture. But one would be very wrong.

It's not that they don't understand the architecture that humans use, its that they don't understand the architecture that they should use. Let me explain. AI is devoid of the paranoia that good programmers have about changing code they're not familiar with. A good programmer is constantly questioning the effects of their changes, nervous that something else could be broken. AI's lack of paranoia creates all sorts of situations where it behaves in a way that would seem arrogant in a human, and can trash an application, forcing you to revert to an earlier version and throw out the changes AI have made.

You don't see this problem initially with AI, when the code base is small enough for AI to handle it. But large applications have a rough O(n²) problem, where the complexity of the code grows faster than the code itself. Once the code base crosses a limit, AI starts to become unreliable at coding and simple problems become intractable. Where is that limit? It depends on many, many things. But you start to feel it as you're crossing it: it takes longer and longer to get things to work and then all of a sudden more things break than get fixed or problems just never are getting fixed.

Here's what a traditional architecture looks like, the kind that AI agents love to build:

horizontal-architecture

That means you have, perhaps, a giant database ORM that talks to the database. If you need to add things to the database, you need to update the ORM to handle it. Those changes could be breaking for someone else; perhaps they didn't expect the new fields and die handling it. With a large application, it's hard to know the impact of any change, and AI isn't really going to try to figure that out anyway. Stuff gets broken, over and over again. You

The way to prevent this -- or at least push it off far, far into the future -- is to adopt an architecture that reduces the complexity of the code base aggressively. You need air-tight isolation between modules in the application, so AI only needs to consider making changes in a very limited scope. This works with AI's tendancy to have blinders on: it can still see all that it needs to see.

The architectural pattern I've adopted (very recently, so it's still on probation so to speak) is something called Vertical Slice Architecture. Vertical sliced architecture puts tightly related features into silos:

vertical-sliced-architecture

What could have been one huge program is instead essentially a series of smaller ones: each feature is pretty much its own application, from top to bottom. The hope is that you can make as many changes as you like to e.g. Feature 3 and not only are all the other features unaffected by your change, but there's virtually no way for them to be affected. Now your AI agent only has to look at Feature 3's code, a much more manageable proposition.

Even better, you can have one agent working on Feature 2 and another on Feature 4, and the odds of them stepping on each other are very small. This really allows you to boost your productivity by having multiple things in flight.

There are of course libraries of shared infrastructure and shared services, but these are as thin and generic as possible. If you do have to make breaking changes, you can version these services. "have_a_hotdog_v1" can continue to work the same way forever, but "have_a_hotdot_v2" can have new but breaking enhancements. And if have_a_hotdog_v1 ever cannot be supported, deleting it will trigger all sorts of super obvious errors in your code making easy to find the impact.

Generating an Architecture Design

I don't have boiler plate for a design, but most chat programs are able to help you come up with one. Here's a theoretical conversation flow:

Conversation Starter

Start with something like:

I want to build this project using the following tools:

  • Python 3.13
  • Flask / Jinja2
  • Bootstrap for UI styling
  • Postgres Database on backend
  • Direct SQL for accessing the database, no ORM
  • It is very important that we use a Vertically Sliced Architecture for this application.

Do you have any questions for me about this?

Your specifics will vary, of course.

Deployment Information

Next, if it's important, I'll describe where I expect to deploy my application, so the AI takes into consideration the limitations that imposes:

I will deploy this to Amazon Lambda, so make sure you keep in mind the limitations that creates (e.g., a serverless environment that can only expose one port to the internet, potentially needing to build a docker container with the app before deployment, etc.)

Deeper Architecture

Levels 1 and 2 are the basics, and they serve mostly to limit the creativity of your AI tool. But level 3 is going in a bit deeper about the architecture of both the application you're developing as well as the architecture of the environment it has to fit into. This is also a lot more variable

You might give it a list of systems it has to work with, database schemas to be aware of, or internal structures to use. You might give it a list of pet peeves, for that matter.

Using The Architecture Design

It's not enough to shove the architecture down a single prompt and then abandon it. You need to make the architecture spec part of your project (i.e., saved in the repository) so that the AI agent can constantly refer to it. If the architecture changes in any material way, have the AI agentg update the specification so that it matches what's being implemented.

Because the application is now a collection of mini-applications, you're going to want to also produce specfications for your UI look and feel, database structure, etc. so it still feels like a holistic program.

But what if I have an existing application I need to work with?

You have an existing application, but it's not vertically sliced, and AI is having a hard time with it? Do you have to refactor the entire application completely before AI is going to work?

Hopefully not, but maybe. An inbetween approach is something called the Strangler Fig Pattern where you slowly replace bits and pieces of your application until it's all running on the new architecture. I tried it and gave up, mostly because the new code ended up being too dependent on the old that it ended up learning bad habits from it.

Final Thoughts

I know, this isn't easy. If someone told you you'd need to produce a ton of technical specifications before you started "vibing", you'd probably think this isn't so vibe-y aftger all. But if you do some ideation with your chat program, you can easily produce an architecture specification that will keep your project going. Just be sure to remind the AI tools about the spec from time to time or put it into its "memory". And, trust me, keeping your AI agent on the rails is the key to getting the productivity gains you want.

Also, I'll admit that I don't know this is the very best architecture to use with AI, or to use with all AI coding tools. It's where I am now. A year from now I might be somewhere else. Maybe a spirograph architecture (I just made that up)...