Code & Cardboard by Karl Daniel

Managing the herd

One of the bigger shifts in being a good engineer lately, I'd say, is learning to work with several agents at once, along with the harnesses that surround them.

Early AI-assisted work meant one task, done a bit faster. Now agents handle the grunt work, this frees us to run multiple implementations in parallel. The challenge then becomes maintaining quality and coherence, whilst tracking the changes several agents bring and stopping them from polluting each other's work. Like a shepherd of sorts.

Now, I don't claim any secret sauce, nor do I think you need to sacrifice your context window upon the altar of the Industrial Markdown Complex. There are, however, a few simple tools and lessons that have made a real difference to how I work.

1. Herdr

No single tool has made more difference to me than Herdr. Yes, it's essentially fancy tmux, but its first-class support for agents makes it hard to recommend anything else.

Herdr organises your terminal into workspaces, tabs and panes, with a mouse-friendly feel somewhere between a terminal and a GUI. Unlike tmux, it automatically detects Claude Code, Codex and a dozen or so other agents, with a sidebar showing whether each is working, blocked on your input, or done. Instead of cycling through terminals to see who needs you, you glance at the sidebar and go where you're needed.

Agents keep running in the background even when you close the terminal, and you can reattach from anywhere, even over SSH. With the built-in skill, Claude can drive Herdr itself, spawning panes, reading their output and setting up layouts for whatever workflow you need.

There's also a healthy plugin ecosystem, ranging from notifications when an agent needs attention to tools that fan a task out across several agents.

Two plugins I've found really useful:

2. Worktrees

The other big change to my workflow is the religious use of worktrees. A worktree lets you check out the same repository several times, each in its own directory and on its own branch, so you can work on multiple branches in parallel.

For agents, that means each one gets its own copy of the repository and can't interfere with or pollute another's work. Two agents sharing a checkout will sooner or later overwrite each other's files or break each other's builds. Each change also ends up on its own branch, ready for its own PR.

Claude Code supports worktrees natively, and a single line in your global instructions (e.g. CLAUDE.md) makes it always create one. By default, each new worktree branches from your remote's main branch rather than whatever you happen to have checked out, so agents start from a clean, up-to-date tree. A few gotchas worth knowing:

3. Harnesses

The other change in how I approach development is more conceptual: accepting that, as engineers, we're moving up an abstraction chain that changes quickly and keeps shifting in what it can do. The harness, by which I mean the tools, context and workflows you wrap around a model, is how you keep up with it.

The latest models, for example, are far better at vision tasks than their predecessors, so an agent can now screenshot the page it just changed, compare it with the design and attach the evidence to the PR. Spotting changes like this and folding them into your harness makes a real difference to how fast you can move, so it's worth revisiting your setup whenever a new model lands. Building a harness can feel a bit administrative at first, but a good one pays back the time you put in, and then some.

Connecting MCP servers or CLIs for tools like Figma, Atlassian or Datadog is one of the easiest wins. An agent picking up a bug can read the Jira ticket, pull the Figma frame and check Datadog for errors before it writes a line of code. That's context you'd otherwise have to paste in by hand, and it's usually more complete than anything you'd have pasted anyway.

4. Guardrails

Whilst agents are non-deterministic, much like the humans they're working alongside, the guardrails around them don't have to be. Unit tests, end-to-end tests and static analysis give the same verdict every time, which makes them a far more reliable way to enforce quality than trusting any one agent, or person, to get it right.

One tool I'd particularly recommend is Fallow, a fast static analyser for TypeScript and JavaScript that catches the kind of mess agents are prone to leaving behind, like dead code, duplication and creeping complexity. Pair it with something like OSV-Scanner to flag dependencies with known vulnerabilities, and you've covered two of the more common ways agent-written code degrades a codebase over time.

All of these checks also need to be fast, because a suite that takes the best part of an hour soon becomes the bottleneck when several agents are shipping changes at once. An agent can only correct course as fast as it gets feedback. Wire them into hooks and CI and they put constant pressure on the agent to get things right, whilst giving reviewers confidence that whatever reaches them has already been checked.

5. Reviewing Intent & Shape

This is probably the most controversial change to accept. As we produce more code, scrutinising every line becomes unfeasible. Yet we still need a human steering the solution over the long run. Models write code very well, but often miss how a solution fits the problem it's meant to solve.

I suspect that's partly down to how they're trained. Much of a model's reinforcement learning comes from tasks with objectively right or wrong answers, where the tests either pass or they don't. That result is fed back through the model via backpropagation, adjusting its weights to make whatever earned the right answer more likely next time. Architectural decisions offer no such clean signal, since whether a design was right might not be clear for months.

That's why looking after the architecture is still very much the human's job, whereas scrutinising individual lines adds little, especially when the next person to read the code is likely to be another agent. Agents should still produce elegant, secure code, but at the level of syntax the implementation matters less than its shape and intent and how they fit the overall solution.

In the PR itself, that means giving the reviewer the intent and a clear description of the change, so they can judge whether the solution has the right shape for the problem and for the system around it, rather than reading it line by line. Attaching test results and screenshots helps too, because the reviewer can see the change working for themselves.

There are still times to read closely, security boundaries and data migrations for a start, but I think we have to accept that newer models like Claude Opus 5.5 and Claude Fable 5.1 are arguably better at producing code than any human ever was. There's nothing to be ashamed of in that when models can now apparently solve the Navier-Stokes Millennium Prize problem (though not without a fair bit of controversy over who deserves the credit). Much like a calculator, they surpass human ability within their domain. We can't keep up by reading harder, so we have to adapt our processes rather than pretend it's still 2010 in the year 2026.

Where this leaves us

Our role as engineers, in so far as it was ever about writing code, is shifting towards orchestrating it. The job at this new layer of the abstraction is mostly keeping the agents unblocked and pointed at a coherent, reliable solution.

Which in essence is what an engineer was always measured against, our ability to produce a working solution. Not code, in fact the less code a solution needs, the better. It just so happens that for the past couple of decades, writing a lot of code and the solution have often been inextricably linked. Undoing that mental link does take time.

The tools here I'm sure will keep changing, probably faster than this post ages, but the habits underneath them, I suspect, will hold for a while yet.

#agents #ai #development #guide #tips