AIMBy Imtiaz HassanAitina Tech R&D

Microservices Break Under Agents — And Why AIM Fits

Share

The four ways the microservices contract fails under autonomous callers, and the three-layer architecture (Agents · Intelligence · MCP) that answers each one.

"A bridge built for cars can survive the occasional pedestrian. A bridge built for pedestrians cannot survive a parade of trucks it was never designed to carry."

The intuition pump

Imagine a microservice-era platform — a clean one, built by a disciplined team in 2021. It has:

  • 30 microservices, each owned by a team of 5–9 engineers.
  • REST APIs between them, documented with OpenAPI.
  • Kafka for async events, a service mesh for auth and retry, OpenTelemetry for traces.
  • Good rate limits, circuit breakers, exponential backoff with jitter.
  • A robust deployment pipeline: blue-green, feature flags, canary.

This is a competently-designed platform. It survives the 2021-era traffic pattern — primarily human-driven requests at human timescales — with ease.

Now, in 2026, you introduce a caller that is not a human: a reasoning agent, acting on behalf of a human, composing three or four of your APIs together at runtime to fulfil a single user intent. The agent does not know your service boundaries. It does not wait before retrying, because it reasons about errors instead of backing off. It does not read your API docs — it reads your tool manifests, if any. It does not rate-limit itself; it reasons about cost, not about concurrency.

Your platform starts breaking in interesting ways. This article is about which ways, and why.

The breakage is not cosmetic. It shows up in the SLO dashboards, in the token-spend dashboards, and — most damningly — in the incident postmortems that read less like "a service was overloaded" and more like "a caller made a sequence of individually-valid calls whose composition the platform was never designed to survive." That last pattern is the tell. Traditional failure modes concentrate at one service; agentic failure modes smear across three, four, sometimes seven. The graph of blame is dense, not sparse.

A useful frame: microservices were designed around a contract between services and their integrators. The integrator was, implicitly, a human engineer with a ticket, a whiteboard, and an OpenAPI viewer. The new caller is a reasoning loop with a token budget and no whiteboard. The implicit contract has been silently re-signed by a counterparty the original authors never met.

The four new requirements (R1–R4)

I organize the breakage into four requirements that microservices, as a default, do not meet. I call them R1 through R4.

R1 — Discoverability at call time.
A microservice is discovered at integration time by a human developer reading docs. An agent needs to discover services at call time by reading a machine-readable manifest. OpenAPI is close to sufficient but not quite — agents need semantic descriptions, example invocations, cost models, and scope assertions alongside the schema. Absent an MCP-style manifest, the agent either hallucinates the surface or is bottlenecked on a human who has to integrate each service by hand.

R2 — Reasoning-safe contracts.
A microservice contract assumes the caller knows what it is doing — it typed the request, it validated the inputs, it handles the returned error codes deterministically. An agent caller types the request based on its reasoning about your description. If your description is ambiguous, the agent types it wrong. Returns a 400. The agent reasons: "let me try a variant." Returns a 400. The agent burns through your rate limit in twenty seconds trying variants, which is not a pattern your capacity planning expected.

R3 — Guardrails at the edge.
A microservice trusts the caller up to the auth token. An agent caller may have a valid token but may have reasoned its way into a request the organization does not want to fulfil — a deletion that will cascade, a disclosure that crosses a PII line, a spend that crosses a budget. The agent is not malicious; it is reasoning within its instructions. The service must therefore enforce semantic guardrails at the edge — not just authentication and input validation, but intent-level policy.

R4 — Cost and cognition as first-class NFRs.
A microservice's NFRs are latency, throughput, error rate, availability. An agent caller adds two: cognitive cost (how many tokens the interaction consumes) and monetary cost (which is directly derivable from tokens). A service that makes the agent do five round-trips to understand what would have taken one round-trip with a better description is directly costing the caller money per call. The service's cost-to-serve is no longer purely its own infrastructure cost; it is the compound cost of everyone reasoning about it.

