writing /

The Fleet — How to Actually Use AI as a Software Engineer

In my post on building agents with Bedrock AgentCore, the whole point was giving a model hands — tools it can call and a loop that decides when to call them. This post is about the other side of that idea: giving yourself a fleet of those loops.

Most engineers use AI the way they'd use a smarter autocomplete. One chat window. One task at a time. You type, you wait, you watch it type back, you copy the result. That's a fine place to start, and it's also where most people stop. Heavy users work differently — not because they type faster, but because they stop babysitting a single conversation and start orchestrating many.

Here's the mental shift: a chat is something you attend; a fleet is something you dispatch. The rest of this post is a ladder from one to the other, in four levels, using Claude Code as the running example. Each level is worth adopting on its own.

Level 1 — Loops: stop re-typing the same prompt

The first habit that separates heavy users is that they almost never do the same thing twice by hand. If a task is worth doing on an interval — poll a deploy, keep tests green, watch a PR for review comments — it should run on a loop, not on your attention.

In Claude Code, that's /loop:

/loop 5m /run-tests

That runs your /run-tests command every five minutes. Drop the interval and the model self-paces — it decides when to check back based on what it's waiting for:

/loop keep checking the PR for new review comments and address them

The point isn't the syntax. The point is a change in posture: work that repeats should not consume you. A loop babysitting a CI run frees you to think about the next thing instead of alt-tabbing to a dashboard every few minutes. The first time you set a loop running and walk away, the "one chat window" model starts to feel very small.

A good rule: any sentence you find yourself starting with "every few minutes, check…" is a loop.

Level 2 — Workflows: when a script beats a conversation

A loop repeats one task. A workflow orchestrates many, deterministically. The distinction matters: a conversation is model-driven — the model decides what to do next — while a workflow is code-driven. You write the control flow (the fan-out, the loop, the verify step) and the model fills in the intelligent parts.

The classic shape is find → verify → synthesize. Say you want to review a branch across several dimensions — correctness, security, performance — and you don't want a single pass that half-covers each. A workflow fans out one agent per dimension, then spawns a skeptic to adversarially verify each finding before it reaches you:

review each changed file for [correctness, security, perf]
  → for every finding, spawn a verifier that tries to REFUTE it
  → keep only findings that survive

Why bother instead of just asking? Three reasons:

  1. Determinism — the same structure runs the same way every time. No "it forgot to check the security angle."
  2. Parallelism — the dimensions run concurrently, so wall-clock time is the slowest single chain, not the sum.
  3. Adversarial rigor — a separate agent whose only job is to disprove a finding kills the plausible-but-wrong results that a single optimistic pass waves through.

You reach for a workflow when the task has structure you can name — a set of files to sweep, a pipeline of stages, a thing that must be checked N independent ways. When the task is exploratory and you don't know the shape yet, stay in a conversation. Heavy users move fluidly between the two: scout in a chat to discover the work-list, then hand the list to a workflow to grind through it.

Level 3 — Subagents: parallel work, isolated context

Inside a single session, you don't have to do everything in your own context window. You can dispatch subagents — independent Claude instances that go off, do a focused job, and return only the conclusion.

This is the antidote to context bloat. When you need to answer "where is X handled across these forty files?", you don't want forty files dumped into your working memory. You want an agent to sweep them and hand back the two-line answer:

Explore agent: find every place we validate auth tokens; return file:line + a one-line note each

The key techniques:

  • Fan out for independent work. If you have three unrelated tasks — update the docs, fix a flaky test, add a config flag — dispatch three agents in a single message so they run concurrently instead of one after another.
  • Use the right agent for the job. A read-only Explore agent for searching, a Plan agent for designing an approach, a general agent for multi-step execution. Specialized agents keep each job's context clean.
  • Keep the conclusion, not the file dump. The whole win is that the subagent reads broadly and you keep only what matters. Your context stays lean; theirs absorbs the noise.

The mental model: you are less the person writing every line and more the tech lead handing out well-scoped tickets and integrating what comes back.

Level 4 — Multiple sessions and tmux: run the fleet in parallel

The final level is spatial. One session, however well-orchestrated, is still one throat to choke. Heavy users run several Claude Code sessions at once, each on its own slice of the work, laid out where they can watch them all.

That's what tmux is for. Split your terminal into panes and put a session in each:

# a 2x2 grid of independent Claude sessions
tmux new-session -d -s fleet
tmux split-window -h
tmux split-window -v
tmux select-pane -t 0
tmux split-window -v
tmux attach -t fleet

Now you have four panes. One session is refactoring a module, another is writing tests for it, a third is drafting a migration, a fourth is on a /loop watching CI. You glance across the grid the way an ops engineer watches a wall of monitors — dipping into whichever pane needs a decision, letting the rest run.

There's one trap to avoid: parallel sessions editing the same files will collide. The fix is isolation. Give each parallel line of work its own git worktree — a separate checkout of the same repo sharing one history:

git worktree add ../blog-feature-a feature-a
git worktree add ../blog-feature-b feature-b

Point one session at each worktree and they can hammer away simultaneously without stepping on each other. Merge when each is done. Some agent tools will even spin up a throwaway worktree per agent for you when parallel edits would otherwise conflict — but knowing the primitive underneath it is what lets you scale past a handful of sessions.

A day in the fleet

Put the four levels together and an ordinary morning looks like this:

  • Pane 1 is running a review workflow on last night's branch — fan out, verify, and by the time I've had coffee it's handed me three confirmed bugs and discarded eleven false alarms.
  • Pane 2 is a session in a worktree, implementing the fix for the first bug while I read the writeup for the second.
  • Pane 3 is a /loop babysitting the deploy pipeline; it pings me only if something turns red.
  • Pane 4 is where I'm actually thinking — sketching the next feature with a Plan agent, dispatching Explore agents to answer "how do we do X today?" without polluting my context.

I'm not typing faster than anyone else. I'm just not the bottleneck for four things at once.

Where to start

You don't get here by flipping a switch. You get here by climbing one rung at a time:

  1. This week: replace one repetitive check with a /loop. Feel what it's like to walk away from it.
  2. Next: the first time you catch yourself doing the same review by hand twice, write it as a workflow.
  3. Then: stop reading forty files yourself — dispatch an Explore agent and keep the answer.
  4. Finally: open a second session in a worktree and let two things happen at once.

The autocomplete model asks "what can this AI do for my current line of code?" The fleet model asks "what are the six things that could be running right now, and which one actually needs me?" That second question is the whole job. Learn to ask it and the tools stop being assistants — they become the team you lead.