agentbreeder
Migrations

From OpenAI Agents

Migrate an existing OpenAI Agents project to AgentBreeder.

Migrate from OpenAI Agents SDK to AgentBreeder

Time to migrate: ~15 minutes Difficulty: Easy What changes: You add an agent.yaml file. Your OpenAI Agents SDK code stays exactly the same.


Before You Start

  • You have an existing OpenAI Agents SDK agent (using the openai-agents package)
  • Your agent code is in agent.py or main.py with requirements.txt
  • Python 3.11+ is installed
  • Docker is installed and running
  • You have installed AgentBreeder: pip install agentbreeder

The Big Picture

The OpenAI Agents SDK gives you a clean API for building agents with Agent, Runner, function_tool, and Handoff. AgentBreeder does not replace any of that. It wraps your agent in a production container and adds everything you need for enterprise deployment: RBAC, cost tracking, health checks, model fallbacks, and org-wide discoverability.

Key insight: Your agent's simplicity is preserved. AgentBreeder adds zero imports to your code.


Before & After

Before: Raw OpenAI Agents SDK

my-agent/
  agent.py            # Agent + tools definition
  requirements.txt
  Dockerfile          # you wrote this
  fly.toml            # or render.yaml, or ECS task def...

After: OpenAI Agents SDK + AgentBreeder

my-agent/
  agent.py            # UNCHANGED
  requirements.txt    # UNCHANGED
  agent.yaml          # NEW -- the AG config

Step-by-Step Migration

Step 1: Verify your agent structure

AgentBreeder accepts either agent.py or main.py. Your file should export an agent variable -- an openai.agents.Agent instance:

# agent.py
from agents import Agent, function_tool

@function_tool
def lookup_order(order_id: str) -> str:
    """Look up an order by ID."""
    return f"Order {order_id}: shipped, arriving tomorrow"

agent = Agent(
    name="Support Agent",
    instructions="You are a helpful customer support agent...",
    tools=[lookup_order],
)

The variable must be named agent. If yours is named differently, add an alias:

my_bot = Agent(name="My Bot", ...)
agent = my_bot  # alias for AgentBreeder

Step 2: Create agent.yaml

name: support-agent
version: 1.0.0
description: "Customer support agent with order lookup"
team: support
owner: you@company.com
tags: [openai-agents, support, production]

framework: openai_agents

model:
  primary: gpt-4o
  fallback: gpt-4o-mini

tools:
  - name: lookup_order
    type: function
    description: "Look up an order by ID"

deploy:
  cloud: local
  secrets:
    - OPENAI_API_KEY

Step 3: Validate

agentbreeder validate agent.yaml

Step 4: Deploy

agentbreeder deploy agent.yaml --target local

Step 5: Test

curl -X POST http://localhost:8080/invoke \
  -d '{"input": {"message": "Where is order #12345?"}}' \
  -H 'Content-Type: application/json'

Step 6: Deploy to cloud

deploy:
  cloud: aws
  runtime: ecs-fargate
  region: us-east-1
  scaling:
    min: 1
    max: 10
    target_cpu: 70
  resources:
    cpu: "0.5"
    memory: "1Gi"
  secrets:
    - OPENAI_API_KEY
agentbreeder deploy agent.yaml --target aws

Concept Mapping: OpenAI Agents SDK to AgentBreeder

OpenAI Agents ConceptAgentBreeder EquivalentNotes
Agent(name, instructions, tools)Export as agent in agent.pyAG wraps it; does not replace it
Runner.run(agent, input)POST /invoke on deployed containerAG server wrapper calls Runner
function_tooltools: in agent.yamlDeclare for documentation; implementation stays in your code
Handoffsubagents: in agent.yaml or orchestration.yamlAG can also orchestrate handoffs at platform level
Agent.modelmodel.primary in agent.yamlAG adds fallback, gateway, temperature
Agent.instructionsprompts.system in agent.yaml (optional)Can reference versioned prompts from registry
guardrail decoratorguardrails: in agent.yamlAG adds PII detection, content filter, hallucination check
RunResultJSON response from /invokeSame data, wrapped in AG response format
Streaming (Runner.run_streamed)Streaming supported via AG serverSSE endpoint at /stream
trace / OpenAI tracingAG tracing (OpenTelemetry)Automatic, framework-agnostic

