Skip to content

OpenAI Agents SDK

Overview

OpenAI Agents SDK (formerly Swarm) is OpenAI's official agent development framework. It provides lightweight yet fully functional agent building primitives, including tool calling, agent Handoff, Guardrails, and other core features.

Core Architecture

graph TD
    subgraph OpenAI Agents SDK
        A[Agent] --> B[Instructions<br/>System Prompt]
        A --> C[Tools<br/>Tool Set]
        A --> D[Handoffs<br/>Agent Handoff]
        A --> E[Guardrails]
    end

    subgraph Built-in Tools
        C --> C1[Web Search]
        C --> C2[Code Interpreter]
        C --> C3[File Search]
        C --> C4[Custom Functions]
    end

    subgraph Execution
        F[Runner] --> G[Agent Loop]
        G --> H[LLM Call]
        H --> I{Tool Call?}
        I -->|Yes| J[Execute Tool]
        J --> H
        I -->|No| K[Return Result]
    end

Basic Usage

Creating an Agent

from openai import agents

# Simplest agent
agent = agents.Agent(
    name="Assistant",
    instructions="You are a helpful assistant.",
    model="gpt-4o"
)

# Run
result = agents.Runner.run_sync(
    agent,
    messages=[{"role": "user", "content": "Hello!"}]
)
print(result.final_output)

Adding Tools

from openai.agents import Agent, Runner, function_tool

@function_tool
def get_weather(city: str) -> str:
    """Get current weather for a city."""
    return f"Weather in {city}: 72F, sunny"

@function_tool
def search_flights(origin: str, destination: str, date: str) -> str:
    """Search for available flights."""
    return f"Found 3 flights from {origin} to {destination} on {date}"

travel_agent = Agent(
    name="Travel Assistant",
    instructions="""You help users plan travel. Use the available 
    tools to get weather and flight information.""",
    tools=[get_weather, search_flights],
    model="gpt-4o"
)

Built-in Tools

from openai.agents import Agent, WebSearchTool

research_agent = Agent(
    name="Researcher",
    instructions="Search the web to answer questions with current information.",
    tools=[WebSearchTool()],
    model="gpt-4o"
)

Code Interpreter

from openai.agents import Agent, CodeInterpreterTool

data_agent = Agent(
    name="Data Analyst",
    instructions="""You analyze data using Python. 
    Write and execute code to answer questions.""",
    tools=[CodeInterpreterTool()],
    model="gpt-4o"
)

File Search (RAG)

from openai.agents import Agent, FileSearchTool

vector_store = client.vector_stores.create(name="knowledge_base")
client.vector_stores.file_batches.upload(
    vector_store_id=vector_store.id,
    files=["doc1.pdf", "doc2.pdf"]
)

knowledge_agent = Agent(
    name="Knowledge Assistant",
    instructions="Answer questions based on the uploaded documents.",
    tools=[FileSearchTool(vector_store_ids=[vector_store.id])],
    model="gpt-4o"
)

Handoff Pattern

Handoff is the core innovation of the Agents SDK, allowing seamless transfer of control between agents.

Basic Handoff

from openai.agents import Agent, handoff

billing_agent = Agent(
    name="Billing Specialist",
    instructions="You handle billing and payment questions.",
    tools=[check_balance, process_payment],
)

technical_agent = Agent(
    name="Technical Support",
    instructions="You handle technical issues and troubleshooting.",
    tools=[check_system_status, restart_service],
)

triage_agent = Agent(
    name="Customer Service",
    instructions="""You are the first point of contact. 
    Route to the appropriate specialist:
    - Billing questions -> Billing Specialist
    - Technical issues -> Technical Support""",
    handoffs=[
        handoff(billing_agent),
        handoff(technical_agent),
    ],
)

result = Runner.run_sync(
    triage_agent,
    messages=[{"role": "user", "content": "I can't log into my account"}]
)

Multi-Layer Handoff Architecture

graph TD
    A[Triage Agent] -->|Billing issues| B[Billing Agent]
    A -->|Technical issues| C[Tech Agent]
    A -->|Sales inquiries| D[Sales Agent]

    C -->|Network issues| C1[Network Specialist]
    C -->|Software issues| C2[Software Specialist]

    B -->|Refund requests| B1[Refund Agent]

