← All posts
·6 min read

Bounded Context: Why Your Agents Keep Disagreeing About What a "Customer" Is

Domain-Driven DesignSystem BoundariesAI Architecture

The bug report usually reads something like: "the support agent says the refund was issued, but billing shows it pending." Nobody wrote broken code. Two agents each have a completely correct, internally consistent idea of what "the order" is — they just aren't the same idea, and nothing in the system ever declared that out loud. Eric Evans named this problem in Domain-Driven Design back in 2003, long before anyone was building multi-agent systems, and the fix he proposed — the bounded context — turns out to be exactly the tool multi-agent AI architectures are missing.

One word, three models, on purpose

A bounded context is a boundary inside which a term has exactly one meaning. Outside it, the same term is allowed to mean something else entirely, deliberately, without that being a bug.

Booking context"customer" means a reservationTripSeatFareSupport context"customer" means a ticket threadTicketSLAAgentBilling context"customer" means an account ledgerInvoiceLedgerRefundACLACLACLSame word, three different models — the boundary is a deliberate translation, not an accident

A booking agent's "customer" is a reservation with seats and a fare. A support agent's "customer" is a ticket thread with an SLA clock running. A billing agent's "customer" is a row in a ledger with a balance. Evans's insight was that trying to unify these into one shared "Customer" object isn't rigor — it's the mistake. You end up with a god-object that every team is afraid to change, because it's carrying fields that only make sense to one of its three audiences, and a change for billing's sake quietly breaks a field support depends on.

The anti-corruption layer is where the discipline actually lives

Bounded contexts aren't allowed to just ignore each other — they still need to exchange information, refunds still need to reference bookings. The mechanism Evans specifies for that crossing is an anti-corruption layer: a deliberate translation step at the boundary that converts one context's model into another's, instead of letting one context's internal shape leak into the next.

In an agent system, this is the difference between a billing agent calling a function that returns the booking service's raw internal object — coupling billing to booking's schema forever, so booking can never refactor without a cross-team migration — and a billing agent calling a small, owned translation that maps "reservation" onto exactly the three fields billing actually needs. The ACL is more code up front. It's also the only thing standing between "these two agents can evolve independently" and "these two agents are one system that happens to be deployed twice."

Why multi-agent systems need this more than microservices did

Microservices got bounded contexts mostly right by accident, because network boundaries forced a translation layer to exist whether anyone thought about DDD or not — you couldn't share a database table across a REST call even if you wanted to. Agent systems don't have that forcing function. It's trivially easy to hand a full JSON object from one agent's context window straight into another's prompt, no translation, no boundary, no anti-corruption layer — and it works fine right up until the two agents' implicit models of "order" or "customer" or "account" drift apart, which they always eventually do, because they're being maintained by different people solving different problems.

The fix isn't a shared schema everyone agrees to freeze forever — that's the god-object problem again, just in prompt form. It's naming the contexts on purpose, writing down which agent owns which model, and putting a small, explicit translation at every place two agents' contexts touch. That translation is usually a page of code. Skipping it is usually a quarter of confused incident reports about why the numbers don't match.

The boundary was always going to exist — the only choice is whether you drew it

Every system with more than one team or more than one agent already has bounded contexts, whether or not anyone named them. The booking logic already means something subtly different to the people who built it than to the people who built billing — that gap doesn't close by wishing it away or by forcing one canonical model on everyone. It closes by admitting the gap exists, drawing an honest line around each model, and putting a translator at every crossing. The alternative isn't "no boundaries." It's boundaries nobody chose, discovered later, in production, by whoever's on call.