AI가 가속한 소프트웨어 엔트로피의 치료법 — Deep Module·Seam·Leverage로 코드베이스 De-slop
Matt Pocock
Matt Pocock이 'code is cheap' 시대의 이면 — AI가 가속한 소프트웨어 엔트로피를 진단하고, improved codebase architecture 스킬로 망가진 코드베이스를 되살리는 과정을 시연. 모듈·인터페이스·deep module·seam·adapter·locality·leverage의 공유 어휘 정리, 1,500 커밋 실제 repo에서의 deepening 후보 발굴과 grilling session, 그리고 에이전트는 전술가·인간은 전략가라는 역할 구분까지.
AI가 가속한 소프트웨어 엔트로피의 치료법 — Deep Module·Seam·Leverage로 코드베이스 De-slop
생각 덩어리
AI는 소프트웨어 엔트로피의 가속기 — code is cheap의 이면
You've probably seen the thousands of LinkedIn CEO posts saying that code is cheap and they can move faster than ever before. But what's happening is that AI has simply accelerated software entropy.
Every time that you make a change that doesn't take into account the entire codebase, you are likely to introduce little things, weird things that make the codebase harder to change. And over time, that just snowballs and snowballs until you end up with a huge ball of mud.
예방이 아니라 치료 — improved codebase architecture 스킬과 공유 어휘
I've made a video about this before introducing folks to the idea of deep modules. And that video focuses more on prevention ... Let's now focus on the cure, how you can take a codebase that feels like it's beyond repair and rescue it. And you can do that with some good old software fundamentals, as well as my improved codebase architecture skill.
This, by the way, is part of my GitHub Skills Repo, which is currently sitting at 41.5k stars. Bonkers.
One of the things that I added to this improved codebase architecture skill recently was a glossary of terminology. Having a shared vocabulary with the AI is super important because it means that you can talk using the same language. ... you can be a lot more precise with what you're asking for.
모듈·인터페이스·구현 — 코드베이스의 핵심 프리미티브
A module is a unit of something in your application. It could be a bunch of React components that all fit together to form a page. It could be a bunch of functions inside your application that are entirely responsible for authentication. Or it could simply be the logger that you've chosen.
In a good code base, these modules talk to each other, and they talk to each other via their interfaces. An interface is everything a caller must know to use the module correctly.
The implementation is then what's inside the module, what it actually does when you call sign-in or sign-out.
Deep module vs shallow module — 배워야 하는 인터페이스당 얻는 행동량
A deep module hides lots of implementation behind a relatively simple interface. A shallow module has a complex interface and kind of not much implementation actually behind it. These ideas are from John Osterhout's book A Philosophy of Software Design, which I recommend you pick up a copy of.
That's what we describe as depth, the amount of behavior a caller can exercise per unit of interface that they have to learn. Really good open-source libraries, like TanStack Query or something, have really good deep modules. In other words, they're hiding a lot of complexity behind a super simple interface.
Seam과 adapter — 테스트가 박히는 자리, fake clock의 원리
These seams are usually where you're going to do your unit testing or your integration testing. ... So, figuring out where your seams are going to live in your application is crucial to getting a good architecture.
When you find out where a seam is in your application, you need some concrete thing, a module, that satisfies that interface. This is what I'm going to call an adapter, which I'm taking from hexagonal architecture.
Inside some tests, you may want to have an adapter that is a fake clock. These both satisfy the interface at that seam, and it means that you can use the fake clock in tests, so you don't have to literally wait 2 weeks for your test to finish.
Locality와 leverage — 유지보수자와 사용자가 각각 얻는 것
For the maintainers, the people maintaining this module, they get locality. Changes to that module and bugs and all the fixes to do with them, they concentrate in one place, in that deep module.
You want high locality, grouping and co-locating the things that matter and that often change together.
The people using this module will get more leverage the deeper the module is. In other words, more capability per unit of interface they have to learn. And so, when we're talking about improving our code bases, these are the two attributes that we're aiming at.
1,500 커밋 실전 데모 — 나쁜 코드베이스의 증상과 deepening 후보 6개
The code base we're going to look at is my course video manager code base, which is the repo of software that I'm actually using to record this video. This code base has had, ooh, around 1,500 commits here, and I wouldn't say it's a ball of mud, but I also wouldn't say it's perfect, either.
Usually a bad code base is one that has a ton of shallow modules in it or one that has very poor leverage for those modules or poor locality where lots of stuff is spread in lots of different places.
This essentially means that the front end could make some changes but the back end because it has a separate parallel implementation could be out of sync with it. So this I think is actually a really good candidate for refactoring into a single module. We gain locality.
Grilling session — shape를 함께 다듬어 GitHub issue로, AFK 에이전트에게
It's got concrete code on both sides to ground this and it enters a grilling session. And in this grilling session we can take the ideas inside here and we can start kind of talking about what a better solution would be.
What you end up doing with this skill is you end up talking about the potential proposed solution, and it will then propose a shape. And once that's all done, you can take that and you can put that in as a GitHub issue into your issue tracker, which can then be picked up by an AFK agent.
It's again come back with two design decisions that it wants my feedback on. And here, I think you've got the flavor of how this skill works and the kind of conversations that you end up having with the AI based on this.
이건 AFK 스킬이 아니다 — 에이전트는 전술가, 너는 전략가
The thing that's important to notice here is just how much this skill demands of you, the user. This is not an AFK skill that you can just sort of run and ... rely on to continually improve your code base. This requires a judgment call from you, the programmer sitting above the LLM. I think of agents as really, really good tactical programmers. They're able to get on the ground and make changes quickly. But they need someone on the level above them who is the strategic programmer.
It allows the sergeant to go and run around the code base and look for potential improvement opportunities. But then you, the general, have to go and actually make the change and decide what's good for the long-term health of the code base.
I recommend that you run this skill, you know, every couple of days, really. ... And leverage as well means testing. If you have a set of really nice clear seams in your code base, then you're going to be able to write really nice tests around those nice deep modules. And the better your tests are, the better the output from the agent is going to be.
We talk about legacy code bases, what we really mean are bad code bases. Code bases that are hard to make changes in. And what you really need before you start making changes in a legacy code base is a harness around the code base to make sure that your changes don't mess anything up. So for that, you need tests ... really nice deep modules that have a lot of leverage and locality. So running improve code base architecture is a great place to start.