Concretely, consider the same operation expressed as a REST contract and as a capability manifest. The REST contract (circa 2021) looks like this:

Listing 10.1 — Capability manifest excerpt (YAML / OpenAPI).

paths:
  /accounts/{id}/retention:
    post:
      summary: Compute retention risk
      parameters:
        - name: id
          in: path
          required: true
          schema: { type: string }
      requestBody:
        content:
          application/json:
            schema: { $ref: "#/components/schemas/RetentionReq" }
      responses:
        "200": { description: "OK" }
        "400": { description: "Bad request" }

That contract is typed but semantically opaque. The agent caller has no handle on what RetentionReq means, what a good invocation costs, or what failure modes it should plan for. The same operation as a capability manifest carries the missing signal:

type RetentionAnalyzeIn = {
    "org_id": str,            # tenant scope, required for isolation
    "customer_id": str,       # Salesforce account id, 18-char form
    "horizon_days": int,      # 30..365, default 90
}
type RetentionAnalyzeOut = {
    "risk": float,            # 0..1, calibrated
    "top_drivers": list[str], # 3..5, ordered by contribution
    "evidence_refs": list[Ref], # OKL + KB citations
    "cost_tokens": int,       # observed, for caller budgeting
}

The difference is not syntactic sugar. The manifest tells the agent what to type, what to expect, and what the call will cost in tokens. R1, R2, and R4 collapse together when the description layer is this thin — and the remedy is to thicken it deliberately, not to keep patching OpenAPI.

These four requirements are not speculative. Every team I have watched deploy agents over an existing microservice platform encounters all four within the first quarter of real traffic. The order in which they bite varies — cost-heavy use cases hit R4 first, compliance-heavy use cases hit R3 first, exploratory use cases hit R1 and R2 first — but the set is invariant.

Four anti-patterns

Let me name a set of four anti-patterns I see repeatedly in microservice platforms re-hosted as "AI-enabled" without architectural reconsideration.

Anti-pattern 1 — "REST + OpenAPI is enough." The team exposes their existing REST APIs via OpenAPI, calls it an MCP server, and considers themselves done. The agents can invoke the APIs, but the descriptions were written for human developers and do not include the semantic hints, example invocations, and failure-mode narratives that agents use to reason. Agents produce correct-looking calls that fail for structural reasons nobody wrote down. Volume of 400s spikes. Rate limits get hit. The team's conclusion: "agents are unreliable." The cause: the manifest is human-era.

Anti-pattern 2 — The "chatbot on top" pattern. A thin UX-level chatbot sits in front of the existing microservices, translating user intent into API calls. It works for 80% of requests and fails badly for the remaining 20% — the ones that require composition across multiple services, reasoning over results, or awareness of policy. The cause: the agent is in the wrong layer. It should not be a front-end veneer over unchanged services; it should be an architectural citizen with access to manifests, memory, and guardrails at the platform level.

Anti-pattern 3 — The "smart endpoint" pattern. Each service grows its own embedded agent. The CRM service has a "smart CRM agent", the HR service has a "smart HR agent", etc. There is no orchestrator, no shared memory, no consistent guardrails. When a user request crosses services, the sub-agents produce inconsistent answers. The cause: the architecture has collapsed orchestration into each service, which is exactly what microservices tried to stop doing in 2015.

There is a fourth anti-pattern worth naming, though it is usually a consequence of the first three rather than an independent choice: "the rate-limit-as-policy" pattern. When agents start over-calling, the reflex is to tighten rate limits. That works briefly; then the agent's retry loop simply queues up against the limit, and the failure mode shifts from 4xx to latency. Rate limits are a capacity control, not a policy control. The right answer is a richer manifest (so the agent gets the call right first time) and semantic guardrails (so wrong intents are refused at the edge, not burned against the quota).

