Skip to main content
Multi-Agent Systems

OpenAI Agents SDK in Production: Enterprise Handoff Architecture for Multi-Agent Systems

OpenAI's Agents SDK — the successor to the experimental Swarm library — is now the vendor-blessed way to build multi-agent systems on OpenAI models. Handoffs, guardrails, and structured outputs are first-class primitives, and it is deliberately small enough to reason about. This is a practical look at what the SDK actually gives you, how it fits into an enterprise architecture, and the deployment patterns we use in production.

Inductivee Team· AI EngineeringJuly 8, 202614 min read
TL;DR

TL;DR. The OpenAI Agents SDK is a small, opinionated Python (and now TypeScript) library for building agents on OpenAI models. It graduated from the Swarm experiment with four primitives worth learning: Agent, Handoff, Tool, and Guardrail — plus built-in tracing and session management. It is not a heavyweight orchestration framework and does not try to be. In production it fits best when the shape of your work is 'route the user to the right specialist agent, then let that agent act within constrained rails,' and when you want a runtime whose entire behaviour you can hold in your head.

From Swarm to Production SDK

The Agents SDK's lineage matters. OpenAI shipped Swarm as an educational, experimental library — deliberately unmaintained — to demonstrate the handoff pattern for multi-agent systems. Teams liked the pattern enough that Swarm ended up in production against explicit warnings. The Agents SDK is OpenAI's response: the same handoff-first mental model, but with the production concerns Swarm ignored — tracing, guardrails, structured outputs, sessions, proper testing — treated as first-class.

The important thing to internalise: the SDK is small on purpose. It has four primitives, a handful of decorators, and a tracing surface. That is the whole thing. Anything bigger you build sits around it, not inside it. Teams coming from LangChain sometimes read this as under-featured and reach for something heavier; teams coming from having written their own agent loop read it as exactly enough.

The Four Primitives

Agent. An LLM plus instructions, a model, and a set of tools. The agent has a name (which is what handoffs address) and can have structured output via a Pydantic schema. That is essentially the type: an agent is a callable object that takes user input and returns a run result.

Handoff. A special kind of tool call where one agent delegates the rest of the conversation to another agent. The receiving agent inherits the message history and continues from there. This is how the SDK models specialisation: you do not build one giant prompt that tries to be a support agent, a billing agent, and a returns agent; you build three narrower agents and let a triage agent hand off.

Tool. A Python function decorated with @function_tool, exposed to the agent, invoked by the runtime when the model asks. Same shape as tool use in the raw Chat Completions API, but with the schema derived from the function signature and docstring automatically.

Guardrail. A function that inspects an input or output and can halt execution. Input guardrails run before the agent starts; output guardrails run before results reach the user. This is where content policy, PII checks, and jailbreak defence live. Guardrails run in parallel with the agent to keep latency down.

On top of these there are two supporting pieces: Sessions for persistent conversation state, and a Tracing surface that records the full run — every agent invocation, every tool call, every handoff, every guardrail decision — for inspection in the OpenAI dashboard or export to your own observability.

How the OpenAI Agents SDK Compares to the Alternatives

vs. Claude Agent SDK

The two SDKs converge on similar territory from different vendors. Both are opinionated, both give you a tight runtime around a model, both take governance seriously. The centre of gravity differs: OpenAI's SDK puts handoffs and guardrails at the front of the mental model; Claude's SDK puts subagents, hooks, and native MCP integration at the front. If your workflow decomposes cleanly into specialist agents that transfer conversations between them, the OpenAI shape fits naturally. If your workflow is one agent with rich tool use, either fits, and the deciding factor is usually the model. Either way, do not choose 'both' — pick one per product and let the AI gateway handle the model-provider question separately.

vs. LangGraph

