Skip to main content

We are all beginners

While visiting multiple organizations and talking to colleagues about integrating AI into their software development lifecycle, I noticed something:

The approaches couldn’t have been more different.

Some teams were embedding AI deeply into every step of development—coding, testing, documentation, even architectural decision-making. Others were deliberately cautious, limiting AI to narrow, controlled use cases.

Opposites. And yet, both felt… reasonable.

That’s when it clicked for me:

We are all beginners.

Not in the dismissive sense. Not in a “we don’t know anything” kind of way. But in the ways as described inside the Dreyfus Model of Skill Acquisition.

 


The Dreyfus model, briefly

The Dreyfus model describes how people acquire skills through five stages:

  1. Novice – Rely on rules and rigid guidelines

  2. Advanced Beginner – Start recognizing patterns, but still need support

  3. Competent – Can plan, prioritize, and make conscious decisions

  4. Proficient – See situations holistically and adapt intuitively

  5. Expert – Operate fluidly, often without explicit rules

In mature domains, you’ll find people across all these levels. There are established best practices, shared language, and a body of prior art to learn from.

AI in software development is not one of those domains.

At least, not yet.

AI has reset the skill curve

What makes this moment unique is that experience hasn’t disappeared, but its advantage has shifted.

I would think that my 20 years of experience still count. But when it comes to integrating AI into a sociotechnical system, how it affects teams, processes, quality, ownership, and architecture, we are, in many ways, back at the novice stage.

And so is everyone else.

There are no stable heuristics yet. No widely accepted patterns. No “this is how it’s done.”

We’re all operating with:

  • Partial understanding

  • Local experiments

  • Context-specific successes

  • And a lot of uncertainty

The recipes are still being written.
The patterns are still emerging.
The war stories that will eventually become best practices… are happening right now.

The trap: Acting like experts too early

One of the biggest risks in this phase is pretending we’ve already reached competence or expertise.

I hear statements like:

  • “This is the right way to use AI in development.”

  • “Developers who don’t use AI like this will fall behind.”

  • “We’ve solved how AI fits into our process.”

Maybe. But probably not.

What’s more likely is that you’ve found something that works in a specific context, under specific conditions, with a specific team.

The danger is turning early success into dogma.

In Dreyfus terms, we’re trying to behave like experts while still being novices.

So how do we move forward?

If we accept that we’re at the beginning of the curve, the question becomes:

How do we learn effectively?

1. Embrace being a novice

Novices need rules—but also need to know those rules are temporary.

It’s okay to start with simple heuristics:

  • “Use AI for boilerplate code.”

  • “Always review AI-generated output.”

  • “Don’t use AI for security-critical logic without validation.”

These aren’t universal truths. They’re scaffolding.

Use them—but don’t get attached to them.

2. Optimize for feedback, not perfection

At this stage, speed of learning matters more than correctness.

Short feedback loops are everything:

  • Try something small

  • Observe the outcome

  • Adjust

This applies at every level:

  • Individual developers experimenting with prompts

  • Teams redefining workflows

  • Organizations exploring governance

The goal isn’t to get it right the first time.

It’s to learn faster than yesterday.

3. Share your “war stories”

Right now, your experiences—good and bad—are incredibly valuable.

Because there is no established body of knowledge yet, every story contributes to it.

What worked?
What failed?
What surprised you?

These are the building blocks of future best practices.

The organizations that learn fastest won’t be the ones with the best initial strategy—but the ones that share and reflect the most.

4. Treat AI as a sociotechnical change

The hardest part of AI adoption isn’t the technology. It’s everything around it.

AI impacts:

  • How developers think

  • How teams collaborate

  • How quality is assessed

  • How knowledge is distributed

  • How decisions are made

This is not a tooling upgrade. It’s a system-level change.

Which means experimentation should go beyond “what tool do we use?” and into:

  • “How does this change our processes?”

  • “What happens to code reviews?”

  • “Where does responsibility sit?”

5. Develop intuition, not just technique

As you move beyond the novice stage, something interesting happens.

It’s no longer about what AI can do. It’s about what it should do.

This is where judgment becomes critical.

  • When is AI helpful vs. harmful?
  • When does it accelerate vs. obscure?
  • When does it empower vs. deskill?

These are not questions with fixed answers.

They are developed through experience.

We’re not behind. We’re early.

It’s easy to feel like you’re late to the game. That others have already figured it out. That there’s a “right way” you haven’t discovered yet.

But if the Dreyfus model teaches us anything here, it’s this:

There are no experts yet. Only learners at different stages of the same new journey.

And that’s a rare moment. Because it means we don’t just have to adapt to the future. We get to shape it.

If you’re experimenting, questioning, struggling, or even failing with AI right now…

You’re not behind.

You’re exactly where you’re supposed to be.

You’re learning.

And that’s the point.!

More information

Dreyfus model of skill acquisition - Wikipedia

Popular posts from this blog

Podman– Command execution failed with exit code 125

After updating WSL on one of the developer machines, Podman failed to work. When we took a look through Podman Desktop, we noticed that Podman had stopped running and returned the following error message: Error: Command execution failed with exit code 125 Here are the steps we tried to fix the issue: We started by running podman info to get some extra details on what could be wrong: >podman info OS: windows/amd64 provider: wsl version: 5.3.1 Cannot connect to Podman. Please verify your connection to the Linux system using `podman system connection list`, or try `podman machine init` and `podman machine start` to manage a new Linux VM Error: unable to connect to Podman socket: failed to connect: dial tcp 127.0.0.1:2655: connectex: No connection could be made because the target machine actively refused it. That makes sense as the podman VM was not running. Let’s check the VM: >podman machine list NAME         ...

Cache stampede: when our cache turned against us

While investigating some performance issues, we ran into an ASP.NET Core API that cached a fairly expensive aggregation query for 60 seconds. Under normal load, that was fine: one request rebuilds the cache, everyone else reads from it. Under peak load, dozens of requests would arrive in that same expiry window, all see a cache miss, and all fire the same expensive query in parallel. The database didn't like that. That was the moment when our caching layer stopped helping and started hurting. A burst of requests comes in at the same time, all miss the cache, and all go hammer the database or the downstream API at once. That's a cache stampede . The cache was supposed to protect our backend, and for a few hundred milliseconds it did the opposite. Why this happens IMemoryCache.GetOrCreate (and its async sibling) looks like it protects you, but it doesn't add any locking on its own. Look at the naive version: public async Task<Report> GetReportAsync(string key) ...

A complex system designed from scratch never works

A few years ago, I worked as an architect on a big mainframe rewrite. I still count it as one of my failures. Not because the technology was wrong, but because I couldn't convince the management team to simplify the approach. Years later, the organization is still struggling to get the new system up and running. I left the project at the time, because I couldn't put my name behind an approach that would take very long and cost a lot of money without a working system to show for it along the way. Gall’s Law That memory keeps coming back to me, because it's a textbook case of Gall's Law playing out in real life. Gall's Law , from John Gall's Systemantics , states it plainly: A complex system that works is invariably found to have evolved from a simple system that worked. A complex system designed from scratch never works, and it cannot be patched to make it work. You have to start over with a simple system that works. What does that mean in practice,...