Handling Handoffs

The OpenAI Agents SDK has a Handoff mechanism for transferring control between agents. There are two ways to handle this with AgentBreeder:

Option A: Keep Handoffs in Your Code (Simple)

If your handoff agents are all defined in the same agent.py, they work as-is. AgentBreeder deploys the entire file as one unit:

# agent.py
from agents import Agent, Handoff, function_tool

billing_agent = Agent(
    name="Billing",
    instructions="Handle billing and payment questions.",
    tools=[lookup_invoice],
)

tech_agent = Agent(
    name="Tech Support",
    instructions="Handle technical issues.",
    tools=[check_status, restart_service],
)

triage_agent = Agent(
    name="Triage",
    instructions="Route customer requests to the right specialist.",
    handoffs=[
        Handoff(target=billing_agent, description="Billing questions"),
        Handoff(target=tech_agent, description="Technical support"),
    ],
)

# Export the entry point agent
agent = triage_agent
# agent.yaml
name: support-triage
framework: openai_agents
model:
  primary: gpt-4o
deploy:
  cloud: local
  secrets:
    - OPENAI_API_KEY

Option B: Separate Agents + AG Orchestration (Advanced)

Deploy each agent independently and use AG orchestration for cross-agent routing:

# orchestration.yaml
name: support-router
version: 1.0.0
team: support
owner: you@company.com
strategy: router

agents:
  triage:
    ref: agents/triage-agent
    routes:
      - condition: "billing"
        target: billing
      - condition: "technical"
        target: tech-support
  billing:
    ref: agents/billing-agent
  tech-support:
    ref: agents/tech-support-agent

deploy:
  target: local

Benefits of Option B:

  • Independent scaling (tech support might need more capacity than billing)
  • Different teams can own different agents
  • Per-agent cost tracking
  • Mix frameworks (triage could be OpenAI Agents, billing could be LangGraph)

Preserving the Simple OpenAI API

One of the OpenAI Agents SDK's strengths is its simplicity. AgentBreeder preserves that completely:

Your code before AG:

from agents import Agent, Runner, function_tool

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

agent = Agent(
    name="Weather Bot",
    instructions="Help users check the weather.",
    tools=[get_weather],
)

# Local testing
result = await Runner.run(agent, "What's the weather in SF?")
print(result.final_output)

Your code after AG:

# Exactly the same file. Zero changes.

The only addition is agent.yaml next to it. You can still run python agent.py for local testing without any AgentBreeder dependency.


Adding Governance

Model fallback (protects against OpenAI outages)

model:
  primary: gpt-4o
  fallback: claude-sonnet-4
  gateway: litellm

With LiteLLM gateway, AgentBreeder can transparently fall back to a non-OpenAI model. Your OpenAI Agents SDK code does not need to change -- the gateway translates the API.

Guardrails

guardrails:
  - pii_detection
  - content_filter
  - hallucination_check

These run as middleware around your agent's responses, before they reach the caller.

Access control

access:
  visibility: team
  allowed_callers:
    - team:support
  require_approval: false

MCP servers (tool sidecar injection)

Attach MCP tool servers as sidecars to your agent:

mcp_servers:
  - ref: mcp/zendesk
    transport: stdio
  - ref: mcp/order-management

Knowledge bases

knowledge_bases:
  - ref: kb/product-docs
  - ref: kb/faq-database

What You Gain

