Rant Code
Burning the world, at a discount, for code

As any tech lead/CTO worth their salt, I have not opened my IDE to write code for a few months now. And as an aspiring blogger I have thoughts about it.
I have thoughts about LLM coding, and they might be slightly different than other people, so buckle your seat belts dear readers and let's wade through some slop together.
LLMs as a general tool
LLMs are a chatbot, they do chatbot things, and when using them you must remember that they strip away most of the intention of whatever you wrote.
Even though most people try to convince me that the written discourse on the internet in general (and LinkedIn in particular) was already truly uniform, I am quite certain that:
It was not.
You did not use to get dumber reading it.
And writing text is supposed to be the thing they excel at!
Seeing the subpar text they produce should make anyone wary of using them for any serious purpose.
A few newsletters I read quite avidly in the past have become intolerable as an LLM takes a sentence that might be interesting and turns it into five paragraphs.
While it might not be yet capable of turning a blog post into a book (we were quite good at that before), it certainly can turn a sentence into a (bad) blog post.
And all that with all the convenience that fast food has. It's fast, it's 'repeatable' and in a world where volume already spoke louder than quality, it is drowning any original thought that might have emerged before.
But it is impressive, and it plays very well to our laziness. I have a podcast, and I don't like marketing, of course I have been tempted more than once to tell the LLM to write some copy for me.
Abstracting cost from output
One thing I must give kudos for is that the abstraction between the cost and the output is marvelously achieved.
In it's more utilitarian view, we don't know (and don't think about) how many tokens are in our subscription, not how much money a token costs, nor what a token is, not how much energy a given token might consume. We don't even know how many tokens any given request will consume.
The above makes it so we don't know if there is a viable business on top of LLMs as a general tool. It might be worth producing an ungodly amount of slop at 200 a month, but there is a number where that is not true. And we don't know what the final price will be.
We don't know either what the energy consumption of all of this "work" is other than "high". I believe in part it is due to it being a complicated subject, and in part that fear is a good marketing tool, for example saying we might have blackouts due to LLMs or that we will have to open a nuclear power plant to power a data center sells.
But there is a more insidious cost being abstracted away, and that is attention, and while attention might be all you need, attention is being destroyed.
First and foremost is the fact that as soon as it becomes apparent that something was spewed out by the machine, my eyes (and I suspect yours) immediately gloss over the rest of the content.
Not less important, by clicking the metaphorical "make longer" button, your idea gets diluted into "it's not this, it's that" and other weird sentence constructions.
Finally, you are probably not paying attention to your "writing" anymore, after all the computers never lie, or never used to lie, and you told it to turn your idea into long form writing "using your voice". How can you be sure your voice is not eerily close to everyone else's voice?
They can't write, can they do something else?
Although the hype machine wants to convince us and sell us today on what LLMs might be able to do in the future, I do believe there are some things it does reasonably well today, at today's subsidized price.
One of the things it does reasonably well is the opposite of 'make this longer'. It is capable of ingesting a fairly large amount of information, in a reasonable time and give you a watered down but mostly sufficient summary. As long as precision is not something you need from it.
You do need to be aware that it had been trained mostly on internet text, so it "wants to give you" actionable advice, and strategy. And it is easy to be fooled into thinking it can think and actually provide advice and analysis.
It also can code, mostly...
But I can code faster now!
Congratulations, after 750 words you finally are at the part that reveals my hypocrisy and that probably interests you more.
I have not opened my IDE to type code in a while. And I think I am mostly faster, but there is a lot to unpack here.
I can give a prompt to the LLM and it builds an app for me
No you can't. If you are not a software engineer, and don't understand the code it is producing you might be able to fight it until it builds something really simple thst mostly works. But you are most probably building a website, that website is pretty simple and you were overestimating the complexity of what you wanted to build.
That is not to say that it is not useful, and it might allow you to create some bespoke webapps for really niche problems, but you can't vibe code your way to solving a problem at scale. Since I can't prove a negative, let's say that with the miriad of people vibe coding the next unicorn, one would expect at least one or two to get some traction.
But my whole organization can now create a PR from a slack message, we are all 10x engineers!
No you are not. But thanks for telling me, I'll make sure to avoid your software for a while.
In the worst of cases, you are creating an intolerable amount of bugs and pushing unreviewed and unintentional code out into the wild.
In the best of cases, the people that know best how to structure and tend to your code are now stuck babysitting a codebase getting filled with half baked ideas.
Code is quite meaningless, but I will presume you have some sort of software you are trying to sell. The functionalities you do not build into it are as important as the functionalities you do build into it. Every piece of functionality you write is a desire path that you are paving other, and if you don't put intention and attention into it, you will end up paving the whole field, getting your users lost in what they try to accomplish and trying to plug holes in a surface area that is untenable.
But it gave me code and now I can scrape recipes of the internet and repurpose them for SEO farming
Yes, I am quite sure it did. But if you have followed along... At what cost? And for what?
But I am a software engineer, and I don't use my IDE anymore! And I am faster?
I am in the same case than you, and I do think you can be significantly faster when assisted by an LLM for coding, but I have feelings again. The rant continues!
Faster?
Faster is really hard to pin down, I know it might seem disingenuous but what do you mean by faster?
Do you produce more code by volume?
Do you have a shorter cycle time?
Are you creating more PRs?
Do you deploy more frequently?
Are you adding more functionality more frequently?
Are you adding functionality that you could not before?
Are you seeing a smaller volume of bugs in production?
All of these are ways to measure "faster" and I would contend that some of them are more interesting than others. Especially Volume and PRs seem to be quite worthless to me.
If I submit myself to that questionnaire today, I would answer:
Do you produce more code by volume?
- Yes
Do you have a shorter cycle time?
- Yes
Are you creating more PRs?
- I was, I stopped
Do you deploy more frequently?
- Yes
Are you adding more functionality more frequently?
- Somewhat
Are you adding functionality that you could not before?
- Yes, at least considering things that where not realistic before
Are you seeing a smaller volume of bugs in production?
- Mostly yes
So I do think I am faster now, but I would not say I am twice as fast as before. There are also some systemic issues that must be tackled in order to be faster.
Asynchronous Code Review, for the despair of many, are a default in our industry, and while we can create a higher volume of code and PRs, we are transferring a bottleneck downstream. And it is a bottleneck that creates a lot of problems, from context switching, to conflicts creeping in the different branches.
You will do too much
If you decided to start doing your engineering from a CLI instead of an IDE, I believe you will have gone through this phase.
Hey! I want to add the possibility to link slack and my app to notify people of changes
Chatbot creates a worktree and churns along...
Hey! I also want to be able to login by taking a picture of my face
Chatbot creates another worktree (some times in the correct place) and churns along...
Hey! Actually I also want to add fingerprints so people can login when they pick up their phone
Chatbot happily tells you yes, creates a worktree and churns along...
Of course all of this goes in parallel and your nervous system is fried and overworked so you are saying yes to everything without even looking. But you do remember to tell it to review itself from time to time
A few hours or days after you have several PRs, probably massive, they read like rants written in code and you need to review them all.
It took me a month to recover from that and actually manage to merge the PRs (at least those I did not discard). I hope this does not sound familiar, but I am quite certain it will.
Reining it in
So, we have to do less, it is not tenable to have 5 projects in parallel. It is a lesson apparently I (and I suspect you) needed to learn again. I am still faster, granted, but now I only swim in one lane instead of trying to encompass the whole pool at once.
I also have realized that we need to contain the Rants it produces in code. We need to constrain it so that it does not spew forth a whole app every time you tipe something in your IDE.
Paul's dotfiles are a great starting point when you want to rein it in, they do shorten cycle time* (*If you are doing TBD), I am still faster, and I pay more attention.
I do feel like I have to babysit the LLM in very predictable ways.
Feedback loops or lack thereoff
One of the reasons I believe LLMs are performing adequately for software engineering is that (most) of the industry has accepted the need for short-ish feedback loops, from Tests (ideally first) to static checkers, going through CI.
And that harnesses and helps the LLM iterate. But some of them are 'hard feedback' and some of them are judgement calls.
LLMs are really good at following hard feedback, they will churn along (most times) until the test goes green, or the static checks pass.
They are really bad at making what I am calling judgement calls though.
A symptom of that is their constant refusal of doing the Refactor part or Red - Green - Refactor. And I believe it is because they don't have a hard gate. Refactoring or not is a judgement call, and so is loading skills dynamically.
As such, you will have to constantly babysit the LLM to do those tasks, and absolutely cannot trust that it will do them. No matter how many times you have written that it should!
In the same vein, you cannot believe it when it says it has reviewed it's output, it does not have the capacity to think critically, and reviews are judgement calls.
Finally, the LLM can give you a mostly correct assessment of a situation, but it will again, and again make a 'recommendation'. And that biases your thinking. LLMs are not fit to make recomendations and when having them sumarize the situation of a part of a codebase or a work in progress, you must remember to be at the drivers wheel.
For very long we have been trained to 'click' yes when prompted, your default position when using an LLM assistant should be 'no' and think through why it should be yes. This is made harder by the fact that it is not trivial to distinguish when the LLM is in need of a decision (e.g. should this function be split in two) or is just not able to perform a decisionless task without explicit agreement from you (e.g. running the tests)
If we disregard (and it is a big disregard) the economics of LLMs, for them to work as well as they should we need to create as many hard gates around them as we can, they are relentless at making something go from red to green, and I do not believe we can base ourselves solely on the tests for that part.
But in the meantime,..
Old is new again
There are practices that help in creating smaller chunks of work and in keeping feedback loops short, hard and manageable.
It seems a lot of people are rediscovering them and renaming them (with the age old fight of Agile vs Waterfall getting a new battlefield). But we have known them for quite a while.
Strive to have tests for the LLM to but its head against (and review those thoroughly if the LLM writes them).
Test behavior rather than implementation.
Have every 'unit' of code do one job and one job only.
Reduce conascence throughout your app
Do not rely on asynchronous code reviews
Work in small chunks that go from green to green and can be deployed independently
Most of these principles and practices have been extensively written about. Notably I would recommend you read at the very least
TDD by example (Kent Beck)
The original article on Software teaming by Woody Zuil
eXtreme Programming (Kent Beck)
Refactoring (Kent Beck and Martin Fowler)
And watch:
- TDD where it all went wrong by Ian Cooper.