LangGraph is a state-machine framework — you model your agent as an explicit graph of nodes and edges, with the graph runtime deciding what runs when. The Agents SDK is the opposite: the LLM decides what runs next, within the rails of tools, handoffs, and guardrails. LangGraph is a better fit when the workflow is well-defined and you need deterministic control over transitions. The Agents SDK is a better fit when you want the model to plan and act, and you are prepared to constrain what it can do through guardrails and tool granularity. Complex production systems sometimes run both — LangGraph as the outer orchestration, an Agents-SDK agent inside specific nodes.

vs. CrewAI and AutoGen

CrewAI models agents as roles in a team and assigns tasks between them; AutoGen models agents as conversational participants and lets them discuss until they converge. Both work, and both introduce more abstraction than the Agents SDK. The SDK's handoff model gives you the specialisation without the metaphor: an agent is a callable, a handoff is a transfer of control, and the trace makes the whole run inspectable. Teams that found CrewAI or AutoGen more surface than they wanted often land on the Agents SDK.

vs. Writing Your Own Loop on Chat Completions

You can build the same shape on the raw Chat Completions API. What you would end up writing looks a lot like the Agents SDK — the SDK captures the answers to about a dozen small design decisions (retry semantics, streaming, session state, guardrail parallelism, structured output validation) that everyone re-decides when they hand-roll. If you have no strong reason to hand-roll, the SDK is engineering time you get back.

The Handoff Pattern: What It Is Actually For

The handoff primitive is the SDK's opinion about how to structure multi-agent systems, and it is worth taking seriously. The shape is: a small triage agent with a broad set of possible handoffs, and specialist agents with tight instructions and narrow tool grants. The triage agent's job is not to solve the user's problem — it is to identify what the user needs and hand off to the specialist who can solve it.

Why this pattern beats one giant prompt: the specialist prompts stay short and unambiguous, tool grants stay minimal, and you can evaluate each specialist independently. It also degrades gracefully — if a new specialist is misbehaving, you disable that handoff and traffic returns to the triage agent's fallback behaviour, without a rewrite.

The pattern breaks down when the specialists need to collaborate mid-conversation rather than transfer control. If your problem is 'a lawyer and an engineer both weigh in on the same question and produce a synthesis,' handoffs are the wrong tool — you want either a parallel-invocation pattern or a proper multi-agent orchestrator like LangGraph or CrewAI. Handoffs assume one active agent at a time.

Guardrails: Where the Production Story Actually Lives

Guardrails are the primitive most teams underestimate. In a demo, guardrails are a nice-to-have; in production they are the difference between a fun prototype and a system you can defend to legal, security, and support.

The SDK's guardrail model is deliberately simple: a guardrail is a function that takes the input (or output) and either passes or raises. Input guardrails run before the agent starts, in parallel with the model call being dispatched. If any input guardrail fails, the run is halted and the failure is returned; the model was never invoked. Output guardrails run before the result reaches the caller, and can halt the response even after generation.

What goes in an input guardrail: prompt-injection detection, PII detection with policy on what to do about it, off-topic detection (so your billing agent does not answer medical questions), rate-limit checks. What goes in an output guardrail: refusal detection, PII leakage, structural checks (does this JSON parse), policy violations. Standard prompt-injection defence still applies here — the SDK gives you the enforcement point but you supply the detection logic, usually a combination of pattern matching for cheap cases and an LLM classifier for the harder ones.

Reference Architecture for an OpenAI Agents SDK Deployment

LayerResponsibilityWhat runs there
Ingress / gatewayTLS termination, authentication, rate limitingAPI gateway (Kong, ingress controller, or a managed API tier)
Application serviceSession routing, agent invocation, business logic around the SDKStateless Python service (FastAPI or similar) hosting the Runner
Agent runtimeAgent loop, tool routing, handoffs, guardrailsOpenAI Agents SDK
LLM accessKey management, budgets, model routing, cost accountingAI gateway (LiteLLM or equivalent)
ToolsEnterprise system integrationIn-process functions for fast internal work; MCP servers for reusable, auditable integrations
Session storePersistent conversation state across turnsRedis or a relational store, depending on retention needs
ObservabilityTraces, prompt versions, evaluations, costLangfuse, LangSmith, or an APM vendor's LLM module
Governance policyRules about what agents may do, in which contextsSmall policy service consulted from guardrails

