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) ...

Azure DevOps/ GitHub emoji

I’m really bad at remembering emoji’s. So here is cheat sheet with all emoji’s that can be used in tools that support the github emoji markdown markup: All credits go to rcaviers who created this list.