↓ Skip to main content

Two Developers, Many Agents

AI - This article is part of a series.
Part 6: This Article

Introduction
#

The last post ended at the start of the Engestofte project, with a promise to explain how my partner and I would split the work with our agents. The class after the project start was about exactly that: collaborative agentic development, where several people and several agents work on the same system. The task for the blog was to share what we have learned from working with agents and with each other.

The project has been running for two weeks now, so there is something to share. Most of it is about how the plan changed once we started building, and what made it possible to work in parallel without getting in each other’s way.


The Plan
#

Before any code, we sat down and made a thorough plan together. We chose the stack (a Spring Boot API, a Next.js frontend and a Payload CMS for the site content), decided to keep them in three repositories, and set up a fourth repo just for docs. The docs repo holds the glossary, the decision records and the plan. It is the single source of truth for what both of us need to know, and each code repo only gets the context it needs.

Then we ran one big grill-with-docs together. It defined the overall plan around feature-driven development and low coupling, meaning as few dependencies between the parts as possible. The point was that two people should be able to work at the same time without waiting for each other.

After that, every feature got its own grilling, spec and tickets, using Matt Pocock’s workflow from the last post.

  1. A plan together

    14/9

    The stack, the repositories and the order of the work, written down as a plan.
  2. A docs repo

    14/9

    Shared context lives here, and each code repo gets a copy of what it needs.
  3. One joint grill

    14/9

    A grill-with-docs for the whole system, built around features and low coupling.
  4. A grill per feature

    From 15/9

    The first feature specs are written the day after.
  5. Parallel implementation

    From 15/9

    Two developers and many agents, on separate branches.
  6. A review per spec

    Later

    On top of the review for each ticket.

The Plan That Didn’t Survive
#

The written plan split the work into two tracks by repository. One of us would take the API, and the other the frontend and the CMS.

That lasted about as long as it took to start. In practice, we both build features end to end, sometimes in the same repo on separate branches. If a frontend feature needs a change to the API or the CMS, the person building it makes that change too. That works as long as we keep to the coding standards and keep communicating.

Breaking changes are handled the simple way. When one of us is implementing something that breaks a repo and merging it to dev, the other keeps hands off that repo until it is done. The design always leaves other work open, so an agent never sits idle.

When we work at different times, we have sometimes continued each other’s features. That is possible because the workflow doesn’t depend on any one agent. The tickets carry the context, so any agent from any provider can pick up where the last one left off.


Three Ideas That Made It Work
#

Looking back at the first two weeks, we agree that it comes down to three ideas:

  1. Low coupling enables parallel work. When the parts don’t depend on each other, two people can build at the same time.
  2. Isolated context makes agents efficient. An agent that only gets the docs and tickets for its own piece has less to read and fewer gaps to fill in on its own.
  3. A shared understanding of the design lets us trust each other. We put a lot into building the design together, so we both know why it is the way it is. In Naur’s terms, it is a theory we both hold. That lets one of us grill a new feature alone, as long as it fits the plan and that understanding. We are both co-owners of the project as a whole, and each of us owns the features we build.

They came out of the planning and the grilling we did together, so they belong to both of us.

The third idea is also why communication matters so much. When we both work from the same understanding, a breaking change is what can catch the other person out, so it has to be shared right away. That is just good practice, but here it rests on the understanding we built together.

So far we have run agents from several providers in parallel with almost no merge conflicts, and we have written close to 200 tickets. How the providers compare is a post of its own.


Bigger Models, Fewer Tokens
#

We also learned something about model size and thinking level, which is how long a model reasons before it answers. For grilling and design, we use large models like Opus on high thinking, because the decisions are made there.

Implementing is different. Medium models like Sonnet on high thinking made mistakes when they implemented. Large models on medium thinking use more tokens per prompt, but fewer tokens overall. For my stance on tokens, that means the number to watch is what a whole ticket costs, not a single prompt.


Reading the Code
#

In the last post, I wrote that I want to read and own the code…

- I haven’t read all of it.

The agents write code faster than one person can read it, and with two of us building in three repos, there is far more of it than I can keep up with. What I do read closely are the specs and the tickets, because they hold the decisions. I also read the review findings, because they show where the code didn’t match those decisions, and I check how each one was handled. To make sure nothing slips through between the tickets, we have also started running a code-review against the whole spec once all its tickets are done.

That changed what owning the code means to me on a project this size. I can’t hold every line, but I can hold the design and the reasons behind it, which is the part Naur calls the theory. The specs are still the way back to it, as I wrote last week. Whether that is enough, I will find out the first time I have to change a part I never read.


Compared to the Class
#

The class material describes the ticket as a contract. A good agent ticket says what to build, and also which files the agent may touch, what it must not change, how the work is verified and when it has to stop and ask. The material separates soft guardrails, which the agent is only told to follow, from hard ones that are enforced: code owners who must approve changes to sensitive files, branch protection, and CI that runs the tests and architecture checks.

Our guardrails are mostly the soft kind. The instruction files, the coding standards and the reviews tell the agents what to do, but nothing stops them. The closest we have to a hard guardrail is a set of architecture tests in the API that check the package boundaries, and no CI runs them (yet). Our tickets don’t list allowed files either. Low coupling and talking to each other do most of that job.

That works for two people who talk all the time. In a bigger team, or with people who don’t know each other’s work, I think the hard guardrails would be needed.

It wasn’t easy. It relies on what the earlier semesters taught us about design principles, architecture and working together, and most of all on good communication between the two of us.


Conclusion
#

On Tuesday we take the bus to Engestofte Gods, where we get to show the prototype to the people who will use it. The next post is about that trip, and about what we learn when the feedback comes from a real customer instead of our teachers.

- Daniel

AI - This article is part of a series.
Part 6: This Article