Nexcubator v0 — the collapse

Nexcubator v0, as sketched in Nexcubator, is a microservices platform. Let us be concrete about how each of R1 through R4 collapses when we introduce an orchestrator agent over it.

R1 collapse. Nexcubator v0's CRM service exposes /accounts/{id}/history via OpenAPI. The orchestrator agent calls it expecting "history" to include recent meetings. It includes only contract-history. The agent does not know; it assumes the returned empty meetings list means there are no meetings. The resulting welcome email says "it's great to see Acme has been so quiet." Acme is not quiet. The agent was misled by a semantically-thin description.

R2 collapse. The HR service accepts POST /hires with a start_date field. The agent reads the description, types start_date: "Monday". The service returns 400 with no useful guidance. The agent retries: "next Monday". 400 again. "2026-04-22". Finally. Three wasted calls. Multiply by thousands of hires per month, across hundreds of services, and you have a cost centre.

R3 collapse. The finance service allows POST /invoices/{id}/void. The orchestrator, on a user's casually-phrased request ("cancel Acme's latest invoice"), invokes it. No edge-level policy stopped the invocation. The invoice was in a state where it should not have been voided. Accounting calls in the morning. The cause: the service trusted the auth token, not the reasoning behind the call.

R4 collapse. Each cross-service user request produces an average of 22 internal API calls (the agent is reasoning its way through), vs 3–4 in the human-driven path. The monthly cost of reasoning is 5x the historical compute bill — and the agent is not any more capable than it was before; it is just paying a tax for a platform whose contracts were written for a different caller.

What this means in practice. The v0 team's dashboards reflect the collapse in four distinct places. The API-gateway 4xx rate climbs by a factor of six. The p99 for cross-service flows doubles, because each extra agent round-trip contributes 400–900ms of model time. The token-spend line — which in 2021 did not exist — now rivals the EC2 bill by the end of the quarter. And the on-call rotation reports a new class of incident: "the agent did something surprising." None of these are fixable at the service level in isolation.

What needs to change

The Nexcubator team — in the series's narrative — reaches the conclusion that most real teams reach: the microservices are not wrong, they are under-specified for the new caller. The remedy is not to throw them away; the remedy is to front them with the right pattern. That pattern is AIM — Agents, Intelligence, MCP — which the next chapter introduces.

Before AIM, the team's default would have been to patch. Add semantic hints to each API's OpenAPI. Write a PII policy. Put rate limits per agent. Each patch would have worked, locally, for six weeks. Then the next unforeseen thing would break.

The book's architectural claim is that AIM is not a patch. AIM is the correct shape. The next chapter gets specific.

One way to feel the difference is to imagine two teams, six months from the v0 collapse. Team A has patched: twenty-seven tickets closed, each shaving a percentage point off the 4xx rate or the token bill. Team B has re-platformed around AIM: one large project, significantly more expensive to start, but whose marginal cost of adding the twenty-eighth capability is near zero. Team A's velocity falls quadratically with surface area. Team B's does not. The architectural bet is that quadratic beats constant eventually, and "eventually" arrives faster than any executive expects.

Measuring the collapse: a diagnostic

Before leaving the microservices critique, it is worth naming a short diagnostic a team can run against its own platform in an afternoon. The diagnostic has four questions, one per requirement.

For R1 (discoverability). Pick one of your APIs at random. Can an agent, given only its OpenAPI document, generate a syntactically-valid call that succeeds on the first attempt 95% of the time? If the answer is "no" or "we have never checked," your manifest is human-era.

For R2 (reasoning-safe contracts). Over a week, log every 4xx your APIs return in response to agent callers. Categorise them: true caller error, ambiguous field definition, or missing semantic hint. If more than 20% fall into the second two categories, your contracts are under-described for their actual caller.