Guardrails

Guardrails ensure agent behavior stays within safe boundaries.

Input Guardrails

from openai.agents import Agent, InputGuardrail, GuardrailResult

class ContentFilter(InputGuardrail):
    """Filter inappropriate input"""

    async def run(self, input_text: str) -> GuardrailResult:
        response = await moderation_llm.invoke(
            f"Is this input safe and appropriate? '{input_text}'"
        )

        if "unsafe" in response.lower():
            return GuardrailResult(
                allow=False,
                message="I'm sorry, I can't help with that request."
            )
        return GuardrailResult(allow=True)

safe_agent = Agent(
    name="Safe Assistant",
    instructions="You are a helpful assistant.",
    input_guardrails=[ContentFilter()],
)

Output Guardrails

class FactCheckGuardrail(OutputGuardrail):
    """Check output factual accuracy"""

    async def run(self, output_text: str) -> GuardrailResult:
        check = await fact_checker.verify(output_text)
        if check.confidence < 0.7:
            return GuardrailResult(
                allow=False,
                message="Let me double-check that information..."
            )
        return GuardrailResult(allow=True)

Agent Loop Details

Execution Flow

# Simplified Runner internal execution logic
class Runner:
    @staticmethod
    async def run(agent, messages, max_turns=10):
        current_agent = agent
        conversation = list(messages)

        for turn in range(max_turns):
            # 1. Check input guardrails
            for guardrail in current_agent.input_guardrails:
                result = await guardrail.run(conversation[-1])
                if not result.allow:
                    return RunResult(final_output=result.message)

            # 2. Call LLM
            response = await llm.create(
                model=current_agent.model,
                messages=[
                    {"role": "system", "content": current_agent.instructions},
                    *conversation
                ],
                tools=current_agent.get_tool_definitions(),
            )

            # 3. Process response
            if response.tool_calls:
                for tool_call in response.tool_calls:
                    if is_handoff(tool_call, current_agent):
                        current_agent = get_handoff_target(tool_call)
                        continue
                    result = await execute_tool(tool_call)
                    conversation.append(tool_result_message(result))
            else:
                # 4. Check output guardrails
                for guardrail in current_agent.output_guardrails:
                    result = await guardrail.run(response.content)
                    if not result.allow:
                        conversation.append(retry_message(result))
                        continue

                return RunResult(final_output=response.content)

Relationship with Responses API

The Agents SDK is built on top of OpenAI's Responses API:

Layer Description
Responses API Low-level API supporting tool calls, streaming output
Agents SDK High-level framework providing Agent abstraction, Handoff, Guardrails

Streaming Output

from openai.agents import Runner

async def stream_response():
    async for event in Runner.run_streamed(
        agent,
        messages=[{"role": "user", "content": "Write a story"}]
    ):
        if event.type == "text_delta":
            print(event.delta, end="", flush=True)
        elif event.type == "tool_call":
            print(f"\n[Calling tool: {event.tool_name}]")
        elif event.type == "handoff":
            print(f"\n[Transferring to: {event.target_agent}]")

Best Practices

1. Agent Design Principles

  • Single responsibility: Each agent focuses on one domain
  • Clear instructions: Instructions should be specific and explicit
  • Appropriate tools: Only give agents the tools they need
  • Reasonable handoffs: Clearly define handoff conditions

2. Error Handling

from openai.agents import RunResult

result = await Runner.run(agent, messages=messages, max_turns=10)

if result.is_error:
    logger.error(f"Agent error: {result.error}")
    fallback_response = "I'm having trouble. Let me connect you with a human agent."

3. Cost Control

  • Use gpt-4o-mini for simple routing
  • Limit max_turns to prevent infinite loops
  • Cache results for common queries

Summary

Core advantages of the OpenAI Agents SDK:

  1. Simplicity: Minimal concepts, quick to get started
  2. Handoff pattern: Elegant multi-agent collaboration approach
  3. Built-in tools: Web Search, Code Interpreter ready out of the box
  4. Guardrails: Native safety mechanism
  5. OpenAI integration: Seamless connection with the OpenAI ecosystem

评论 #