:: BLOG

Vibe coding vs programming with AI: what really changes

Giuseppe Tufo · · 6 min read

Take two people with the same tool and the same AI model. The first types a sentence, accepts whatever comes back and keeps going. The second decides what to build before asking anything, and checks at the end that the result is the right one.

Same tool. After a few weeks of work, very different results.

In this article I explain where the difference lies, what remains a human job, and how we at microPP build software with AI coding agents.

What is vibe coding?

The term was coined by Andrej Karpathy in a post on 2 February 2025: a way of programming where you give in to the vibes and "forget that the code even exists". You tell the AI what you want, it writes the code, you don't look at it and you just check whether it works; if it doesn't, you ask the AI to fix it.

Simon Willison puts it simply: vibe coding means building software with an AI without reviewing the code it writes.

For a prototype or a weekend experiment it works, and it's fun. The trouble starts when the same approach is used for software that other people rely on: clients, colleagues, users.

Should you review code written by AI?

It is the most common question, and the experts disagree:

My experience points the same way as antirez. A year ago I read and fixed everything; today models have improved and reading every line just slows me down. It works like a growing company: the people leading it no longer know every single action, but they know the plan, the purpose and the reasons behind each decision.

There is one condition, though: if I don't read the code, I need another serious way to check it. More on that below.

What stays human: specifications and decisions

Delegating like this requires knowing how to program. The reason is simple: AI tends to suggest the most familiar, most popular choice first. Often that's fine, but it isn't always the best one for the project. People who see the whole picture and know architecture and design recognise it and discard it; people without that knowledge keep the familiar choice, often without noticing.

A study of eight models points the same way: without context, models favour popular libraries and languages over the most suitable ones. It measures libraries and languages, not architecture, so I cite it as a signal, not as proof.

Two examples from BlockLog, an app we are building for a climbing gym (Go backend, a Python component that uses AI to recognise holds on the wall, Flutter app):

  1. The login. The app was meant to have a single sign-in with a role choice: climber or route setter. The mockup showed exactly that. The AI decided to build two separate apps. My specification was ambiguous, and the model filled the gap its own way.
  2. The holds. I had asked to highlight the holds of a boulder problem by turning the wall grey and keeping the holds in colour. The model kept the wall in colour and covered the holds with yellow squares joined by a dashed line. It followed the idea, not the implementation I had asked for.

In both cases I noticed by looking at screenshots of a user flow, not by reading the code.

How we work: the agent loop

With BlockLog we handed development over to the agents, but not with a single prompt:

  1. Define the app starting from the idea.
  2. Discuss the architecture with the AI as a peer: it works if you come prepared and already know where you want to go.
  3. About twenty steps, each closed by a check in the emulator with screenshots.
  4. Checkpoints where I test the app myself and propose changes.

We don't use the same model for everything: we pick it by task difficulty, because every model has a real cost. One agent coordinates the work, another keeps the project documentation up to date, and implementation is done by the model best suited to each task.

How we verify without reading the code

Three levels, most important first:

  1. Behaviour tests. The agent uses the app in the emulator like a person would and saves screenshots of every step; then we test it ourselves. That is how both BlockLog episodes surfaced.
  2. Tests that are themselves tested. The Go code has its own tests, but AI tends to write tests that always pass. So we check them with mutation testing: small changes are introduced into the code and the tests must catch them. Recent research also suggests that model-written tests can reach good coverage while finding few defects.
  3. Cross-model reviews. Code is reviewed by models from different families than the one that wrote it, because they have different blind spots. It helps, but it is no guarantee: models tend to prefer their own outputs, yet the best models often make the same mistakes even across vendors. The real verification is still on behaviour.

Vibe coding or programming with AI? Five questions to tell

If you can't answer, you're closer to vibe coding than you think. That's fine for a prototype; it isn't for software other people depend on.

In short: specifications at the start, because that's where AI fills the gaps its own way; tests at the end, because that's where you find out what really happened; and developer expertise in between, to discard the obvious choice and reach the right one.


Planning custom software and wondering how AI can speed things up without cutting corners on quality? Tell us about your project: we'll get back to you within 24 hours.

The research cited here points in the same direction as my experience; it is not definitive proof.

OTHER SERVICES

LET'S TALK

Tell us about your project

> Initializing connection...

Have a software project in mind? Tell us about it: we'll get back to you within 24 hours with a first assessment.

EMAIL:

info@micropp.net

Protected by reCAPTCHA - Privacy - Terms