Skip to content
Founder & CTO

Why Domain-Driven Design Is the Missing Blueprint for AI Agent Architecture

Rohit Sinha
Rohit Sinha

  The race to build AI agents is on. Enterprises are standing up autonomous     systems faster than they can think through what those systems should   actually do. The result is a familiar pattern: overlapping responsibilities,   unclear ownership, agents that hallucinate at the seams where systems hand   off, and architectures that collapse under the weight of their own complexity.

 

We've been here before — not with AI, but with microservices.

A decade ago, teams discovered that decomposing a monolith into services wasn't a technical problem. It was a design problem. You couldn't just split a codebase arbitrarily and call it distributed architecture. You needed principled boundaries. You needed Domain-Driven Design.

 

I believe the same is true today for AI agents. And I've found that the most powerful framework we have for deciding what agents to build and where their responsibilities begin and end is one we already know: DDD.

 


 

The Core Problem: Agent Sprawl

Ask most engineering teams building agentic systems how they decided on their agent architecture and you'll get some version of: "We knew we needed a research agent, so we built one. Then we needed something to take actions, so we added another. Then things got complicated."

This is bottom-up, feature-driven agent design. It works until it doesn't — which is usually the moment you need to scale, debug, or hand it to someone else.

The missing ingredient is a top-down, domain-informed view of where intelligence should live and why.

 


 

DDD Was Built for This Problem

Domain-Driven Design, introduced by Eric Evans in 2003, was designed to manage complexity in large software systems by aligning software structure with business reality. Its central concepts — Bounded Contexts, Ubiquitous Language, Domain Events, and Context Maps — were built to answer one question: how do you carve up a complex system into parts with clear ownership and minimal coupling?

That is exactly the question we face with AI agents. The translation is more natural than you might expect.

 

 
   The Four DDD Concepts That Map to Agent Design
BOUNDED CONTEXT Where the model is consistent → Agent Boundary DOMAIN EVENTS What happened — past tense → Inter-Agent Messages UBIQ. LANGUAGE Shared vocabulary per domain → System Prompts CONTEXT MAP How contexts relate → Orchestration Design

 

Bounded Contexts → Agent Boundaries

The most important concept in DDD is the Bounded Context: a boundary within which a particular model is internally consistent and meaningful. Inside the boundary, terms have precise definitions. Outside it, the same word might mean something different.

In agent design, a Bounded Context maps almost directly to an agent boundary.

Consider an e-commerce platform. Order Management, Inventory, Payments, Shipping, and Customer are natural Bounded Contexts — each with its own data, rules, and language. Each becomes a natural agent. The Order Management Agent doesn't need to understand how Payments works internally; it only needs to know what signals to send and receive.

This gives you something invaluable: agents that can fail and recover in isolation. When your Payments Agent hits an edge case, it doesn't take down your entire system. The boundary contains the blast radius.

 

 
   E-Commerce Platform — Bounded Contexts as Agent Boundaries
ORDER MGT orders, line items cart, fulfillment Order Agent INVENTORY SKU, stock levels reorder points Inventory Agent PAYMENTS transactions, auth refunds, ledger Payments Agent SHIPPING carrier, tracking manifests, labels Shipping Agent CUSTOMER profile prefs Cust. Agent Each context owns its own vocabulary, data, and rules — and fails in isolation

 

Subdomain Classification → Where to Invest in AI

DDD distinguishes between three types of subdomains, and this distinction is one of the most practically useful ideas for AI systems:

Core Domains are your competitive differentiators — the things that make your business unique. This is where you invest the most engineering effort in DDD, and it's where AI adds the most transformative value. A logistics company's route optimization, a fintech's credit decisioning model, a healthcare company's clinical summarization engine — these are Core Domain agents worth investing heavily in.

Supporting Domains are necessary but not differentiating. They support the core but aren't where the magic happens. A simpler, well-constrained agent (or even a rules-based system) is often sufficient here.