For R3 (guardrails at the edge). Take one of your "destructive" endpoints — a DELETE, a void, a refund. List the checks the endpoint performs before executing. If all of the checks are syntactic (auth, schema, rate-limit) and none are intent-level (is this an appropriate call given the requester and the state), your edge is naked.

For R4 (cost as NFR). Compute the fully-loaded token-and-infrastructure cost per agent-initiated request, for your top ten agent-callable flows. If you cannot compute it — because tokens are not attributed back to callers, or because infrastructure cost is not per-request-attributable — you are flying blind on the NFR that will dominate your P&L within two quarters.

Most teams fail at least two of the four on first assessment. The failure is not indictment — it is a starting point. The diagnostic maps directly onto the AIM investments of the following chapters: R1 and R2 are why Layer M exists; R3 is why guardrails span Layers A and M; R4 is what Layer I's structured audit path makes measurable.

Diagnosis is only half a chapter. The second half names the pattern we will spend the next three chapters standing up: AIM — Agents, Intelligence, MCP. Microservices broke under the four requirements of §10.2; AIM is the architectural shape that answers each of them.

The three layers

AIM is a three-layer architectural pattern for building systems whose primary callers are autonomous agents. The three layers are:

  • A — Agents (the decision layer)
  • I — Intelligence (the memory layer)
  • M — MCP (the action layer)

The AIM Pattern.

the diagram shows the three layers stacked horizontally with their sub-components. Each layer has clear responsibilities; each is composed of recognizable building blocks; each is sized to the engineering concerns it owns. The claim is that every well-formed agentic system has all three layers — and that systems with only one or two are the source of the anti-patterns in Microservices Break Under Agents — And Why AIM Fits.

AIM is not MVC-reskinned. MVC is about UI separation within a single program; AIM is about the distribution of reasoning, memory, and action across an organization's runtime. The layers are not "render / logic / data." They are something structurally new. I will be precise below.

A historical parallel, made explicit. Architectural patterns tend to emerge when a new caller or a new constraint breaks a prior pattern's assumptions. MVC emerged from Smalltalk-80 in the late 1970s, when Trygve Reenskaug needed a way to separate what the user saw from what the program remembered — the user was the novel caller, and the pattern's shape fell out of the need to let the model evolve independently of the view. Three-tier (presentation, business logic, data) arrived in the mid-1990s as client-server strained under web-scale concurrency — the browser was the novel caller, and the pattern's shape fell out of the need for a stateless middle tier that could be horizontally scaled. SOA in the early 2000s, and microservices from around 2014, were responses to organizational scale — teams of teams needed contracts between groups of humans, and the pattern's shape fell out of Conway's law applied to deployment pipelines.

AIM is the next link in that chain. The novel caller is the autonomous agent. The constraints it imposes — discoverability at call time, reasoning-safe contracts, guardrails at the edge, cognition-as-NFR — are not accommodated by any prior pattern. The shape that falls out is three layers: one for reasoning, one for memory, one for action. The lineage is: Smalltalk-80 gave us MVC; client-server gave us three-tier; microservices gave us SOA-done-right; agents give us AIM. Each pattern retains the wisdom of the prior — AIM still uses REST and OpenAPI underneath, just as microservices still use TCP and HTTP — but re-partitions around the new caller's constraints.

Layer A — Agents

The Agents layer is where reasoning happens. It contains:

  • Orchestrator agents — top-level agents that receive user or system intent and decide how to fulfil it, typically by delegating to sub-agents.
  • Sub-agents (specialists) — domain-scoped agents (CRM, HR, PM, Finance, Knowledge) that the orchestrator delegates to.
  • Collaborator agents — the five-agent chain of Stop Adopting Ai Blindly the Five Agent Chain (Sentinel, Scout, Connector, Auditor, IQ Architect), which handle the organizational-brain responsibilities asynchronously.
  • Guardrails and policy — the constraint system attached to every agent: PII, denied topics, regional scope, cost ceilings.

