The Unbearable Light of Coding

Last month, I built a full retrieval system with embedding, hybrid search, and GUI in about 25 hours. Last weekend, I spent two days trying to debug it – and realized that I had no idea how my software worked.
Let's be honest: I pushed the GitHub repo without writing a single line of code. Am I sad about it? Kind of. The amount of technical skepticism weighs heavily on my shoulders, much more than I'm used to. Will I regret it? It is possible. Will you know?
I wanted to share my story here because I believe this is something that many developers are going through right now, and many more will in the years to come.
Because let's face it: you can have a code of honor and be proud of your expertise, but nothing beats the speed of GitHub Copilot & Co. If your colleague on AI steroids posts features and pushes updates twice (is greatly underestimated) as fast as you, who do you think is closest to the company door when the budget gets tight?
The productivity benefits are real, even if you use these tools to create documents. And there is a small step from:
“Write lines of text for this function.“
to
“Write a task.“
That quick little step takes you to a whole different level of productivity.
But here's my personal story, what I've learned, and where I think this leaves us as developers.
Project: building my own NotebookLM (but robust)
For background, I set out to build a RAG-style text retrieval system in the spirit of NotebookLM, without the rigor. The program takes a private PDF library, processes it, and returns verbatim answers from that corpus. No pronunciation, no tricked out sentences, just “give me the exact passage that answers my question so I can search again in the original PDF.”
Admittedly, this is a more scientific, less confusing way to use your books. But maybe I'm not the only one who is tired of checking all the LLM answers against the source.
The software configuration was straightforward:
- Robust import pipeline: moving directory trees, extracting text from PDFs, and making them into paragraphs and overlapping blocks.
- Hybrid Storage & Retrieval: a storage layer that combines standard SQL tables, a full-text inverted index search engine (for exact keyword matching), and a vector database (for semantic understanding).
- Reweighting Strategy: some idea of pulling a wide candidate pool through lexical search, then reordering the results using density vector matching to get the best of both worlds.
- Full UI: dashboard to manage PDF library, monitor import progress, and display results with deep links back to source text.
On paper, this is all straightforward. Python, Streamlit, SQLite+FTS5, FAISS, sentence transformation model, all wrapped in a Docker container. No external cloud dependencies, just a private NotebookLM‑ish tool running on my machine.
The write-first method
I didn't start with code, but with documentation. I already had my general project skeleton from the cookiecutter template, so the structure was there: requirements area, design decisions, release method and testing, all sitting nicely in a docs folder waiting to be filled.
I wrote down the use case, sketched the architecture, the algorithms to be used, the requirements. I defined the goals, limitations, and major components in a few bullet points, then let genAI help me expand into longer sections once I had a rough idea in place. So I gradually moved from the basic idea to filling out more detailed documentation describing the tool. The result wasn't the best script ever, but it was clear enough that, in theory, I could give the whole bundle to a junior developer and they'd know what to build.
Freeing my AI colleague in the codebase
Instead, I gave it to the machine.
I opened the doors and let my fellow GitHub Copilot into the codebase. I asked it to draft the project as it would see fit and complete the necessary text files. Once the basic structure was set and the tool seemed to work with one algorithm, I also asked it to generate a pytest suite, test it, and iterate if it ran into any errors. Once this was done, I proceeded to ask it to run other algorithms and combine some cases.
Basically, I followed my usual approach to software development: start with a working core, then expand with additional features and tweak things whenever the incremental build runs into major problems. Is this the best architecture in the world? Probably not. But it's in the spirit of the Pragmatic Editor: keep things simple, repeatable, and always “ship” — even if the deployment is internal and only to me.
And there is something deeply satisfying about seeing your ideas become a working tool for the day. Working with an AI partner felt like the project leader I always wanted to be: even my half-baked wishes were anticipated and executed in seconds as working code.
When the code didn't work, I copied the stack trace into the dialog and let the agent fix itself. If stuck in the install rabbit hole, I've changed models from GPT5 to Grok or back again and it clears the error like it's rival siblings.
Following their thought process and seeing the codebase grow quickly was exciting. I only kept a rough time estimate for this project, as this was a side test, but it was certainly no more than 25 hours to generate > 5000 lines of code. Which is quite a good result for a relatively complex tool that would have kept me busy for several months. It's still far from perfect, but it does what I intended: I can experiment with different models and truncation algorithms on top of the retrieval shape that returns voice responses from my library, and the exact source, to jump straight to the base document.
Then I left it alone for a month.
A technical debt hangover
When I came back, I didn't want to add a big feature. I wanted to install an app in Docker so I could share it with a friend.
In my head, this was a neat Saturday morning job. Instead, it turned into a painful weekend of Docker configuration issues, poorly resolved paths within the container, embedding repositories and FAISS directories that live in places I haven't clearly separated from the code, and tests that pass on my local machine but fail (or never run properly) within CI/CD.
Some of these stories are entirely up to me. I happily thought that my CI/CD pipeline (generated by AI) would “take care” of it by running tests on GitHub, so that platform conflicts would emerge early. Spoiler: they didn't.
back when Copilot suggested a seemingly simple fix: “Just add a reference to the working directory here.” Instead of letting her touch the code, I wanted to stay in control and only ask for directions. I didn't want any damage to a codebase I hadn't looked at in weeks.
That's when I realized how much money I spent.
Not only could I not see why the error occurred in the first place, I could not identify the file or passage that I should have made the change to. I didn't know what was going on.
Compare that to another project I did with a partner three years ago. I still remember how some tasks were connected and a stupid bug we spent hours hunting, only to find that one of us had misspelled the name of the thing.
An unusual fact
I saved a lot of development time by skipping the low-level implementation work. I remained in control of the architecture, goals, and design decisions.
But not the details.
I was the technical lead on a project where the only developer was AI. The result sounds like a very fast, multi-concept contractor build to me. The code has unusually good documentation and decent testing, but its mental models just didn't fit into my head.
Can I fix something if I need to make a change and the internet is down? Actually: no. Or at least not faster than if I inherited a codebase from a colleague who left the company last year.
Despite the better-than-average documentation, I still stumble over “WTF” pieces of code. To be fair, this happens with human-written code too, including mine from a few months back. So does GenAI make this worse? Or just as soon?
So… is writing with a vibe good or bad?
Be honest: both.
The pace is crazy. The ratio is true. The productivity gap between people who use these tools intensively and those who don't will only grow. But you trade the proximity of the implementation of property management.
You go from master to operator. From architect to project lead. From knowing every screw in a machine to trusting the robot that assembled the car. And maybe that's just what software engineering is quietly turning into.
Personally, I now feel like a project leader or lead architect: I am in control of the big picture, and I am confident that I can choose a project in a year and extend it. But at the same time, it doesn't feel like “my” code. In the same way that, in the old setup, the lead architect does not “own” every line written by their team.
My system, my design, my responsibility.
But the code? The code is mechanical.



