A Field Journal on AI Agents in the SAP Stack
Agents with SAP
Issue 001 · N° 003 · ArchitectureJAN 29, 2026 · 4 min

When your orchestrator calls SAP's agent: patterns and pitfalls

What changes when SAP is an agent, not just an API — and what a Vertex AI orchestrator needs to know before delegating across vendor lines.

SAP AI CoreVertex AIA2AMulti-agentBTP

A logistics planner needs three things before recommending a shipment reroute: current inventory in S/4HANA, carrier slot availability from a third-party service, and a delay forecast from BigQuery. All three are online. None are wired together. You can write one integration that knows all three systems, or you can build three agents that each know one — and let them talk.

This dispatch is about the second option, and specifically the part that gets interesting: what happens when the SAP side is itself an agent, not just an API.

SAP as an agent, not just a data source

The previous dispatches treated SAP as the thing at the end of an OData call. That model still works. But as SAP embeds more intelligence into its platform — through SAP AI Core, through Joule, through agents that reason over business objects on BTP — the SAP side will sometimes be the smart side.

An SAP AI Core-hosted agent has the same shape as what we built in the A2A dispatch: a runtime, tools scoped to specific OData services, and an A2A endpoint with an AgentCard. What's different is who built and operates it. An SAP-owned agent carries SAP's view of what callers are allowed to do. It may enforce business rules the calling orchestrator knows nothing about — and that's by design.

{
  "name": "sap-inventory-agent",
  "description": "Returns stock levels and material availability for logistics planning.",
  "url": "https://inventory-agent.btp.example.com/a2a",
  "version": "1.0.0",
  "skills": [
    {
      "id": "check_material_availability",
      "description": "Returns available-to-promise quantity for a material across plant codes.",
      "inputModes": ["text", "data"],
      "outputModes": ["data"]
    }
  ],
  "authentication": { "schemes": ["bearer"] }
}

The skills list is a contract between agents. The Vertex orchestrator doesn't need to know which entity sets are involved or what filters apply. It only needs to know that check_material_availability takes a material number and plant codes and returns quantities.

Discovery, delegation, and parallel dispatch

From a Vertex AI orchestrator's perspective, the SAP agent is just another A2A endpoint. Discovery is the same pattern from the A2A dispatch: fetch the AgentCard, cache it, match skills to the task. What changes is that the orchestrator may now dispatch to multiple sub-agents at once. The inventory check and the carrier check are independent — there's no reason to run them sequentially.

import asyncio
from google.cloud.aiplatform.agents import A2AClient
 
sap_inventory = A2AClient.from_card(
    "https://inventory-agent.btp.example.com/.well-known/agent.json"
)
carrier = A2AClient.from_card(
    "https://carrier-agent.run.app/.well-known/agent.json"
)
 
inventory, capacity = await asyncio.gather(
    sap_inventory.run_task_async(
        skill="check_material_availability",
        message={"material": "MAT-5001", "plants": ["DE01", "DE02"]},
    ),
    carrier.run_task_async(
        skill="check_capacity",
        message={"shipment_id": "SHP-9921", "plant": "DE02"},
    ),
)
 
if inventory["available_qty"] > 0 and capacity["slots_available"]:
    recommend_reroute("DE02")

The synthesis at the end is a deterministic gate, not a model decision. The model decides which skills to invoke. The code decides what to do when both results are in hand.

Trust doesn't cross the boundary automatically

When the Vertex orchestrator calls the SAP agent, a bearer token arrives at a BTP endpoint. The SAP side has to decide what that bearer is allowed to do. Two patterns:

Service account identity. The orchestrator authenticates with its own client credentials. BTP sees "the orchestrator", not any individual user. Simple to set up, fine for background workflows with no human in the loop.

Propagated user identity. The orchestrator exchanges the user's Google Workspace token for a BTP-compatible one. The SAP agent now knows who is asking, and BTP's authorization checks apply normally.

The choice matters more than it looks. A service account with broad inventory-read access can query on behalf of any user — including users who shouldn't have that access at the SAP layer. The orchestrator becomes an unintentional escalation path.

The SAP agent is still the security boundary. A2A authenticates the caller. It does not give the caller new privileges.

What to keep in mind before you build

A few things that don't show up in the demo but matter in production:

Data residency. When the SAP agent's artifact moves from BTP into a Vertex AI runtime, data has crossed a boundary. For material codes and quantities that's likely fine. For anything touching personal data, check your compliance posture before the first deploy.

Audit stitching. BTP logs the task call. Vertex logs the delegation. They live on different platforms with different formats. If you ever need to reconstruct why the system made a recommendation, you need a correlation ID that flows through both. Build that into task metadata from the start.

Skill surface drift. AgentCards evolve. When the SAP team adds a new skill — say, approve_purchase_requisition — the orchestrator sees it on the next card fetch. If your system prompt is loose, it might try to use it. Audit new skills in a remote AgentCard before relying on them.