The Agent Industry Is Rebuilding SOA, Mistakes Included
Strip the labels off the agentic architecture diagrams I'm shown this year and you find service-oriented architecture, circa 2006. The ideas are good ones. But the industry is repeating the two mistakes that gave SOA its
Strip the labels off the agentic architecture diagrams I'm shown this year and you find service-oriented architecture, circa 2006. The ideas are good ones. But the industry is repeating the two mistakes that gave SOA its bad name, and I can see both in the agent designs I review with companies.
I didn't watch SOA from the sidelines. At Microsoft I worked on the standards, from XML 1.0 and XML Schema through SOAP and the WS-* specs for security and reliable messaging, and I built them into products. The core ideas held up. A service owns a business capability and its data. It publishes a contract. Other services compose it into a larger process. Microsoft's WCF even taught it as the ABC: address, binding, contract. Swap "service" for "agent" and "contract" for "tool definition," and you have most of what's on whiteboards today. I've written about the contract side already, in MCP Is the WSDL Moment for Agents. The contracts were never the real problem. What went wrong in SOA happened between the boxes.
Mistake one: the smart pipe
SOA's integration layer was the enterprise service bus. It started as a way to route messages. Then it grew into the place where routing rules, data transformations and, eventually, business logic lived. One team owned it. Every change to how two services talked became a ticket in that team's queue, and the bus became the part of the system nobody could change quickly. The microservices movement answered with a phrase James Lewis and Martin Fowler made popular in 2014: smart endpoints and dumb pipes.
The agent version is the supervisor agent that sits in the middle of every request. It reads the input, decides which specialist agent gets it and rewrites the message on the way through. Over time its prompt fills with rules. Refunds over a certain amount go to finance. This customer tier gets a different tone. Never call the pricing agent during a month-end close. That prompt has become the bus. Change one sentence in it and every agent behind it behaves differently, and nothing in the system records why.
Keep the router thin. Business rules belong in the agents that own those decisions, where they can be tested. The plumbing between agents (delivery, retries, identity) belongs in a runtime that has no opinions about your business at all.
The gateway is the new bus. The same pull is showing up in infrastructure. Agent gateways sit in front of every model call, tool call and agent-to-agent call, and each release adds more rules: authorization policies, prompt guards, rate limits, message transformations, and now "semantic" governance policies that judge what a request means. Each feature is reasonable on its own. Together they recreate the position the ESB held: one box in the middle of every request, owned by one team, holding rules nobody else can change quickly.
I'm not a fan, for three reasons. First, the rules migrate. A gateway that can transform messages and judge content will end up holding business policy, because it's the easiest place to put it. Second, it's another synchronous hop. A gateway governs a call, but it can't make one durable. When an agent restarts mid-task, the gateway has nothing to resume. Third, it puts security at the perimeter, when it belongs with the workload. Identity and access control should travel with each agent and be checked on every call, wherever that call goes, not only on the calls that happen to pass through the middle. It's the same conclusion I reached about MCP: identity, retries and crash recovery belong in the runtime, not the protocol, and not in a box in the middle either.
There's a fair case for a thin gateway at the edge, for things like model provider keys, token budgets and failover. Keep it to that. Rules about who may call what belong in the runtime, enforced next to each agent. Rules about what the business does belong in the agent itself.
Mistake two: the synchronous chain
SOA projects loved request/response. Service A called B, which called C, and each one waited. The availability of the chain was roughly the product of its links, so three services at 99.9% gave you about 99.7%. The slowest call set the response time for everyone.
Agents make this worse in two ways. First, each hop now takes seconds or minutes of model calls instead of milliseconds. Second, each waiting agent is holding a context window, a half-finished plan and sometimes a reservation on something real. When the third agent's pod is rescheduled mid-call, the first two wait for a reply that never comes. When they time out and retry, the third agent may already have done the work once.
Asynchronous messaging and durable workflows were the fix then, and they're the fix now. Today they can be the same thing. When a workflow hands work to an agent, that hand-off is itself a durable message: the runtime records it, delivers it and records the result, so a restart resumes the run instead of starting a second one. In Dapr Workflow, calling an agent as an activity or child workflow, or waiting on an external event, gives you the hand-off and the run in one runtime, with no separate bus between the agents. Pub/sub still has its place for events arriving from outside the run. The pattern I'd start most teams on is a parent workflow calling specialist agents in a fixed order: Four Durable Agentic Patterns.
That might sound like the supervisor I just warned against. It is not. The supervisor accumulates policy in a prompt nobody can test. The workflow owns the process, meaning the sequence, the branches and the durability. It does this in deterministic code you can test, version and review, with every step recorded. The domain decisions stay in the agents that own them.
That is what good multi-agent orchestration looks like: a workflow, not a supervisor prompt.
"But don't LLMs change everything?"
The strongest counter-argument is real, and it's getting stronger. Deciding which agent should handle an ambiguous request takes judgment, so the router can't be dumb. Models are good at that judgment now, and they are becoming fast and cheap enough to use it everywhere.
Look at where that's heading. A new class of structured decision models, with TypeSafe's Jev the first I've seen (and of course OpenAI reply), returns a typed decision with a calibrated confidence score in milliseconds instead of generating prose. TypeSafe calls these "smart if-statements," and that is the important part. The judgment isn't moving into a smarter pipe. It's becoming a function call inside the workflow: unstructured input in, a typed choice and a confidence score out, and ordinary code deciding what to do with it. A high-confidence route goes to the agent, a low-confidence one goes to a person, and every decision is a recorded step.
That's smart endpoints and dumb pipes again, with a much smarter endpoint. The judgment sits in a typed call you can test and score. Policy, like "refunds over a certain amount go to finance," stays in the agent that owns it. Delivery, retries and durability belong to the runtime. And when decisions are this cheap, a single run will make thousands of them, so recording each one matters more. After a restart, the run should resume with the choice already made, not ask the model again and perhaps get a different answer.
The things that broke SOA integrations haven't gone anywhere. The network partition (split brain), the restarted process (machine craps out) and the message delivered twice all happen between agents, and none of them care how clever the decision was. Smarter decisions are a stronger argument for a dumber pipe, because now you have better places to put the logic.
Two checks for your next design review
Before your next agentic architecture review, check two things:
Does any business rule live in the router's prompt, or in your gateway's policies? If so, move it into the agent that owns that decision.
Does any agent wait synchronously on another for longer than you'd wait for a web page to load? If so, make that call a durable workflow step instead.
And if you're unsure how much autonomy a step needs, start with the least that does the job. That's the core of Diagrid's agents vs workflows vs chains explainer.
We spent a decade unlearning the enterprise service bus. Let's not spend the next one unlearning the supervisor agent, or the agent gateway full of business logic.
Originally published on Medium.
Originally published by Dev.to AI. Aggregated on AIWithGhost for educational purposes — full credit and traffic to the original publisher.