When I started Ceres, the plan had seven specialist agents. A soil agent, a weather agent, a pest agent, and so on, each an expert, all feeding a daily garden briefing. It sounded great in the spec. A week in, I tore half of it out.

Agents are the hype cycle right now, so I want to be honest about what I learned building one for real, in my own garden, with nobody to impress. Most of the lessons are about restraint. The rest are about what happens after you stop being clever and the thing has to run every morning whether or not you’re watching.

Complexity Has To Earn Its Place

The seven-agent plan was solving a problem I didn’t have yet. I was architecting for a level of sophistication the actual task didn’t need. A lot of what I imagined as separate reasoning agents turned out to be plain data lookups and one decent prompt. The soil data doesn’t need an agent to reason about it if the answer is a threshold check.

The rule I landed on: an agent earns its place when the task genuinely requires independent reasoning and can’t be a function call or a single prompt. If you can write the logic as an if statement, it’s not an agent, it’s an if statement wearing a costume.

Tearing Half Of It Out Was The Progress

The week I cut the schema and half the agents felt like going backwards. It was the opposite. Every agent I removed was one less thing that could fail silently, one less prompt to maintain, one less handoff where context got dropped. The system got more capable by getting simpler, which is deeply annoying and almost always true.

This is the part the hype posts skip. Adding agents feels like building. Removing them is usually where the actual product shows up.

Where Multi-Agent Actually Pays Off

I’m not anti-agent. Ceres does still use multiple agents, because the garden briefing really is several different kinds of thinking. Diagnosing a plant from a photo is a different task than deciding watering priority from soil and weather. Those don’t collapse into one prompt cleanly, so keeping them separate is worth the complexity.

The test is whether the tasks are genuinely different kinds of reasoning that would fight each other in a single prompt. When they are, agents help. When they’re the same task chopped into pieces for the aesthetic of it, they just add failure points.

The Run Doesn’t End When The Answer Does

The agents I kept still broke, just not the way I expected. They rarely gave me a wrong answer. They gave me a good answer and then quietly assumed somebody acted on it.

Ceres tells me when something is ready to pull, “The garlic is ready, get it out this week.” Correct, useful, exactly what I built it for. Then a few briefings later it stops mentioning the garlic entirely, as if the job were closed. Nobody ever told it the garlic came out of the ground. It inferred that from the passage of time, which is a generous way of saying it guessed.

Sometimes I did harvest it. Sometimes half a bed is still sitting out there going soft. The briefing has no idea which, and neither does the plant catalog.

That’s not an agent problem. The reasoning was right both times. It’s a state problem, and a specific one: the run doesn’t finish when the model produces text. It finishes when the garlic is actually in the kitchen, and that might be a week later, or never.

The fix is obvious enough. A harvested flag and a date on each plant in the catalog, so a bed doesn’t drop out of the briefing until a human says it’s done.

The fix is cheap. What it exposed isn’t. I had built a system with no way to hold a step open and wait for the world to catch up. Every step assumed it was complete the moment the response came back. That assumption is fine for a chat reply and completely wrong for anything that spans a season.

Every multi-agent system I’ve looked at eventually grows this same layer. Somebody writes the retry logic. Somebody writes the part that remembers where a long-running job left off. Somebody writes the field that separates genuinely done from assumed done. It gets rebuilt per project, usually badly, by people who wanted to work on the agent and not on the plumbing.

What Belongs To The Runtime

The line I’d draw now is that the agent owns the reasoning and the runtime owns everything about the run surviving. Where it is. Which steps are actually complete rather than assumed complete. What to retry and how many times. What happens when the next step is three weeks out and depends on a person doing something in a garden.

When that split isn’t clear, every agent carries a little smear of orchestration logic, and the state gets less trustworthy with each one you add. That’s the real cost of the seven-agent plan I cut. Not seven prompts. Twenty-one edges between them, each one a place where something could get quietly marked done that wasn’t.

How I’d Sequence It On A Roadmap

If I were building an agentic feature on a team, I would ship the single-prompt version first. Get it working, get it measured, feel where it actually breaks. Only split into agents at the specific seams where one prompt visibly can’t hold two jobs at once.

But I’d pick the execution model before the second agent, not after. Splitting is the exact moment you inherit the state problem, and bolting durability onto something that already assumes every step finishes the instant it returns is a rewrite, not a patch. Start simple, earn the complexity, and let the failures tell you where the seams are instead of guessing up front like I did with Ceres. Just don’t be surprised when the seams turn out to be the hard part.

The multi-agent architecture should be the thing you grow into because the product demanded it, not the thing you start with because it’s on every conference slide this year. And when you do grow into it, most of the work won’t be the agents. It’ll be everything holding them together.