A Production-Shaped Agent Setup

python
# agents.py (sketch — real projects split this across modules)

from agents import Agent, Runner, function_tool, GuardrailFunctionOutput, input_guardrail
from pydantic import BaseModel

# ---- Structured outputs ----
class TicketDecision(BaseModel):
    action: str          # 'route_billing', 'route_returns', 'answer_directly'
    rationale: str

# ---- Tools ----
@function_tool
def lookup_order(order_id: str) -> dict:
    """Look up an order by ID. Read-only."""
    return order_service.get(order_id)  # your service

@function_tool
def create_refund_request(order_id: str, reason: str) -> dict:
    """Create a refund request. Requires supervisor approval before it is executed."""
    return refund_service.create_pending(order_id, reason)

# ---- Input guardrails ----
@input_guardrail
async def block_prompt_injection(ctx, agent, input_text):
    # Cheap heuristics first, LLM classifier for anything ambiguous.
    verdict = injection_classifier.classify(input_text)
    return GuardrailFunctionOutput(
        output_info={'score': verdict.score},
        tripwire_triggered=verdict.is_injection,
    )

@input_guardrail
async def enforce_scope(ctx, agent, input_text):
    # This agent handles support. Reject medical, legal, financial advice.
    verdict = scope_classifier.classify(input_text)
    return GuardrailFunctionOutput(
        output_info={'topic': verdict.topic},
        tripwire_triggered=not verdict.in_scope,
    )

# ---- Specialist agents ----
billing_agent = Agent(
    name='billing',
    instructions=BILLING_INSTRUCTIONS,
    tools=[lookup_order, create_refund_request],
    model='gpt-4.1',
)

returns_agent = Agent(
    name='returns',
    instructions=RETURNS_INSTRUCTIONS,
    tools=[lookup_order],
    model='gpt-4.1',
)

# ---- Triage agent ----
triage_agent = Agent(
    name='triage',
    instructions=TRIAGE_INSTRUCTIONS,
    handoffs=[billing_agent, returns_agent],
    input_guardrails=[block_prompt_injection, enforce_scope],
    model='gpt-4.1-mini',   # cheaper model for routing
)

# ---- Runtime ----
async def handle_message(session_id: str, user_input: str):
    result = await Runner.run(
        triage_agent,
        input=user_input,
        session=session_store.get_or_create(session_id),
    )
    return result.final_output

Structured Outputs, and Why They Matter More Than You Think

Every agent that returns to a system rather than a human should return a structured output. The SDK supports this natively via Pydantic: give the agent an output_type, and the SDK will enforce it — retrying if the model produces malformed output, or failing loudly if it cannot.

Why this matters: an agent whose output is a validated schema is composable. You can chain it, log it, evaluate it, and route on its fields deterministically. An agent whose output is prose is a black box that needs another LLM call to parse. The engineering cost of defining a Pydantic model is far smaller than the operational cost of parsing free-form text at every downstream step.

The pattern that works: user-facing conversational agents return prose; every other agent — routing, extraction, classification, tool selection, planning — returns a schema. Even 'chat with structured metadata' is a common shape: the visible answer is prose, the metadata (confidence, sources cited, next action) is structured. The SDK supports this cleanly.

Warning

Tracing is on by default and it goes to OpenAI. By default the SDK's tracing surface exports traces to the OpenAI platform dashboard. That is fine for many teams; for regulated or sensitive workloads, you either need to opt out of that export and point traces at your own observability, or ensure your OpenAI enterprise agreement covers where trace data lives. Decide this before you deploy, not after.