The Agents layer is where the The Vocabulary of the Agentic Era vocabulary of Intelligent Agent lives. It is the layer that thinks.

A typed signature for an orchestrator's dispatch is useful, because it makes the separation between the layer's interface and the layer's internals obvious:

Listing 10.2 — Agent protocol sketch (Python).

class Orchestrator(Protocol):
    def handle(self, intent: UserIntent, ctx: RequestCtx) -> AgentResponse: ...

class SubAgent(Protocol):
    capability_scope: set[str]            # e.g. {"hrm.*", "kb.*"}
    guardrails: GuardrailSet
    def act(self, task: SubTask, ctx: RequestCtx) -> SubResult: ...

Notice what is not in these signatures: no tool invocation primitives, no memory handles. Those belong to Layers M and I respectively. The agent receives intent, produces response; everything else is delegation. When you see an agent class growing private fields for a cache, a DB connection, or an HTTP client, you are watching a boundary violation compile.

Layer I — Intelligence

The Intelligence layer is the memory. It is what lets the agents in Layer A be smarter than a single in-context reasoning call. It contains:

  • Vector / semantic memory — pgvector, OpenSearch, Pinecone — for similarity retrieval.
  • Graph / relational memory — Neo4j, Neptune — for supersession, scope, provenance, and cross-entity relationships.
  • Structured / audit memory — DynamoDB, Postgres — for authoritative records and state transitions.
  • Knowledge Base (retrieval surface) — Bedrock Knowledge Bases or equivalent, tying together embedded corpora with a retrieval API.

The Intelligence layer is exactly the three-tier Knowledge Store of The Knowledge Store Pattern, expanded to include external knowledge-base corpora (documents, wikis, product manuals, etc.) that are embedded and made retrievable but do not pass through the OKL lifecycle.

The retrieval contract the rest of the system sees is deliberately narrow:

class Intelligence(Protocol):
    def recall(self, query: RecallQuery) -> list[RecallHit]: ...
    def supersession(self, entity_id: str) -> list[LearningRef]: ...
    def remember(self, signal: Signal) -> WriteAck: ...

Three verbs: recall, supersession, remember. Every Layer-A agent speaks only in those terms. The underlying store topology — pgvector today, OpenSearch tomorrow, something else in 2028 — is an implementation detail behind the interface. This is the discipline that makes the platform portable; it is also the discipline that prevents one team from pinning the whole organization to a particular vector store's quirks.

Layer M — MCP

The MCP layer is the action surface. It is how agents discover and invoke tools — internal and external — in a caller-agnostic, manifest-described way. It contains:

  • Internal tools — capabilities implemented inside the organization's boundary, fronted by an MCP server that exposes their manifests.
  • External MCP servers — third-party capabilities (SaaS integrations, partner capabilities) the organization consumes.
  • Legacy adapters — wrappers over REST / gRPC / SOAP endpoints that bring the existing API surface into the MCP-manifest world, usually at L1 or L2 of the Capability Maturity Model (The Capability Maturity Model L0 to L4).
  • Policy tools — the approval, audit, and operational tools that are themselves agent-invocable (e.g., approval.request, audit.log.append, cost.check.budget).

The MCP layer is how Layer A's agents act in the world. Every side effect an agent has passes through this layer. The layer is also where per-capability guardrails are enforced, supplementing the agent-level guardrails of Layer A.

The invariant is worth stating as a signature. Every MCP-exposed capability has the shape:

class Capability(Protocol):
    name: str                        # e.g. "retention.analyze"
    manifest: Manifest               # schema + semantics + cost model
    guardrails: list[Guardrail]      # edge checks: PII, scope, budget
    def invoke(self, args: dict, ctx: CallCtx) -> CapabilityResult: ...

The manifest is the load-bearing artefact. It carries the JSON schema (the syntax), the semantic description (what the capability means), the example invocations (what a good call looks like), the failure-mode narrative (what can go wrong and why), and the cost model (token and currency cost per call, typical p50/p95). Agents read manifests the way humans read documentation — which is to say, they read them before every invocation, not at integration time.

