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.
A friend of mine sometimes jokes that code is “fractally busted” when it’s wrong at every level, from single lines all the way up to the design of the system’s main interfaces.
That’s also roughly what I find after a long English-only session with a coding agent. Our conversation covers a lot of ground... and leaves out details at every level. When I look at what got built, the misunderstandings are fractal too.
I agree it’s important to design it yourself, but UML is only one level. Lately I’ve been using a scratch Python file (or even a scratch repo) that Claude and I both edit. Never mind that I’m writing Rust. Python reads like pseudocode, and pass and ... (Ellipsis) let me skip whatever I don’t care about. At any level where I do care, I can say exactly what a method’s signature should look like, what fields a domain model should have, or how it should maintain key invariants. Everywhere else I leave an ellipsis, maybe a docstring, and let the agent decide.
It works both ways: I ask the agent to sketch the current system in Python, with some details elided and others spelled out. Then I edit the sketch and have the agent push the changes back into the much bigger Rust+Tauri app.
Time will tell whether this approach has legs, but when I want to be precise, I find it sometimes pays to just write some code.
This is the way. I can write pseudo code (ie Python) and I leave a breadcrumb trail of comments where I want it to implement. Hell the code doesn’t even need to have valid syntax if you forgot some function signature, but that small amount of guiding can produce significantly better results than a blind implementation from the model.
I’ve also tried spending an hour or two first before handing over control. That way there’s something pre-existing it can work from.
I don't have this experience at all. My workflow is:
* Bite sized jobs, about what you would expect for a traditional user story.
* 10-15 minutes discussing the implementation. It's almost the exact same conversation I would have with a human engineer. I'm almost entirely asking questions - "How would you do Xyz? What about this problem? What about that problem?"
* At the end of the conversation, both the AI and I have a good understanding of the problem and the solution.
* I say "do it".
* There are occasions when I don't fully understand what it wants to do. I'll tell it to do the work, then we discuss it afterwards. Sometimes we change things, sometimes I just need to see the code to understand.
* It doesn't commit code. I do.
This has been really effective for me, easily 10X'd or more my pace of development. Sometimes I have to ask for a lot of rework and sometimes it one-shots it. But I never ship something I don't understand and it always feels like "my" code. Very satisfying. More satisfying than typing it all out; the typing was never the fun part of programming.
I've found that current models will almost automatically sketch out some things in Python (or another suitable language for the type of task, or an implementation language you've already stipulated) while proposing a design, and you can go through a conversation of "what if we did xyz instead?" and at some point "okay, let's try writing a full prototype" (perhaps tacking on a bunch of decisions here so that things are resolved enough to work with).
But that's at the scale of <1kloc. Might be different if you're trying to do a bigger feature all at once.
I suspect that's a problem both with human read/written code, and LLM written code -- larger features should be chunked up into more manageable to understand and reason about functions, and assembled at higher levels.
Guiding the LLM (or humans structuring/guiding juniors) to shape the abstractions help make the overall feature and reliability of the code much better.
The best results for me have been when I write something 100% in a language and when it is done the AI takes my implementation and ports it to another language.
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 is maddening. I've been pulling 40/50/60 hour weeks for 21 years in the tech industry at various different companies. I haven't broken 200k base salary, though benefits are pretty great where I'm at. To think I could've memorized some leet code problems, got a job at FAANG and been making 300k base for the past 5+ years while working 10-hour weeks is - yep, maddening.
The best time to be aware of the socioeconomic class differences in tech was 20 years ago, the second best time is now. Also some folks just find it difficult to study leetcode problems purely to "prove" themselves, for various psychological reasons. If you can, it helps a lot, as does graduating from top universities with a direct pipeline into these companies. Social signalling is much more valuable nowadays than capabilities.
Sometimes the grass really is greener - company culture can be actually incredibly toxic and compensation very below market, but when surrounded by people who normalize it most folks will project that experience out to the rest.
Sour grapes is when you assume that a privilege another person has must actually be bad. In this case the temptation is to say you could have been successful in big tech but you are too moral. (Other people must be making moral compromises).
Sour grapes is when you can't have something, so you say it must be bad as a cope. I am successful in tech. It just took until my mid 30s to be a millionaire working on infrastructure instead of my late 20s working on surveillance, but I am perfectly happy with that. I have everything I could want, and didn't need to make those compromises. I say the thing is bad because it's bad.
I might be lucky (in a sense I am, but in another sense "all" I've done is work boring normal jobs and have low expenses), so maybe my path is not perfectly reproducible, but that's kind of the point of temptation: it has to be tempting. And quick, easy, sure money is the bait. You'll never even be held accountable. The only cost is looking around at the bad things in the world and knowing it wouldn't have been there without you.
Personally, the only reason I have to continue working these days is to give my kids a better future, so creating a hellscape for them to inherit would defeat the purpose.
Did you go to Stanford or a similar pedigreed college? Unless you did that or broke that 200k barrier already by getting high up in a lower tier company, just memorizing some leet code problems wasn’t going to get you into a FAANG.
They care a lot about prestige. Or at least did before AI. Don’t know what their current hiring practices look like.
I didn't go to college, I went the "self taught" route. I'm peeking at 200k base now, 21 years in as mentioned across a handful of industries. You may be right and it was not (and will never be) reachable, but it's still frustrating to think about.
Don't feel bad. It is not about skill in those job, it is about "cultural fit". You must project a personality that will fit in with FAANG culture or you won't get the job unless you're famous globally due to having starting some huge open source project.
Comfort yourself with the fact that you did not have to sell your soul, sit through endless woke sexual harassment videos where you are taught that the white man is the source of all evil, and in endless management meetings.
Why are you upset its this way elsewhere? Those kind of working conditions are much more favorable don't you think? Why would you want to work 60 hour weeks?
I think we passed the inflection point of the normal 150-500 Lear code problems, understand DSA and systems design really well. Personally, I think companies are much more selective now and have all reduced the size of their engineering orgs.
There’s always been a percentage of luck getting offers from big tech companies, but it’s way more luck than than merit it has ever been.
The majority of those who get in are able to socially signal, through affiliations with other high paying companies or paper from prestigious (read: socially exclusive) institutions.
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.
Good philosophy. Don’t write code to show your own cleverness. Write code for the poor bastard who will eventually have to debug it at 2am while that outage timer ticks on and everyone keeps asking how much longer.
The code isn’t for you. It’s for them.
Of course, there’s also a chance you’ll be them. :)
The incentive structures are all fucked up. It's far more profitable for all parties involved to just slop out some barely maintainable bullshit that only just meets the product manager's criteria for external quality while completely neglecting the internal quality of the software [0].
By the time the system starts to experience strain under the weight of its technical debt two years later, the original tech lead/architect of the project has already added it to his resume as another bullet point, found a new job at 20% higher comp, and no longer has to ever look at that code, ever again.
Now it's the next asshole's problem. Good luck!
[0] Freeman & Pryce 2009 for the "internal quality" vs. "external quality" dichotomy
I think part of the problem is the original product manager has also added this as a bullet point on their resume and gotten promoted. They get to watch the dumpster fire from a safe distance.
The 30+ hours were often just goofing off/video games/porn, very few are in 30 hours of meetings. The amount of grift, non-work, fake work, etc that remote well paid tech workers get to do is absurd.
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).
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.
Yes, but that's in psychology. Different fields have their own terms without causing too many issues. Communication breaks down when we reuse terms for different things within the same field.
They may not be related, but having a good understanding of the psychological NLP actually lends it self really well to NLP and prompt engineering. As much as a lot of people 'claim' it to be parapsychology (even within this thread), check out books like Strategies of Genius and how it breaks down a lot of the main concepts. It's very 'meta-cognition' if you will, but, the parallels are eye opening given how long the concepts have been around. If someone has never done serious mind mapping or brain storming and entity-node relationship type work with databases, it would be quite a leg up helping them understand and mentally map out concepts like that.
Same for "AI". LLM is about the only kind of AI we talk about now, so the two blended. Nothing dramatic I guess, but it bothers me when tech people, who are supposed to know the difference, confuse the two.
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).
Good luck! I took the plunge last year and am just finishing up med school pre-requisites. I'd say at least 6/30 of my O Chem II class are former software engineers.
Thank you! I'm still in a very exploratory phase about what exactly I mean by switching into healthcare. I don't have prereqs done at all, and my current plan is to enroll in a second bachelor's next year and start working through bio and chem courses. I'm looking at a bunch of different options from nursing to PA school to medical physics, and I think I really need to start shadowing people in different professions.
Med school interests me, but I'm a woman in my late 20s who would like to have children, and if I started down the med school road now I wouldn't be done with training until my late 30s, where PA and nursing school don't have that problem. Medical physics is kind of in the middle.
Oh interesting. I was looking at bio-informatics briefly but never even considered medical physics. It's crazy just how big healthcare is and how ignorant I was to it prior to making the transition. Would agree that shadowing has a huge impact on determining what you want to do in the future. My cousin went the PA route over med school and honestly I think it's the best from an ROI and free-time perspective. In her early 30's now and every other weekend she's in a different country.
Understand completely. I'm a little older than you but the high chance of giving up a family was the first thing on the negative column when I was deciding paths.
Awesome! I'm taking prerequisite classes (probably for Physician's Assistant school) while picking up a few shifts at the local EMS station. Good luck on your journey!
literally in the same boat, gonna see if i can't use ai to build some products to make money and help people, or else i'll go into healthcare and make (significantly less) money and help people.
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.
It's really bad now, yeah. :( It just really hurts that I spent well over a decade of my life learning and honing skills to engineer safe, quality software and now it's just, useless.
No one cares at best, or I'm callously told "keep up or fall behind" at worst. When that's not even the problem, it just, sucks now. There's no joy in anything I do professionally.
Can I ask where you went? I'm seriously looking for an exit, I just don't know what yet. Maybe a trade, in Scandinavia the pay is actually comparable, I just don't want to go back to school.
It just really hurts that I spent well over a decade of my life learning and honing skills to engineer safe, quality software and now it's just, useless.
It can feel that way with all the hype but I very much doubt that is really true. I see an industry that is rapidly dividing into two camps - "move fast and break things" and "this actually needs to work". Writing everything with agents and merging while barely even checking what is in the PR has become standard practice in the former but it will get you laughed out of the room in the latter.
I was fortunate and saved up enough to live frugally and just work on passion/learning projects for a while. I've been considering going back into commercial software development as a solo dev and leveraging AI, but keeping the focus on quality and craftsmanship. In my opinion there's never been a better time to start a new, ambitious project if you're passionate about quality software.
I agree, that's acutally what I'm doing right now: living frugally in a cheap country while building an ambitious high quality pruduct.
I never had a better time "professionally" (albeit no income yet!) so far in my whole life! Apparently it's truly like the best of times and the worst of times to be building software, if you have the luck and the luxury to be able to work only for yourself than it's really a great time to be alive.
Some people just can't turn off their brains and play drone for dozens of hours a week for decades. It feels existentially, aesthetically, and sometimes ethically crushing to spend a whole life doing work you can't expect yourself to respect or value, no matter how much you get paid or how little the work overtly demands of you.
Often, the lack of meaningfully challenging demands being put on you is punishing on its own. It can feel like a relief for a week or month or year, but if you catch a glimpse of that being your whole future, you can come to recognize yourself as being in a mind-eroding secular purgatory.
This anguish is especially common among on highly capable people, high achievers, and those used to some kind of ambition. And by accident of its history, there's a lot of those people in this industry and some of them are going nuts now.
Man, I have the same feeling.
A long time in your life you build the career and now it’s just feeling so empty, like you are not a engineer anymore, now everyone can use AI and without checking code they would have good results.
> now everyone can use AI and without checking code they would have good results
?!!?
No way. Are you sure? What kind of work? Here there’s still a lot of care needed to navigate the LLM work, like knowing when to make it quit, rewrite, refactor, follow your outline.
It feels magic but when I watch people who don’t know what they are doing trying to make something new (not almost a clone of an existing product), they get pretty frustrated.
I once lost out on 3 months severance and a laptop when I quit a place and they shuttered two and a half weeks later. There had been no direction from the top for over a month other than "ehh, do something useful". I was working remotely and slowly going crazy.
> This anguish is especially common among on highly capable people, high achievers, and those used to some kind of ambition. And by accident of its history, there's a lot of those people in this industry and some of them are going nuts now.
I went nuts for years, until I sold off my interest in my dream partnership.
10 years of heaven. All the benefits and none of the downsides of my internal colleagues. Then 14 years of bureaucracy aimed at predictability over progress, which was infinitely more difficult for me to dodge as an external player.
Compensation for my interest was very objectively valued, with the rate of stalled progress priced in. Which made complete sense, while also being its own madness.
I walked away from so much value, but I don't regret it for a minute.
This exact mentality is extremely toxic and is why the historical "anti-work" movements (i.e. Anarchists) have been kneecapped, often by their supposed best friends (i.e. Commies). The major disagreement circa the 2nd internationale was "is work good, but bad that you're exploited and not paid well?" (the Marxist view) vs "Work fucking sucks and we should abolish it" (The Anarchist view)
I can't believe how much mental justification needs to be made by otherwise highly intelligent people (Bertrand Russel wrote In Praise of Idleness) to defend the right to not work.
No, I fully reject any notion of life value coming from work, and those who hold your view are basically jailors to those who don't want our identity defined by work.
That's not how the world works, and I don't need this in a thread where I'm dealing with the grief of a good career. Please shove off.
I would gladly not work and learn cello and physics independently if that were a real possibility, but it's not, and it won't be within my lifetime.
I had a job in a system that required jobs to survive that genuinely didn't bother me. I actually quite enjoyed it most of the time. Now it's permanently dead and I need something else, or I am homeless and starve to death.
> No, I fully reject any notion of life value coming from work, and those who hold your view are basically jailors to those who don't want our identity defined by work.
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.
I’m not sure how to say this without sounding smug, but the last year has shown that most of those things just… don’t matter. It’s just the next level of the “variable naming PR comment battle”, so will become obsolete very soon.
Obviously there are mission critical systems where it matters, but if “your code can be A/B tested” or “slowly rolled out”, chances are, it doesn’t matter.
You'll find that design matters when token spend starts facing real accounting.
Tech debt is still tech debt, even if there exist models that can wade through, because it's going to require increasingly sophisticated models navigating increasingly large context windows and increasingly speculative workspace operations to keep making progress on it.
Vendors like Anthropic and OpenAI are laying a pit trap when they demonstrate how their models can independently code their whole platform as it becomes increasingly byzantine and inscrutable because not only do they benefit from internal/prerelease models but they have effectively unlimited spend because all that spending acts as a lure to draw you into their trap.
For everybody else, design still matters. People are just working really hard to make you forget.
Personally I think I could probably be content for the rest of my days running something like Z.ai glm-5.3-flash locally, so I'm not that worried about the token spending (and still can't understand how OAI/Anthropic/etc convinced the market they have any kind of moat to motivate those kind of evaluations, but that's another topic...)
That said, I also feel like betting on readability, maintainablility, taste, etc, being an important aspect of software, at least until code will remain some sort of human readable artifact. We'll still want to be able to understand it and perhaps occasionally add/edit by hand, make sense of it without trusting blindly what any kind of program (LLM based or not) will tell us about it, and so on.
The problem here is not the vendors.
The "problem" is that design mattered when producing code was a truly manual effort. Writing things down, aligning specs, design, contracts, all of that would mold what could come next.
Now ANY design from amazing to terrible can be regenerated and generated dozens of times over for literal single digit dollars.
Cost of tokens is NOT a problem unless you have a codebase with hundreds of person-years of effort. Not many people do.
I don't think this is true. Good implementation is secret sauce, and not re-producible for external observation alone. I'm even aware of software techniques which only exist within companies, despite much public effort to recreate them.
It may encourage more secrecy and backend style designs though.
Honestly, I keep hearing this argument, but the past 2 years have shown the opposite. OAI/Ant are not the only companies providing inference.
There are legitimate FAANG-like companies that have general guidelines about “when to use Fable/GLM/DS” and etc. to keep the costs down. And I think it’ll continue that way.
You didn't address the argument about tech debt. How do you get the greatest quantity of maintainable, high quality code within a given token budget? The answer, at least so far, seems to be human experts in the loop. We've also been hearing for years that LLMs are going to automate away software development entirely, but software job postings are steadily rising.
>How do you get the greatest quantity of maintainable, high quality code within a given token budget?
Doesn't matter as much. The cost of "maintenance" is going down, from what I can see internally, from other companies, and every story i'm reading from other organizations as well. Token budgets are changing, but model quality and effectiveness are going up as well.
> We've also been hearing for years that LLMs are going to automate away software development entirely, but software job postings are steadily rising.
I think this has been contested from day 1. SE jobs might be automated, but jobs might increase, if there's possibility of starting new companies / new investments / etc.
I'm still not clear on what you're really saying. If a human programmer's input doesn't matter at all, then anyone should be able to prompt a model until it spits out the software they want. That might work today for building fun tech demos, but I don't see it happening on projects that have a minimum bar for security/reliability and long-term maintenance. Would you say, for example, a team of 10 managers with no software experience can be as successful as a team of 10 expert programmers at building a large project like an operating system, with both teams having access to the same AI models and budget?
No, because expert programmers will not know what they’re building, and skew the prompts and ask for the right things.
The analogy would be math people with AI vs. non-math people with AI trying to solve some problems. I cannot solve the problems because I have no idea how to prompt it to go specific way. But it doesn’t matter how dirty your scratchpad was, because you got to the solution.
> I don't see it happening on projects that have a minimum bar for security/reliability and long-term maintenance
I don’t get this, because this is currently, right now, at this second, happening across huge projects. My point was that maintainability is less of an issue than before. Also, frankly, over years, I’ve seen bad code that AI wouldn’t even write. So there can be a case that the maintainability/code quality isn’t even going down as the models get better.
API design matters if anyone outside your app consumes it. Duplicate code makes changes hard and most compilers can't optimize it away. Bad file structure wastes tokens and makes off target edits more common.
These things are important even in a repo with zero human code. A project that's filled with tech debt will always be hard to work with no matter what latest frontier model you're using.
I think a lot of this can be automated with slop detectors that flag messy unreadable code and make agents rewrite it, but you can't say it doesn't matter.
I can see three likely explanations for how my personal experience with modern AI programming tools differs so much from a lot of the advocacy I see online.
1. We are working on different types of application and code.
2. I am in a bubble and no-one in it has experienced the standards and productivity that SOTA AI tools can achieve.
3. The advocates are in a bubble and no-one in it has experienced the standards and productivity that expert developers can achieve.
I hope the answer is 1. I fear the answer is 2. I suspect the answer is 3.
Well I work on writing Jax and PyTorch machine learning experiments in Python, so I doubt that I'm working on entirely different types of code from what LLMs get trained on.
You can work the way you want to work. In my experience, letting the agent make every decision leads to a big ball of mud that requires touching dozens of files to make a change. More context is needed, it burns through tokens much faster, and the agent takes shortcuts and builds technical debt. So the way I prefer to work is to have changes targeted to a single file or small set of files where I've defined the API. Maybe that will change in the future, I'm not set in stone here.
> In my experience, letting the agent make every decision leads to a big ball of mud that requires touching dozens of files to make a change
It seems too early to make any conclusion like that. We've still only been doing agentic coding for a year and capability significantly improved during that time. I don't think anybody on either side of this debate can have actual empirical evidence to support conclusions about where it lands longer term.
The main argument I see is that it probably pays to be slightly conservative because the cost of being wrong by maintaining too much oversight and shipping slightly less code is better than the cost of ending up with an entirely unmaintainable system. In some cases it will be more than "slightly less" but in almost all complex pre-existing systems, you are rate limited by a lot of other factors outside of code production, so the effective difference just isn't that high.
At agentic coding velocity, tech debt becomes obvious much more quickly. Empirical evidence is a bit of a ridiculous bar to hold for software development - we are as quantitatively blind now as we have ever been - but at least for me the anecdotal evidence is very clear. Today's agents hill-climb and their software architecture is pretty reliably bad without a human in the loop.
And it's debatable how much better they will get quickly. Verifiable rewards for maintainability of software is, I think, possible but very hard.
When I said "in my experience" I meant literally that, my experience so far. I'm not making any predictions. I'm definitely anticipating things improving at a rapid pace, which is why I think it's good to run frequent experiments. If in a month I find that an agent can one-shot a 20k line project without creating an unreadable, unmaintainable mess, that will be great.
I share that experience. To the point that I don't think I'd want to work (at least for as long as I have the luxury of having a choice) on a project where an AI has been let loose.
I also see devs, seniors as well, that have a different experience. At least that's what they say. I stay open to the possibility that I'm doing or seeing it 'wrong', but I'm far from convinced. I do like to experiment like you wrote in a later comment, things may change, and even now I do find it can be very powerful, for the right tasks.
That's why I don't rely on their design. But I also don't write the design from scratch. I use a conversation with the model to build a plan. I let it do the things it thinks is right, and I add corrections where I want to see something different. Or more accurately I "ask questions" which lead the model to making those changes itself. I don't say "use this design pattern here instead" but "Why didn't you choose to use this design pattern instead? What are the tradeoffs that you see?" When I notice a pattern in how the model deviates in how I prefer things, I add additional instructions to the prompt to try to close the gap over time and I get better first shot responses.
A friend of mine is getting into AI more than I am and seems to like doing random coding tasks to see what it can do. Like, coding a clock app in Window with NTP/PTP. Or coding a multi swarm agent that is so poorly designed it hurts my soul. I want to say the clock app came in at 300 Mb and god knows how much memory usage it was pulling. LLMs have all these different pieces but it still doesn't know the optimization that an engineer might know with experience. Because of the amount of slop being generated, we're essentially line workers that deal with automation being implemented in factories. Very much the the technology version of the 'American Factory' documentary on Netflix. Unless we're at the forefront of this SOTA hotness, we're behind in all aspects.
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.
Its really sad that you think that an intelligence that cannot learn is better than you at everything.
The advantage I have is that I know things that are not in the training distribution. Things about our business, our product, and its internal architecture. Without this knowledge, some new features cannot be designed successfully.
Some day I expect that will change, but all the patchwork "memory" systems, all the docs etc, will never get there because at some point they just pollute context. Knowledge has to be integrated, and that is what happens during sleep for humans, during pre-training and RL for models. LLMs are terribly inefficient at learning though and degrade generally during fine-tuning.
I'm not disagreeing with you - I give agents a lot of input and spend a lot of time iterating with them before I'm happy with the result. My point was only that I don't think that I'm somehow superior in design patterns or any other general part of coding just because I happen to be human or because I have years of experience.
No one at all claimed that, certainly not the person you responded to. They're talking about how to use these tools in a way that gives you insight into what they produce. So, as an engineer, you know the shape of the output, before it's made.
Why is that so hard to believe? I don't always do this, but I do course-correct Claude on almost every big change. YOLOing it would superficially look fine, until the latent issues catch up with you.
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.
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.
That certainly can be true but I would challenge "generally". If you're working on something novel then it's not exactly unusual for even SOTA models to produce a first attempt that makes some very bad assumptions but then get stuck when instructed to use correct axioms instead. This looks a lot like the suduko meme - without any real insight into the problem the models end up just iterating around in circles and never finding a solution.
You probably won't see this very often if you're working on simple CRUD web applications where there are millions if not billions of lines of code in the training data set. IME you will probably see it quite frequently if you're working on - for example - software to control some kind of equipment or analyse the results of some kind of experiment where the LLM might have little if any training data about the field you're operating in.
Any time the LLM can establish a tight feedback loop it can iterate effectively enough to make good progress. But if for one reason or another that feedback loop is long, the more guidance and direction they seem to need. If they cannot correct their course based on feedback from their own output they need an outside observer to push them towards different paths. CRUD stuff is the obvious easy answer. It represents some absurd amount of software development work and is drastically overrepresented in training data. For good and bad. Lately I've been working on a diffusion model for terrain generation. The goal is to be able to recreate realistic terrain based on water flow and erosion on top of plate tectonics for much longer geological time terrain adjustments. These are much longer feedback loops. Sometimes it'll spend 6+ hours training a diffusion model on my 5090 just for the quality to degrade compared to the last experiment. So letting the model go wild trying different approaches and evaluating the results doesn't work nearly as well as when it can iterate 1000 times in those 6 hours while checking its own answers.
Any time the LLM can establish a tight feedback loop it can iterate effectively enough to make good progress.
Not any time. Your feedback loop must provide some direction so the iteration is at least heading towards an improvement. For novel applications you might not have a convenient way to do that yet.
Even with that provision there's still a possibility of incrementally updating output converging on a local maximum. That local maximum might not be a solution at all. If it is a solution then the model might still miss much better solutions that a real developer with more insight might find.
As you said yourself the models need external feedback if they don't have sufficient information to make adjustments by themselves. In some cases that feedback might be "Start again because you're hopelessly off track". Sometimes even when they start again they just get hopelessly off-track again. That can happen even if they are explicitly prompted to do something else. So even closely supervising the LLM and not using self-iterating agents isn't guaranteed to get good results for novel applications.
Maybe I'm overly pedantic, but in my mind a feedback loop involves both feedback and a loop. So by my reckoning the "feedback loop" must, by definition, guide the direction of the next step. I hold this true of feedback loops with zero LLM tooling involved. It's the same thing. The "entity" determining whether to continue the loop or not must have a good enough definition of success or improvement. Of course there is a lot of variability in how effectively the feedback is delivered. That's one of the variables the human setting up the loop is responsible for establishing in our brave new world.
You're right though that in new territory you may often have domain experts who still cannot adequately define success in an automated fashion because this is literally something that hasn't been created before. So they must be a part of the loop. They cannot necessarily put into code and descriptions what "better" or "right" is for an LLM to follow. But they can recognize it when they see it. In this case, it's still best to create the tightest feedback loop you can. If the LLM is waiting 2 days for your feedback, the loop is 2 days long.
I would say that a system with some sort of binary evaluation that indicates whether it succeeded or not is receiving feedback. It could also be some kind of sliding scale - how close did it get?
Either of those might be useful for determining a good future direction to iterate in but that would surely depend on the nature of the problem and how it's possible to search for solutions. I'd still call it a feedback loop even if the evaluation wasn't enough to point in a specific direction for a further iteration though. YMMV.
That's a great perspective. Come to think of it, I wonder about the quality of the build123d code it generated when I vibe-coded a prototype complex assembly. Now I'm curious.
I don't think the distinction between statistical correlation and understanding is as clear-cut as you're suggesting.
For example, Li et al. (2023), Emergent World Representations, showed that a GPT model trained only to predict Othello moves developed an internal representation of the board state, without being explicitly taught the rules or board structure.
I don't do this at all. I just YOLO merge after reading the change description. Senior dev, paid well at a FAANG.
I don't really care about the code being unmaintainable. Fable 6 or whatever will take care of it, just like Opus 5.5 takes care of our Opus 4.6 slop. The code working and our feature shipping is way way more important.
It seems unrealistic protect our jobs by keeping it a secret if LLMs really can do them (still a big if). Maybe if we as an industry had formed unions but it seems a bit late for that.
My job evolved long ago, I'd certainly be worthless at my job if I insisted on keeping the shape of a typical SWE. Automating YOLO merges - we're working on that, I can't wait.
I would say I am now responsible for more big-picture decisions than I was previously, with Claude taking on the role of SWE (or a team of them). Despite this, there is still way more work than people.
> I don't really care about the code being unmaintainable. Fable 6 or whatever will take care of it
> The code working and our feature shipping is way way more important.
I like that we both use AI very differently (you YOLO, I don't) but can agree that these are basically the important questions. If a company or team answers them like you do, I agree with the conclusion (YOLO). To me that's still a decision to be made though, and to be made wisely. Whether to accept the code may become unmaintainable, to forwardly rely on Fable 6 and to ship above anything (or at least a lot) else.
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.
Unironically this is where I converged. Shipping the feature is the most important thing, Opus 5.5 is good enough with correctness that I merge off the title or description alone.
A year from now Fable 6 will de-slopify, so I don't really care about having pretty abstractions. That's simply not my job anymore. Sacrilege, I know.
This is the way I feel about it too. I admire designing systems and abstractions upfront, but until I have a clear way to do that, I'm happy with whatever the agent produces. I still decide on architecture, pipelines, and algorithms, and let the agent fill in interfaces, methods, and packages. Are any of them good? Certainly not. But they work. And until that needs to change I'm not too concerned, except with my job title which seems to have lost a lot of its meaning.
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
A chilling early experience with AIs that seriously affected my thinking on AIs:
I was working on a ground-up implementation of a SPICE circuit simulator that would generate code to do realtime simulation of electrical circuits. Much of the work was derived from complex mathematics in a couple of papers that I was using as a guide, and from The Spice Manual (3rd edition) which serves as a guide/standard to the Spice language, including detailed mathematical formulae, expressed in standard mathematical notion (but no code) for most of the simulation operations.
When transcribing formulae into code by hand, I had gotten in the habit of providing references to page numbers and equation numbers in comments in the code, and "footnote" comments that provided URLs to the original material.
Imagine my surprise when Claude also provided correct comment references to pages and equation numbers when I asked it to write code to implement diode models.
As someone who's written those numbers by hand enough times pre-AI to still recite them in my sleep, they are indeed right. Didn't expect to see a D2Q9 LBM simulation on HN today, thanks for making me smile.
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.
Worth mentioning: Sometimes we choose initial abstractions that don't survive well and need to be adjusted as the project evolves. Claude is extremely good at performing large rewrites that are needed if you need to adjust an abstraction on the fly.
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.
SREs _can_ support a service without knowing the details, but knowing the details massively reduces MTTR.
Knowing the codebase is often the difference between proactive resolution ("This keeps happening when that log message keeps appearing; here is the PR that fixes this bug; here is the runbook on what to do if something like this class of problem appears") and reactive resolution (increasing quota, which costs money and might not always be possible; rolling back, which might introduce security concerns; etc.)
This is probably the biggest reason why SREs at big tech companies are usually also SWEs or SWE-adjacent.
Yes, agents, but given that AI-generated codebases grow and change too quickly for humans to keep up, the issue becomes over-reliance on agents over time, a Russian Roulette style of problem when the cost to access to these models keeps increasing...
> 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.
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
I haven’t seen the risk-driven approach explicitly mentioned here. I think it applies not only to code review, but especially to design.
It reminds me of George Fairbanks’ Just Enough Software Architecture. He tells a story about his father, a civil engineer, who didn’t apply every engineering technique he knew when installing a mailbox. He just dug a hole, put in a post, and filled it with concrete.
The idea is simple: the effort you spend on architecture should be proportional to the risks involved. Sometimes you need careful analysis, sometimes you don’t.
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've tried this but the problem is your design inevitably has gaps in it. When doing it yourself you would run into those gaps and be forced to revise your design as you go. You might even be forced to go right back to the drawing board. But AI agents will never, ever do that. You tell it to implement a given set of abstractions and they just will, no matter how ridiculous the implementation becomes. There's no part of an LLM that says "hold on, this doesn't feel right". How could it even when you're feeding it piecemeal tasks and not revealing the whole architecture? It's like asking for a first floor bathroom with the plumbing in a specific place that makes no sense given the rest of the building. It will do it, every time, because it will build the plumbing under the floor that you didn't ask for.
Although I was personally fairly invested in UML, OO, etc., in the 2010s, it is undeniably true that classes, inheritance and all that is incredibly out of fashion today - people just found it didn't really help. It's interesting that this is now the solution to AI coding.
> 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
I try to do this as well. It certainly feels better and makes me more confident that the code will make sense when it implements it. But I’ve found even with a very firm design an LLM will undermine it in the details. It will be convinced there is a particular way to do something, I will tell it not to do that and give it a complete alternative, and it will say it implemented it as written. And if you just look at the data structures and function signatures things look fine. But you look at the actual implementation details and it will try in some awkward way to implement things totally differently.
You don't always design bigger systems from scratch as greenfield applications, most of the time you are delivering smaller features in incremental ways or fixing bugs. Even for greenfield projects, you can plan with the LLM and come up with a design you like at the high level but that still does not spare you from knowing (or not) how lower levels work, which is OP's original complaint.
In essence you basically say that you don't read or review the code produced in detail, you just know the high level design of how the system works.
This is the only way to work with AI and ensure your code is still (somewhat) maintainable in a year+.
Anyone who's ever directed AI at a very large legacy code base will have noticed that AI just gets dumber and slower the worse (larger + inconsistent) the code base gets (just like us humans do).
The big difference is that with AI you can get to the point where the code base is an unmaintainable legacy mess in a fraction of the time that it used to take.
Directing architecture is the only way to mitigate this to some extent.
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.
After over a decade of software engineering I've rarely if ever found a bug that needs to patches ASAP over an incident due to a poor abstraction. The bugs are usually the actual code inside the abstraction which you are most definitely handing over to LLMs and losing context over.
Unfortunately llms are very good at creative hacks that undermine the whole design. I've caught it on the act multiple times. But I'm sure my code base by now is understandable at the surface level, but underneath I don't really know how it's doing it. Even if I have a reasonable understanding of what. If you're a manager and don't understand how, you can rely on your engineers to know it. When you're an engineer and you don't know how. It means no one knows.
In practical terms it probably doesn't matter. But it's still an unsettling feeling.
Serious question: how is a consumer of software can I tell that it was written with bad abstractions? Is there a signal that software is well written and maintainable other than very high cost?
I’m willing to believe that software you authored or designed yourself is better than whatever Claude spits out. I’m not as confident that the cost benefit ratio pencils out anymore. In fact, I would say most software does not need to be particularly good or well thought out. The vast majority of things I need software to do for me day-to-day at work are so niche and specialized that I tend to prefer AI slop that I can get now for a few tens of dollars at a time and something expertly crafted by a true artisan for thousands of times higher cost.
99% of software out there is a huge ball of mud even if the senior/architect/<insert egotistical title here> started out by building it with the sexiest abstractions. Things just tend to rot and complexify. Software engineers never figured out a way to prevent that, though it is easy to be fooled by the preening and pontificating we do to make ourselves seem like the "very serious professional engineer who cares about code quality very much". I'd keep using AI if it's working for you.
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.
I agree your way is the only way, and is similar for me as well.
I have very particular ideas about how everything must work. Very particular ideas about which should be the tech stack. Meaning I don't have anything that uses nodejs or Rust.
The algorithms used, the abstractions that matter to me. Almost everything is different to what the AI would do if left to its own devices.
And many times I try to patch the code myself, and succeed, before giving up to the AI.
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?
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.
I do the same but I find that sometimes there are little bugs everywhere just because idk, the implementation left a query outside a transaction and made two instead of one, a very minor thing. Or a sequence of events is out of order and it matters. And you don’t see that while abstracted away.
100% agree. I spend hours working on specs, project requirements -> tech spec -> testing -> validation -> roadmap. Making sure to capture intent and constraints. And then i let an llm orchestration have at it. I agree with others in this thread, that I don't understand how others don't do this and feel comfortable pushing to prod. I'd feel even more embarrassed if I vibed something to prod and it broke. That being said, I honestly feel like I'm doing way more "software engineering" now than ever in regards to really understanding every aspect and intention of the features I'm implementing. And even then I still miss things, but it's not catastrophic and re-aligning later is much easier.
But yes I agree, I don't let the llm "design" or even "ideate" with it. I have it run validation on my own assumptions and see if those hold up, but even when they don't I am the one to construct the solution.
If you insisted on taking the time to do this in the OP’s role at Meta, I’m guessing that you’d be disciplined or fired for taking too long to produce work. You’d also be dropped into work of colleagues who didn’t produce UML before shipping their code.
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.
Spending time upfront designing is sound advice for any software engineer. LLMs can also save time here as well, if you're disciplined enough to not proceed until the design is polished.
I'm curious: With your approach, how do you make sure your code is secure? For example, how do you show that it isn't riddled with XSS or other injection vulnerabilities?
You've just decided that your level of abstraction is better than someone elses but where's the evidence it's actually better? This has been the main tension between programming philosophies forever.
Just because something makes you comfortable doesn't mean it's actually good.
100% agreed. Although its less about writing it and more about holding it in your mind. Think what you may of vibe coding it's very hard to justify rolling every line by hand when modern LLMs can produce pretty reasonable code at scale.
Coding is however just one small aspect of bringing software into being. We generally start with an intuition. That intuition comes from context.
That context, hard won as it is, for software engineers at least, was mostly a side effect.
You had to buffer a significant portion of the system in your mind to be able to manipulate it. LLMs remove that constraint. Now you can just prompt from the upstream intuition and its passable a good portion of the time.
Notice the catch? If you don't get to the beat of the system your interaction with it will be jarring, for yourself, for the person using the software and for the agent building it.
So I made a tool to help get the context into my head faster. No its not an app (it could be but meh) Its a skill that helps the LLM make a voice narrated walkthrough of the complexity so you retain context
Check a demo here if you want https://theronburger.github.io/review-story/
I used to take a lot of pride in my engineering but I honestly think the LLM is a better designer than I am.
It still needs a lot of back and forth before I'm comfortable it's not doing slop architecture, but once it's on thesame page as me it genuinely is better at it than me.
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.
> It can produce a working machine that does the job
Until it doesn’t, and then you’re too stupid to understand why not. Was it that your prompt wasn’t good enough? Does the model not have enough context? Is it even possible for your request to be satisfied?
> What does human stupidity have to do with this?
You answered this yourself:
> but you won't be able to understand it.
And:
> I'm saying ask the AI something beyond your intellectual capabilities. Or ask it something beyond your intrinsic knowledge base.
What’s the limit to this? “Claude build me a nuclear fusion reactor.” Surely we can agree that there’s a limit or we’d already be living in some post-scarcity utopia. So what’s the limit?
I’m suggesting a limit: human stupidity is limitless while compute is finite. We can use the word “ignorance” if the word “stupid” is too inflammatory.
> Until it doesn’t, and then you’re too stupid to understand why not. Was it that your prompt wasn’t good enough? Does the model not have enough context? Is it even possible for your request to be satisfied?
You’re unable to comprehend the topic of the conversation.
We’re talking about querying the model with prompts and asking for solutions beyond your intelligence. You’re talking about flawed prompts.
> You answered this yourself
You’re rude af. Not understanding something is not intrinsically bad.
In fact you use things you don’t understand on a daily fucking basis. Your iPhone, your car, your computer. All of these things have aspects of it beyond your intellectual capability to fully grasp or comprehend and yet you use it. Sometimes these people who make these things produce faulty products and you ask for a refund and are more careful in the future about what you trust, sometimes the product is exemplary.
Relying on an LLM to do something for you is much of the same.
Get it? Probably not. What are you going to do? Call me stupid again because you have nothing substantial to say? lol.
Edit: you edited your response which is uncharitable. But whatever I’ll respond to your new statements below.
> What’s the limit to this? “Claude build me a nuclear fusion reactor.” Surely we can agree that there’s a limit or we’d already be living in some post-scarcity utopia. So what’s the limit?
I agree. But this is not the topic of conversation. I’m talking about querying LLM to do something beyond your ability. This is something you can do and also stay well within the obvious limit you’re implying here.
> I’m suggesting a limit: human stupidity is limitless while compute is finite. We can use the word “ignorance” if the word “stupid” is too inflammatory.
You don’t need to suggest a limit. It’s obvious ai can’t build a nuclear reactor. Nobody needs to be told this.
A clever quote doesn’t prove shit. Ok so human stupidity is limitless. Computer is also finite. I agree.
How the fuck does the above two facts which I agree with have anything to do with me asking the LLM to make something I have no knowledge about? “Hey LLM write an emulator for this Zelda n64 game.”
The prompt is well within the “limit” of what an LLM can do. Compute is still limited. And human stupidity is still boundless. Nothing has changed. Why? Because someone is ignorant and unaware they are prancing off topic onto orthogonal concepts.
I’m using the word “you” in the generic, impersonal way, like the word “man” in German.
But in your argument we are all essentially idiots compared to AI, and should essentially embrace that, dunno why you take offense to it. I essentially agree. Where I disagree is how far we can make it without human intelligence in the loop because of finite compute power.
Nobody is talking about how far we'll go or what the end game will be. That is NOT the topic of the conversation!
I'm saying right now in your personal workflow you are giving up many useful features of AI when you only allow it to implement your design as opposed to letting it design for you.
There is an in between here that developers seem to keep forgetting: Design the software architecture yourself — do some whiteboarding, figure out your abstractions and your UML, then write that in your prompt for the LLM to implement through a plan.
Velocity stays high. Cognitive overhead remains low. You know enough of your architecture from the “unit” level to see how the pieces work meaning you can still work fast and understand it without hating the quality it produces. This has worked wonders for my company; I’ve managed to personally write tools that are barely distinguishable from what I’d write by hand, and I’m confident enough to discuss its architecture from top to bottom. If the LLM ever produces a unit with a poor implementation, I just rewrite that unit.
Basically: do the “engineering” part of software engineering instead of throwing LLMs at the wall until code sticks. It doesn’t take much time to come up with a good design, compared to repeatedly iterating on a bad design and maintaining it for years to come.
LLMs suck at design, and that’s why they lead to this bad code. But if a human spends an hour to build nice SOLID abstractions, and tell the LLM each responsibility — they are pretty good at using and wiring these parts together.
It’s weird how much the author fixates on Vim being “visible” and implies multiple cursors and features in Sublime aren’t. Just because your brain is trained to not think about it anymore doesn’t make it any less visible.
Multiple cursors aren’t a native feature in many tools, it is still something to learn how to use, let alone effectively — just as Vim key bindings are. Plus, vim is more than just a TUI choice for terminal-only users, it’s key bindings for people that have learned that a keyboard is a natural extension of themselves and would rather not jump back and forth to mice repeatedly — just as “multiple cursors” can be to a sublime user of 15 years.
That's not what I was saying. I used vim macros specifically as an example, not Vim as a whole.
> I’ve had people tell me how “fun” it was to build a macro to handle some one-off text-refactoring problem. But when I looked at what they were doing and how long it took, my honest reaction was: I could have done that in Sublime in a minute with multiple cursors, or just written a quick script.
and
> What baffles me is that so many people treat that friction—the effort of working around a tool’s limitations—as the “fun” part, and then advertise it as evidence that the tool is great.
If you can affectively use vim macros, then GREAT! But if you cannot, even with using vim for decades, then please don't advertise them as the "fun" part.
The things about multiple cursors is that you think about the processing while doing it, while most people using macros looks at the structure of the text first and then devise the macro. I wouldn’t say the latter is faster, but it’s a different mindset.
And the other thing is that vim has the “dot” command to repeat your last edit. Similar to macros, you think about your local edit first, then about where to repeat it (usually tied to the next item in the search list).
Edit (after reading the article).
Both vim and emacs (which have the steep learning curve) are aimed at power users. It’s best to compare them to professional tools like CAD, DAW, industrial appliances,… The friction when learning is because a lot of users don’t know what’s possible to do or even have the kind of problems that experienced users do (or they fail to perceive them as issues). After a while, it becomes like an extension of your thinking and the tool disappears.
Exactly. And I'm no purist - I'm happy to use "dot" with a mouse if I want to easily repeat an edit in tens of places if they're not nicely aligned or searchable.
One of the things about Emacs and Vim is that you have commands that does things. They all have the same conceptual model. In vim, you have the text objects, the motions, and the counts (and more advanced ones like line and pattern addressing). In emacs, you have the point, the mark, and the arguments (including the universal one) (the advanced ones are which modes are currently active). That’s mostly the internal state that matters when you think about an edit which changes A to B.
You think about the evolution of the internal state and the suitable commands just appears, just like you think of an idea and the suitable words appears. Learning commands is like expanding your vocabulary, not learning how to speak. Learning how to speak is internalizing the aforementioned conceptual model.
> The things about multiple cursors is that you think about the processing while doing it
That visual feedback is EXTREMELY useful because I learn of the edge cases to what I am editing in bulk (usually formatting code or tables or whatever) as I am editing it. When you do a macro, you have to try and get it right, and then try again from the start each time to get it right. `dot` et al are not enough in that regard. So the multiple cursors approach is better not because it's a different mindset, but it produces a different feedback loop to correct mistakes.
If you still prefer the macro approach over the multiple cursors approach, then you do you. But as an example in the article, I have seen people think they are being productive by their own standards, and they really aren't.
You're over-fixating on the misuse of macros and generalize that to make a statement about Vim [1], almost as if that's the only useful feature in Vim. There are more basic editing commands that are much simpler, quicker, and powerful. It's what is actually used most of the time.
Also, getting bulk editing perfect, including the edge cases, is inefficient regardless of the tools you use. For the majority of those cases, I would just combine simple search and replace (cgn), dot repeat (.), and undo plus skip (un) for the edge cases. Then jump back (N) to the edge cases and make manual edits. It's quick, provides instant visual feedback, and requires less cognitive work than trying to process it all at once. And that's the approach people likely have in mind when they mention dot repeat.
> That visual feedback is EXTREMELY useful because I learn of the edge cases to what I am editing in bulk (usually formatting code or tables or whatever) as I am editing it
I do not disagree with that
> When you do a macro, you have to try and get it right, and then try again from the start each time to get it right.
But you are wrong in that, because you assume that visual feedbacks are necessary. They are useful. Using vim and the likes is very much like playing the piano or driving a car. You’re always one step ahead of your actions because translating intent into operations is effortless as they are ingrained in muscle memories. I don’t even look at the cursor much of the time because it will be where I need it. I don’t care for mistakes because they are easily corrected.
Even then, I rarely use macros because they are at the high end of the power spectrum. Only writing your own commands is higher on the list. Easy macros are easy to create, powerful macros are created only when necessary and are worth the carefulness. I don’t think there’s something similar to named registers and emacs counters with multiple cursors solutions. Or the ability to have multiple macros ready to go at anytime (very useful for data cleanup).
> I’ve had people tell me how “fun” it was to build a macro to handle some one-off text-refactoring problem.
I can't relate, either as a Vim user myself or having heard other users.
To the extent that it happens, it's surely because the macro can be seen as a sort of programming. Vim offers you two esoteric programming languages, if you want to see them that way: vimscript obviously, and the simple concatenation of Vim commands. But any system consisting of a text editor plus a way to record and play back its commands gives you the latter. Vim isn't doing anything special to create that second esolang; it's just bundling the playback mechanism.
But that rather is the point: creating the macro is as much "scripting" as actually using vimscript is. Not only is it recorded in an at-register, but it can be stored as plain text in a vimrc file. It should be compared to "written a quick script" and not to "used multiple cursors"; and any sensible Vim user would have a different approach (commonly powered by :%s/foo/bar/g , perhaps with backreferences) to the cases where Sublime's multiple cursors shine. (Yes, you can use visual-block across multiple lines if everything lines up; and yes, it's inferior to a real multiple-cursor system; and no, I don't think I've ever personally had a use case for it.)
There are people who reach a level of proficiency where they enjoy the challenge of an intentionally difficult to use programming language. Vim macros are accidentally a programming language, and definitely not intentionally difficult. And using them to "handle some one-off text-refactoring problem" is entirely missing the point, and a sign that one has more room to grow in proficiency and a lot more room in wisdom.
In short, the people you've heard this from should not at all be taken as representative of Vim users.
What I find especially weird is that I'm not sure I've ever heard anyone describe vim as a puzzle that's fun to solve. The most common sentiment is that it has a learning curve, but ends up being worth it.
My intro to vim was a guy using some kind of web browser in vim, or maybe it was a browser with vim controls, and I was like wtf. But I did end up using vim for just code/text editing without any fancy macros, it was worth.
I don't think of vim as a puzzle, but I do use it because I find it fun to use in some ineffable way. Note that I also don't claim that it makes me more productive; I use it because it sparks joy, regardless of however productive it makes me.
> multiple cursors really are better than macros 99.999% of the time (since they give direct visual feedback)
I don't know what he means, vim macros also give direct visual feedback while writing them. You just edit as normal while recording, and replay those edits later. I think it is technically possible to write a macro without seeing the live effect on the text as you write it, but I've never done that.
I looked up multiple cursors out of interest, I guess the advantage is that it's one interface that is easy to explain. I would use multiple vim commands to replace it in practice.
I'll agree that multiple cursors are maybe better than macros for most of the things that someone would use multiple cursors for, but usually I wouldn't use macro's.
But I think most of the things I do with macro's cannot be done with multiple cursors.
I would be very interested in being proven wrong, if someone has some examples of "this is where multiple cursors are great, and vim doesn't have a good alternative".
> You just edit as normal while recording, and replay those edits later.
And there is the problem. The first time you do the edit, it might be fine, but when you make a mistake in the edit, you then have to go back and correct all of the cases. With multiple cursors, I am seeing instant visual feedback on all instances of the cursor at once. I am getting literally 2D spatial information, compared to the 1D spatial information per each replay. The multiple cursors approach is better not because it's a different mindset or whatever, but rather it produces a different feedback loop to correct mistakes.
If you still prefer the macro approach over the multiple cursors approach, then you do you. But as an example in the article, I have seen people think they are being productive by their own standards, and they really aren't.
Agreed. I used to enjoy vim macros, but ever since switching to Helix I reach for its multiple cursors all the time and barely use its macros. But that doesn’t mean multiple cursors don’t have a learning curve, I still need to think of he method to place the cursors in the right places.
Aside from what some other users have said, logging is fundamentally an observable side-effect of your library. It’s now a behavior that can become load-bearing — and putting it in library code forces this exposed behavior on the consumer.
As a developer, this gets frustrating. I want to present a clean and coherent output to my callers, and poorly-authored libraries ruin that — especially if they offer no mechanism to disable it.
It’s also just _sloppy_ in many cases. Well-designed library code often shouldn’t even need to log in the first place because it should clearly articulate each units side-effects; the composition of which should become clear to understand. Sadly, “design” has become a lost art in modern software development.
In Java world logging in libraries is effectively a no-op unless explicitly enabled by user, so side effects are negligible. And it actually does make sense, e.g. when a library is offering a convenient abstraction level over i/o, parsing or other stuff with initially unknown failure modes, where some logs may help clarifying the picture beyond handling an exception or error code. The way logging is done there is the art of good software design, which has never been lost (it may have not reached other platforms though). So I disagree with you and some other commenters: strict Verbot is dogmatic, and good design is never dogmatic.
You definitely are not alone in feeling this way, it’s happening everywhere now and it’s driving me nuts too.
I have the same complaint at work, where coworkers are using it for writing pull request descriptions, and it pumps out slop buzzwords like “streamlined the documentation”. Like, you didn’t streamline anything, you ran prettier on a markdown file!
On top of this type of description being useless marketing jargon, the writing style risks to train future LLMs to devolve their writing styles further into this. More frighteningly, how long until the excess amount of LLM-generated slop text like this starts training future humans reading it? People tend to model how they speak off of what they hear and read, and it’s everywhere now.
> how long until the excess amount of LLM-generated slop text like this starts training future humans reading it
Not much. Add to it deference to technology and the innate preference for new stuff not liked by previous generations: sloppy LLM style will look more authoritative than well thought human style of parents and older siblings.
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.