Just want to "me too" this. I have two weeks a year where I unplug completely from my daily work and it often results in a new project or skill that I wouldn't have thought of otherwise
But... it shouldn't. People are arguing that a bad abstraction is better than none at all. Badly-implemented abstraction is the same. If you hit code that is duplicated organically a dozen times, you don't make it a baker's dozen. You spend a bit of extra time at least stubbing out the abstraction so future organic duplication can at least share an entry point. Abstractions grow organically too, in well-tended codebases.
The gold standard is code samples. I've got 1000-line convention documents with very simple rules like "Early returns on a single line". Llms sometimes ignore these or misinterpret them in unusual ways.
But if I tell it "read these files that use the same conventions" first, there's no misunderstanding, and the agent also picks up the general "tone" of the code. I have very little to tweak if I've defined the problem well.
> But if I tell it "read these files that use the same conventions" first, there's no misunderstanding, and the agent also picks up the general "tone" of the code. I have very little to tweak if I've defined the problem well.
Oh that is a bloomin' great idea, and I can fully see how it might work better.
Can't tell you how valuable this comment has been to me and now I feel so much better about evidently kicking a hornet's nest ;-) Thank you so much.
Glad I could help. I've been trying to use coding agents more than makes sense this year to get a feel for the tech. There's no good set of guidelines yet and everything feels like secret knowledge.
If you're using a coding agent like codex or claude code, I've also seen marked improvement by telling the agent to keep a journal of decision points, and every file read or written. And then, here's the important part, read the last five journals before starting. It primes the context with whatever you were working on and keeps a new session more focused that if it has to go searching for keywords through the whole codebase. It can also be an interesting read.
Having worked with LLMs, you absolutely can golf most (>50%) lines of code out of existence. I regularly do, because it picks the wrong abstractions and sticks with them.
I think that AGI will make heavy use of LLMs. It's not a straight path, but a component.
To compare with the human brain, have you ever been so drunk you don't remember the night, but you're told afterwards you had coherent conversations about complex topics? There's some aspect of our minds that is akin to a next-token-generator, pulling information from other components to produce a conversation. But that component alone is not enough to produce intelligence.
I've been through a few cycles of using LLMs and my current usage does scratch the itch. It doesn't feel like I've lost anything. The trick is I'm still programming. I name classes and functions. I define the directory structure. I define the algorithms. By the time I'm prompting an LLM I'm describing how the code will look and it becomes a supercharged autocomplete.
When I go overboard and just tell it "now I want a form that does X", it ends up frustrating, low-quality, and takes as long to fix as if I'd just done it myself.
YMMV, but from what I've seen all the "ai made my whole app" hype isn't trustworthy and is written by people who don't actually know what problems have been introduced until it's too late. Traditional coding practices still reign supreme. We just have a free pair of extra eyes.
I also use AI to give me small examples and snippets, this way it works okay for me
However this still takes away from me in the sense that working with people who are using AI to output garbage frustrates me and still negatively impacts the whole craft for me
Having bad coworkers who write sloppy code isn't a new problem, and it's always been a social problem rather than a technical one. There was probably a lot less garbage code back when it all only ran on mainframes because fewer people having access meant that only the best would get the chance, but I still think that opening that up has been a net benefit for the craft as a whole.
Before there was some understanding that at least they wrote and understood their own garbage code
Now it is not true. Someone can spend a few minutes generating a non-sense change and push for review. I will have to spend a non-trivial amount of time to even know it’s non-sense.
This problem is already impacting projects like curl who just recently closed their bug bounty because of low-effort AI generated PRs
> Before there was some understanding that at least they wrote and understood their own garbage code
> Now it is not true. Someone can spend a few minutes generating a non-sense change and push for review. I will have to spend a non-trivial amount of time to even know it’s non-sense.
The problem sounds basically the same to me honestly. If someone submits code that I can't understand and asks me to review it, the onus on them to explain it. In the previous case, maybe they could, but if they can't now, the review is blocked on them figuring out how to deal with that. If that's not what's happening, it sounds more like an process or organizational problem that wouldn't be possible to fix with the presence or absence of tooling.
> This problem is already impacting projects like curl who just recently closed their bug bounty because of low-effort AI generated PRs
External contributions are a bit of a different problem IMO. I'd argue that open source maintainers have never had any obligation to accept or review external PRs though. Low effort PRs can be closed immediately with no explanation, and that's fine. It's also totally possible and acceptable to limit PRs to only people explicitly listed as contributors. I've even seen projects hosted on their own git infrastructure that don't allow signing up through the web UI so that you can only view everything in the browser (and of course clone the repo, which already isn't something that requires credentials for public git servers).
I guess my overall point is that the changes are more social than technical, and that this isn't the first time that there was a large social shift in how development worked (and likely won't be the last one either). I think viewing it through the lens of "before good, after bad" is reductive because of how it implies that the current changes are so large that everything else beforehand was similar enough to gloss over what had been changing over time already. I'm not convinced that the differences in how programming was achieved socially and technically between 43 years ago (when the author says they started programming) and the dawn of LLM coding assistants were obviously smaller than the new changes that having AI coding tools have introduced, but that isn't reflected by the level of cynicism in most of these discussions.
You can’t really claim any PR is “low-effort” without actually reading and digesting the thing
Yes in the past you could check “oh this doesn’t have back trace or any steps to reproduce, close with won’t fix”
Now you cannot do that, the “low-effort” could be a 500+ lines code change with accompanying documentation and a 300 lines in prose describing the “problem” alongside with “backtraces” showing the issue
Except, the fix is non-sense but you have to read 500+ lines too know that. The documentation doesn’t match the changes but you have to read it to know that. The backtraces literally contain made up functions but once again you need to look closely to verify.
And if the thing isn’t immediately obvious to be AI generated then you’ll end up asking questions which will get forwarded to some AI and end up playing broken telephone.
All of this literally happened to curl in different issues.
I see comments like this a lot. In fact, I've run into it in my own side projects that I work on by myself -- what is this slop and how do i fix it? I only have myself to blame.
I can't speak to open source orgs like curl, but at least at the office, the company should invest time in educating engineers on how to use AI in a way that doesn't waste everyone's time. It could be introducing domain-specific skills, rules that ensure TDD is followed, ADRs are generated, work logs, etc.
I found that when I started implementing workflows like this, slop was less and if anyone wanted to know "why did we do it like X" then we can point to the ADR and show what assumptions were made. If an assumption was fundamentally wrong, we can tell the agent to fix the assumption and fix the issue (and of course leave a paper trail).
Engineers who waste other engineers' time reviewing slop PRs should just be fired. AI is no excuse to start producing bad code. The engineer should still be responsible for the code they ship.
> Engineers who waste other engineers' time reviewing slop PRs should just be fired. AI is no excuse to start producing bad code. The engineer should still be responsible for the code they ship.
Yeah, this is the unfortunate truth about what's going on here in my opinion. The underlying problem is that some workplaces just have bad culture or processes that don't do enough to prevent (or even actively encourage) being a bad teammate. AI isn't going to solve that, but it's also not really the cause, and at the end of the day, you're going to have problem at a place like that regardless of whether AI is being used or not.
Serious question: so what then is the value of using an LLM? Just autocomplete? So you can use natural language? I'm seriously asking. My experience has been frustrating. Had the whole thing designed, the LLM gave me diagrams and code samples, had to tell it 3 times to go ahead and write the files, had to convince it that the files didn't exist so it would actually write them. Then when I went to run it, errors ... in the build file ... the one place there should not have been errors. And it couldn't fix those.
The value is pretty similar to autocomplete in that sometimes it's more efficient than manually typing everything out. Sometimes the time it takes try select the right thing the complete would take longer to type manually, and you do it that way instead, and sometimes what you want isn't even going to be something you can autocomplete at all so you do it manually because of that.
Like autocomplete, it's going to work best if you already know what the end state should be and are just using it as a quicker way of getting there. If you don't already know what you're trying to complete, you might get lucky by just tabbing through to see if you find the right result, or you might spend a bunch of time only to find out that what you wanted isn't coming up for what you've typed/prompted and you're back to needing to figure out how to proceed.
I mean, it's not actually autocomplete. But it serves the same role. I know approximately what I want to type, maybe some of the details like argument-order are a bit foggy. When I see the code I recognize it as my own and don't have too much trouble reading it.
But I use LLMs one level higher than autocomplete, at the level of an entire file. My prompts tend to look like "We need a new class to store user pets. Base it on the `person` class but remove Job and add Species. For now, Species is an enum of CAT,DOG,FISH, but we'll probably turn that into a separate table later. Validate the name is just a single word, and indicate that constraint when rendering it. Read Person.js, CODE_CONVENTIONS.md, and DATA_STRUCTURES.md before starting. When complete, read REFACTOR.md"
With the inclusion of code examples and conventions, the agent produces something pretty close to what I'd write myself, particularly when dealing with boilerplate Data or UI structures. Things that share common structure or design philosophy, but not common enough to refactor meaningfully.
I still have to read it through and understand it as if I'd written it myself, but the LLM saves a lot of typing and acts as a second pair of eyes. Codex currently is very defensive. I have to remove some unnecessary guardrails, but it will protect against rare issues I might not have noticed on my first pass.
I've found small features helps. If I ask the ai "do this", I wait 10 minutes for it to be finished, then another 30 understanding what was written
Instead, I start out broad. "I'm thinking of this feature. Let's talk about what components will go into it and where that code will live... Here are my initial thoughts. Let me know if I get anything wrong..."
This puts it in a conversation mode and gets you on the same page, and best of all it's quick. The llm agent isn't searching files and building, it's just giving general opinions
Once I have a good idea of the architecture, I move on to "write this class. Here is an overview of how I would do it", or point the agent to an existing file with the right conventions in place. Once again, if you've done your conversation doesn't take long. 20-second turnaround.
Then it's time to refine. "Move this function here, refactor that"
If you're going to have to understand the code anyway, read it while your writing it. Line by line, function by function, class by class. "Growing" a feature this way keeps you and the llm in sync. It doesn't go off on tangents. And building incrementally keeps you in the loop and in your flow. You don't have 5 things going at once. You have 1, faster.
I've let agents do their thing for a dozen minutes and usually end up having to rewind the whole thing piece by piece to understand what's actually happening
If you're truly vibe coding, maybe you don't have to read the code and can have a dozen agents on a dozen projects. But if you're making Serious Software, I don't see how you can commit code unseen. And in that case, you're not losing anything working incrementally and reading code as it's written?
I'm in the JS ecosystem pretty regularly and "restrictive with no benefit" is the right description. I use JSON5 now when I have to, which greatly reduces the restrictions. I already have a build step so throwing in a JSON5 -> JSON converter is negligible.
As for FracturedJson, it looks great. The basic problem statement of "either minified and unreadable or prettified and verbose" isn't one I had put my finger on before, but now that it's been said I can't unsee it.
reply