Before we start, let's lay down a little bit of groundwork. I am not going to talk about the ethical or economic issues surrounding the use of LLMs. If I did do that, then it would be abundantly clear that LLMs cannot be used responsibly. There are many other blog posts out there that will describe how LLM development exploits workers in the third world, how it erases authorship, spreads misinformation, centralizes power among tech oligarchs and has set us on a path of another financial crisis once the investor money runs out and somebody has to foot the bill for tech that will never pay for its investments.
Instead, we will put ourselves into a world of fantasy where these concerns do not exist, one in which an engineer can happily say that pi is three, Euler's number is three and moral behavior is also three.
The kind of responsibility I want to talk about is the kind where you are accountable for the output of your work. One of the baseline expectations that we tend to have of one another in this world is that you should, as part of your work, aim to produce outcomes that at least try to avoid causing harm to others either intentionally or due to negligence. When that expectation is violated, people tend to get somewhat irate, which I think is fair and expectable. In addition to your outcomes, you are also generally expected to carry out your work in a way that is at least somewhat resource-conscious. I wouldn't be taken seriously at work if I insisted on buying a new laptop every month in order to complete a few Jira tickets. So, you also have some amount of responsibility in ensuring that you roughly use the right tools for the right job.
I believe that these two kinds of responsibility, one of being accountable for your output and the other of being accountable for your process, make LLMs nearly impossible to use while maintaining that responsibility.
The LLM "minimalist"
Let's look at an LLM user that tries to maximize accountability of output. In order to do this, they try to section off their use of LLMs such that the output is possible to review and understand and impact is highly localized. This is the kind of stuff you often hear referred to as "mechanical" work: generating boilerplate or little code snippets, individual functions that you already know they will work and so on. You aren't really introducing any notable risk, because all the code you end up generating works basically the same as all the other code you have already created.
This seems sensible at first, until you start asking the following two, annoying questions:
- If you are just generating the same boilerplate over and over again, why aren't you just using snippets and templates for a tiny fraction of the cost?
- Why are you generating industrial quantities of boilerplate in the first place? Could it be that you are just attacking a symptom of a larger problem while ignoring it?
If you are dealing with so much mechanical work, I would argue that your code probably isn't very good in the first place. But process-wise, I think you are also not really making a very good trade. So to me at least all of the talk about mechanical tasks and boilerplate just isn't very sensible or convincing. You are basically trying to hammer in nails with a chainsaw. You'll probably find a way to drive the nail in, but there's probably a better way.
The vibecoder pipeline
So, in order to actually get some bang for your buck, LLMs need to be applied to larger tasks. But here's where human nature and the way the LLMs have been designed seems to regularly come into conflict with the principle of responsibility over output.
A lot of self-described responsible LLM users talk initially about how they are generating small pieces of code and then reviewing it all very carefully to understand what the output is. And, seemingly, the output is correct enough in enough of cases, that these people tend to get to a point where they become mostly supervisors over a process that seems to work fine most of the time.
Humans suck at supervising processes that works correctly most of the time.
So, the tendency that I have seen both online and in-person at work seems to be that people stop reviewing the output after a month or two of LLM use and this compounds, since these people feel okay with having the LLM spew more and more code out, at which point attempting to review the code becomes essentially impossible anyway, since you'd never keep up with the rate of output. The skills of the programmer also atrophy over time, so while they may have been able to understand some of the code decently well a while ago, they probably have a worse chance at it now. So, you just end up letting the LLM do its thing and maybe possibly do a cursory review or test of the system under implementation once in a while, although increasingly that's the job of the LLM too.
There's a term for this: vibecoding. Often applied derogatorily, but invented by the vibecoders themselves.
The results often aren't very pretty for the people that decide to lift the lid of software developed like that. Sure, in a surprising number of cases the software works for the most part. But the code is often a travesty of good practice, with multiple redundant implementations of the same things, code smells that would make you cry and probably more than a few bugs. And assuming that the bug-per-kiloline of code for an LLM is roughly in line with a decent programmer, the mere rate of output guarantees that there are probably quite a few bugs of various levels of criticality in there, with more on the way.
But even if the code is perfect, can you really say that the vibecoder is actually accountable in any way? Sure, their prompts created it, which means that maybe they have some kind of a concept of what the system might be intended to do, but really they have about the same level of understanding about what the system actually does as a dog has about the tax system of Denmark. So, if the vibecoder needs to answer any real questions about the function of their system, just about the best thing they can do is ask the LLM and defer to its response. The only real way the vibecoder is able to show any actual, personal accountability of the code base is by getting fired or thrown in jail if/when the code they ended up generating gets somebody killed due to a negligent error. Because at the end of the day, a court is unlikely to take "the LLM wrote the code" as a valid excuse.
The mandatory ending ramblings
I don't know if there are any good pieces of advice I can give, because it seems like most of the tech industry is very insistent on sprinting into this field of rakes. Either way, I don't see how this is going to be sustainable in any way, the main difference is whether the machine will choke on the inevitable, massive price hikes, or if it will take until we start to run out of people that actually have any idea of how our technology stacks even work.
However, to them who might be in need of some faux wisdom, I would recommend that if you are a programmer, try to keep your skills and curiosity intact. You should have the amount of self-respect that you recognize your job isn't to conjure up spells for the magic word box. So, best use the magic box sparingly and maybe learn a few additional editor shortcuts so you can cut down on the boilerplate generation.