How the three layers compose

A user request arrives. It enters the Agents layer via the orchestrator. The orchestrator pulls Intelligence — retrieves relevant learnings, knowledge, prior interactions — to shape its plan. It invokes MCP tools to act — querying systems, making updates, triggering downstream capabilities. Results flow back up: tool results are incorporated into the orchestrator's context, memory is updated with what happened, the user receives a response.

In parallel, the collaborator agents (Sentinel, Scout, Connector, Auditor, IQ Architect) run asynchronously over the signal stream, consuming the evidence of what happened and updating the Intelligence layer so that future A-layer calls benefit.

This is the full motion. Every real Nexcubator interaction, from "summarize Acme's renewal risk" to "onboard the new engineering hire", executes this motion. The layers are what keep the motion coherent rather than ad-hoc.

A worked walkthrough: retention.analyze through all three layers. Let me trace a single call through the stack, end to end, so the motion is not abstract.

A manager asks: "What is Acme's retention risk over the next quarter?" The request enters the ingress, is authenticated, and hits nex-orchestrator in Layer A. The orchestrator reads the intent, decides this is a CRM-adjacent retention question, and delegates to nex-crm-agent.

M receives first. The sub-agent discovers retention.analyze in its Layer-M manifest catalogue. The manifest advertises:

Listing 10.3 — Manifest excerpt (Python).

# retention.analyze — manifest excerpt
inputs  = RetentionAnalyzeIn  # org_id, customer_id, horizon_days
outputs = RetentionAnalyzeOut # risk, top_drivers, evidence_refs, cost_tokens
cost    = { "p50_tokens": 2_400, "p95_tokens": 6_800, "usd_p95": 0.09 }
guards  = ["scope:org_id", "pii:redact_email", "budget:per_call<=0.20usd"]

I is consulted second. Before invoking the capability, the agent calls Intelligence.recall with a retrieval query over OKL entries relevant to retention for SaaS accounts — the graph store returns the supersession-current version of L-FUNC-CS-028 ("exec-sponsor departure triggers a 14-day window"), and the vector store returns three semantically similar past cases. The Intelligence layer also returns a structured fact: Acme's exec sponsor changed 11 days ago. This is the evidence that will anchor the reasoning.

A reasons third. The agent composes a plan: call retention.analyze, then call crm.next_action if the risk exceeds 0.6. Guardrails at Layer A check the plan against the agent's scope (it may operate on Acme), against PII rules (no personal data leaves the VPC), and against the cost ceiling for this user. Plan approved.

M executes fourth. The capability runs. It reads from the structured store, computes features, calls the scoring model, and returns:

{
  "risk": 0.71,
  "top_drivers": ["exec-sponsor-change-11d", "usage-decline-22pct", "support-ticket-spike"],
  "evidence_refs": [{"type":"okl","id":"L-FUNC-CS-028"}, {"type":"usage","id":"acme-90d"}],
  "cost_tokens": 3104
}

A composes fifth. The agent now invokes crm.next_action (risk exceeds threshold), gets a recommendation ("schedule an exec-level check-in within 7 days"), and formats a response to the manager. The response cites both L-FUNC-CS-028 and the usage-decline evidence.

I learns sixth. A signal is emitted: {capability:"retention.analyze", customer:"acme", risk:0.71, evidence:[...]}. Sentinel picks it up from EventBridge within seconds, validates it, and files it as provisional evidence. If, two weeks later, the recommended check-in happens and Acme renews, that outcome is written back and reinforces L-FUNC-CS-028's support. If the check-in is skipped and Acme churns, that counterfactual is also captured — and Scout may propose a new learning about missed-intervention churn.

