← All Posts Technical

Grounding is the moat: why the model is the least interesting part of your AI stack

What I learned building a headless, agentic AI orchestrator that turns a customer complaint into revenue - across a CRM, a data warehouse, a policy knowledge base, and two agents built on a different platform entirely.


A quick disclosure before anything else: I’m an AI Solutions specialist at Salesforce. So when I tell you the platform turned out to be load-bearing in this build, you have every right to be skeptical. That’s exactly why I built the brain on Claude - a model and an agentic SDK from a different company - and put Salesforce underneath it as a tool, not the boss. I wanted to know whether the platform still earns its place when it is explicitly not in charge - something I’ve come across incessantly from the “build vs buy” crowd, who don’t miss a second before saying “we’ll build everything for AI ourselves; why do we need an existing platform?” (the so-called SaaSpocalypse). This post is the honest answer, minuses included.


TL;DR - I built a headless AI orchestrator (Claude Agent SDK) that owns a customer conversation and delegates everything else: to local specialist subagents, to two Agentforce agents reached over the open A2A protocol, and to every backend system through a uniform MCP fabric. In one chat, a customer’s broken-pendant complaint became a ₹53,500 booking - grounded live in a CRM, a data warehouse, and a policy knowledge base, with a governance gate on every write. The lesson: the model is interchangeable; the grounding is the moat. Below: the architecture, the honest build log, what surprised me, and what I deliberately left for later.

Everything here is a proof of concept. “AURIC” is a fictional premium jewellery brand. “Priya” is a persona. The numbers are demo numbers. The plumbing, the protocols, and the headaches were all very real.


The broken clasp

Priya messages in on a Saturday. Her pendant’s clasp has broken. It’s an 18-karat gold piece she bought a while ago, and she’s annoyed - the kind of annoyed that quietly churns a good customer.

Normally that conversation goes one way: a chatbot, phone call, or email asks for her registered number, tells her to check her warranty certificate, and suggests she visit a store. Generic. Forgettable. An eventual cost to the company.

On the headless agent architecture, it went somewhere else. By the end of a single chat, Priya had:

  • her broken pendant logged as a real service case in her existing workflow, from the same entry point (the chat channel), confirmed covered under warranty at zero cost;
  • a clear answer on her savings scheme - whose underlying system of record was different from the service workflow’s;
  • and a recommendation she actually wanted: a pair of diamond earrings, funded almost entirely by her scheme balance and her expiring loyalty points, with a festival offer stacked on top.

She came in with a complaint. She left having booked ₹53,500 of new jewellery - and happier, not just placated. A cost conversation became a revenue conversation, in one thread. Two hours later, a store executive got a complete, freshly-built call brief to close her in person.

No human was in the loop until the very last yard. So how does a complaint turn into a sale without a salesperson? That’s the whole story.

The cost-to-revenue journey across eight turns: verify and ground, recall preferences from memory, identify the broken piece, cite the warranty policy, get a coverage ruling from a peer agent, open a real case behind a governance gate, pull the savings balance and design an offer, and book a ₹53,500 opportunity.

One conversation, eight turns, zero handoffs - complaint to ₹53,500.

The thesis: grounding is the moat

Most “enterprise AI” conversations get stuck on the wrong question - whose model is smarter? Wrong fight. Modern models are excellent generalists out of the box; drop one into a chat window and it’ll write you a poem, debug your code, and sound charming while it does. That was never the hard part.

What it won’t do is know that Priya is a Gold-tier customer since 2022 with a ₹1.34 lakh lifetime value, a 68% affinity for diamonds, 4,200 loyalty points about to expire, and a savings scheme two months from maturity. None of that lives in the model. It’s scattered across systems:

  • the CRM holds the system-of-record customer and her assets;
  • a data warehouse holds her scheme ledger and the propensity scores;
  • policy documents hold what her warranty actually covers;
  • and increasingly the intelligence is scattered too - different teams build different AI agents on different platforms.