Generic Domains are commodity — things like email, calendar, document generation. Wrap these in thin agent shells or call APIs directly. Don't build elaborate reasoning systems for things that don't create competitive advantage.

This taxonomy prevents one of the most expensive mistakes in AI development: building sophisticated agents for things that don't matter, and under-investing in the ones that do.

 

 
   Subdomain Classification — AI Investment Allocation
CORE DOMAIN Your competitive differentiator — invest deeply in AI here Sophisticated Agent Fine-tuned · Deep tools · Heavy investment SUPPORTING DOMAIN Necessary but not differentiating — lean agent is enough Lean Agent Constrained · Defined I/O · Moderate investment GENERIC DOMAIN Commodity — use a tool or API, don't build an agent Tool Wrapper / API No reasoning needed · Minimal investment

 

Domain Events → The Nervous System Between Agents

In DDD, Bounded Contexts communicate through Domain Events — immutable records of things that happened, expressed in past tense: OrderPlaced, PaymentFailed, InventoryDepleted.

This is the right model for inter-agent communication for three reasons.

First, it preserves loose coupling. Agents don't call each other directly. They emit events and react to events. The Order Management Agent doesn't know or care how the Payments Agent processes a payment — it only knows that PaymentConfirmed arrived, and it can proceed.

Second, it creates an audit trail. Every event is a record. When something goes wrong in a multi-agent system — and something always will — you can trace the exact sequence of events that led to the failure. This makes debugging agentic systems dramatically less painful.

Third, it enables asynchronous operation. Not every agent needs to respond in real time. Some can batch events and process them on their own schedule. The event-based model accommodates this naturally.

 

 
   Domain Events as Inter-Agent Communication
Order Agent Payments Agent Fulfillment Agent OrderPlaced event emitted PaymentConfirmed event emitted Agents never call each other directly — they emit events and react to events

 

Ubiquitous Language → System Prompts and Schemas

Every DDD Bounded Context has a Ubiquitous Language: a precise, shared vocabulary used consistently by domain experts, engineers, and the codebase itself. The same word means the same thing everywhere within the boundary — and possibly something different outside it.

For AI agents, this maps directly to system prompt design and schema definition.

An Inventory Agent should think and speak in terms of SKUs, reorder points, safety stock, and lead times — not generic terms like "product" or "quantity." This precision isn't just good engineering practice; it materially reduces ambiguity in the agent's reasoning and lowers the likelihood of hallucinations at the conceptual seams.

When you define your agent's input and output schemas, you are publishing its Ubiquitous Language. Do this deliberately.

 

 
  Ubiquitous Language — Inventory Agent Vocabulary
✗ GENERIC VOCABULARY Vague terms that invite misinterpretation product quantity low stock delay buffer warehouse Agents fill vocabulary gaps with assumptions → hallucinations ✓ UBIQUITOUS LANGUAGE Precise domain terms used consistently SKU stock level reorder point lead time safety stock fulfillment hub Precision reduces ambiguity and lowers hallucination risk

 

Context Maps → Orchestration Architecture

DDD's Context Map documents how Bounded Contexts relate to each other. The patterns it defines translate directly into orchestration design:

The Customer-Supplier pattern, where one context produces for another, maps to a linear pipeline: a Research Agent produces a structured brief that a Writing Agent consumes.

The Anti-Corruption Layer pattern, where a translator sits between two contexts with incompatible models, maps to an adapter agent that normalizes outputs from a legacy system before passing them to a modern agent.

The Published Language pattern, where contexts agree on a shared event format, maps to a common schema that all agents in your ecosystem adhere to — the foundation of a composable agent platform.

Drawing your Context Map before writing a single line of agent code is one of the highest-leverage activities you can undertake.

 

 
  Context Map Patterns → Agent Orchestration
CUSTOMER-SUPPLIER Research Writing Upstream produces, downstream consumes ANTI-CORRUPTION LAYER Legacy Adapter Modern Adapter agent normalizes incompatible outputs PUBLISHED LANGUAGE Shared Schema Common event format all agents agree on

 

