{ "cells": [ { "cell_type": "markdown", "id": "1e5b29d1", "metadata": {}, "source": [ "# Multi-Agent Orchestration with OpenAI Agents SDK: Financial Portfolio Analysis Example\n", "\n", "## Introduction\n", "\n", "*This guide is for readers already familiar with OpenAI models and LLM agents, and want to see how to orchestrate a team of agents for a real-world, complex task.*\n", "\n", "**What You'll Learn**\n", "\n", "In this notebook, you'll learn how to use the OpenAI Agents SDK to design and implement a complex multi-agent collaboration system. Specifically, you'll see how to:\n", "- Build a workflow where multiple specialist agents (Macro, Fundamental, Quantitative) collaborate under a Portfolio Manager agent to solve a challenging investment research problem.\n", "- Use the \"agents as a tool\" approach, where a central agent orchestrates and calls other agents as tools for specific subtasks.\n", "- Leverage all major tool types supported by the SDK (custom Python functions, managed tools like Code Interpreter and WebSearch, and external MCP servers) in a single, integrated workflow.\n", "- Apply best practices for modularity, parallelism, and observability in agentic patterns.\n", "\n", "**Why this matters**\n", "\n", "The \"agents as a tool\" pattern is a powerful way to build transparent, auditable, and scalable multi-agent collaboration . This example demonstrates how to combine deep specialization, parallel execution, and robust orchestration using the OpenAI Agents SDK.\n", "\n", "By the end of this guide, you'll have a clear blueprint for building your own multi-agent workflows for research, analysis, or any complex task that benefits from expert collaboration.\n" ] }, { "cell_type": "markdown", "id": "ed547489", "metadata": {}, "source": [ "\n", "---\n", "\n", "## Table of Contents\n", "\n", "1. [What is Multi-Agent Collaboration?](#what-is-multi-agent-collaboration)\n", "2. [Collaboration Patterns: Handoff vs. Agent-as-Tool](#collaboration-patterns-handoff-vs-agent-as-tool)\n", "3. [Architecture Overview](#architecture-overview)\n", "4. [Supported Tool Types](#supported-tool-types)\n", "5. [Setup](#setup)\n", "6. [Running the Workflow](#running-the-workflow)\n", "7. [The Head Portfolio Manager (PM) Agent](#the-head-portfolio-manager-pm-agent)\n", "8. [Breaking Down the Head Portfolio Manager Agent](#breaking-down-the-head-portfolio-manager-agent)\n", "9. [Example Output](#example-output)\n", "10. [Best Practices When Building Agents](#best-practices-when-building-agents)\n", "11. [Further Reading & Best Practices](#further-reading--best-practices)\n" ] }, { "cell_type": "markdown", "id": "26670dad", "metadata": {}, "source": [ "\n", "---\n", "\n", "## What is Multi-Agent Collaboration?\n", "\n", "**Multi-agent collaboration** means multiple autonomous agents (LLM \"nodes\") coordinate to achieve an overarching goal that would be difficult for a single agent to handle. Instead of one monolithic prompt, each agent handles a specific subtask or expertise area, and an orchestration layer connects these agent \"nodes\" into a coherent workflow. This approach is useful for complex systems – for example, a financial analysis might be broken into macro-economic analysis, fundamental company analysis, and quantitative signal analysis, each handled by a different agent specialist. The agents share information and their results are combined to produce a final outcome.\n" ] }, { "cell_type": "markdown", "id": "4d5f3a58", "metadata": {}, "source": [ "\n", "### Collaboration Patterns: Handoff vs. Agent-as-Tool\n", "\n", "The OpenAI Agents SDK supports multiple patterns for agents to work together:\n", "\n", "- **Handoff Collaboration:** One agent can _handoff_ control to another agent mid-problem. In a handoff architecture, each agent knows about the others and can decide when to defer to a more appropriate agent. This is flexible for open-ended or conversational workflows, but can make it harder to maintain a global view of the task. [Read more in the SDK docs.](https://openai.github.io/openai-agents-python/handoffs/)\n", "\n", "- **Agent as a Tool:** In this approach, one agent (often a central planner or manager) **calls other agents as if they were tools**. Sub-agents don't take over the conversation; instead, the main agent invokes them for specific subtasks and incorporates their results. This model keeps a single thread of control (the main agent orchestrates everything) and tends to simplify coordination. **This repo uses the agent-as-tool model:** the Portfolio Manager agent remains in charge, using the other specialist agents as tools when it needs their expertise. This choice keeps the overall reasoning transparent and allows parallel execution of sub-tasks, which is ideal for complex analyses.\n", "\n", "For more on these collaboration patterns, see the [OpenAI Agents SDK documentation](https://openai.github.io/openai-agents-python/multi_agent/).\n", "\n", "---\n", "\n", "## Architecture Overview\n", "\n", "Our system follows a **hub-and-spoke design**. The **Portfolio Manager agent** is the hub (central coordinator), and the **specialist agents** are the spokes. The user's query (e.g. \"How would a planned interest rate reduction affect my GOOGL holdings?\") goes first to the Portfolio Manager. The Portfolio Manager agent is prompted to break down the problem and delegate to the appropriate specialist agents. It treats each specialist as a callable tool, invoking them for their portion of the analysis. All three report back to the Portfolio Manager, which then synthesizes a final answer for the user.\n", "\n", "\n" ] }, { "cell_type": "markdown", "id": "a7a2ef1e", "metadata": {}, "source": [ "\n", "---\n", "\n", "## Supported Tool Types\n", "\n", "A key advantage of the Agents SDK is the flexibility in defining **tools** that agents can use. Tools can range from simple Python functions to external services. In this project, we use:\n", "\n", "- **MCP (Model Context Protocol) Server:** Used to connect agents to external tools and data sources in a standardized way. This project uses a local MCP server for Yahoo Finance data (see `mcp/yahoo_finance_server.py`). [Learn more: OpenAI MCP docs](https://openai.github.io/openai-agents-python/mcp/) | [MCP Spec](https://modelcontextprotocol.io/)\n", "\n", "- **OpenAI Managed Tools:** Managed tools are built-in, hosted tools provided by OpenAI that require no custom implementation. They offer powerful capabilities out of the box, such as **Code Interpreter** (for quantitative/statistical analysis) and **WebSearch** (for up-to-date news and data). These tools are easy to integrate, maintained by OpenAI, and allow agents to perform advanced actions like code execution and real-time information retrieval without additional setup.\n", "\n", "- **Custom Tools:** Custom tools are any Python functions you define and register as tools for your agent. The Agents SDK makes this easy: just decorate your function, and the SDK will automatically extract its name, docstring, and input schema. This is ideal for domain-specific logic, data access, or workflow extensions. \n", " In our project, we use custom tools to access FRED economic data ([see FRED API](https://fred.stlouisfed.org/docs/api/api_key.html)) and perform file system operations.\n", "\n", "Custom tools give you full flexibility to extend your agent's capabilities beyond built-in or managed tools. [See the SDK docs on function tools.](https://openai.github.io/openai-agents-python/tools/#function-tools)\n", "\n", "> **Want to add more tools?** The SDK supports a wide range of tool types, including web search, file search, code execution, and more. [See the full list of supported tools in the SDK documentation.](https://openai.github.io/openai-agents-python/tools/)\n", "\n", "---\n", "\n", "## Setup" ] }, { "cell_type": "code", "execution_count": null, "id": "b128b837", "metadata": {}, "outputs": [], "source": [ "# Install required dependencies\n", "!pip install -r requirements.txt" ] }, { "cell_type": "markdown", "id": "21c2f377", "metadata": {}, "source": [ "**Before running the workflow, set your environment variables:**\n", "- `OPENAI_API_KEY` (for OpenAI access)\n", "- `FRED_API_KEY` (for FRED economic data, see [FRED API key instructions](https://fred.stlouisfed.org/docs/api/api_key.html))" ] }, { "cell_type": "code", "execution_count": null, "id": "c70bf2c3", "metadata": {}, "outputs": [], "source": [ "import os\n", "\n", "missing = []\n", "if not os.environ.get('OPENAI_API_KEY'):\n", " missing.append('OPENAI_API_KEY')\n", "if not os.environ.get('FRED_API_KEY'):\n", " missing.append('FRED_API_KEY')\n", "\n", "if missing:\n", " print(f\"Missing environment variable(s): {', '.join(missing)}. Please set them before running the workflow.\")\n", "else:\n", " print(\"All required API keys are set.\")" ] }, { "cell_type": "markdown", "id": "f3b2c4e5", "metadata": {}, "source": [ "---\n", "\n", "## Running the Workflow \n", "\n", "Edit the question to whatever you'd like, but keep the date field to improve accuracy!\n", "\n", "