Comment by bitwizeshift
4 hours ago
I’m surprised I haven’t see anyone say this yet, but I don’t let the LLM design the code at all, I let it implement a design I have created.
By that I mean that, rather than let the LLM do the entire structure, I take the time to create the full hierarchy of abstractions and actors that I want my code to do. I decide, at the UML level, how abstractions will sit and interact — and then I make the LLM implement those gaps.
The key thing here is that, by doing this, I DO know how the code works. I may not know how each unit is implemented, but I know each unit’s responsibilities and how they interact with one another. I’ve found that LLMs are HORRIBLE at writing decent abstractions, regardless of how much prompting and skills I’ve given it. It will always get the job done, but it will often be unmaintainable and require bigger and heavier refactors as I introduce more and more requirement changes.
But by flexing my basic design skills, I don’t have those issues. Future refactoring fit into easy abstractions that I’ve designed. And by documenting it up front, I also have what becomes a living document on how this work will turn out.
It takes a few hours up front to plan ahead, but it makes the LLMs job easier and use less tokens, and it makes the code better long term. I don’t care if one unit is suboptimal, as long as the abstraction is right — because at worst I can change an implementation for a better one later.
I agree with this approach, but I'm a bit surprised this has to be said at all. These are basic software design principles and I imagine it's the default way any experienced programmer would approach the problem. I wonder if the people not using this approach are primarily junior developers who have never seen how real software is built, or if it's leaking into the senior levels as well.
Most people in the industry right now, even at FAANG and even among people carrying "senior" titles at these places, have little experience with "software design principles" -- tens of thousands of brilliant Ivy League graduates with surreal compensation packages have spent the last decade pulling tickets off JIRA and pasting least-change-possible patches onto existing code for about 10 hours a week while spending the other 30+ hours barely engaged at meetings.
This hurt to read but checks out in my experience. These types also tend to love tossing debt over silo'd walls and pointing the finger a lot if/when anything goes wrong.
I'm old enough now to be a protected class, so I don't want people accusing me of ageism, because that's not where this is coming from - but there's a type of person that clearly is on their last job of their career and knows it and I try to avoid them like the plague, I've seen it too many times.
[dead]
I work on my code this way, but I have no idea what my colleagues are doing, and it's impossible to review thousands of new/changed lines a week.
I just approve PRs, because I have to. I don't know what else to do. I can barely keep an eye on all my code.
Actively looking, but job market is rough in Northern Europe. I quit caring about quality in any capacity here, the company has clearly chosen its direction, against my very vocal complaints.
My last interview, with what I thought was a great company, failed when I didn't understand what NLP was when they asked me about it.
> NLP? > Natural Language Programming, it's the future. Claude, GPT, etc.
I laughed, he didn't, looked offended and said it was a serious question. I had thought it was a joke, said "oh you mean LLMs". I tried to answer seriously, of course, but that was my third round technical interview and I didn't get a call back.
Just getting a paycheck and producing mediocre work until I get something new. (Senior engineer, 10 YOE, patents, 3 years at a unicorn).
Also considering becoming an electrician.
I will be unhappy if they steal the meaning of NLP. NLP means Natural Language Processing and LLMs are only a subset of NLP. I would have concerns about anyone who claims to have technical knowledge and asserts NLP means "natural language programming." Those are the same kind of people who might suggest Lisp should add mutable objects.
3 replies →
I'm in what I think will be my last tech job before retraining into something else. The aspects I like about the work are gone, I'm coasting at a small company that's not a great fit, has a visa cliff, and is poorly paid, and the steps it would take to become competitive in an LLM driven tech job market are less appealing to me than the steps it would take to switch over to a different career (likely in healthcare).
4 replies →
Yeah, I imagine it's something that needs to be enforced at the organizational level. I sympathize with anyone who takes pride in their work and needs to deal with mindless coworkers pushing slop without any accountability. I left corporate software development (before LLMs were a thing) over frustration with the general culture and I can only imagine it's gotten worse since then.
3 replies →
Sounds like a cushy job. Why would you want to leave?
10 replies →
The LLMs know design principles too, being an experienced developer doesn't make you as special as you might think.
Don't get me wrong, LLMs are way better than me at most things, but I don't think you can deny that the current generation of models makes questionable decisions sometimes. Especially on project structure, API boundaries, and code duplication. I also think they just have bad taste in general, though of course that's more subjective.
12 replies →
I've been doing this a long time and i would say since the last 3 months or so i've spent more time learning from llm code than correcting llm code. It's not bad and takes approaches and makes decisions i wouldn't have thought of. I'm not too ashamed to admit that, a model just as access wider and deeper experience with code than I do.
> doesn't make you as special as you might think.
Way to come off as incredibly insecure. There's no need to randomly put people down.
6 replies →
The LLMs have been trained on all kinds of code. They often choose a hacky solution because that's what they encountered in similar situations in their training. It generally only takes a few words to guide them to a better design than what they saw in the wild, but if you don't guide them, they follow the herd.
2 replies →
Existing abstractions can be easily applied to similar contexts, but designing abstractions seems backwards. The system abstractions should be grown and extracted from the working code. Idk how you know the right thing without going through the complexity of building it.
> I’ve found that LLMs are HORRIBLE at writing decent abstractions, regardless of how much prompting and skills I’ve given it. It will always get the job done, but it will often be unmaintainable and require bigger and heavier refactors as I introduce more and more requirement changes.
I quote this just to put extra weight on this! It's surprising, the effect size of this statement.
Replying to save OP, and this comment!
Agreed. Even with opus 5.5 which everyone praises for its wonderful coding abilities, I keep catching awful coding abstractions or missing abstractions.
It can keep patching everything left and right whenever a new requirement comes up so it does not "need" to build abstractions, and it will only do it to please the human reviewer.
The key is to stop caring (/s?)
I really don't think that's enough. You understand the product but not the process.
This is okay as an end user who only cares about features but can be disastrous when something goes wrong and your only hope is to prompt an LLM that might or might not be (a) available or (b) not read into the context of the codebase.
The scope of the problem worsens when you consider that many teams STILL don't own what they write and have SREs serve as their first-line. These folks NEED to know how the hot paths of the services they support work without the memory or tools that your Claude account has. This is much much harder to do on a codebase that's a billion SLOC for no reason with inconsistent code style and questionable tests littered everywhere
I think that writing the code OR having written a lot of code in the past is the only way to REALLY understand what's going on.
Good SREs can support a service without being familiar with the details. They use generic mitigations (e.g. rollback to a know good release, request an emergency quota increase, etc) to quickly stop the bleeding without needing to understand the root cause. Later the SWEs who understand the code can debug at their leisure. Having a deep understanding of the service obviously helps but is not essential. I expect agents are already applying these generic mitigations at bleeding edge companies but do not have firsthand experience as an SRE to confirm.
Agreed. I generally feel pretty comfortable with letting LLMs implement stuff like individual functions or algorithms. But I feel like it takes some effort to make sure separate things stay separated... (I do think it also helps LLMs if the code to stays nicely abstracted.)
On the other hand, I do some stuff with physics simulations and LLMs will spit out arrays like
static constexpr std::array<int, Q> cx{0, 1, 0, -1, 0, 1, -1, -1, 1};
static constexpr std::array<int, Q> cy{0, 0, 1, 0, -1, 1, 1, -1, -1};
static constexpr std::array<real_t, Q> w{ real_t(4) / 9, real_t(1) / 9, real_t(1) / 9, real_t(1) / 9, real_t(1) / 9, real_t(1) / 36, real_t(1) / 36, real_t(1) / 36, real_t(1) / 36};
static constexpr std::array<int, Q> opp{0, 3, 4, 1, 2, 7, 8, 5, 6};
and it's like ??? I know what these are for, but I have no clue if any of the numbers are right :-)
Sounds a bit like the brain sandwich: https://terriblesoftware.org/2026/10/02/the-brain-sandwich/
Sure, but the best way to come up with a good design is to talk it out with the LLM.
Soon that will be counterproductive and you'll be better off trusting whatever design it comes up with.
I tend to work in a middle ground space here. I want to influence and approve and, most importantly, understand whatever design I'm pursuing. I don't want to fastidiously write the whole design out myself.
I've been starting in the ChatGPT web UI, having long conversations, having it generate Markdown plans, and then editing those plans; I hand those off to implementation agents.
> I have created.
Are you working on a team? I've found that for solo projects this works but, even when you own the design of your piece, integrating with the work of several people doing this ultimately leads to even the part you initially designed no longer working exactly as you remember it.
A good chunk of my time now is spend working with an LLM to understand how other parts of the code base work and how they relate to and interact with the product features I manage. But I'm still on a small enough team that this is possible. I'm not surprised at all that an engineer at an org the size of Meta would not even be able to perform this level of work in understanding what's happening.
Yes this is on a team that I lead. We have augmented our practice so that teams do the design reviews together to ensure we are all understanding the changes. It’s also helped uplevel devs to think in terms of design practices.
It still has sharp edges but IMO it’s the best we have at the moment, and it works. It also means we deliver larger volumes of code, but we mostly look for alignment with the original review — so our reviews are more focused on what tests say behavior should be
This feels right. It fits the "Assembly to C" style transition of abstraction in that we're going from "code to design of code."
A question I've been struggling with, however, is what are the artifacts that live at this level? Are they design docs? Are they standardized? If I read your design docs, will I understand the code or do I need to "decompile" (use a coding agent to explain) to get back to this level of abstract for me to edit it?
Yeah I do something similar, basically it all comes down to more babysitting and being more involved with the actual architecture, correcting stupid mistakes, and reviewing the code (and comments!) the LLM leaves behind.
Sometimes you do need to see how things are implemented before you know that a design doesn’t work, I’ve never been big on large upfront design work and prefer more iterative development. This can still be perfectly done with LLMs.
> rather than let the LLM do the entire structure, I take the time to create the full hierarchy of abstractions and actors that I want my code to do. I decide, at the UML level, how abstractions will sit and interact — and then I make the LLM implement those gaps.
Do you do this with every repository that's brand-new to you? You refuse to, for example, use an agent to learn where the feature should generally live? This seems absurdly slow for that purpose, because even though humans can still get a deeper understanding of a codebase after several months, an agent can get a much deeper understanding over a timeline of the initial few days. Unless everything is already meticulously documented for you, I suppose.
I don’t believe I said I don’t use agents for things like research? There’s a difference between trying to get your bearings in a new codebase with an LLM pointing you in the right direction so that you can understand things, and just letting an LLM like Claude take the wheel to do a change for you.
Yes, new codebase we take the time to learn, as every good developer should. Ramp-up doesn’t have to be that long to get one’s bearings.
Also, changes don’t have to be deadbolted into bad designs. If the code was bad before and you have a change to make, it can sometimes be faster in the long run to redesign it and rebuild it so that it can scale better with future requirements. LLMs make this part fast and easy — but again, requires design, and designs require human brain involvement and understanding of the codebase
This is where myself and a colleague have settled. We design for longevity but it can still type, search, and debug faster than we can.
Same here. I review plans w rendered diagrams. Data structures, flowcharts, uml sequences, and component architecture docs.
I have found that making the AI look the plantuml and the rendering and reviewing before presenting it to me results in much more legible designs. To me the peak of this would be a shared interactive whiteboard w the ai during design.
Same. I let the LLM work inside a framework that I made.
Of course I only arrived at the framework after trial and error with an LLM showed me the shape of the problem and the framework presented itself to me.
LLMs certainly helps with designing and is the best brainstorming tool one can have beside their own brains.
This is too the paradigm I’ve settled upon after a year of using these tools.
[dead]
Agreed, otherwise the risk is receiving the average of what LLMs think are best practice.
Planning is fundamentally so critical to ensuring alignment and outcomes, that over time how one plans can be better trained into the process to help do more and more of it.
[dead]
The issue is the LLM can often design thing superior to anything you can do. Now this isn't always the case but it is often the case. By limiting yourself to code only YOU design you are cutting off a major portion of of AI capabilities that is highly leverage-able.
The pace of AI is literally changing so fast that we can't keep up. Your strategy here was probably true around 3 to 4 months ago. Right now it's no longer true. Not many people understand navier stokes and that's what AI can offer, it can offer some superior problem solving methodology with the level of complexity of navier stokes that you have no hope of understanding without years of study and education to get yourself up that level.
This is not a trivial question with a trivial answer.
Unfortunately your answer is outdated. I think if trendlines continue, the answer is trending violently towards putting more and more trust towards AI.
Compute is finite but human stupidity is limitless. You can ask AI to do something unimaginably stupid and it will spend its full capacity trying to satisfy your stupid request, which may not even be possible.
For those of us with practical budgets not measured in the millions, that bar for stupidity is pretty damn low, and I’m not convinced that there’s enough compute being built to account for every idiot in the world.
What does human stupidity have to do with this? If you're too stupid to ask it a good prompt then you're probably too stupid to design something for it to do.
I'm saying ask the AI something beyond your intellectual capabilities. Or ask it something beyond your intrinsic knowledge base. It can produce a working machine that does the job, but you won't be able to understand it.
You can still verify the machine works by using the machine... but you won't necessarily understand it. Similar to how you own a smartphone... you know it works, but you will never fully understand everything about it.