That is one call. It crossed all three layers, incurred ~3,100 tokens, consulted two stores, triggered two capabilities, and wrote one signal. Every step had a contract. Every contract had a guardrail. This is what "AIM in motion" means in operational terms.

What AIM is not

AIM is frequently confused with two neighbouring ideas. Let me head them off.

  • AIM is not a RAG architecture. Retrieval-Augmented Generation is a technique for grounding an LLM in external documents. AIM includes RAG (in Layer I, via the Knowledge Base retrieval surface) but is a much broader architectural pattern. A RAG system with one agent and no memory of its own outputs is not AIM-complete.
  • AIM is not an agent framework. AutoGen, CrewAI, LangGraph are frameworks you can use to implement the Agents layer of AIM. AIM is framework-neutral; it describes what the layers must do, not how to code them. You can build AIM on Bedrock, on OpenAI's Assistants API, or on a custom framework, and the architectural decisions are the same.

Two objections that come up every time AIM is introduced to a skeptical team. Both deserve answers.

"Why not just LangGraph / CrewAI?" Those frameworks give you the A — a way to structure orchestrators, sub-agents, and their interactions. They do not give you I (durable, queryable memory with supersession semantics) or M (a manifest-described action surface with edge-level guardrails). A LangGraph-only system is what the "smart endpoint" and "chatbot on top" anti-patterns tend to decay into: reasoning is present, memory is ad-hoc, action is whatever the framework's tool wrapper happens to do. You can build the Agents layer of AIM on top of LangGraph and nothing is lost. The question to ask is not "framework vs. pattern" — those compose — but "does your system have all three letters, or only one?"

"Isn't AIM just MVC renamed?" No. MVC partitions a single program by what the user sees: Model is state, View is rendering, Controller is input handling. AIM partitions an organizational runtime by what the agent does: Agents is reasoning, Intelligence is durable memory, MCP is action. The axes are different. MVC has no equivalent of a capability manifest, no equivalent of supersession memory, no equivalent of an edge-level guardrail engine. If you squint, every architecture has three letters and a metaphor; the letters are not the pattern — the constraints the letters refuse to let you violate are.

Nexcubator redesigned, in AIM

Let me redesign Nexcubator in AIM terms, to make the pattern concrete.

Agents (Layer A):
- Orchestrator — nex-orchestrator (Claude Sonnet 4.6, Bedrock Agent, system-message routing)
- Sub-agents — nex-crm-agent, nex-hr-agent, nex-pm-agent, nex-finance-agent, nex-knowledge-agent
- Collaborator agents — Sentinel, Scout, Connector, Auditor, IQ Architect

Intelligence (Layer I):
- Vector: OpenSearch Serverless, holding embedded OKL entries and product docs
- Graph: Amazon Neptune, holding OKL supersession, team ownership, capability graph
- Structured: DynamoDB, holding canonical OKL records and audit events
- Knowledge Base: Bedrock Knowledge Bases over nex-documents-bucket

MCP (Layer M):
- Internal MCP server at mcp.nexcubator.io, exposing:
- hrm.retain, hrm.onboard, hrm.review
- crm.next_action, crm.get_history, crm.score_health
- pm.plan, pm.status, pm.deliver
- finance.collect, finance.forecast, finance.invoice
- kb.find_document, kb.summarize
- External MCP servers: Salesforce, Workday, Jira, Xero, Slack, Google Workspace
- Legacy adapters: legacy payroll, legacy reporting — wrapped at L2 pending replatform
- Policy tools: approval.request, cost.budget.check, audit.log.append

Aim in Practice Hr Crm Pm on Aws Bedrock will implement this Bedrock-native; Aim in Practice Hr Crm Pm on Aws Bedrock and The Anatomy of a Capability and the Protocol Shift will deepen individual capabilities.