FeatureOpenAI Agents SDK Only+ AgentBreeder
Agent definitionAgent()Same (unchanged)
Tool definition@function_toolSame (unchanged)
Running agentRunner.run()Same locally; HTTP endpoint in production
DeployManualagentbreeder deploy agent.yaml
Multi-cloudManualOne-line change
Model fallbackNot built-inDeclarative, cross-provider
RBACNot availableAutomatic
Cost trackingNot availablePer-agent, per-model
Guardrails@guardrail decoratorDeclarative + your custom guardrails
Agent discoveryNot availableOrg-wide registry
Health checksNot availableAutomatic
AutoscalingManualDeclarative
Audit trailNot availableEvery invocation logged
Multi-agent orchestrationHandoffs (in-process)Handoffs + cross-service orchestration

What Stays the Same

  • Your Agent definitions (name, instructions, tools)
  • Your function_tool implementations
  • Your Handoff configurations
  • Your Runner.run() invocations for local testing
  • Your guardrail decorators (AG adds platform-level ones on top)
  • Your ability to run standalone: python agent.py

Troubleshooting

"Missing agent.py or main.py"

AgentBreeder accepts either filename. If your entry point is something else:

# agent.py
from my_bot import agent  # re-export

"No 'agent' variable found"

The AG server wrapper imports agent from your file. Make sure it is exported at module level:

agent = Agent(name="My Agent", ...)  # must be at module level, not inside a function

OpenAI API key not found in container

Add it to secrets:

deploy:
  secrets:
    - OPENAI_API_KEY

For local deploy, set it in your environment before running agentbreeder deploy, or create a .env file in the agent directory.

Streaming responses

The AG server wrapper supports streaming via Server-Sent Events. The /stream endpoint uses Runner.run_streamed() under the hood.

Multiple agents in one file

If you have multiple agents with handoffs in one file, export the "entry point" agent (the one that receives initial input) as agent:

agent = triage_agent  # the first agent that receives input

AG imports this agent and uses it as the entry point. Handoff targets are resolved from the same module automatically.

Container health check fails

The default health check hits /health on port 8080. If your agent's dependencies take time to initialize (downloading models, connecting to databases), the check may time out. Ensure heavy initialization is lazy or happens at import time before the server starts.


Full Example

agent.py:

from __future__ import annotations
import math
from agents import Agent, Runner, function_tool


@function_tool
def web_search(query: str) -> str:
    """Search the web for information on a given query."""
    return (
        f"Search results for '{query}':\n"
        f"1. Wikipedia article on {query}\n"
        f"2. Recent news about {query}\n"
        f"3. Academic papers related to {query}"
    )


@function_tool
def calculator(expression: str) -> str:
    """Evaluate a mathematical expression safely."""
    allowed_names = {
        "abs": abs, "round": round, "min": min, "max": max,
        "pow": pow, "sqrt": math.sqrt, "pi": math.pi, "e": math.e,
    }
    try:
        result = eval(expression, {"__builtins__": {}}, allowed_names)
        return str(result)
    except Exception as e:
        return f"Error: {e}"


agent = Agent(
    name="Research Assistant",
    instructions=(
        "You are a helpful research assistant. Use your tools to find "
        "accurate information and provide well-structured answers."
    ),
    tools=[web_search, calculator],
)


async def main() -> None:
    """Run the agent interactively for local testing."""
    result = await Runner.run(agent, "What is the square root of 144 plus 25?")
    print(f"Agent response: {result.final_output}")


if __name__ == "__main__":
    import asyncio
    asyncio.run(main())

requirements.txt:

openai-agents>=0.1.0
openai>=1.60.0

agent.yaml:

name: research-assistant
version: 0.1.0
description: "A research assistant agent built with the OpenAI Agents SDK"
team: examples
owner: dev@agentbreeder.com
tags: [example, openai-agents, research, tools]

framework: openai_agents

model:
  primary: gpt-4o-mini

tools:
  - name: web_search
    type: function
    description: "Search the web for information"
  - name: calculator
    type: function
    description: "Evaluate mathematical expressions"

deploy:
  cloud: local
  secrets:
    - OPENAI_API_KEY

Deploy:

agentbreeder deploy agent.yaml

On this page