Where the OpenAI Agents SDK Tends To Be the Right Choice

You are already committed to OpenAI models

The SDK is optimised for the Responses and Chat Completions APIs. If OpenAI is decided and you want a runtime that plays to its shape — including reasoning models, structured outputs, and computer-use — this is the fit.

Your workflow decomposes into specialists with a triage step

The handoff model is opinionated. If your product has a natural pattern of 'figure out what the user needs, then route to the right expert,' the SDK's shape is exactly right and other frameworks are overkill.

You want production primitives — guardrails, tracing, sessions — in the box

You do not have to build the plumbing. Guardrails run in parallel with model calls, sessions persist across turns, and traces cover the whole run. That is a lot of scaffolding you avoid.

You value a runtime you can hold in your head

The SDK is small. You can read the source over a lunch break. For teams that value understanding their production stack top to bottom, that is a real advantage over larger frameworks.

Where It Is Not the Right Choice

If your workflow is a rigid pipeline with occasional model calls, an agent runtime is overkill — a workflow engine calling the OpenAI API directly is simpler. If you need agents that collaborate mid-conversation rather than transfer control, handoffs are the wrong primitive and a proper multi-agent orchestrator is a better fit. If your primary model is not OpenAI, the SDK does support other models via LiteLLM but it is not its centre of gravity — the Claude Agent SDK or a framework-agnostic runtime will feel more natural. And if compliance forbids sending your data to hosted OpenAI endpoints at all, the interesting question is which self-hostable model and runtime you can use, not which vendor SDK.

Seven Decisions Worth Making Before Your First Deploy

  • Handoff topology. Draw the agent graph before you write code. A triage agent plus three or four specialists is a proven shape. Twenty specialists behind one triage agent is a warning sign — either merge some, or introduce a second triage layer.
  • Model per agent. Use cheaper models for routing and more capable models for specialists that do the actual work. A gpt-4.1-mini triage agent handing off to a gpt-4.1 specialist is a common cost pattern that also improves triage latency.
  • Guardrail placement. Input guardrails belong on the entry point — usually the triage agent, so nothing bypasses them. Output guardrails belong on the specialist that produces user-facing output. Do not sprinkle guardrails across every agent; concentrate them at the edges.
  • Structured outputs everywhere except the user-facing surface. Every internal agent should return a Pydantic model. The one exception is the agent that produces the final message to the human, which returns prose.
  • Session store. Redis for high-volume, short-retention chat. Postgres for regulated workloads that need long retention and audit. Whatever you pick, decide up front what session-expiry, session-length, and session-privacy look like.
  • Tracing destination. OpenAI-hosted for teams comfortable with that data location; disabled and forwarded to your own observability platform for regulated workloads. This is a compliance decision, not a technical one.
  • Route through an AI gateway. Point the SDK at LiteLLM or equivalent rather than directly at api.openai.com. You get key management, budgets, virtual keys, and per-tenant cost accounting for free, and you keep the option of moving traffic to a different provider without a rewrite.

How To Approach an OpenAI Agents SDK Pilot

Pilot shape that works: pick one product surface with real traffic and a natural triage pattern — support intake, sales qualification, an internal ops helpdesk. Build one triage agent plus two or three specialist agents. Wire input guardrails on the triage agent — prompt-injection detection and scope enforcement, at minimum. Point the SDK at your AI gateway. Route traces to your observability platform. Run it in shadow mode for a week, then suggested-action mode for another week where the agent proposes and a human accepts, then autonomous for the safest actions only.

At the end you will have concrete numbers on handoff patterns (which specialist gets routed to and how often), guardrail trip rates (how often did we block), cost per conversation, and the specific failure modes that come up in your context. That is the input you actually need to decide the next investment — more specialists, better guardrails, richer tools, or a rethink of the topology.