So when a customer reaches out, the agent answering is usually working blind - it sees a fragment, not the whole person. The real fight isn’t intelligence; it’s grounding: the unified customer, the real workflow, the cross-session memory, the trust layer. That’s the unglamorous part a do-it-yourself stack takes quarters to build - and the part an enterprise platform already has sitting there.

That’s the bet this POC tests: you bring the agent orchestrator - any model, any cloud, your choice - and the platform brings the grounding. If that’s true, the model is interchangeable and the substrate is the moat. Let me show you the shape of it.

The architecture: two planes and a fabric

Headless agentic architecture: a horizontal Claude Agent SDK orchestrator on top, an agent plane (local subagents + Agentforce peers over A2A) and an MCP fabric beneath it, sitting on a data foundation of CRM, Customer 360, Snowflake and governance.

The shape of it: one orchestrator, two planes, a uniform MCP fabric, and a data foundation.

The key design idea is one word: horizontal.

At the top sits a single orchestrator, built on the Claude Agent SDK. It owns the conversation. But - and this is the important part - it doesn’t try to be everything. It delegates. Below it, the system splits into two clean planes.

The agent plane - who does the work. On one side, lightweight specialist subagents that run locally and cheaply: a triage classifier, a knowledge advisor that does retrieval over policy docs, a clienteling strategist that decides the next best action, and a call-prep writer. On the other side, two peer agents that live on Salesforce’s Agentforce - a Service Agent that rules on warranty, and a Loyalty Agent that designs offers - reached over the open A2A (agent-to-agent) protocol. The orchestrator talks to its own subagents and to agents another team built on another platform, the same way. No lock-in. That distinction matters: it means an enterprise can keep the agents it has already invested in and still put one brain on top.

The MCP fabric - how anyone reaches anything. Underneath both planes is a uniform tool interface built on MCP (the Model Context Protocol). Reading the unified customer, writing through existing automation, querying the warehouse, retrieving policy, searching the catalog - every agent reaches every system the same way. Want to add a new vertical? Add an agent and its MCP server. You don’t rewrite the brain.

A few deliberate choices inside that fabric are worth calling out, because they’re where the “respect the customer’s estate” philosophy actually lives:

  • Why so many systems? Because each does a job the others can’t. The system-of-record owns the truth and takes every write. The identity layer answers “who is this person, across everything.” The warehouse does deep analytics and ML scores. Per-agent memory carries context across sessions. The agent needs all four - and MCP makes them feel like one.
  • Two write paths, on purpose. One path does direct create/update on the CRM. The other invokes the customer’s existing Flow and Apex (Salesforce process automation tools that customers have spent years building) rather than reimplementing the logic. The agent drives the workflow estate; it doesn’t rebuild it. This is the difference between an AI that bolts on and an AI that fits in.
  • Governance wraps every edge. Every tool call passes through a hook that can allow it, deny it, or pause for a human. Reads run free; writes to the CRM stop and ask. That hook is the trust story - autonomy where it’s safe, a human where it matters.

That’s the design. The interesting part was building it.

What I actually built

The horizontal agent orchestrator is a Python service built on the Claude Agent SDK. It runs a multi-turn loop: it owns the conversation state, decides which tool or agent to call next, and keeps a running trace of every step. The reasoning model is the large Claude model; the cheap, high-volume work (classification, retrieval synthesis) is offloaded to a smaller, faster one. That split is most of why a full conversation costs cents, not dollars.

The local subagents are four focused roles, each a tight prompt with a narrow job:

  • triage - classifies the incoming message so the orchestrator knows whether it’s a service, loyalty, scheme, or sales intent;
  • knowledge advisor - does retrieval-augmented generation over the policy documents and answers with citations;
  • clienteling strategist - takes the assembled customer picture and decides the next best action;
  • call-prep writer - produces the human follow-up brief at the end.

The peer agents are two Agentforce agents that I did not write into my orchestrator’s brain but built separately on the platform - they’re independent, they live on Salesforce, and I reach them over A2A like any other team’s agents: a Service Agent that applies warranty rules, and a Loyalty Agent that designs the offer.

