---
title: "OpenAI Agents"
description: "[**OpenAI-Agents**](https://openai.github.io/openai-agents-python/) is a lightweight Python library for building agentic AI apps. It includes a few abstractions:"
---


* **Agents**, which are LLMs equipped with instructions and tools
* **Handoffs**, which allow agents to delegate to other agents for specific tasks
* **Guardrails**, which enable the inputs to agents to be validated

This guide outlines common agent workflows using this SDK. We will walk through building an investment agent across several use cases.

```python
from agents import Agent, Runner, WebSearchTool

agent = Agent(
    name="Finance Agent",
    instructions="You are a finance agent that can answer questions about stocks. Use web search to retrieve up‑to‑date context. Then, return a brief, concise answer that is one sentence long.",
    tools=[WebSearchTool()],
    model="gpt-4.1-mini",
)
```

## Design Considerations and Limitations

| Design Considerations | Features & Limitations |
| :--------------------- | :---------------------- |
| Model support | First class support for OpenAI LLMs, and basic support for any LLM using a LiteLLM wrapper. Support for reasoning effort parameter to tradeoff on reducing latency or increasing accuracy. |
| Structured outputs | First-class support with OpenAI LLMs. LLMs that do not support `json_schema` as a parameter are [not supported](https://openai.github.io/openai-agents-python/models/#structured-outputs-support). |
| Tools | Very easy, using the `@function_call` decorator. Support for parallel tool calls to reduce latency. Built-in support for OpenAI SDK for `WebSearchTool`, `ComputerTool`, and `FileSearchTool` |
| Agent handoff | Very easy using `handoffs` variable |
| Multimodal support | Voice support, no support for images or video |
| Guardrails | Enables validation of both inputs and outputs |
| Retry logic | ⚠️ No retry logic, developers must manually handle failure cases |
| Memory | ⚠️ No built-in memory management. Developers must manage their own conversation and user memory. |
| Code execution | ⚠️ No built-in support for executing code |

## Simple agent

An LLM agent with access to tools to accomplish a task is the most basic flow. This agent answers questions about stocks and uses OpenAI web search to get real time information.


<Card title="phoenix/tutorials/agents/openai/openai_agents_basic.ipynb at main · Arize-ai/phoenix" href="https://github.com/Arize-ai/phoenix/blob/main/tutorials/agents/openai/openai_agents_basic.ipynb" icon="github" horizontal description="Basic agent notebook"/>

```python
from agents import Agent, Runner, WebSearchTool

agent = Agent(
    name="Finance Agent",
    instructions="You are a finance agent that can answer questions about stocks. Use web search to retrieve up‑to‑date context. Then, return a brief, concise answer that is one sentence long.",
    tools=[WebSearchTool()],
    model="gpt-4.1-mini",
)
```

## Prompt chaining

This agent builds a portfolio of stocks and ETFs using multiple agents linked together:

1. **Search Agent:** Searches the web for information on particular stock tickers.
2. **Report Agent:** Creates a portfolio of stocks and ETFs that supports the user's investment strategy.

<Card title="phoenix/tutorials/agents/openai/openai_agents_prompt_chaining.ipynb at main · Arize-ai/phoenix" href="https://github.com/Arize-ai/phoenix/blob/main/tutorials/agents/openai/openai_agents_prompt_chaining.ipynb" icon="github" horizontal description="Prompt chaining notebook"/>

```python expandable
portfolio_agent = Agent(
    name="Portfolio Agent",
    instructions="You are a senior financial analyst. You will be provided with a stock research report. Your task is to create a portfolio of stocks and ETFs that could support the user's stated investment strategy. Include facts and data from the research report in the stated reasons for the portfolio allocation.",
    model="o4-mini",
    output_type=Portfolio,
)

research_agent = Agent(
    name="FinancialSearchAgent",
    instructions="You are a research assistant specializing in financial topics. Given an investment strategy, use web search to retrieve up‑to‑date context and produce a short summary of stocks that support the investment strategy at most 50 words. Focus on key numbers, events, or quotes that will be useful to a financial analyst.",
    model="gpt-4.1",
    tools=[WebSearchTool()],
    model_settings=ModelSettings(tool_choice="required", parallel_tool_calls=True),
)
```

## Parallelization

This agent researches stocks for you. If we want to research 5 stocks, we can force the agent to run multiple tool calls, instead of sequentially.

<Card title="phoenix/tutorials/agents/openai/openai_agents_parallelization.ipynb at main · Arize-ai/phoenix" href="https://github.com/Arize-ai/phoenix/blob/main/tutorials/agents/openai/openai_agents_parallelization.ipynb" icon="github" horizontal description="Parallelization notebook"/>

```python expandable
@function_tool
def get_stock_data(ticker_symbol: str) -> dict:
    """
    Get stock data for a given ticker symbol.
    Args:
        ticker_symbol: The ticker symbol of the stock to get data for.
    Returns:
        A dictionary containing stock data such as price, market cap, and more.
    """
    import yfinance as yf
    stock = yf.Ticker(ticker_symbol)
    return stock.info

research_agent = Agent(
    name="FinancialSearchAgent",
    instructions=dedent(
        """You are a research assistant specializing in financial topics. Given a stock ticker, use web search to retrieve up‑to‑date context and produce a short summary of at most 50 words. Focus on key numbers, events, or quotes that will be useful to a financial analyst."""
    ),
    model="gpt-4.1",
    tools=[WebSearchTool(), get_stock_data_tool],
    model_settings=ModelSettings(tool_choice="required", parallel_tool_calls=True),
)
```

## Router agent

This agent answers questions about investing using multiple agents. A central router agent chooses which worker to use.

1. **Research Agent:** Searches the web for information about stocks and ETFs.
2. **Question Answering Agent:** Answers questions about investing like Warren Buffett.

<Card title="phoenix/tutorials/agents/openai/openai_agents_routing.ipynb at main · Arize-ai/phoenix" href="https://github.com/Arize-ai/phoenix/blob/main/tutorials/agents/openai/openai_agents_routing.ipynb" icon="github" horizontal description="Routing notebook"/>

```python expandable
qa_agent = Agent(
    name="Investing Q&A Agent",
    instructions="You are Warren Buffett. You are answering questions about investing.",
    model="gpt-4.1",
)

research_agent = Agent(
    name="Financial Search Agent",
    instructions="You are a research assistant specializing in financial topics. Given a stock ticker, use web search to retrieve up‑to‑date context and produce a short summary of at most 50 words. Focus on key numbers, events, or quotes that will be useful to a financial analyst.",
    model="gpt-4.1",
    tools=[WebSearchTool()],
)

orchestrator_agent = Agent(
    name="Routing Agent",
    instructions="You are a senior financial analyst. Your task is to handoff to the appropriate agent or tool.",
    model="gpt-4.1",
    handoffs=[research_agent,qa_agent],
)
```
## Evaluator-Optimizer

When creating LLM outputs, often times the first generation is unsatisfactory. You can use an agentic loop to iteratively improve the output by asking an LLM to give feedback, and then use the feedback to improve the output.

This agent pattern creates reports and evaluates itself to improve its output.

1. **Report Agent (Generation):** Creates a report on a particular stock ticker.
2. **Evaluator Agent (Feedback):** Evaluates the report and provides feedback on what to improve.

<Card title="phoenix/tutorials/agents/openai/openai_agents_evaluator_optimizer.ipynb at main · Arize-ai/phoenix" href="https://github.com/Arize-ai/phoenix/blob/main/tutorials/agents/openai/openai_agents_evaluator_optimizer.ipynb" icon="github" horizontal description="Evaluator-optimizer notebook"/>

```python expandable
class EvaluationFeedback(BaseModel):
    feedback: str = Field(
        description=f"What is missing from the research report on positive and negative catalysts for a particular stock ticker. Catalysts include changes in {CATALYSTS}.")
    score: Literal["pass", "needs_improvement", "fail"] = Field(
        description="A score on the research report. Pass if the report is complete and contains at least 3 positive and 3 negative catalysts for the right stock ticker, needs_improvement if the report is missing some information, and fail if the report is completely wrong.")


report_agent = Agent(
    name="Catalyst Report Agent",
    instructions=dedent(
        """You are a research assistant specializing in stock research. Given a stock ticker, generate a report of 3 positive and 3 negative catalysts that could move the stock price in the future in 50 words or less."""
    ),
    model="gpt-4.1",
)

evaluation_agent = Agent(
    name="Evaluation Agent",
    instructions=dedent(
        """You are a senior financial analyst. You will be provided with a stock research report with positive and negative catalysts. Your task is to evaluate the report and provide feedback on what to improve."""
    ),
    model="gpt-4.1",
    output_type=EvaluationFeedback,
)
```

## Orchestrator worker

This is the most advanced pattern in the examples, using orchestrators and workers together. The orchestrator chooses which worker to use for a specific sub-task. The worker attempts to complete the sub-task and return a result. The orchestrator then uses the result to choose the next worker to use until a final result is returned.

In the following example, we'll build an agent which creates a portfolio of stocks and ETFs based on a user's investment strategy.

1. **Orchestrator:** Chooses which worker to use based on the user's investment strategy.
2. **Research Agent:** Searches the web for information about stocks and ETFs that could support the user's investment strategy.
3. **Evaluation Agent:** Evaluates the research report and provides feedback on what data is missing.
4. **Portfolio Agent:** Creates a portfolio of stocks and ETFs based on the research report.

<Card title="phoenix/tutorials/agents/openai/openai_agents_orchestrator.ipynb at main · Arize-ai/phoenix" href="https://github.com/Arize-ai/phoenix/blob/main/tutorials/agents/openai/openai_agents_orchestrator.ipynb" icon="github" horizontal description="Orchestrator-worker notebook"/>

```python expandable
evaluation_agent = Agent(
    name="Evaluation Agent",
    instructions=dedent(
        """You are a senior financial analyst. You will be provided with a stock research report with positive and negative catalysts. Your task is to evaluate the report and provide feedback on what to improve."""
    ),
    model="gpt-4.1",
    output_type=EvaluationFeedback,
)

portfolio_agent = Agent(
    name="Portfolio Agent",
    instructions=dedent(
        """You are a senior financial analyst. You will be provided with a stock research report. Your task is to create a portfolio of stocks and ETFs that could support the user's stated investment strategy. Include facts and data from the research report in the stated reasons for the portfolio allocation."""
    ),
    model="o4-mini",
    output_type=Portfolio,
)

research_agent = Agent(
    name="FinancialSearchAgent",
    instructions=dedent(
        """You are a research assistant specializing in financial topics. Given a stock ticker, use web search to retrieve up‑to‑date context and produce a short summary of at most 50 words. Focus on key numbers, events, or quotes that will be useful to a financial analyst."""
    ),
    model="gpt-4.1",
    tools=[WebSearchTool()],
    model_settings=ModelSettings(tool_choice="required", parallel_tool_calls=True),
)

orchestrator_agent = Agent(
    name="Routing Agent",
    instructions=dedent("""You are a senior financial analyst. You are trying to create a portfolio based on my stated investment strategy. Your task is to handoff to the appropriate agent or tool.

    First, handoff to the research_agent to give you a report on stocks and ETFs that could support the user's stated investment strategy.
    Then, handoff to the evaluation_agent to give you a score on the research report. If the evaluation_agent returns a needs_improvement or fail, continue using the research_agent to gather more information.
    Once the evaluation_agent returns a pass, handoff to the portfolio_agent to create a portfolio."""),
    model="gpt-4.1",
    handoffs=[
        research_agent,
        evaluation_agent,
        portfolio_agent,
    ],
)
```

This uses the following structured outputs.

```python expandable
class PortfolioItem(BaseModel):
    ticker: str = Field(description="The ticker of the stock or ETF.")
    allocation: float = Field(
        description="The percentage allocation of the ticker in the portfolio. The sum of all allocations should be 100."
    )
    reason: str = Field(description="The reason why this ticker is included in the portfolio.")


class Portfolio(BaseModel):
    tickers: list[PortfolioItem] = Field(
        description="A list of tickers that could support the user's stated investment strategy."
    )


class EvaluationFeedback(BaseModel):
    feedback: str = Field(
        description="What data is missing in order to create a portfolio of stocks and ETFs based on the user's investment strategy."
    )
    score: Literal["pass", "needs_improvement", "fail"] = Field(
        description="A score on the research report. Pass if you have at least 5 tickers with data that supports the user's investment strategy to create a portfolio, needs_improvement if you do not have enough supporting data, and fail if you have no tickers."
    )
```