If you would like help with the architecture — the handoff graph, the guardrail suite, the tracing and evaluation setup, or connecting agents to your existing AI governance framework, gateway, and observability layertalk to us. We have run this shape across customer-facing, employee-facing, and internal-ops deployments, and the reference architecture is far more repeatable than most first builds assume.

Frequently Asked Questions

Is the OpenAI Agents SDK the same thing as Swarm?

It is the production successor to Swarm. Swarm was explicitly an educational, unmaintained experiment. The Agents SDK keeps the handoff pattern that Swarm demonstrated but adds the production concerns Swarm ignored — tracing, guardrails, structured outputs, sessions, testing — and is maintained. If you have code on Swarm, migrating is the right move.

Can we use non-OpenAI models with the Agents SDK?

Yes — the SDK supports non-OpenAI models via LiteLLM as a model provider, so any provider with a LiteLLM adapter can be plugged in. That said, the SDK's centre of gravity is OpenAI models, and features like the Responses API integration and computer-use are OpenAI-specific. For genuinely provider-agnostic work, either accept that trade-off or pick a framework designed around provider flexibility from the start.

How does this compare to LangGraph for us?

LangGraph is a graph-orchestration framework where you model the workflow explicitly as nodes and edges. The Agents SDK hands control to the model and constrains it through guardrails and handoffs. LangGraph fits when the workflow is deterministic and you want tight control over transitions. The Agents SDK fits when you want the model to plan and act. Complex systems sometimes use both — LangGraph as the outer orchestrator, an Agents SDK agent inside specific nodes.

How do handoffs actually work under the hood?

A handoff is a special tool call. When the current agent decides to hand off, the runtime terminates the current agent's turn and starts the target agent with the accumulated message history. The target agent picks up as if it had been in the conversation the whole time. This is why the pattern works cleanly for triage-plus-specialists and awkwardly for problems where agents need to collaborate mid-conversation.

Where should we put guardrails and how many?

Input guardrails belong on the entry-point agent — usually the triage agent — so nothing can bypass them by being routed to a specialist. Output guardrails belong on whichever agent produces user-facing output. Two to four guardrails on the entry point is typical: prompt-injection detection, scope enforcement, and PII checks. Do not put the same guardrails on every agent — that is duplication and slows things down.

Is tracing safe to leave on for our compliance posture?

By default, SDK traces are exported to the OpenAI platform dashboard. Whether that is acceptable depends on your enterprise agreement with OpenAI and your regulatory context. If it is not, disable the built-in export and route traces to your own observability platform via the SDK's trace processor hooks. Decide this before you deploy, not after — retrofitting is much harder than starting with the correct configuration.

How does this fit alongside our AI gateway and observability?

Cleanly. Point the SDK's OpenAI client at your gateway (LiteLLM or equivalent) rather than directly at api.openai.com — the gateway handles keys, budgets, and per-tenant accounting. Route traces to your observability platform via the trace processor hooks. The SDK stays focused on the agent loop, the gateway owns access, observability owns the trace data. Those layers do not overlap.

Written By

Inductivee Team — AI Engineering at Inductivee

Inductivee Team

Author

Agentic AI Engineering Team

The Inductivee engineering team — a remote-first group of multi-agent orchestration specialists, RAG pipeline architects, and data liquidity engineers who have shipped 40+ agentic deployments across 25+ enterprises since 2012. Our writing is grounded in what we actually build, break, and operate in production.

Agentic AI ArchitectureMulti-Agent OrchestrationLangChainLangGraphCrewAIMicrosoft AutoGen
LinkedIn profile

Inductivee is a remote-first agentic AI engineering firm with 40+ production deployments across 25+ enterprises since 2012. Our engineering content is written by active practitioners and technically reviewed before publication. Compliance: SOC2 Type II, HIPAA, GDPR, ISO 27001.

Ready to Build This Into Your Enterprise?

Inductivee engineers agentic systems, RAG pipelines, and enterprise data liquidity solutions. Let's scope your project.

Start a Project