The MCP fabric is a set of small servers, each wrapping one system behind the same tool interface:

  • customer-read → the unified customer profile;
  • sf-platform → direct reads/writes on CRM objects (assets, opportunities);
  • sf-workflow → invokes the customer’s existing Apex/Flow to create the case;
  • snowflake → live queries against the analytics warehouse;
  • rag → semantic search over the policy corpus;
  • catalog → product search.

The governance layer is a pair of hooks around every tool call - one that runs before (allow / deny / pause-for-human) and one that runs after (log it to the trace). It’s small, and it’s the most important code in the project.

Build it on Claude, or call it over A2A?

This is the architectural fork that mattered most, so it’s worth slowing down on. For every specialist capability - warranty rulings, loyalty offers, triage, retrieval - I had a choice: build it as a local subagent inside my own orchestrator, or call out to a separate agent over A2A. I did both, on purpose, and the split taught me where the line actually sits.

A local subagent is just another Claude/LLM call with a tight prompt, living in my process. A peer agent over A2A is an independent agent - its own platform, its own logic, its own lifecycle - that I reach through a protocol. Same conversation, two very different ownership models.

Decision guide for building a capability as a local Claude subagent versus calling it as a peer agent over A2A.

The fork: build on Claude for reasoning, call over A2A for owned-and-governed logic.

Here’s how the trade-off shook out:

Local subagent (build on Claude)Peer agent over A2A
Best forReasoning, synthesis, routing, drafting - work that’s prompt + contextCapabilities with their own system of record, rules engine, workflow, or compliance surface
LatencyFast - one in-process model callSlower - network hop, and async tasks need polling
ControlTotal - I own the prompt, model, and output shapePartial - I own the question, the other team owns the answer
Iteration speedInstant - edit a prompt, rerunCross-team - versioning, publishing, and someone else’s roadmap
Reuse / ownershipMine alone; reinventing what another team may already runShared org asset - the warranty logic already exists and is governed
Failure modeFails in my process; I see the whole stackFails behind a gateway; I get a status code and a trace, not the internals
AuditabilityMy trace onlyRuns under its own identity and audit trail on its own platform

The rule I landed on: build it on Claude when the work is reasoning over context; call it over A2A when the work has its own source of truth or its own governance. The triage classifier and the call-prep writer are pure reasoning - they belong in my process. But the warranty ruling? That logic already exists on the platform, it’s already governed, and another team owns it. Rebuilding it inside my orchestrator wouldn’t just be wasted effort - it would create a second, divergent copy of a rule that’s supposed to have one home. That’s the anti-pattern A2A exists to prevent.

There’s a deeper point here about the “build everything on one model” temptation. It’s seductive because it’s fast - no protocols, no cross-team contracts, no gateways. And for a greenfield prototype, do that; don’t let interop dogma slow you down. But at enterprise scale, “build everything on Claude” quietly means “reimplement, in my prompt, business logic that already lives somewhere governed and has taken years to perfect.” You end up with shadow copies of warranty rules, pricing logic, and eligibility checks - each one a thing that can drift out of sync with the real system. A2A is the seam that lets the orchestrator use that logic without owning it.

The honest build log

If you take one thing from this section: the AI was the easy part. Here’s what actually consumed the days.

What was trivially live vs. what fought me. Reading and writing the CRM through queries and Apex? Frictionless. Local retrieval over policy docs? Frictionless. The surprises were all in the config and data layer: the demo org’s own background automation fired on every record insert and broke things in test contexts; field-level security silently returned zero rows until I granted the right permissions (fields deploy clean, queries come back empty, and nothing tells you why); and the unified-customer pipeline simply hadn’t been ingested yet, so I mocked that one surface honestly.

Another point became a design principle. The mocked customer-360 surface sits behind the exact same MCP interface as the live ones. Promoting it from mock to live is a configuration change, not a rewrite. The orchestrator never knows the difference. If you’re a skeptical architect, this is the single most reassuring property of the whole system.

