> Fact is, vibe-coded projects devolve over time into an unmaintainable mess. The reason is simple, yet hard to fix: code maintainability and good architecture don’t have good measurements that we can apply, because it takes months, years even, to notice the effects of bad architecture or of unmaintainable code.
>
> For one, AI is not trained on what it means for code to be maintainable. For instance, any reinforcement learning done needs a reward signal that can be measured immediately, not in months or years.
Sad to say, but this is no different from human written code. Human written code just takes even longer to realize the mistakes because the pace is slower.
I think at the end of the day, it is not impossible to have AI write "good" or "high quality" code. If anything, once the patterns are established, AI will be more likely to adhere to the patterns and rules than any human team. It requires the most experienced engineers on the team to split their time writing the core patterns and documenting them in references/skills.
But it takes a lot of "taste" and a willingness to slow down a bit with AI (to create necessary artifacts), something teams find hard to do when you can ship so fast now.
My experience has been that there is a camp of very senior engineers that are unwilling to adapt to reality and focus on documentation and writing (effectively producing skills and agent guidance which multiplies their effectiveness); they will cling to their knowledge thinking coding a sacred art.
To me the difference is humans (ideally) will learn when they build something in a non-optimal way, and so will improve over time to become a competent engineer / architect. We cannot be perfect but to me a huge part of life is learning from failure and improving yourself, something that LLMs short-circuit and cannot replace.
LLMs cannot truly learn and so are destined to produce whatever the "average" software looked like at their training cutoff, or worse to produce code based on _other_ LLM generated code.
LLMs learn, and in two main ways: in-context and in training stages, release to release. The former is quick and sample efficient - perfect for adjusting AI behavior on the fly, and for enabling AI's own problem-solving capabilities. The latter modifies the "behavior defaults" and gives you performance gains that stick.
Why do you think that "write maintainable code" is somehow impossible to learn for an AI? We already have AI storming the frontiers of research math - way beyond the "average" of the field. If you can RL for "better at math", I see no reason why "better at maintaining code" would be somehow impossible.
You can construct an RL env where a codebase is presented as a "tree", and the AI is given one change to make at a time - and the per-change reward is not just whether the change itself has been evaluated as "made successfully", but also whether it made future changes down the line more or less likely to be successful, and harder or easier to make.
This is a formulation already used by some "maintainable code" benchmarks, so I expect something like it to make is way into frontier lab RL pipelines some time between "next week" and "a couple months ago".
> Human written code just takes even longer to realize the mistakes because the pace is slower.
Yes but the ceiling is still higher, and that's the author's point. If you vibe code, without code review, code becomes a mess quickly. If humans write code by hand, then this is often the case too, but crucially, this is not unavoidable. Sure, most codebases are a terrible mess, but some are not. AIs unfortunately got trained on all of them (+ reinforcement-learned stuff) and therefore their quality standard is about as low as that of the average codebase, ie pretty damn bad.
But there are plenty examples of acceptably decent yet long-lived codebases, both in OSS and inside companies. You simply couldn't get that quality by vibe coding. (unless you review every line of code and every design decision, at which point you're about as fast as you would be writing it all by hand, assuming some seniority)
>Sad to say, but this is no different from human written code. Human written code just takes even longer to realize the mistakes because the pace is slower.
I really don't think so, poor written human code IME is rarely overly complex, where as the AI code is almost always vastly over complex. Naturally complexity can be an issue because it leads to more surface area for failures and challenges to diagnose, but where I am REALLY seeing an issue is the complexity hiding an issue. Something that should normally fail or produce an error is covered up by something multiple layers deep in the code that returns an incorrect value instead of an error when something goes off the rails.
AI written code is a function of the human created constraints around it.
That is why I believe the most senior engineers on the team with the most scars and most experience need to shift into writing those constraints instead of writing code.
In writing those constraints, they can multiply their effect across a tireless fleet of agents that generally want to copy existing patterns and can be guided to use skills.
> Sad to say, but this is no different from human written code. Human written code just takes even longer to realize the mistakes because the pace is slower.
When the pace is slower you can notice mistakes earlier because you have time to reflect. It also allows you to detect when it’s becoming hard to maintain and you can correct course, rather than after it has become an unworkable mess.
It doesn't mean that people do. This is a false narrative we tell ourselves. Yes, there are craft-oriented devs and teams, but these are the exception rather than the rule because in the end, it is the GTM and business teams that define what, when, how and rarely the engineering teams.
There is no team without tech debt because there is no "golden" project where every decision has been made right because of reflection on decisions made wrong.
After a certain point, people would be forced to refactor, because they find themselves unable to handle the complexity.
With LLMs, there is no such friction. So the complexity get piled upon complexity in the form of a million best practices that is indiscriminately followed...
> After a certain point, people would be forced to refactor, because they find themselves unable to handle the complexity.
This is a fallacy; this is why legacy code exists that teams just work around. They lack the tests to verify it, the person that wrote it is long gone, it's handling some mission critical dataflow so no one touches the code and just builds around it.
>They lack the tests to verify it, the person that wrote it is long gone, it's handling some mission critical dataflow so no one touches the code and just builds around it.
Yes, "code rot" is not in any way an AI-unique problem. Codebases like Flash Player or Bethesda Engine have been deep in decay long before AI was capable of contributing to them.
Historically, this was caused by hiring the cheapest developers one can find, having high turnover, outsourcing, pushing to ship at any cost and more. AI just lets you get there faster, and without having to hire bargain bin Indians.
The thing is, today's AI is already far better at "code rot per feature shipped" than the worst of developers - and I struggle to believe that we're at the limit there.
I've already seen benchmarks that test for AI's ability to make incremental changes and tweaks to code continuously - thus, tracking whether earlier changes make the latter changes harder. This makes for a clear target to RL for.
AI is not better nor worse at producing code rot; just faster at it.
AI produced code is a function of the team driving and instructing the agents along with the scaffolding produced by the team (skills, examples, docs, comments); same with human teams.
A team that cannot guide a human team to produce better code will not be able to guide an AI team to produce better code because it's the same skillset: being able to write good docs, create constraints structurally in code, produce core architecture that enforces good behavior.
Not entirely wrong, but there's a very big hole: "the scaffolding produced by the team" also includes the scaffolding produced by past AIs.
An AI that knows how to keep the documentation accurate and up to date, and does it by default, would, all other things equal, rot your codebase less. An AI that changes the code without checking whether it obsoleted a bunch of examples in the docs would rot your codebase more.
While I think that you can reduce "AI-induced code rot" with good prompting and steering, you could also make headway against it at model level, by making the AI "well-behaved" by default.
> "the scaffolding produced by the team" also includes the scaffolding produced by past AIs.
This statement is also true of humans. Everything you've stated here is also true for human engineers.
> "the scaffolding produced by the team" also includes the scaffolding produced by past engineers.
But the agent can be instructed reliably to keep documentation accurate and up to date and will then do so dutifully. Put it in AGENTS.md that it must always update the /docs directory by creating a new doc or updating an existing doc and it will do it. (Yes, adherence may be 95% of the time, but that is likely several points higher than with most non-NASA human teams)
Better yet, extract docs from code comments. Even better when the docs are spatially co-located and line of sight as the agent crawls through code.
> Sad to say, but this is no different from human written code.
I don't think so. It's true that human also write shitty code but the key difference is we actually remember what is the intention behind those crappy implementations so someone can fix it later. aka it is the matter of long term memory that currently LLM architecture is not capable of.
You can argue that claude can read the whole linux codebase and report bugs, but they can only report local bugs, not systematic one. 1M context windows seems like huge, but the effective range is actually pretty limited, and it still does not equal to human insight.
> aka it is the matter of long term memory that currently LLM architecture is not capable of
Long term memory is easier than you think when you consider what an agent has to do when it is reading and editing code: instruct the agent to leave comments on its rationale and reasoning directly in the code. This is infrastructure free memory that every agent that then sees the code will read. Your code review agent will see the reasoning and decision making your coding agent formulated. When an agent comes and refactors this code in 6 months, the comments will be there (and it will update it!). When an agent is trying to troubleshoot an issue, it will read the comment. No infrastructure needed! Don't overthink it; use comments.
Code comments are line-of-sight for agents and one of the cheapest, highest leverage ways to get better coding performance from AI because unlike skills that may or may not activate, comments end up in context as long as they are well placed and carry the right instructions.
Best places to have it leave comments: 1) start of the file because it frequently uses `sed -n 1,200p` to read files and 2) inside the body of the method because it may find by keyword and read a few lines past. If your harness is set up with an LSP, language standard comments are also useful because then it can read comments on the member.
Tips for comments: point it to other, related members or artifacts; point it to external canonical docs; point is to a specific issue number or PR; have examples directly in the comment using your language's example markers; point it to example, reference usages in code. Use AGENTS.md to tell your agents how you want it to leave comments and to specifically read, follow, and maintain comments.
You don't need infrastructure or special architecture; Every coding agent is text-in, text-out. You need comments that get carried with text-in and a bit of guidance to the agent on how to use comments effectively.
No, developers definitely do not remember what they did two months ago. If you are busy, even two weeks is a problem. That is why we discuss documentation so much, self-documenting code, tickets and tests.
Well, and "intention" is a mine field of its own.
I've seen LLMs "connect the dots" across complex systems many times before. When it works, it's shocking how quickly it can pin down a bug that spans across the software stack.
1M context window is plenty. Once it's skimmed the code and come up with a theory for the problem, it can spin up a subagent that has a whole fresh context window and it can dedicate the whole thing to that one hunch.
CharlieDigital · · focus · HN ↗
I think at the end of the day, it is not impossible to have AI write "good" or "high quality" code. If anything, once the patterns are established, AI will be more likely to adhere to the patterns and rules than any human team. It requires the most experienced engineers on the team to split their time writing the core patterns and documenting them in references/skills.
But it takes a lot of "taste" and a willingness to slow down a bit with AI (to create necessary artifacts), something teams find hard to do when you can ship so fast now.
My experience has been that there is a camp of very senior engineers that are unwilling to adapt to reality and focus on documentation and writing (effectively producing skills and agent guidance which multiplies their effectiveness); they will cling to their knowledge thinking coding a sacred art.
throwaway19268 · · focus · HN ↗
LLMs cannot truly learn and so are destined to produce whatever the "average" software looked like at their training cutoff, or worse to produce code based on _other_ LLM generated code.
Ouroboros eat your heart out
throwthrowuknow · · focus · HN ↗
ACCount39 · · focus · HN ↗
Why do you think that "write maintainable code" is somehow impossible to learn for an AI? We already have AI storming the frontiers of research math - way beyond the "average" of the field. If you can RL for "better at math", I see no reason why "better at maintaining code" would be somehow impossible.
You can construct an RL env where a codebase is presented as a "tree", and the AI is given one change to make at a time - and the per-change reward is not just whether the change itself has been evaluated as "made successfully", but also whether it made future changes down the line more or less likely to be successful, and harder or easier to make.
This is a formulation already used by some "maintainable code" benchmarks, so I expect something like it to make is way into frontier lab RL pipelines some time between "next week" and "a couple months ago".
skrebbel · · focus · HN ↗
Yes but the ceiling is still higher, and that's the author's point. If you vibe code, without code review, code becomes a mess quickly. If humans write code by hand, then this is often the case too, but crucially, this is not unavoidable. Sure, most codebases are a terrible mess, but some are not. AIs unfortunately got trained on all of them (+ reinforcement-learned stuff) and therefore their quality standard is about as low as that of the average codebase, ie pretty damn bad.
But there are plenty examples of acceptably decent yet long-lived codebases, both in OSS and inside companies. You simply couldn't get that quality by vibe coding. (unless you review every line of code and every design decision, at which point you're about as fast as you would be writing it all by hand, assuming some seniority)
hattmall · · focus · HN ↗
I really don't think so, poor written human code IME is rarely overly complex, where as the AI code is almost always vastly over complex. Naturally complexity can be an issue because it leads to more surface area for failures and challenges to diagnose, but where I am REALLY seeing an issue is the complexity hiding an issue. Something that should normally fail or produce an error is covered up by something multiple layers deep in the code that returns an incorrect value instead of an error when something goes off the rails.
CharlieDigital · · focus · HN ↗
That is why I believe the most senior engineers on the team with the most scars and most experience need to shift into writing those constraints instead of writing code.
In writing those constraints, they can multiply their effect across a tireless fleet of agents that generally want to copy existing patterns and can be guided to use skills.
latexr · · focus · HN ↗
When the pace is slower you can notice mistakes earlier because you have time to reflect. It also allows you to detect when it’s becoming hard to maintain and you can correct course, rather than after it has become an unworkable mess.
CharlieDigital · · focus · HN ↗
There is no team without tech debt because there is no "golden" project where every decision has been made right because of reflection on decisions made wrong.
mohamedkoubaa · · focus · HN ↗
lolakutty · · focus · HN ↗
After a certain point, people would be forced to refactor, because they find themselves unable to handle the complexity.
With LLMs, there is no such friction. So the complexity get piled upon complexity in the form of a million best practices that is indiscriminately followed...
CharlieDigital · · focus · HN ↗
lolakutty · · focus · HN ↗
What you say here is not always the case.
ACCount39 · · focus · HN ↗
Historically, this was caused by hiring the cheapest developers one can find, having high turnover, outsourcing, pushing to ship at any cost and more. AI just lets you get there faster, and without having to hire bargain bin Indians.
The thing is, today's AI is already far better at "code rot per feature shipped" than the worst of developers - and I struggle to believe that we're at the limit there.
I've already seen benchmarks that test for AI's ability to make incremental changes and tweaks to code continuously - thus, tracking whether earlier changes make the latter changes harder. This makes for a clear target to RL for.
CharlieDigital · · focus · HN ↗
AI produced code is a function of the team driving and instructing the agents along with the scaffolding produced by the team (skills, examples, docs, comments); same with human teams.
A team that cannot guide a human team to produce better code will not be able to guide an AI team to produce better code because it's the same skillset: being able to write good docs, create constraints structurally in code, produce core architecture that enforces good behavior.
ACCount39 · · focus · HN ↗
An AI that knows how to keep the documentation accurate and up to date, and does it by default, would, all other things equal, rot your codebase less. An AI that changes the code without checking whether it obsoleted a bunch of examples in the docs would rot your codebase more.
While I think that you can reduce "AI-induced code rot" with good prompting and steering, you could also make headway against it at model level, by making the AI "well-behaved" by default.
CharlieDigital · · focus · HN ↗
Better yet, extract docs from code comments. Even better when the docs are spatially co-located and line of sight as the agent crawls through code.
npn · · focus · HN ↗
I don't think so. It's true that human also write shitty code but the key difference is we actually remember what is the intention behind those crappy implementations so someone can fix it later. aka it is the matter of long term memory that currently LLM architecture is not capable of.
You can argue that claude can read the whole linux codebase and report bugs, but they can only report local bugs, not systematic one. 1M context windows seems like huge, but the effective range is actually pretty limited, and it still does not equal to human insight.
CharlieDigital · · focus · HN ↗
Code comments are line-of-sight for agents and one of the cheapest, highest leverage ways to get better coding performance from AI because unlike skills that may or may not activate, comments end up in context as long as they are well placed and carry the right instructions.
Best places to have it leave comments: 1) start of the file because it frequently uses `sed -n 1,200p` to read files and 2) inside the body of the method because it may find by keyword and read a few lines past. If your harness is set up with an LSP, language standard comments are also useful because then it can read comments on the member.
Tips for comments: point it to other, related members or artifacts; point it to external canonical docs; point is to a specific issue number or PR; have examples directly in the comment using your language's example markers; point it to example, reference usages in code. Use AGENTS.md to tell your agents how you want it to leave comments and to specifically read, follow, and maintain comments.
You don't need infrastructure or special architecture; Every coding agent is text-in, text-out. You need comments that get carried with text-in and a bit of guidance to the agent on how to use comments effectively.
exploderate · · focus · HN ↗
Well, and "intention" is a mine field of its own.
StilesCrisis · · focus · HN ↗
1M context window is plenty. Once it's skimmed the code and come up with a theory for the problem, it can spin up a subagent that has a whole fresh context window and it can dedicate the whole thing to that one hunch.
williamse · · focus · HN ↗
[dead]
_superposition_ · · focus · HN ↗