The inventory looks denser than it is. The orchestrator is one agent. The sub-agents are five. The collaborators are five. The MCP server is one. The knowledge base is one. The three memory stores are three. The external integrations look numerous but each is a manifest-wrapped single capability, not a bespoke codebase. A greenfield team with AIM on hand can stand up the whole stack in roughly six engineer-weeks; a team patching a v0 into AIM shape typically takes three times as long, because every capability migration is an exercise in teaching the old service new manners. Greenfield bias is not an accident of AIM; it is a property shared by every architectural pattern that partitions differently than the status quo.

The boundary lines AIM draws

Three boundary decisions AIM makes explicit.

Boundary 1 — Reasoning never lives in Layer M. MCP tools execute; they do not reason. The moment you find a tool doing "smart" conditional logic, you are duplicating Layer A responsibility inside Layer M. Move it upward.

Boundary 2 — Memory never lives in Layer A. Individual agents have working context, but durable memory lives in Layer I. An agent with a private persistent cache is an anti-pattern — the cache is invisible to the rest of the system, unauditable, and drift-prone.

Boundary 3 — Side effects never leak around Layer M. An agent in Layer A that calls an AWS API directly, bypassing an MCP tool, is a security and audit hole. Every side effect goes through a manifested, guard-railed Layer-M tool.

These three boundaries are the ones most frequently violated under deadline pressure. Every violation produces a debt the team pays within two quarters. The right move is to hold the boundaries.

What this means in practice. In IAM terms, the boundaries turn into three distinct role families. Layer-A agents assume a role that can call Bedrock and read manifests — nothing else. Layer-M Lambdas assume per-capability roles scoped to the specific AWS services that capability touches (a Salesforce read-only role for crm.get_account_history, a DynamoDB write role for audit.log.append). Layer-I components run under their own roles, and the only way in from Layer A is via the three-verb Intelligence interface. If you audit your IAM trust policies and find an agent role with dynamodb:* on the OKL table, you have collapsed the A/I boundary; fix it before the next quarter.

In network terms, the topology is: agents in one VPC subnet with egress only to Bedrock endpoints; MCP capabilities in a second subnet with egress to their specific downstream systems via PrivateLink or NAT; memory stores in a third subnet with no egress at all, only ingress from MCP via VPC endpoints. The subnet boundaries enforce what the role boundaries assert. Belt and braces, again.

Observability as a fourth axis

A question that reliably comes up at this point: if AIM is three layers, where does observability live? The answer is that observability is not a layer but a cross-cutting property of all three, and it earns enough architectural weight to be considered the implicit fourth axis.

Every layer emits structured signals:

  • Layer A emits reasoning traces: the chain of thought, delegations, and tool-choice rationales that produced a response.
  • Layer I emits recall traces: which memories were retrieved for which query, with similarity scores and supersession decisions.
  • Layer M emits invocation traces: which capability was called, with which arguments, which guardrails fired, which downstream systems were touched.

Together, these traces form the audit record of a single user interaction. The discipline is: every trace event is JSON, every trace event has a correlation id (trace_id + span_id), every trace event is appended to an immutable log. CloudWatch Logs and an S3 WORM bucket are the Bedrock-native implementation; Vision Driven vs Cost Cutting and the Invisible Downgrade unpacks the operational practice in depth. What matters here is the architectural claim: a well-formed AIM system is fully explainable after the fact. If your platform cannot reconstruct why an agent did what it did, using only logs, you are missing a constraint AIM requires you to hold.

Synthesis

AIM is the pattern: three layers (Agents, Intelligence, MCP), each with clear responsibilities, each composing into the canonical motion of receiving intent → retrieving context → acting → learning. Nexcubator redesigned in AIM terms is a concrete system. The boundary lines — no reasoning in M, no memory in A, no side effects around M — are the operational discipline. Aim in Practice Hr Crm Pm on Aws Bedrock walks three Nexcubator capabilities end-to-end in AIM; Aim in Practice Hr Crm Pm on Aws Bedrock implements on AWS Bedrock.

← Back to The Software Lens library