A2A was a precise treasure hunt. Connecting the orchestrator to those Agentforce peer agents was the most finicky part. A few things I’d tell anyone doing this:

  • The A2A endpoint is a global gateway, not your org’s hostname. My first dozen probes hit the org domain and got clean 404s.
  • A custom OAuth scope has to exist before you create the connected app. Skip it and you get a token that looks valid but is missing the one scope the gateway checks.
  • The transport is JSON-RPC 2.0, not REST. Every message needs its own ID, and the response can come back synchronously or as an async task you poll.

Each 4xx was a signal, not noise. And the payoff - the moment that proves the architecture - is the grounded A2A call: the orchestrator bundles Priya’s full profile into the message it sends the Loyalty Agent, and the peer agent reasons over real context instead of guessing. What came back wasn’t a generic FAQ answer - it was a points-expiry alert with the exact date, a specific offer code, and the customer’s Gold-tier redemption cap correctly applied to the math.

The OAuth insight worth its own paragraph. I authenticated the orchestrator to those agents using the client-credentials flow. That means the token represents a fixed, scoped integration user - not the human in the chat. For a server-side orchestrator, that’s the correct default: least privilege, one auditable service identity, no impersonation. If you later need each action to run as the actual end user - with their permissions and their name in the audit trail - you swap to an interactive flow. Same endpoint, same code path, only the grant changes.

Two OAuth flows for A2A side by side. Client credentials on the left, authorization code / token exchange on the right.

System identity vs end-user identity. The “whose permissions?” question, answered.

The warehouse was a pleasant surprise. Once wired, Snowflake was zero friction. I promoted its MCP server from mock to live with a handful of environment variables and no code change. (Two footnotes for the next person: one of my column aliases collided with a reserved keyword, and the brand-new server-side DDL for hosting an MCP endpoint has a serialization bug in this beta - the plain connector is the production path for now.)

Agentforce’s Agent Script is its own language. Not Python, not YAML, not anything an AI model has seen much of. Coding assistants will confidently hallucinate its syntax. The only ground truth is the platform’s own validator - run it early, run it often.

And the cost? I pulled this straight from the run trace: a full conversation was ~54,600 input tokens and ~2,200 output tokens - about $0.16, including the follow-up call brief. The expensive reasoning runs on the big model; the cheap, high-volume work runs on a smaller, faster one. Enterprise-grade agentic AI, it turns out, is not expensive to run. It’s expensive to ground - which is the whole point.

Five things that surprised me

Some of these I expected to be hard and they were easy; some I expected to be trivial and they ate a day. Mostly I was wrong about which was which.

  1. The model needed almost no prompt-engineering for the reasoning. I expected to spend days coaxing the orchestrator into the right sequence of tool calls. I didn’t. Give a capable model good tools, clear descriptions, and a crisp objective, and the planning mostly takes care of itself. The effort went into the tools and the grounding, not the brain.

  2. Grounding changes the model’s personality, not just its facts. An ungrounded agent hedges - it’s vague because it’s guessing. The moment it could actually see the asset, the balance, the warranty clause, its tone shifted: confident, specific, done arguing with itself. Same model, completely different presence.

  3. The “resolve before you sell” ordering is load-bearing. Early on I let the orchestrator surface the offer too eagerly and it felt like a pushy upsell. Forcing it to fully close the service issue first, and only then look for a genuine next-best-action, is what makes the revenue moment feel like help instead of a hustle. The sequencing is a product decision, not a technical one.

  4. The boring infrastructure was the long pole. Certificates, gateways, permissions, scopes. I budgeted my time for the AI and spent it on plumbing. If you’re scoping one of these, double your estimate for everything that isn’t the model.

  5. “Mock” stopped feeling like a compromise. Because every mock sits behind the same interface as the live systems, the mocked surfaces never felt like fake demoware - they felt like parts not yet plugged in. That reframing matters: it’s the difference between “this demo is smoke and mirrors” and “this is the real architecture, with two cables still to connect.”

