Skip to main content

Command Palette

Search for a command to run...

The Agent-First Workflow: Building Software with AI

Published
7 min read
The Agent-First Workflow: Building Software with AI

Software engineering is changing faster than most of us can comfortably adapt to. The capabilities of LLM models change almost monthly. New tools appear every week. Advice that felt solid three months ago already feels outdated.

This post is an attempt to capture how I currently work with AI agents when building software. Think of it as a snapshot in time rather than a definitive guide.

About six months ago I wrote that I was getting roughly 50% of my working code from AI agents. A lot has changed since then — and so has my approach.

AI Agent is Just Another Engineer

As AI tools have advanced, my workflow has evolved accordingly. Now, I believe that in most cases, there is no legitimate reason to write code by hand anymore.

I will only type code manually when I’m confident it’s faster than prompting an agent — which usually means a few lines at most. If the change requires thinking about structure, edge cases, or multiple files, I involve an agent. In practice, this means 95–100% of the code I deliver is AI-generated. My role shifts more toward guiding the work than writing the implementation.

More importantly, agents are no longer just a code generation tool for me. They are part of the entire development workflow. Instead of thinking about them as autocomplete on steroids, I treat them more like collaborators that help with:

  1. Exploring possible approaches.

  2. Structuring work.

  3. Implementing changes.

  4. Reviewing code.

  5. Refining the final solution.

What helped me the most was adopting a simple mental model:

Work with AI as if you're guiding another engineer through a task.

In that situation, you would typically explain the problem clearly, share the relevant context, discuss constraints, agree on a rough plan, review the implementation and refine the result together.

Working with AI agents turns out to be surprisingly (or perhaps unsurprisingly) similar. The quality of the result is largely determined by how well the work is prepared and guided.

Once I started thinking about agents as collaborators rather than tools, my workflow naturally evolved around that idea. What emerged is a simple process that I now follow for most non-trivial changes.

The workflow

The process I currently follow looks roughly like this.

Step 1 — Describe the Problem Clearly

Everything starts with a clear problem description.

This step sounds trivial, but it's where many failures start. You have to know what the problem is. Even better if you roughly know what the solution should look like. If the problem description is vague, the agent will produce vague solutions.

I try to ensure the description covers four elements:

  1. The exact problem.

  2. Current behavior.

  3. Desired behavior.

  4. Constraints.

Here's a simplified example of this pattern.

Problem:
Offline mutations sometimes disappear when the page reloads.

Current behavior:
The foreground queue stores mutations in memory.

Desired behavior:
Mutations should persist across reloads using IndexedDB.

Constraints:
- Must not block UI rendering
- Must support retry logic
- Should work with React Query mutations

This does two things — it forces clarity of thinking and it gives the agent a precise target. In my experience, spending an extra minute here saves several iterations later.

Step 2 — Prepare the Context

Before touching the codebase, I usually expand the context around the problem. This step is essentially research with the help of agents, either outside or within the codebase, depending on how much I want the agent to recognize existing patterns.

Typical questions I ask include:

  • What are common solutions to this problem?

  • What patterns are used in similar systems?

  • What trade-offs should I consider?

  • What implementation approaches might work here?

At this stage I’m not asking the agent to plan or write code yet. Instead, I’m gathering ideas, architectural options, potential pitfalls and possible implementation patterns.

The goal is to enter the codebase with a rough map in mind.

Step 3 — Plan the Implementation

Once the problem is clear and the context is prepared, I ask the agent to help produce an implementation plan. I do this for almost every task and I highly recommend it, even if it feels like overkill. In my experience, it drastically reduces the number of iterations needed after the initial implementation attempt.

When creating a plan, the most important rule here is:

Encourage the agent to ask questions.

You probably haven't thought of everything you should up front and you certainly didn't specify everything in your prompt. Have the agent discuss edge cases, simplify the approach, or describe assumptions. Keep the discussion going as the agent reads relevant files, identify affected areas of the codebase, propose structural changes, and outline the implementation steps.

In my experience, a good plan has two characteristics:

  1. Concrete enough to visualise the solution. You should be able to roughly imagine how the system will look after the change.

  2. Flexible enough to benefit from delegation. Agents are most useful when they can still adjust implementation details while working.

The result should feel like a clear but adaptable roadmap.

Step 4 — Implementation and Iteration

Now the agent begins implementing the plan, and what follows is highly iterative.

Even with a good plan, I expect several things to happen — imperfect structure, missed edge cases, minor architectural drift or suboptimal abstractions.

That’s normal. Instead of trying to get everything perfect in one prompt, I treat this phase as guided iteration. The loop usually looks like this — the agent implements a change, I briefly review the diff and check the behavior and request further refinements.

During this phase I typically focus on three things in this order.

  1. Behavior. Does the feature actually work how it should?

  2. Structure. Is the code organised in a way that makes sense? Is it going to be easy to maintain and change over time?

  3. Readability. Would another engineer (or agent) understand this code quickly?

I usually continue this process until I'm happy with the functionality and the code structure.

Step 5 — Full Review Pass

Once the feature works, I always run a final review pass. This step is important because agent-generated code can accumulate small issues during iteration.

There are multiple layers to it. First, I read through the code myself. Second, I usually ask the agent to do the same for me. Finally, I add additional tools on top, like CodeRabbit or Cursor Bugbot, to cover the change holistically, double check alignment with project rules, and find subtle bugs.

Step 6 — Ship 🚀

At this point the feature should be ready to go.


The important part is that the implementation has already gone through multiple structured passes — planning, iteration and review. Not every change requires every step in this workflow, but in my experience, most meaningful changes benefit from the full process.

The key idea is not the exact sequence — it's the process discipline.

Conclusion

To sum it up in one sentence:

Agentic software engineering is mostly about structured problem decomposition and process discipline.

The better the process, the more effective the agents become.

This is just a snapshot in time. Six months ago my workflow looked different, and six months from now it probably will again.

For now, most of my work still involves a single agent at a time. One direction I'm already exploring is parallel agent workflows — orchestrating multiple agents working on different parts of a problem simultaneously.

Either way, it’s a fascinating time to be building software.

If you enjoyed the article or have a question, feel free to reach out on Bluesky! 👋

Further Reading and References