How I made this project using AI
Why?
In my team in my day job, we used Cursor and moved to Claude. It all works very well, and it's a lot of fun, (we see at least 2x productivity increase and an order-of-magnitude improvement in quality) but...
I'm chewing my fingernails, "Will costs go up?"
Introduction
The process of software development has been disrupted by tools like Copilot, Claude, and Cursor. I also got myself a key and used it with GPT-5, connected to my IDE to see just how expensive it got. I chewed up $10 in the space of a week, just using it casually on a few evenings.
Then I found OpenCode, which I can use in pay-as-you-go mode with their free Big Pickle model.
Most AI tools chew up a lot of tokens trying to work out what we mean. We use them inefficiently. I have a theory, and I decided to test it ...
Theory?
- Don't let the LLM write the tests, or we'll spiral down a vortex of foolishness.
- First write the tests and design the basic class structure yourself.
All the creative work - the architecture, the design, and the logic should be specified up front.
I.e. "help the LLM write good code."
Edit: after embarking on the work to prove or disprove my theory - I - well I neither proved nor disproved it - I modified it. Read on...
Don't drink too much hAIpe.
I don't address any of these tools as an actual person with "please" or "thank you". A tool in a machine does not have a soul, and is certainly not conscious.
LLMs are useful. Very useful when it comes to languages - and computer code is a language - but they are inanimate objects. They are electronic machines. At their very "core", they are virtual models of human language. People have used the misnomer "neural networks" when describing the internals of LLMs. This software architecture was originally inspired by the brain. However, modern AI networks function very differently from actual human neurology. LLMs are masters of syntax and form. They learn how words sit next to each other. They do not have a mind, consciousness, or an internal understanding of the real world. They use math and statistics to predict the next word. They calculate probabilities from massive data sets. The human mind uses biological neurons, emotions, and sensory experiences.
Maybe it's just my quirk, but I am uneasy about the way people personalise an AI with a name like "Claude", which, by the way means "lame" or "crippled". It's a computer program. I prefer to think of it as a machine. It speaks, and in fact can put words together very well, but that does not make it alive, does not give it a soul, and it is incapable of anything approaching emotion. It can only imitate us. Remember it is Artificial Intelligence.
At times I've been amazed at how good the LLMs are at writing code and making very valuable summaries and conclusions about the code. They seem wise, and I've been even more uneasy (than I have about the personalisation of AIs), when I sense in my own spirit that I'm almost in awe. Personalise them, and be in awe of them, and you are one step away from worshipping them, or treating them as a counsellor. This is serious: DON'T DO THAT. Someone committed suicide because he was receiving counselling advice from an LLM. Don't even blame the LLM in that case. Blame our culture which is so eager to look up to them, fear them, and treat them like a guru or god of some sort. This is idolatry of the worst type possibly imaginable.
Let's get into it
I started with the Document class, and a test for the class. The documentation and description of the class will be written into the test, because the tests will become the "documentation" for the project. Look at the tests if you want to know how it works.
I wrote an AGENT.md file.
I created a base class:
class DockbModel(BaseModel):
model_config = ConfigDict(populate_by_name=True)
A stub class "Chapter" with nothing in it (which I'll expand later.)
class Chapter(DockbModel):
id: str
And an exception class:
class EditTextRangeError(Exception):
def __init__(self, message: str, start: int, end:int):
super(message)
self.start = start
self.end = end
Then I created a model "Document", which at this stage is not much more than a stub itself.
And here is the test (as it started).
This is all the coding and documentation I did before I put the LLM to work.
Following is the prompt I used:
I have written a test file for the Document model: @tests/dockb/models/test_document.py
Most fail at present, because I have not written the body of the function
apply_append_text in @src/dockb/models/document.py .
Then I accidentally pressed ENTER, and OpenCode just jumped into it.
It fixed a bug I'd written into the exception class (I was calling super() as if it was super().__init__()).
Unfortunately, there was also a bug in my test, and it added some automation into the function which I didn't want, so I fixed the text and removed that logic.
Note to self: tell the LLM if it sees a potential bug in the test, and has to write complex or defensive code to work with the buggy test, prompt me about it.