The Granularity Question

The most common question I get when walking teams through this framework is: how fine-grained should agents be?

Here is a practical rule of thumb: Bounded Context = one agent by default. Then ask:

  • Is this agent trying to do two conceptually distinct things? If yes, split by Aggregate.
  • Is this agent so narrow it has no meaningful reasoning to do? If yes, demote it to a Tool — a function the orchestrator calls, not a reasoning entity.

A tool is deterministic and stateless. An agent reasons, decides, and can fail in interesting ways. The distinction matters because agents are expensive to run, hard to debug, and introduce non-determinism. Don't create agents where tools will do.

 

 
   The Granularity Decision Framework
Bounded Context default: one agent Does it do two distinct things? Or is it too narrow to reason? TOO BROAD Split by Aggregate Two agents, cleaner ownership TOO NARROW Demote to a Tool Deterministic · No reasoning needed JUST RIGHT Keep as One Agent Clear ownership · Isolated failure


A Real-World Illustration

Let me ground this with a concrete example: a recruiting platform.

The Core Domain is candidate matching — algorithmically and semantically connecting the right candidates to the right roles. This is the competitive differentiator. It gets a sophisticated, heavily-tuned agent with deep context about the company's hiring philosophy, role requirements, and candidate signals.

The Supporting Domains — resume parsing, interview scheduling, feedback aggregation — get leaner agents. Each has a defined input, a defined output, and a constrained set of tools.

The Generic Domains — sending emails, updating calendars — become tool wrappers. Not agents. Just functions.

 

   
   Recruiting Platform — DDD-Informed Agent Architecture
CORE DOMAIN ★ Candidate Matching Agent ← most AI investment here SUPPORTING DOMAINS Resume Parsing Agent Interview Scheduling Agent Feedback Aggregation Agent GENERIC DOMAINS 📧 Email Tool (SendGrid) 📅 Calendar Tool (Google) Not agents — just functions CandidateShortlisted → InterviewScheduled → FeedbackReceived

 

The Context Map defines that CandidateShortlisted is the event that flows from the Matching Agent to the Scheduling Agent. The Scheduling Agent doesn't need to understand why a candidate was shortlisted — only that they were.

 


 

Where the Analogy Breaks Down

I want to be honest about where this framework has limits, because applying it too rigidly creates its own problems.

 

 DDD assumes deterministic behavior.   Agents are probabilistic. You need retry logic, fallback paths, and confidence     thresholds that DDD doesn't account for. Build these explicitly.
 
 DDD assumes clear data ownership.  Agents operate on context windows, not databases. If you're not careful about what   context you inject, agents can "see" across boundaries in ways that violate the isolation   you're trying to create. Treat your system prompt and injected context as the enforced   boundary — not just the architectural diagram.
 
  DDD was designed for synchronous, transactional systems.  Agentic systems are often long-running, stateful, and asynchronous. You'll need to   augment the DDD model with thinking about session state, checkpointing, and human-   in-the-loop interruption points.

 

The Practitioner's Starting Point

If you're a CTO or architect beginning this work, here is where to start:

1

Map your domain. Before a single prompt is written, draw your domain map. Identify your Bounded Contexts and classify your subdomains as Core, Supporting, or Generic.

2

Draw your Context Map. Define how contexts relate and what events flow between them. This is your orchestration architecture before it's code.

3

Define the Ubiquitous Language for each agent. Write the system prompt with the vocabulary of that domain. Define the input and output schemas precisely.

4

Build the simplest thing that could work. Start with one agent. Expand when a real limitation demands it — not because it feels more sophisticated.

 

"The most resilient AI systems I've seen built aren't the most complex. They're the ones where someone took the time, before writing code, to understand the domain."
 

That discipline — taking the domain seriously — is what DDD has always been about. It turns out it's what great agent architecture is about too.

 

Rohit Sinha is a CTO with experience building large-scale AI and distributed systems. He writes about the intersection of engineering architecture and emerging technology.

Share this post