The moments that actually land

Screen recording of the live demo: the customer conversation on the left, the orchestrator's step-by-step trace on the right, and the KPI cards flipping from cost to revenue as a broken-clasp complaint turns into a ₹53,500 booking.

The demo, running live - conversation on the left, the orchestrator’s trace on the right.

When I run this live for customers, there are a few moments where the room goes quiet.

Memory. Early in the chat, the agent mentions it’ll follow up on WhatsApp - because that’s her preferred channel - and that it knows she likes delicate gold. Nobody told it that in this conversation; it’s cross-session memory, surfacing on its own.

A real case, created mid-conversation. When Priya asks to open the repair, the governance gate pauses, then writes an actual case into the CRM - through the company’s existing Apex, not some shadow path. I flip to the org and it’s right there, with a real case number and a matching Opportunity record when she books. It’s not a mockup of a workflow; it’s the workflow.

The flip. A broken clasp becomes a ₹53,500 booking, and you can watch the KPI cards at the top of the screen change from “cost” to “revenue” in real time.

The contrast. Then I turn a capability off - cut the live grounding - and ask the same question. The agent immediately degrades into the generic chatbot: “please share your registered number,” “check your certificate,” “visit a store.” That delta, side by side, is the entire argument.

The lever was never on/off - it’s accuracy. Grounding doesn’t make the agent work; it makes the agent worth talking to.

The same customer question answered two ways. With grounding off, a generic chatbot. With grounding on, the orchestrator names her exact pendant, confirms zero-cost warranty coverage, quotes her live savings balance, and makes a funded offer.

Same question, grounding off vs on. The delta is the argument.

The plus / minus, honestly

I don’t trust build logs that only have pluses. Here’s the balanced read.

What genuinely worked:

  • Grounding is real and reusable. The unified customer, the existing-workflow invocation, the policy retrieval - these did the heavy lifting, and they’re not things I had to invent.
  • Open protocols mean no lock-in. MCP and A2A let me wire a Claude-based brain to Salesforce-based agents without either side owning the other.
  • Governance is a real trust layer, not a checkbox. Pausing for a human before a write is the feature that lets you actually deploy this.

What’s rough, and I won’t pretend otherwise:

  • Pilot edges are sharp. A2A is pilot-era for many providers and finicky to stand up. The memory-enabled version of one agent isn’t reachable over A2A yet.
  • Latency is the wildcard, and the trace names the culprit. Pure reasoning turns were quick - 3 to 6 seconds. But turns that called a peer agent over A2A were the tent-poles: the live warranty ruling took the longest, the loyalty-offer turn about 31s, the catalog-plus-opportunity turn about 37s. That’s not the model being slow - it’s the network hop plus async task polling on the A2A side. It’s also a neat confirmation of the build-vs-A2A trade-off: the seconds live exactly where you’d predict.
  • The enterprise infra tax is real. Certificates, gateways, permissions, scopes - the plumbing consumed far more time than the AI did.
  • Observability is siloed today. The orchestrator traces locally; the platform agents trace in the org; the warehouse logs its own queries. There’s no single pane that stitches one request across all of them yet.
  • This is a POC. The chat looks like WhatsApp but isn’t a real channel integration. The unified-customer pipeline isn’t ingested. I’m showing the pattern, not shipping the product.

How this evolves - what I parked on purpose

Naming what’s not done is part of the argument, because of that mock/live seam: everything I parked is a swap-seam, not a rewrite. The orchestrator doesn’t change when these go live.

  • Cross-session memory, fully wired once the agent-platform pilot catches up to A2A.
  • A live unified-customer MCP - ingest the data streams, run identity resolution, flip the same interface from mock to live.
  • Shared, unified observability - one correlated trace across orchestrator → subagents → peer agents → tool calls → systems, stitched by a single request ID.
  • An agent-governance fabric. Everything I hand-wired - minting tokens, controlling scopes, routing to the right endpoint, auditing every action - is exactly what an integration-tier agent fabric productizes.
  • Per-user A2A identity, when a use case needs each action to run as the actual human.
  • A different path altogether, a future post: flip the whole thing inside-out and let the platform’s own agent be the orchestrator.

