I think this should be renamed "I know when you're vibe coding with a last generation LLM".
Claude 4 Opus would not make any of the mistakes mentioned, because it knows and understands everything in your codebase. It would know when there's an existing utility function for that particular task, or that you prefer a functional rather than OOP approach. You say you want developers to care about the code they write, well, this is the next best thing; I believe it's as close as we'll see to a machine being able to "care" in my lifetime.
> No one would write a class when we’re using a functional approach everywhere.
do people really think functional coding shouldn't involve writing classes?
i can't imagine writing what i think of as code in a "functional programming style" without tons of dataclasses to describe different immutable records that get passed around. and if you're feeling fancy, add some custom constructors to those dataclasses for easy type conversions.
This is all true. The best way to treat LLM's as they are now is one step above the abstraction offered by compiled languages over assembly. You can describe something in plain english, note its explicit requirements, inputs and outputs, and an LLM can effectively write the code as a translation of the logic you are specifying. Using LLM's, you are best served minimizing the entropy they have to deal with. The transformer is essentially a translation engine, so use it as a translator, not as a generator.
That being said, every few months a new model comes out that is a little less encumbered by the typical flaws of LLM's, a little more "intuitively" smart and less needing of hand-holding, a little more reliable. I feel that this is simply a natural course of evolution, as more money is put into LLM's they get better because they're essentially a giant association machine, and those associations give rise to larger abstractions, more robust conceptions of how to wield the tools of understanding the world, etc. Over time it seems inevitable that providing an LLM any task it will be able to perform that task better than any human programmer given it, and the same will go for the rest of what humans do.
Setting up a linter, formatter and having a lot of strict type checking are really helpful when using an llm to generate code, just like they are when you start receiving contributions from people who don't know or don't agree with the style rules that you implicitly follow. As are tests. Basically anything automated that helps ensure the right style and behaviour of your code becomes very useful with coding agents as they can just run whatever command you tell them to check for issues and/or fix them if possible.
This is a story of a bad LLM user (in this context), which is perhaps implied by “vibe coding” but folks should be aiming higher. Making people review slop is lazy, rude and disrespectful.
LLMs would also need to use historic commits as context, rather than just the current state of the codebase in isolation. Most codebases I've worked with go through migrations from a legacy pattern A to a newer and better pattern B, used across different parts of the codebase. Rarely can these migrations be done in a single go, so both patterns tend to stick around for a while as old code is revisited. Like the HTTP example, even if LLMs pick up a pattern to follow (which they often don't), it's a coin flip whether they pick the right one or not.
I've also noticed that the effort to de-slop the shit-code is quite significant, and many times eats the productivity gains of having the LLM generate the code.
> Because no one would write an HTTP fetching implementation covering all edge cases when we have a data fetching library in the project that already does that.
> No one would implement a bunch of utility functions that we already have in a different module.
> No one would change a global configuration when there’s a mechanism to do it on a module level.
> No one would write a class when we’re using a functional approach everywhere.
Boy I'd like to work on whatever teams this guy's worked on. People absolutely do all those things.
A risk with vibe coding is that it may make a good developer slightly faster, but it will make bad developers waaaay faster. Resulting in more bad code being produced.
The question then is: do the bad developers improve by vibe coding, or are they stuck in a local optimum?
In my experience pretty much all of these issues stem from a combination of short context windows and suboptimal “context engineering”.
If the agent has a clean, relevant context explaining what global functions are available it tends to use them properly.
The biggest challenge is how to construct the right context for each request, and keep it clean until the feature is finished. I expect we will see a lot of improvements in this area the coming months (sub-agents being an obvious example).
I personally treat the LLM as a very junior programmer. He's willing to work, will take instructions, but his knowledge of the codebase, and patterns we use is lacking strongly. So it needs a LOT of handholding, very clear instructions, description of potential pitfalls, and smaller, scoped tasks, and reviewed carefully to catch any straying off pattern.
Also, I make it work the same way I do: I first come up with the data model until it "works" in my head, before writing any "code" to deal with it. Again, clear instructions.
Oh another thing, one of my "golden rule" is that it needs to keep a block comment at the top of the file to describe what's going on in that file. It acts as a second "prompt" when I restart a session.
It works pretty well, it doesn't appear as "magic" as the "make it so!" approach people think they can get away with, but it works for me.
But yes, I still also spend maybe 30% of the time cleaning up, renaming stuff and do more general rework of the code before it comes "presentable" but it still allows to work pretty quickly, a lot quicker than if I were to do it all by hand.
This matches my experience. And I do mind the unnecessary comments. I always tell juniors that every line is important and the presence of a comment is a powerful tool for communicating with future developers. Think of it like labelling circuits on a fusebox. Now these garbage code generators are putting comments on everything because they don't understand anything and can't tell what it's redundant.
But this is only scratching the surface of what's wrong, as the article elaborates.
The thing is people claim these things are making them faster. I don't believe it. What I believe is they are faster at generating shit. I know that because a baby can coax an LLM into producing shit too.
I do not believe you can spend that much time writing the correct prompt - use this exact function, follow this pattern, add a comment here, don't add one there, no, not like that - and still be quicker than just writing it yourself directly in the language.
It's like if I speak French fluently but only communicate through a translator that I instruct in English but constantly have to correct when they miss the nuance in my speech. I'd just speak French!
So, no, I don't believe it.
What I believe is that many, many software developers have been manually writing boilerplate, repetitive and boring code over and over again up until this point. I believe it because I've seen it. LLMs will obviously speed this up. But some of us already learnt how to use the computer to do that for us.
What I also believe is developers exist who don't understand, or care to understand, what they are doing. They will code using a trial and error approach and find solutions based purely on perceived behaviour of the software. I believe it because I've seen it. Of course LLMs will speed up this process. But some of us actually think about what we're writing, just like we don't just randomly string together words in a restaurant and then just keep trying until we get the dish we want.
heck, I'm sitting in a team with a code base so full of slop that was written by humans, the AI can't even fix it and I'm burned out from trying to make it better. and I get told to be quiet about code standards because the team is still learning.
> I want people to care about quality, I want them to care about consistency, I want them to care about the long-term effects of their work.
Yeah, that's not happening.
LLMs enable masses of non-technical people to create and publish software. They enable scammers and grifters who previously would've used a web site builder to also publish native and mobile apps, all in a fraction of the time and effort previously required. They enable experienced software developers to cut corners and automate parts of the job they never enjoyed to begin with. It's remarkable to me that many people who have been working in this industry for years don't enjoy the process of creating software, and find many tasks to be a "chore".
A small part of this group can't identify quality even if they cared about it. The rest simply doesn't care, and never will. Their priorities are to produce something that works on the surface with the least amount of effort, or, in the case of scammers, to produce whatever can bring them the most revenue as quickly and cheaply as possible. LLMs are a perfect fit for both use cases.
Software developers who care about quality are now even a smaller minority than before. They can also find LLMs to be useful, but not the magical productivity booster that everyone else is so excited about. If anything their work has become more difficult, since they now need to review the mountains of code thrown at them. Producing thousands of lines of code is easy. Ensuring it's high quality is much more difficult.
I don't think that it's people no caring. I think many (most?) of us are biased to accept what we already have that's working. I noticed that of myself when I tried programming with an LLM "agent". After all the fuzzing around, many iterations of novels I had to write as many prompts, once the LLM produced something that worked, I had to fight with my instinct of just pushing that for review.
I also noticed that the time I had to spend on reviews from some of my colleagues increased by 9 times (time tracked). So I don't know how much faster they are being at producing that code, but I think it's taking longer overall to get that ticket closed.
All major AI assistants already come with ways to not have any of these issues.
Claude Code has /init, Cursor comes with /Generate Cursor Rules, and so on. It's not even context engineering: There are out of the box tools you can use not to have this happen. And even if they do happen: you can make them never happen again, with these same tools, for your entire organization - if you had invested the time to know how to use them.
It is interesting how these tools split up the development community.
I love how so many people are eager to criticize LLM code, when in fact, according to my experience it is pretty superior to anything I have seen produced by human programmers, most of the time. It is documented, the code is explained at each step of its creation, and it is pretty readable when you dig into it. I have 30 years of experience in coding, and I have been playing with these LLM for 3 years. Yeah!!! Of course, sometimes they produce very bad code. But in average, the code they produce is largely on par with my fellow humans. And since, they produce the whole explanation of it, it takes a couple of minutes to understand it. And if you don't understand the main points of the code, the LLM will tell you all about it. When did you have a colleague that was eager to explain his/her code to you??? When did you have a colleague that did produce a code you could understand in a few minute??? I really think these tools are quite useful, no need to wrap yourself into the mantel of expertise and look down on these LLM, because sometimes they will produce a code you don't like.
Personally I think caring is the resource in extremely short supply here and I don't think vibe coding has much to do with it causally. AIs are just tools - basically all of the issues the author has raised are present with human juniors too, and can be resolved quite easily with a little more guidance/interaction in both cases. I don't think AIs are universally causing people to care less about quality output, although that may be true for some people who didn't care much in the first place.
The common counter-argument here is that you miss out on training juniors, which is true, but it's not always an option (we are really struggling to hire at my startup, for instance, so I'm experimenting with AI to work on tasks I would otherwise give to a junior as a stop-gap).
Another aspect to consider is that what we used to consider important for software quality may change a lot in light of AI tooling. These things aren't absolutes. I think this is already happening, but it's early days, so I'm not sure what will play out here.
41 comments
[ 2.3 ms ] story [ 51.2 ms ] threadClaude 4 Opus would not make any of the mistakes mentioned, because it knows and understands everything in your codebase. It would know when there's an existing utility function for that particular task, or that you prefer a functional rather than OOP approach. You say you want developers to care about the code they write, well, this is the next best thing; I believe it's as close as we'll see to a machine being able to "care" in my lifetime.
do people really think functional coding shouldn't involve writing classes?
i can't imagine writing what i think of as code in a "functional programming style" without tons of dataclasses to describe different immutable records that get passed around. and if you're feeling fancy, add some custom constructors to those dataclasses for easy type conversions.
That being said, every few months a new model comes out that is a little less encumbered by the typical flaws of LLM's, a little more "intuitively" smart and less needing of hand-holding, a little more reliable. I feel that this is simply a natural course of evolution, as more money is put into LLM's they get better because they're essentially a giant association machine, and those associations give rise to larger abstractions, more robust conceptions of how to wield the tools of understanding the world, etc. Over time it seems inevitable that providing an LLM any task it will be able to perform that task better than any human programmer given it, and the same will go for the rest of what humans do.
I've also noticed that the effort to de-slop the shit-code is quite significant, and many times eats the productivity gains of having the LLM generate the code.
The legal department may have a different idea there.
> No one would implement a bunch of utility functions that we already have in a different module.
> No one would change a global configuration when there’s a mechanism to do it on a module level.
> No one would write a class when we’re using a functional approach everywhere.
Boy I'd like to work on whatever teams this guy's worked on. People absolutely do all those things.
The question then is: do the bad developers improve by vibe coding, or are they stuck in a local optimum?
If the agent has a clean, relevant context explaining what global functions are available it tends to use them properly.
The biggest challenge is how to construct the right context for each request, and keep it clean until the feature is finished. I expect we will see a lot of improvements in this area the coming months (sub-agents being an obvious example).
Also, I make it work the same way I do: I first come up with the data model until it "works" in my head, before writing any "code" to deal with it. Again, clear instructions.
Oh another thing, one of my "golden rule" is that it needs to keep a block comment at the top of the file to describe what's going on in that file. It acts as a second "prompt" when I restart a session.
It works pretty well, it doesn't appear as "magic" as the "make it so!" approach people think they can get away with, but it works for me.
But yes, I still also spend maybe 30% of the time cleaning up, renaming stuff and do more general rework of the code before it comes "presentable" but it still allows to work pretty quickly, a lot quicker than if I were to do it all by hand.
But this is only scratching the surface of what's wrong, as the article elaborates.
The thing is people claim these things are making them faster. I don't believe it. What I believe is they are faster at generating shit. I know that because a baby can coax an LLM into producing shit too.
I do not believe you can spend that much time writing the correct prompt - use this exact function, follow this pattern, add a comment here, don't add one there, no, not like that - and still be quicker than just writing it yourself directly in the language.
It's like if I speak French fluently but only communicate through a translator that I instruct in English but constantly have to correct when they miss the nuance in my speech. I'd just speak French!
So, no, I don't believe it.
What I believe is that many, many software developers have been manually writing boilerplate, repetitive and boring code over and over again up until this point. I believe it because I've seen it. LLMs will obviously speed this up. But some of us already learnt how to use the computer to do that for us.
What I also believe is developers exist who don't understand, or care to understand, what they are doing. They will code using a trial and error approach and find solutions based purely on perceived behaviour of the software. I believe it because I've seen it. Of course LLMs will speed up this process. But some of us actually think about what we're writing, just like we don't just randomly string together words in a restaurant and then just keep trying until we get the dish we want.
Yeah, that's not happening.
LLMs enable masses of non-technical people to create and publish software. They enable scammers and grifters who previously would've used a web site builder to also publish native and mobile apps, all in a fraction of the time and effort previously required. They enable experienced software developers to cut corners and automate parts of the job they never enjoyed to begin with. It's remarkable to me that many people who have been working in this industry for years don't enjoy the process of creating software, and find many tasks to be a "chore".
A small part of this group can't identify quality even if they cared about it. The rest simply doesn't care, and never will. Their priorities are to produce something that works on the surface with the least amount of effort, or, in the case of scammers, to produce whatever can bring them the most revenue as quickly and cheaply as possible. LLMs are a perfect fit for both use cases.
Software developers who care about quality are now even a smaller minority than before. They can also find LLMs to be useful, but not the magical productivity booster that everyone else is so excited about. If anything their work has become more difficult, since they now need to review the mountains of code thrown at them. Producing thousands of lines of code is easy. Ensuring it's high quality is much more difficult.
I also noticed that the time I had to spend on reviews from some of my colleagues increased by 9 times (time tracked). So I don't know how much faster they are being at producing that code, but I think it's taking longer overall to get that ticket closed.
Can't agree more.
Claude Code has /init, Cursor comes with /Generate Cursor Rules, and so on. It's not even context engineering: There are out of the box tools you can use not to have this happen. And even if they do happen: you can make them never happen again, with these same tools, for your entire organization - if you had invested the time to know how to use them.
It is interesting how these tools split up the development community.
> It works, it’s clear, it’s tested, and it’s maintainable.
It would be super funny if he ended his blogpost there.
I can imagine stuff like this happening when copy pasting from/to ai online chat interfaces, but not in a properly initialized project.
The agent will read all the crappy, partly outdated documentation all over the project and also take the reality of the project into consideration.
It's probably a good idea to also let it rewrite the programmer facing docs. Who else is going to maintain that realistically?
The common counter-argument here is that you miss out on training juniors, which is true, but it's not always an option (we are really struggling to hire at my startup, for instance, so I'm experimenting with AI to work on tasks I would otherwise give to a junior as a stop-gap).
Another aspect to consider is that what we used to consider important for software quality may change a lot in light of AI tooling. These things aren't absolutes. I think this is already happening, but it's early days, so I'm not sure what will play out here.
And by definition of this, you should care about the spec.
How code looks like, doesn't matter that much, as long it adheres to the spec.