we'll recalibrate eventually based on understanding what level of abstraction we can operate on. If these code bases become unmanageable then the trend will correct itself.
I doubt this if the patterns of tech/software over the last <x> years remain. We'll just get buggier, worse-functioning, more expensive products/software built by fewer, more burned out developers. But your manager will love the sales presentation, so all will be well.
It seems obvious--and correct me if I'm wrong--that using AI requires less mental effort; and a less exerted mind is a weaker mind. A weaker mind will continue to create more and more fragile code.
Well, it's a nice thought-stopper by now, but IME it requires more and I can see the oldschool devs struggling with it every day.
Every once in a while I go "manual". It's restful and entertaining to write syntax by hand. It has this peculiar dare I say autistic delight, sorting the colored blocks and getting a little kick out of it. I understand the nostalgia but the progress is breathtakingly slow - as expected. You cannot do 6502 assembly by hand and expect to be fast in any meaningful sense of the word.
I usually juggle four, five active projects at a time and make days worth of manual progress on them in a morning. Support calls and colleagues questions interject occasionally. It's much more work than before, but I like it because dev work is super boring and now it's getting more interesting.
Like many people try to say AI is raising the bar. What we call normal software now will be childrens' toys tomorrow. The world expects ambitious projects, stuff that is hard and stands out.
AI is great at following patterns and loves to write tests. Start with good patterns that most teams would not have the discipline to write by hand and it is possible to get very robust code.
AI will write tests to the level of depth that you ask it to.
Try:
- Clearly identify the invariant being tested focus on exercising the invariant
- High volume, low signal tests increase CI and build times
- Avoid low signal tests; raw coverage is not the objective
- Avoid write-then-read tests when risk is low (no transformations, no business logic in application code on write or read path)
- Use explicit test execution [Explicit] when test code is used to exercise code in local environments only and should not run in CI
What's useful is to have a second agent that reviews the tests impartially and trim the ones that are low signal.
You also need to understand why agents write high volume, low value tests: because other ways of exercising the code (e.g. Playwright, E2E, curl) are even more expensive and not as consistent. So you have some recourse here by: 1) giving agents another way to exercise the code (e.g. provide it a REPL to your code) or 2) tell it to write some unit tests as explicit only (does not run in CI).
For our tests, we also added a small helper library[0] that cleans up tests to make them easier to read (smaller context for both humans and agents) as well as to write. Agents write average code by default. Your job as an engineer in this age is to help agents write good code.
Every once in a while something comes up that proves beyond a doubt that 99% of human beings on planet earth cannot think for themselves. And most sensible things that human beings do, they do by following the herd or "instructions".
Tell me again where there is NO widespread automatic consensus about how imperative is that one HAVE TO use these things from a sandbox?
The last time this happened was when the whole world agreed that it is alright to take a device with multiple cameras, mics AND 24x7 internet connectivity to our most private places...
Yes, it does, much more than the person sitting next to you or yourself. I wrote probably 1-2 MLoC in C and C++, and I literally see no reason why would I not be using the AI to produce code when it's already much better than I am, and much better than pretty much anyone I know or have worked with.
It can only simulate the outcomes of intuition in its training set.
The likely uncloseable gap is that some intution is unspoken, literally felt by the brain's default mode network and by parts of the prefrontal cortex.
LLMs basically never shower, do the washing up, kick their foot in the dirt while sitting on a park bench with a coffee: the domain of the default mode network. And they never sit frustrated looking at things, guided by their long experience, with the feeling that there is a solution before they can even say the words.
> LLMs basically never shower, do the washing up, kick their foot in the dirt while sitting on a park bench with a coffee: the domain of the default mode network. And they never sit frustrated looking at things, guided by their long experience, with the itchy brain feeling that there is a solution before they can even say the words.
I'm sure the training data of LLMs contains a lot of those things, though.
It may contain writings about these things, not the actual things. That's more like saving a jpg at high compression over and over if you want catchy metaphors.
FWIW, I guess it probably doesn't always matter too much in a tool where you want a logical, correct, standard, robust outcome like agentic coding.
Those outcomes are more easily averaged and we are after all talking about artificial intelligence.
I just think it's important to note, every now and then, that words aren't feelings or thoughts, and that an author's next book cannot be calculated from only the words of their previous books, etc.
An LLM is nothing but itchy brain feeling. Its neural network is trained to output "there is a solution" whenever there is a solution, before "knowing" what the solution is.
Humans still havent't accepted The Bitter Lesson[1].
Compute > Insight. Every time.
We can keep searching for essential human characteristics that humans have and AI lacks, but every attempt increasingly resembles an ego-preserving negotiation with the inevitable march. It's reminiscent of the God of the Gaps[2], but for human exceptionalism. As AI competency encroaches on more and more of human ability, we'll retreat into smaller and smaller gaps - foxholes of inimitablity.
As long as human value is justified by ability, quality, or characteristic, this problem will endure. The one escape hatch is the classical liberal idea that human value isn't tied to anything, that, by virtue of being human, people have universal, inalienable worth.
We should stop the project to attempting to substantiate human value by other means.
Imagine a junior engineer in the same position: they write shallow tests, they write overly complex code.
What do you do? You provide guidance, support and tooling so they can write better tests and code. You supervise and help them meet the standard. It is the same with AI agents (including the challenge of how to carry that knowledge around and transfer it). You are responsible.
You are also responsible for the understanding part: know what is being worked on, glance at changes, inspect the outcomes, cross-check specifications, tests, product requirements. The 'moving too quickly' idea is the other side of the same coin; it is your responsibility to keep track of where things are going. The exact same thing happens in a project where you have ten developers (or 200) working together — you cannot possibly read all of the code they write.
When I guide a junior engineer, I'm helping a human being become a better version of him/herself, who also helps me grow as a human being and will contribute with their unique ideas and world view, to the team, the organisation, the industry and society.
When I do the same with an LLM, I'm just repeating the same guidance over and over again out of frustration just to get something done.
Comparing an LLM to a junior engineer is frankly a disgrace.
How do you suppose project leads, principal engineers, EMs provide guidance? You don’t have to read the code being written by entire teams/departments for that.
They don't. They manage highly autonomous very well educated senior engineers, who can do the work autonomously. LLMs can't, they are closer to interns with dementia (and occasional genious revelations).
That was how I understood "code was never the bottleneck". If I need a deep understanding of the code, I might as well write it myself. It won't increase the time I need for the task appreciably.
Exactly, same thing with considering AI a higher level language. If I have to think of all the corner cases and design choices in plain English, then I much rather use a programming language whose main purpose is exactly to define cases and behavior of your design
The silent part is "undirected". You can patch these holes by observing them and the author us aware. By itself, these are the flaws.
I think speed is the biggest flaw though. If i could get variable speed while planning vs building, thatd change some things. I run local models, so i am mostly in the slow lane. When patching these flaws, i want it to read the code parts and diagnose quickly.
When its coding, i want to see the problems its encountering with the prompt. I usually observe its thinking a few rounds and if it misunderstands, i redirect.
But in all of this, i want a dial that just speeds up once i feel its doing the right thing.
SOTA today, to me, would put a model floor like qwen3.8-flash-next on a platform i can dial up the speed. Thats all. I think many of us will bring our own harness, so the only hard point is how dumb the engineers tools are.
Since im building local, my tools do a lot more management. So.e of tge opinions i see on HN trigger a "skill issue" reflex because we have a whole shopping mall now if tools and the incurious seem oblivious to how these models are used by cloud providers.
Learning about the raw capabilities of LLMs makes getting them to "do the right thing" is now just a job description.
Lastly, the last decade of tech oligarchy exposes how little education elites had about humanity and wicked problems. Elon musk reinventing public transportation several times ignorantly. The fact that a social program requires the consent of the people it helps. LLMs are a stark lesson in the difficulty of knowing all the constituent parts and still being unable to predict outcomes.
> Elon musk reinventing public transportation several times ignorantly.
In interviews, he admitted that the Hyperloop was intended to mess up the California High Speed Rail project because trains are boring. It's the opposite of ignorance, it's malice. Hanlon's inversion.
I do agree with some parts but not others. Reverting a flawed changed, e.g. should have never been as difficult as I have seen it been in some orgs before the advent of LLMs. Same for poor UX landing, both are issues that sure, may be thrown into sharper relief now, but were issues in some code bases and not others and remain that way today. More over, they are issues which can be permanently addressed in the former and in the later are one of the key sources of differentiation today.
On code readability, shallow tests and general quality, I can agree emphatically, though not universally. In other words, there are models which write the densest, hardest (for me) to parse code and tests that break with the lowest load/timing deviations yet proof less than nothing.
These do that regardless of how much one ships in my experience however so I wouldn’t attribute this to the velocity and more poor data at the heart.
I know this reads a bit like “you are using the wrong model” and I understand if someone testing e.g. an OpenAI models understandably extrapolates across all models and considers poor parse-ability in code a likely result of velocity, but you can always step back and work slower, plus, for what it’s worth, I struggle to parse OpenAI code when running their models through my evals after step 7 which is still a fairly measured in scope code base.
Essentially, I have seen LLMs, even the newest frontier, produce barely legible slop when building simple CRUD and I have seen a massive rewrite of the existing Firefox code base using APZ to enable an infinite canvas of browser tiles grow in a manner where, even at this stage having replaced a lot outside Places and Gecko, I can walk through changes made and explain the logic, as well as look at any part I haven’t been in for a while and find my bearing even without assistance.
AI is a force multiplier in whatever you apply it to. Most software companies output binaries with new features, whether it runs locally or on a server. Binaries with new features. None of the business owners give a shit about what is in the binary. It may be extremely fragile and only work for one type of user, but if they only have one type of user nobody cares. Most software doesn't keep evolving forever and at some point gets rewritten as a 2.0 version or whatever, so the quality was never as important.
It doesn't have to be that way. You can use AI just as effectively to produce quality source code as you can slop binaries. It depends on the business priorities and what is actually important.
The caveat is if you are the one engineer on the team trying to use AI the right way to produce quality source instead of binaries as fast as possible, you might get left behind or let go since your work no longer aligns with the business.
After 7 months and a 500k LOC codebase I can say that in my experience the fragility is inconsequential.
Disclaimer: I have no SaaS platform, it's a mobile app.
In my experience maintenance does not suffer long term with codebase size, if anything it became easier with model advances.
Most people talking about suboptimal implementation, fragility, and maintenance burden seem to theorize and extrapolate with no actual experience in implementing a large project with AI.
I can't blame them, I see the same in my day job, but the results after 500h+ on a separate project show that the concerns do not manifest in practice.
Purely for the models running your code base, have you ever ran an assessment of what that fragility costs you? Tool call error frequency, unnecessary test failures that the model then addresses but wouldn’t in a more parsable code base, inefficiency in navigation, anything of that sort? A model landing changes doesn’t mean it does it well.
I have seen all those when running a fairly new eval inspired by something I read in the ts-rust repo, giving a simple GPT-6 Astra code base to Opus 5.5.
Implementation accuracy was higher and token usage lower when Opus 5.5 got a Fable 5.1 built code base of the same feature set and coverage compared to the fragile GPT one. Incidentally I struggled to parse the latter but not the former.
Yes, a modern model will happily work on the most unmaintainable slop (doesn’t even need to be LLM derived slop, we have all seen bad Human written code) and that is great if you have an old code base to maintain. But if one can avoid it, even if one uses only models and never looks at the code, being efficient has value. Heck, rewrites are doable and affordable now, I have restarted projects and the gains were quickly apparent, even if we just look at model usage efficiency gains.
I started the project during 'copy snippets from ChatGPT web' days, so technically not entirely generated, but I don't think much is left of those days.
What do you get from this metric if it’s written by a LLM? It could be 50k or 500k or 5M; that doesn’t mean anything about how much labor you put in it.
My comment was not really about labor put in, more that the thread seems to be about the ability of AI to handle a large, evolving code base. So unless an LLM one-shot it, it does seem like a demonstration of that ability.
I recently spent a couple of hours reducing 1k lines of code produced by an LLM to about 100. Purely extrapolation, but imagine what if your project was 50k instead of 500k?
Let me tell you the story of the developer trying to reduce the number of tokens they use. It was a moonlit night, only the faint spinning of a Noctua fan audible and our intrepid developer...
I try to keep an eye on interfaces to make sure they are sane.
Beyond that, if there is 1k lines of code behind that interface, does it really matter? You can replace it with the 100 lines later and the rest of the app will be none the wiser. Treating the code behind the interfaces as being throwaway has been a maxim in programming since, like, forever.
I have a similar position - maintainability of code written by AI no longer matters in any meaningful way, as as the models advance, one simply rewrites.
At the current pace, the very idea of maintaining software will become as relevant as the idea of trimming wicks, stropping razors - or making every frame you take with a camera count.
When the marginal cost of replacement drops to a sufficiently low level, the entire paradigm changes.
I say this as someone with 30+ years of development experience, who built everything to be maintained until the heat death of the universe. I just don't think it's a relevant question in this brave new world.
Interesting analogy choices. Aren’t straight razors still the highest quality shave? We go with electric and cartridge because it’s faster and cheaper and takes less skill to get a decent result
Digital cameras are another interesting one. Since capturing images is so cheap we just snap a bunch of frames without a lot of thought towards composing them carefully, with a side effect that we get an overwhelming amount of mediocre frames and a few good ones, but we have to sift through.
I’m still not convinced I want to make this tradeoff in programming. But I work in scientific computing where I think it’s (still) really important to understand what modeling assumptions you are making through code
Yup - I think there will remain a space for artisanal code for a decent while yet, particularly in things like scientific computing, safety critical systems, and similar - but for most purposes, the cartridge shave will be good enough, more convenient, and much, much cheaper.
> In my experience maintenance does not suffer long term with codebase size, if anything it became easier with model advances.
This reminds me of Moore's law in the 1990s.
If you program ran slowly, or used too much RAM, you could spend six months optimising it (or removing features). Or you could just sit on it for six months and release it as it is - hardware moved on so fast that, by then, it probably ran successfully.
Your suggestion is a bit like this: don't worry, the pace of model understanding will catch up faster than the code will get disorganised.
I'm not saying I agree but it's an interesting idea.
Nah, Ive seen sloppy code bases. They really are hazards to the operations and companies they support. I'm not anti ai, but people opting to lose complete control of their own products so there engineers don't have to think are suffering from it, and it will get worse and worse and worse.
how many users do you have and how long has your app been out there?
unless that number is very large, then you have no idea whether your app is fragile or not
example: I own a Polestar 4. Great car, love it. I have non-deterministic SW glitches. Other people have non-deterministic SW glitches, but they're not the same ones as me. Other people never encounter any glitches. Others have tons of glitches that I don't have. Every new car that is sold, is another edge case. We had a Tesla for years, and the SW was rock solid, great stability. Why? Because their SW has been out there for over a decade with millions of experience points, and they have a large team that are aggressive about fixing and rolling out updates almost daily. Until you get to that point, you can't judge whether your vibe-coded app is stable or not.
You'd know the answer if you bothered reading the thread before posting the one hundredth 'you need a million users to judge maintainability' comment I receive on HN.
it's really hard to judge because depending on what the app does it could be reasonable or total slop.
i'm working on a fairly complex application and it's not even near 200k loc. but this is the second version - the first was vibe coded and was over 400k and full of bugs/issues that were slowing down development. i rewrote it and it's half the size, half the dependencies, and much faster & more robust.
is it more complex than your app? hard to say since neither of us want to disclose our identities :)
I did an analysis on the code I'm working on pre-AI and post-AI. There is no appreciable difference in implementation code size before and after, but the total LoC has grown substantially from having a lot more test code.
So you're probably right. Without AI the average lazy developer would write 50k implementation code and 0 lines of test code, and now they have 450k lines of test code in addition to their 50k of implementation code. It might not be great test code, but I know which I'd still rather have (hint: the tests).
I strongly disagree AI generates codebases of the same size as humans excluding test code. You can just look at Codex, codebase that is almost millions of lines of Rust Code (source) for a desktop app/ Terminal UI’s. I saw a lab employee somewhere cope on X by saying their terminal UI is as complex as a game engine, but last I checked, they just need to generate some 2D pixels, not entire 3D worlds with physics and sounds that is done with ~500k lines of code.
LLMs are laughably bad at writing code in some languages and shockingly good in others, so I can see that being the case if you chose poorly. But, especially when you have decided that you aren't even going to look at it, why would you use a shitty language?
I guess it's early to tell. Thankfully I can write code however the fuck I want in my job. I am not even searching for anything else right now because of this alone.
Vibe-coded adobe clones are only the beginning. Existing codebase moats have decreased significantly over the last year. Going forward green field protein buildouts will have a very tough time justifying to their boards why they want to be slower than competition.
Try using a statically typed language, refined types, and functional programming. Your tests become limited to things that are hard or impossible to assert with the type system.
We do this with OCaml, and it works pretty great. I have a particular style that I like and it takes some working of skill files to ensure it adheres to it, but in terms of just writing OCaml, despite being a relatively unpopular language, I have not had issues in any model that I've used.
> Your tests become limited to things that are hard or impossible to assert with the type system
Type systems are not a panacea. You still have to be logical and careful about them, especially around boundaries where types are just assumptions and not logical inferences. Then you have functions that switch type, but only a subset of the input is actually valid (string -> int for a number parser). Checking for NaN is like checking for Null.
Type systems does help, but they need the same attention as code to be actually helpful.
I feel this is a nice theory but needs even more ruthless oversight in order for the LLM to pick the correct abstractions and types, as your tests are now effectively your higher level type system choices.
Step 2: Prompt the agent to comment out the "when" code and check if the tests fail. (If tests don't fail it's a poor test)
Step 3: Prompt the agent to write mutation tests to harden the suite
Step 4: Prompt the agent to write property-based tests.
Step 5: Prompt the agent for 100% code coverage
Step 6: Keep a look out for small issues with steps 2-5 above and refine a Skill or Rule to package the workflow and plug gaps in the model's current shortcomings.
Step 7: Dedicate some time to manually reviewing and thinking about interesting edge cases worth testing.
---
If you follow these steps, you will have better test coverage than 99.9% of any code an engineer ever wrote pre-AI... and it will be almost completely automated.
My team's incidents and bugs are DOWN this year while we're shipping more.
Leveraging AI effectively requires a new paradigm of interaction. The name of the game is to use techniques and strategies and guardrails that create an environment that produce good software.
It’s also a great way for AI to keep creating backwards compatible bloat code when refactoring and whatnot because “tests are failing” when those tests are testing absolutely silly stuff (LLMs have a tendency to want to validate exact output rather than behavior).
I don’t think anyone has figured out the proper solution yet, I personally try to get the LLM to write code similar as I would have written it myself.
What do you mean "exact output rather than behavior"?
If you mean asserting against hardcoded literals, then that is the preferred testing shape in most cases. And for good reason.
If you change production code and a unit test fails, that is useful. Idk why that's silly. If you want to test more complex interaction write a UITest or integration test.
I honestly think we're all living in different worlds. There's probably large differences in capability on a per-language, per-team, per-codebase, per-engineer environment that are producing wildly different perceptions in output quality.
It would add tests for exact error messages, for example. It would add tests that the process exited with very specific error codes. Basically tests that I would never ever write myself.
And yes everyone works in different domains. I work at a database vendor myself, so mostly lower-level work.
I’m very happy and successful with LLMs, I just don’t think that these “just move all your tests to your type system!” or “get 100% test coverage” rules are an answer in the long term as we haven’t yet figured out how to do this well.
I personally treat tests as components that need to be well architected, maintained, and add them risks increasing technical debt and needs to be treated as such.
LLM's are way better at generating realistic tests than any engineer I've ever worked with as long as you are pedantic about asking for it and making sure it follows it.
I find this level of testing to have many downsides. For example, it means changing behavior "breaks" 100s of tests. The LLM doesn't have a good sense of what behavior is important to cement via tests and what isn't.
We shouldn't worry about that. We should be grateful about the mountains of technical debt, because that will be the social security of the post boomers generations: working till death fixing the last hurrah of the boomers.
My experience has been sort of the opposite. In the past 6 months I don’t think I’ve introduced a single production bug through my work, which is unheard of (for me, at least).
LLM code is verbose, and often quite inflexible, but that rigidity and verbosity tends to come from the AI being very thorough about ensuring the code does exactly what’s expected, and it seems to leave much less room for error as a result. It acts as a really good forcing function for specificity on requirements, and for thinking through "what if" scenarios.
In this instance, a monolithic rails API for a series of iOS apps with a few million daily active users. But I also work on some other TypeScript projects and have felt similar benefits there.
If the article is correct: AI generated codebase creates incidents that are more severe and take longer to recover from, companies will dial it back after they get burned bad enough.
If it's a skill issue: Maybe some coders can push the frontier out even a lot more than others before such things happen. Then the problem is the human in front of the screen.
> Here are the four most common ways that I have seen AI generating a fragile codebase. / Four signs that you have a fragile codebase
It would be nice if the listed symptoms (which have their own issues, e.g. "AI writes overly complex code" - overly complex for who?) were backed up with numbers or at least case studies, rather than stating "this is how you can recognize that X is happening", then stating "X is happening" in the title.
AI coding requires a lot of care to observability and verification.
If you can’t measure the problem, is it really a problem? A lot of assertions about code fragility seem to merge in with bike shedding arguments about style and what one person sees as readable.
But in the end if you have 100k of slop but we can know with high levels of certainty it does what it needs to - does it matter?
Every big company codebase with millions of lines devolves into a similar state. The small codebase starts with clean conceptual integrity. It then inevitably decays into incomprehensible spaghetti code as more people are added to it. Various reasons for it including the later devs caring less about the code than the initial team of devs, deadlines, avoiding refactoring because of fear about breaking things, etc
There was a time we all on HN agreed that contracting out the code was a bad idea. That ownership of the code was important, and if you sent your code out to a one off contractor it would come back as unmaintainable liability.
The shift in thanking leads me to believe that the real reason HN hated contracting out the code was the fact that you had to pay the contractors for their work.
There is also the possibility that a lot of HN hated outsourcing to contractors for the same reason a lot of HN hates AI: they were taking our jobs ;-)
And I think the outcome will be the same in both cases: we figure out how to outsource effectively. In fact, many of the same strategies we developed then are applicable now.
Not uniformly of course, no large community is that homogeneous in their opinions, but if you look at the stories and comments that get upvoted more than others, they tend to be heavily on the negative side. Heck TFA is a prime example.
As a more general example, most commenters here still believe that most of the revenues flowing around is circular investments even if there are multiple sources showing e.g. enormous growth in broad enterprise AI spend. I’ve linked many such sources in the past, but somehow they never get much traction around here. Wonder why that is ;-)
No I think the argument is more like… on average the code AI produces is better than what the majority of developers were producing before AI. Don’t forget HN crowd is the exception. The people that post here are like 1% of total programmers that like this as more than just a job. The industry at large, 99%, is just people doing their job writing average to poor code and going home. AI does that better now.
I doubt we're really the exception, and I think a good developer from the before times can still guide AI to produce a reasonably maintainable codebase over time. Most likely, a bad developer from the before times will still be able to guide AI to produce a mess. But yeah. It seems to me that the latest models produce above average code, based on the messes I've seen (and helped produce) over the last 25 years or so. It's not as good as what I'd build by hand these days, but it's good enough, when in the right hands.
This is actually a perfect depiction of what "bug-driven development" looks like, which is basically where the current generation of AI-only codebases are headed.
People the very least need to learn how to write memory prompts for their specific use case... Seemingly everyone is running with defaults or 100k+ stars skill abominations. My granma used this because important AI person said it is the way, look man it has 100k stars, it mussbegood!
If you feed back everything you had to fix with abominable intelligence generated code into your memory files, you'll end up with a pretty good prompt baseline that will steer the given model towards proper code generation.
563 comments
[ 6.1 ms ] story [ 205 ms ] threadI say that as a frustrated slop fighter.
That part was obvious, no need to explain it.
Every once in a while I go "manual". It's restful and entertaining to write syntax by hand. It has this peculiar dare I say autistic delight, sorting the colored blocks and getting a little kick out of it. I understand the nostalgia but the progress is breathtakingly slow - as expected. You cannot do 6502 assembly by hand and expect to be fast in any meaningful sense of the word.
I usually juggle four, five active projects at a time and make days worth of manual progress on them in a morning. Support calls and colleagues questions interject occasionally. It's much more work than before, but I like it because dev work is super boring and now it's getting more interesting.
Like many people try to say AI is raising the bar. What we call normal software now will be childrens' toys tomorrow. The world expects ambitious projects, stuff that is hard and stands out.
AI is great at following patterns and loves to write tests. Start with good patterns that most teams would not have the discipline to write by hand and it is possible to get very robust code.
Try:
What's useful is to have a second agent that reviews the tests impartially and trim the ones that are low signal.You also need to understand why agents write high volume, low value tests: because other ways of exercising the code (e.g. Playwright, E2E, curl) are even more expensive and not as consistent. So you have some recourse here by: 1) giving agents another way to exercise the code (e.g. provide it a REPL to your code) or 2) tell it to write some unit tests as explicit only (does not run in CI).
For our tests, we also added a small helper library[0] that cleans up tests to make them easier to read (smaller context for both humans and agents) as well as to write. Agents write average code by default. Your job as an engineer in this age is to help agents write good code.
[0] https://github.com/zeeq-ai/zeeq-biome
Tell me again where there is NO widespread automatic consensus about how imperative is that one HAVE TO use these things from a sandbox?
The last time this happened was when the whole world agreed that it is alright to take a device with multiple cameras, mics AND 24x7 internet connectivity to our most private places...
[1] https://www.youtube.com/watch?v=vWAGrSgEB4A
It can only simulate the outcomes of intuition in its training set.
The likely uncloseable gap is that some intution is unspoken, literally felt by the brain's default mode network and by parts of the prefrontal cortex.
LLMs basically never shower, do the washing up, kick their foot in the dirt while sitting on a park bench with a coffee: the domain of the default mode network. And they never sit frustrated looking at things, guided by their long experience, with the feeling that there is a solution before they can even say the words.
I'm sure the training data of LLMs contains a lot of those things, though.
Those outcomes are more easily averaged and we are after all talking about artificial intelligence.
I just think it's important to note, every now and then, that words aren't feelings or thoughts, and that an author's next book cannot be calculated from only the words of their previous books, etc.
Compute > Insight. Every time.
We can keep searching for essential human characteristics that humans have and AI lacks, but every attempt increasingly resembles an ego-preserving negotiation with the inevitable march. It's reminiscent of the God of the Gaps[2], but for human exceptionalism. As AI competency encroaches on more and more of human ability, we'll retreat into smaller and smaller gaps - foxholes of inimitablity.
As long as human value is justified by ability, quality, or characteristic, this problem will endure. The one escape hatch is the classical liberal idea that human value isn't tied to anything, that, by virtue of being human, people have universal, inalienable worth.
We should stop the project to attempting to substantiate human value by other means.
1. https://en.wikipedia.org/wiki/Bitter_lesson
2. https://en.wikipedia.org/wiki/God_of_the_gaps
What do you do? You provide guidance, support and tooling so they can write better tests and code. You supervise and help them meet the standard. It is the same with AI agents (including the challenge of how to carry that knowledge around and transfer it). You are responsible.
You are also responsible for the understanding part: know what is being worked on, glance at changes, inspect the outcomes, cross-check specifications, tests, product requirements. The 'moving too quickly' idea is the other side of the same coin; it is your responsibility to keep track of where things are going. The exact same thing happens in a project where you have ten developers (or 200) working together — you cannot possibly read all of the code they write.
Seeing all of these as downsides is a choice.
When I do the same with an LLM, I'm just repeating the same guidance over and over again out of frustration just to get something done.
Comparing an LLM to a junior engineer is frankly a disgrace.
For that you need to actually read the code and it's somehow in odds with the whole vibecode idea.
Plus it won't give you the 10x boost the management expects. Only not looking at the code will.
I think speed is the biggest flaw though. If i could get variable speed while planning vs building, thatd change some things. I run local models, so i am mostly in the slow lane. When patching these flaws, i want it to read the code parts and diagnose quickly.
When its coding, i want to see the problems its encountering with the prompt. I usually observe its thinking a few rounds and if it misunderstands, i redirect.
But in all of this, i want a dial that just speeds up once i feel its doing the right thing.
SOTA today, to me, would put a model floor like qwen3.8-flash-next on a platform i can dial up the speed. Thats all. I think many of us will bring our own harness, so the only hard point is how dumb the engineers tools are.
Since im building local, my tools do a lot more management. So.e of tge opinions i see on HN trigger a "skill issue" reflex because we have a whole shopping mall now if tools and the incurious seem oblivious to how these models are used by cloud providers.
Learning about the raw capabilities of LLMs makes getting them to "do the right thing" is now just a job description.
Lastly, the last decade of tech oligarchy exposes how little education elites had about humanity and wicked problems. Elon musk reinventing public transportation several times ignorantly. The fact that a social program requires the consent of the people it helps. LLMs are a stark lesson in the difficulty of knowing all the constituent parts and still being unable to predict outcomes.
Welcome to Socioligy 101 tech nerds.
In interviews, he admitted that the Hyperloop was intended to mess up the California High Speed Rail project because trains are boring. It's the opposite of ignorance, it's malice. Hanlon's inversion.
As much as he's malicious, he's also rediculously stupid in conception.
On code readability, shallow tests and general quality, I can agree emphatically, though not universally. In other words, there are models which write the densest, hardest (for me) to parse code and tests that break with the lowest load/timing deviations yet proof less than nothing.
These do that regardless of how much one ships in my experience however so I wouldn’t attribute this to the velocity and more poor data at the heart.
I know this reads a bit like “you are using the wrong model” and I understand if someone testing e.g. an OpenAI models understandably extrapolates across all models and considers poor parse-ability in code a likely result of velocity, but you can always step back and work slower, plus, for what it’s worth, I struggle to parse OpenAI code when running their models through my evals after step 7 which is still a fairly measured in scope code base.
Essentially, I have seen LLMs, even the newest frontier, produce barely legible slop when building simple CRUD and I have seen a massive rewrite of the existing Firefox code base using APZ to enable an infinite canvas of browser tiles grow in a manner where, even at this stage having replaced a lot outside Places and Gecko, I can walk through changes made and explain the logic, as well as look at any part I haven’t been in for a while and find my bearing even without assistance.
AI is a force multiplier in whatever you apply it to. Most software companies output binaries with new features, whether it runs locally or on a server. Binaries with new features. None of the business owners give a shit about what is in the binary. It may be extremely fragile and only work for one type of user, but if they only have one type of user nobody cares. Most software doesn't keep evolving forever and at some point gets rewritten as a 2.0 version or whatever, so the quality was never as important.
It doesn't have to be that way. You can use AI just as effectively to produce quality source code as you can slop binaries. It depends on the business priorities and what is actually important.
The caveat is if you are the one engineer on the team trying to use AI the right way to produce quality source instead of binaries as fast as possible, you might get left behind or let go since your work no longer aligns with the business.
Disclaimer: I have no SaaS platform, it's a mobile app.
In my experience maintenance does not suffer long term with codebase size, if anything it became easier with model advances.
Most people talking about suboptimal implementation, fragility, and maintenance burden seem to theorize and extrapolate with no actual experience in implementing a large project with AI.
I can't blame them, I see the same in my day job, but the results after 500h+ on a separate project show that the concerns do not manifest in practice.
I have seen all those when running a fairly new eval inspired by something I read in the ts-rust repo, giving a simple GPT-6 Astra code base to Opus 5.5.
Implementation accuracy was higher and token usage lower when Opus 5.5 got a Fable 5.1 built code base of the same feature set and coverage compared to the fragile GPT one. Incidentally I struggled to parse the latter but not the former.
Yes, a modern model will happily work on the most unmaintainable slop (doesn’t even need to be LLM derived slop, we have all seen bad Human written code) and that is great if you have an old code base to maintain. But if one can avoid it, even if one uses only models and never looks at the code, being efficient has value. Heck, rewrites are doable and affordable now, I have restarted projects and the gains were quickly apparent, even if we just look at model usage efficiency gains.
Even if I ended up with a project of 50k lines, that would take multiple times the effort it took me to get this app ready for the initial release.
Realistically, I wouldn't have finished the project at all.
It doesn't happen often to me. If it does, I find it often handles extra edge cases I only would have found by using the customer as a guinea pig.
Where else did you think they came up with the "10x developer" thing?
(Yes I know LoC is a useless productivity measure, that's just a joke. Obviously it's number of PRs..)
But in doing so, you will also 10x the features delivered. Maybe 5x, who knows?
But you definitely won't have to go through and decimate the generated code as a rule.
Oh, for sure.
I'm assuming the GGP's system can be expressed in 5k to 1k lines of Java or Kotlin.
Let me tell you the story of the developer trying to reduce the number of tokens they use. It was a moonlit night, only the faint spinning of a Noctua fan audible and our intrepid developer...
Beyond that, if there is 1k lines of code behind that interface, does it really matter? You can replace it with the 100 lines later and the rest of the app will be none the wiser. Treating the code behind the interfaces as being throwaway has been a maxim in programming since, like, forever.
At the current pace, the very idea of maintaining software will become as relevant as the idea of trimming wicks, stropping razors - or making every frame you take with a camera count.
When the marginal cost of replacement drops to a sufficiently low level, the entire paradigm changes.
I say this as someone with 30+ years of development experience, who built everything to be maintained until the heat death of the universe. I just don't think it's a relevant question in this brave new world.
Digital cameras are another interesting one. Since capturing images is so cheap we just snap a bunch of frames without a lot of thought towards composing them carefully, with a side effect that we get an overwhelming amount of mediocre frames and a few good ones, but we have to sift through.
I’m still not convinced I want to make this tradeoff in programming. But I work in scientific computing where I think it’s (still) really important to understand what modeling assumptions you are making through code
This reminds me of Moore's law in the 1990s.
If you program ran slowly, or used too much RAM, you could spend six months optimising it (or removing features). Or you could just sit on it for six months and release it as it is - hardware moved on so fast that, by then, it probably ran successfully.
Your suggestion is a bit like this: don't worry, the pace of model understanding will catch up faster than the code will get disorganised.
I'm not saying I agree but it's an interesting idea.
how many users do you have and how long has your app been out there?
unless that number is very large, then you have no idea whether your app is fragile or not
example: I own a Polestar 4. Great car, love it. I have non-deterministic SW glitches. Other people have non-deterministic SW glitches, but they're not the same ones as me. Other people never encounter any glitches. Others have tons of glitches that I don't have. Every new car that is sold, is another edge case. We had a Tesla for years, and the SW was rock solid, great stability. Why? Because their SW has been out there for over a decade with millions of experience points, and they have a large team that are aggressive about fixing and rolling out updates almost daily. Until you get to that point, you can't judge whether your vibe-coded app is stable or not.
“It’s not a code base that warrants that size, it’s a mobile app”
“Fragility is inconsequential to me and I am blind to my users dealing with it”
i'm working on a fairly complex application and it's not even near 200k loc. but this is the second version - the first was vibe coded and was over 400k and full of bugs/issues that were slowing down development. i rewrote it and it's half the size, half the dependencies, and much faster & more robust.
is it more complex than your app? hard to say since neither of us want to disclose our identities :)
So you're probably right. Without AI the average lazy developer would write 50k implementation code and 0 lines of test code, and now they have 450k lines of test code in addition to their 50k of implementation code. It might not be great test code, but I know which I'd still rather have (hint: the tests).
My code has never been stronger.
just curious, and tempted to do the same, so far I don't like the code made by llms in dynamic languages codebases
Type systems are not a panacea. You still have to be logical and careful about them, especially around boundaries where types are just assumptions and not logical inferences. Then you have functions that switch type, but only a subset of the input is actually valid (string -> int for a number parser). Checking for NaN is like checking for Null.
Type systems does help, but they need the same attention as code to be actually helpful.
Step 3: Prompt the agent to write mutation tests to harden the suite
Step 4: Prompt the agent to write property-based tests.
Step 5: Prompt the agent for 100% code coverage
Step 6: Keep a look out for small issues with steps 2-5 above and refine a Skill or Rule to package the workflow and plug gaps in the model's current shortcomings.
Step 7: Dedicate some time to manually reviewing and thinking about interesting edge cases worth testing.
---
If you follow these steps, you will have better test coverage than 99.9% of any code an engineer ever wrote pre-AI... and it will be almost completely automated.
My team's incidents and bugs are DOWN this year while we're shipping more.
Leveraging AI effectively requires a new paradigm of interaction. The name of the game is to use techniques and strategies and guardrails that create an environment that produce good software.
I don’t think anyone has figured out the proper solution yet, I personally try to get the LLM to write code similar as I would have written it myself.
If you mean asserting against hardcoded literals, then that is the preferred testing shape in most cases. And for good reason.
If you change production code and a unit test fails, that is useful. Idk why that's silly. If you want to test more complex interaction write a UITest or integration test.
I honestly think we're all living in different worlds. There's probably large differences in capability on a per-language, per-team, per-codebase, per-engineer environment that are producing wildly different perceptions in output quality.
And yes everyone works in different domains. I work at a database vendor myself, so mostly lower-level work.
I’m very happy and successful with LLMs, I just don’t think that these “just move all your tests to your type system!” or “get 100% test coverage” rules are an answer in the long term as we haven’t yet figured out how to do this well.
I personally treat tests as components that need to be well architected, maintained, and add them risks increasing technical debt and needs to be treated as such.
I was describing general strategy, that when applied in concert is more than the sum of its parts.
E.g I mentioned property-based testing, that is another angle at which a test avoids assertions that are too fine grained.
I think it has much more to do with overall architecture and design, and as for now, human oversight.
LLM code is verbose, and often quite inflexible, but that rigidity and verbosity tends to come from the AI being very thorough about ensuring the code does exactly what’s expected, and it seems to leave much less room for error as a result. It acts as a really good forcing function for specificity on requirements, and for thinking through "what if" scenarios.
So terse and flexible code can't be made to do exactly what is expected?
If the article is correct: AI generated codebase creates incidents that are more severe and take longer to recover from, companies will dial it back after they get burned bad enough.
If it's a skill issue: Maybe some coders can push the frontier out even a lot more than others before such things happen. Then the problem is the human in front of the screen.
It would be nice if the listed symptoms (which have their own issues, e.g. "AI writes overly complex code" - overly complex for who?) were backed up with numbers or at least case studies, rather than stating "this is how you can recognize that X is happening", then stating "X is happening" in the title.
If you can’t measure the problem, is it really a problem? A lot of assertions about code fragility seem to merge in with bike shedding arguments about style and what one person sees as readable.
But in the end if you have 100k of slop but we can know with high levels of certainty it does what it needs to - does it matter?
Here's the famous commentary about Oracle RDBMS codebase of 25 million lines: https://news.ycombinator.com/item?id=18442941
Every big company codebase with millions of lines devolves into a similar state. The small codebase starts with clean conceptual integrity. It then inevitably decays into incomprehensible spaghetti code as more people are added to it. Various reasons for it including the later devs caring less about the code than the initial team of devs, deadlines, avoiding refactoring because of fear about breaking things, etc
The shift in thanking leads me to believe that the real reason HN hated contracting out the code was the fact that you had to pay the contractors for their work.
And I think the outcome will be the same in both cases: we figure out how to outsource effectively. In fact, many of the same strategies we developed then are applicable now.
As a more general example, most commenters here still believe that most of the revenues flowing around is circular investments even if there are multiple sources showing e.g. enormous growth in broad enterprise AI spend. I’ve linked many such sources in the past, but somehow they never get much traction around here. Wonder why that is ;-)
Not really? A lot of companies have comparable codebases that are kept in check.
Service-oriented architecture helps at this scale by forcibly creating boundaries.
This is actually a perfect depiction of what "bug-driven development" looks like, which is basically where the current generation of AI-only codebases are headed.
If you feed back everything you had to fix with abominable intelligence generated code into your memory files, you'll end up with a pretty good prompt baseline that will steer the given model towards proper code generation.