Very cool, but I'm skeptical. Over the last year, every Cursor/Claude/Codex project I've worked on devolves into shitty, grafted-on, duct-tape and bandaid'ed architecture, with "fixes" just working around broken code, and tons of duplication that lead to whack-a-mole. The system works at first, but then bugs start piling up and eventually take over. Everyone I talk to shares the same experience. Not to mention that if I, human overseer, don't course correct it many times a day, it goes off into Neverland.
Yet I see comments and articles like above every week, where someone says "Yeah, I just left my agent run for a few nights, and then it made this awesome tool."
There is a huge gap here, but I can't pinpoint it yet. Either I (and everyone I talk to) is Doing It Wrong, or your code is actually flawed at its core and bugs will take exponentially longer to fix and never converge, or... I just need to let my agent run for 3 months??
> Over the last year, every Cursor/Claude/Codex project I've worked on devolves into shitty, grafted-on, duct-tape and bandaid'ed architecture
I've noticed this pattern as well when people decide to vibe code a large project.
They usually get their MVP quickly, but as soon as they want a new feature or to fix a bug, the LLM takes the shortest possible route to a solution. The problem is that after about a dozen rounds of "the honest fix" and "load-bearing code" (insert your favorite claudeism) it's a tangled mess of enterprise-grade spaghetti.
I think it's because the people full-on vibe coding just don't have the experience or time to design large scale systems and anticipate what might cause problems if they want to change something later.
IMO coding agents can be useful, but the only safe place is the manageable changes you would design up and hand off to a junior anyway (but can't because your company decided to outsource years ago).
If you just say “implement this” you’re going to have a bad time after a certain point.
You really need to add yourself as a human in loop to be in the middle of design choices. That is, ask the model for a plan, what the trade offs are, should parts of the code be refactored before the next feature, etc.
Also, there’s an element of reading the code and ordering refactors. I’ve noticed that for embedded code codex loves to to do everything in a main.c and too many compiler defines. Asking it to propose a refactoring into modules helps a lot.
It’s just like writing real code, if you don’t do design up front and don’t aggressively refactor as the requirements change, it becomes a mess.
Please check out the code and let me know what you think. I have driven a few large refactorings that I don't think Claude would have done on its own. The two big ones were related to handling tokenization and parsing (Claude's original code had circular dependencies and would scan forward in the lever instead of using the parser to determine structure) and the second was for using subshells for command substitution instead of inline and having dual FD and buffer handling.
The only way I've found to make it work on long term AI-code-only projects is to have it constantly refactor, with the axes of refactoring usually provided by me.
> Not to mention that if I, human overseer, don't course correct it many times a day, it goes off into Neverland.
Doesn't that happen to a human engineering team if you don't course correct it many times a month (which in code output is similar to an LLM in a day)?
The current project I am developing with AI is so bloated that I've spent more time and tokens cleaning up the repo (to the tune of tens of thousands of lines removed) than actually creating it in the first place. AI is very very happy to create a mess.
IME you can get good results if:
1. You have very good tests. The agent can write them, but you have to prompt it to do that, and some human input may be needed here.
2. You have a good, modular architecture. Again, this is something that needs to be prompted and/or developed up front. Agent work can scale if you divide and conquer, so that any given task has a well-defined scope, limiting the amount of context needed to handle it well. If you let an agent just build a big pile of code, you’ll have issues.
Once you have the above, you’re more likely to be able to just let the agent run.
This is why you hear about things like SQLite being ported to Rust (by multiple groups!) It has a comprehensive unit test suite and a good existing architecture. Such porting projects are benefitting from already having done the upfront work that I mentioned, plus they have the original source code as a reference implementation.
Because of that, most of what I do involves a lot of interaction with the agent. That’s because I’m typically working on complex existing systems, that don’t necessarily have the above properties, and agents aren’t at the point where they can handle that autonomously.
[dead]
> tons of duplication that lead to whack-a-mole
The future is duplication. Code is no longer meant to be read by humans but by machines.
I've been doing a lot of experimenting with this with a c++ compiler project[0]. I definitely experienced a lot of challenges, but I do believe it is possible to end-up in a consistent space by putting in some very careful guardrails. I covered some of the things i learned in the follow on blog posts. My more recent runs have been producing better code after continuing to improve harnesses, tests, and prompts. New blog post coming soon on v2 and v3 reruns. I'll be kicking off some v4 runs soon. Here is a teaser showing the later runs: https://storage.googleapis.com/ralph-run-viewer-zippy-960/in...
[0]: https://medium.com/@vishvananda/i-spent-2-billion-tokens-wri...