Horseless carriage: AI is not just for faster coding
Vibe coding in progress.
We often talk about AI in software development as a way to write code faster, but that’s only part of the story. As tools evolve, so do our workflows, expectations, and roles. From low-stakes experimentation through “vibe coding” to structured multi-agent systems, this blog post explores how AI-augmented programming is reshaping how we code and think about building software altogether.
There’s no shortage of opinions on AI-augmented programming. Either it will, or it won’t replace software engineers. It’s either the best thing ever for productivity or leads to wasting time debugging weird bugs created by the AI. Opinions on which specific large language model is best are usually based on the person’s anecdotal experience.
One recurring theme in many of these opinions is that they are based on, at best, the current state of AI-augmented programming or, at worst, an outdated understanding of the state from last year. The field is moving so rapidly that it is challenging to keep up and make good arguments about where it is headed.
Perhaps because it’s hard to understand the direction of AI-augmented programming, many arguments look at it in terms of how things have worked in the past. By now, it should be clear that with such a massive paradigm shift, this doesn’t always work.
More than just faster coding
Just like people of the past thought of cars as horseless carriages, people today might think of AI-augmented programming as something that makes you write code faster. This thinking is partly correct but is somewhat limited and can be misleading. Writing code faster does not automatically lead to delivering higher-quality software faster, and it certainly does not lead to better outcomes on its own.
The software industry has a long-standing tradition of overemphasizing output over outcomes. New methodologies like agile development and DevOps have often been seen by many as tools for delivering more software faster. It looks like this same trend is also continuing with AI-augmented programming, with a lot of the conversation revolving around productivity as measured by lines of code produced. Less attention is given to how we could make use of AI for better outcomes. However, a simple program with good product-to-market fit is better than a complex one without.
Rather than thinking about AI-augmented programming in terms of how programming has worked in the past, we could also look at what it enables that wasn’t possible before. What new use cases does it allow that were either impossible or impractical in the past? How should we change our behaviors due to these new use cases? Thinking this way can lead to better insights.
Explosion of experimentation
There’s been a lot of talk lately about vibe coding. The term was coined by Andrej Karpathy and defined as follows:
“There's a new kind of coding I call "vibe coding", where you fully give in to the vibes, embrace exponentials, and forget that the code even exists. … It's not too bad for throwaway weekend projects, but still quite amusing. I'm building a project or webapp, but it's not really coding - I just see stuff, say stuff, run stuff, and copy paste stuff, and it mostly works.”
Commentators often dismiss this type of coding as producing low-quality code and various security issues. That’s true, at least with the current models – you probably shouldn’t run this code in production, though some will do so anyway. But what if we think of what new use cases this type of programming enables?
One of the core principles of DevOps listed in The DevOps Handbook is a culture of continual experimentation and learning. When you can generate code much faster, you can build many more demos, prototypes, and proofs-of-concept. This experimentation allows you to discover the right thing to build quicker and to demonstrate and communicate ideas more effectively to your coworkers.
However, you need to be mindful not to consider these experiments production-quality and be sure to throw away the code once it has served its purpose. Sometimes, there can be an aversion to throwing away the prototype since it’s basically working, and effort went into building it. If the effort needed is significantly reduced, that might also help to let go of the prototypes more easily.
Show, don’t just tell
As a practical example of this approach, I recently created a demo of a web application for a customer using what could be called a structured approach to vibe coding. I had a concrete description of the data model I wanted to use in JSON format. I specified the technologies I wanted to use based on my familiarity with them, and iteratively built the web app with the AI writing most of the code. I finished the application in about one workday’s worth of hours while also working on other stuff, and I recorded a demo of the application and shared it in Slack for comments. I could have done this without AI, but it probably would have taken a week or two, which is quite a lot for what I intended to be a throwaway demo. The exercise served its purpose well: Showing what the intended workflow with this application could look like in the future, and getting people excited about the possibilities of automation.
Another benefit is that you don’t need to be a programmer to create these prototypes. Anyone can create something to communicate an idea quickly or to turn a vague idea in their head into something more concrete. You can start with a prompt to generate your concept, then refine the app the AI created a couple of times before showing it to someone else for feedback. You can either do this from scratch with a fresh codebase or add features to an existing codebase.
Once you know better what should be built based on some quick vibe coding experiments, you can write the production code more easily. Of course, you can still have the AI assist with the production code. However, the productivity increase there won’t be as dramatic since you need to understand the code and be more mindful of architecture and maintainability.
From a programmer to a product manager
When moving beyond demos and experimentation, vibe coding doesn’t cut it anymore, and a more structured approach is needed. For common problems and programming languages, the current state-of-the-art large language models are already good enough to write significant portions of code, leaving the programmer to review the code and set up rules and workflows for the AI. Managing the context for the AI and providing good guardrails and clear instructions are essential. The work of a programmer moves closer to that of a product manager: Create an unambiguous roadmap for what the product you’re building should do and provide context and feedback for the AI to implement it.
In addition to defining a roadmap for the AI, the programmer must provide a clear set of rules as guardrails. Agentic coding tools like Cursor, Roo Code, and Cline implement a rules system for this. For example, the programmer can use these rules to enforce a specific workflow for the AI agent, like using test-driven development or a particular coding style. They can also prevent the AI from making certain common mistakes that these agentic tools will make without explicit guidance.
In this phase, you do need to understand what good code looks like, how to test it, and how to structure it. At least for now, the AI will regularly get these parts wrong, though good rules and context help a lot to reduce clear mistakes. Experience in software engineering is still needed to review code, write it yourself when necessary, and give good instructions for the AI.
Multi-agentic workflows
Taking a step further from the programmer becoming a product manager to an AI assistant, future and already some current workflows involve orchestrating a set of AI agents with different roles. For instance, one model writes the code while another reviews it, and a third model is responsible for planning and breaking down the implementation into logical, incremental steps. What’s left to the programmer is to supervise the AI agents and provide good, clear instructions. With its recently released Boomerang Tasks, Roo Code is an example of a tool that is already implementing this workflow.
Using multiple models allows for selecting the most suitable model for each type of task. For example, some models may be best suited for planning, while others are excellent for producing code. This leads to better results with fewer mistakes, and can also be cheaper since the most expensive model doesn’t need to be used for everything.
What’s left for humans to do?
Software is ultimately built for humans; only humans can tell what they want from that software. Quite often, we don’t even know exactly what we want from software. In a way, articulating good instructions and managing context for a bunch of AI agents is a different interface for programming computers. In his blog post “The End of Programming as We Know It,” Tim O’Reilly argues that there have been similar shifts in programming paradigms before, like moving from flipping switches on a computer to writing assembly and later higher-level compiled languages, and that large language models are just the next iteration of this development.
Not all software engineering fundamentals will change when AI agents are introduced into the workflow. My colleague Niko recently wrote an excellent blog post about how lean principles interact with AI-augmented coding and that more output doesn’t necessarily lead to better outcomes.
Risto Laurikainen is a DevOps consultant who has worked on platform engineering before it was called platform engineering. He has worked on building and using these platforms for more than a decade in various roles from architecture to team leading.