Who this is for (and who it isn’t)

If you’re an enterprise architect weighing build-vs-buy for agentic AI - this is the honest middle path. You don’t have to choose between “buy a closed agent platform and hope it fits” and “build everything yourself over four quarters.” You can own the orchestrator and the model choice, and rent the grounding. The integration surface is open protocols, not a proprietary SDK you marry forever.

If you’re a developer or SE who’s tired of demos that fall apart when you ask a follow-up question - the whole point here is that it doesn’t fall apart, because it’s reading real data and invoking real workflows. The trace is visible. You can see exactly which system answered each part of the question.

If you’re on the business side and “AI strategy” still sounds like a slide - the takeaway is one sentence: the value isn’t a smarter chatbot, it’s connecting the agent to the systems that already know your customer, so a service ticket can become a sale without anyone having to bolt the two together by hand.

Who it isn’t for, yet: anyone who needs this in production tomorrow. This is a proof of concept that proves the pattern. I’d put it in front of a CIO to make an architectural argument - not in front of a million customers.

Questions I keep getting

“Isn’t this just a chatbot with extra steps?” No - and the contrast is the proof. A chatbot answers from the model’s general knowledge. This answers from your data and your workflows, and it takes governed actions that show up in your system of record. The “extra steps” are the entire value.

“Why not just let the platform’s agent be the brain?” You can - that’s Path B, and it’s a great fit for plenty of customers. I built Path A first specifically to test the harder claim: that the platform stays valuable even when it isn’t the orchestrator. The two paths aren’t rivals; they’re the same grounding story told from opposite ends.

“What stops the agent from doing something dumb or destructive?” The governance hook. Reads are free; every write pauses for a human in this build, and destructive operations are denied outright. You tune that dial per action - full autonomy where the blast radius is zero, human-in-the-loop where it isn’t.

“How locked-in am I?” Less than with any single-vendor agent stack. The brain talks to the systems over MCP and to other agents over A2A - both open protocols. Swap the model, swap a data source behind its MCP server, add a peer agent from another team: none of those is a rewrite.

Final thoughts

Strip it back and this is a build-vs-buy argument. The do-it-yourself path to a grounded enterprise agent is quarters of work: identity resolution, retrieval plumbing, workflow wrappers, a memory store, a governance layer, an audit trail, agent-to-agent interop. I know, because I just touched every one of those and only had to build a fraction of them - the rest already existed, reachable through one protocol.

That’s what the smarter-model conversation keeps missing. The demo only works because both halves run together: a best-in-class model as the brain, and an enterprise platform as the governed, grounded, memory-aware substrate under it. On its own, the model is a clever stranger; the platform, without a good model, is a database with a chat box in front of it.

You win AI in the enterprise not by replacing what companies have, but by orchestrating it.

I built the brain on someone else’s model on purpose - to find out whether the substrate still mattered when it wasn’t the one in charge. It mattered more, not less. Priya’s scattered data turned into one coherent conversation, her broken clasp turned into a ₹53,500 opportunity, and not one of the underlying systems had to move to make it happen.


This was a nights-and-weekends proof of concept, built solo. The orchestrator and MCP servers are Python; the two peer agents are authored on Agentforce; the warehouse is Snowflake; retrieval runs on a local vector index over policy documents written for the fictional brand. I leaned heavily on AI coding tools throughout - which is its own lesson: they’re superb at the orchestration glue and useless at the parts with no public training data (the platform’s own agent-scripting language being the sharpest example).

Opinions here are my own, not my employer’s. If you’re building something similar and want to compare notes - or you think I’ve got part of this wrong - I’d genuinely like to hear it.