This repository contains small, focused examples built while learning the OpenAI Agents SDK. The examples use openai-agents with an OpenAI compatible Gemini endpoint, and show how to build single agents, agents with tools, agents with memory, and multi agent systems.
- Python:
>=3.12 - Main dependencies:
openai-agents,python-dotenv,requests,pydantic - Environment variable required:
GEMINI_API_KEY
Most files create an AsyncOpenAI client with:
base_url="https://generativelanguage.googleapis.com/v1beta/openai/"We create this custom AsyncOpenAI client because these examples use a Gemini API key with Gemini's OpenAI compatible endpoint. If you are using an OpenAI API key directly, you usually do not need to create a custom client or set a custom base_url; the SDK can use the default OpenAI client configuration.
For RAG, you can also use OpenAI's proprietary vector store directly instead of building your own retrieval storage from scratch.
Run any example directly, for example:
uv run python chapter5/long_term_basic_persistant_memory.pyFile: chapter3/customer_service_agent.py
Concepts learned:
- Creating an
Agent - Running an agent with
Runner.run_sync - Adding a Python function as a tool using
@function_tool - Creating a handoff from one agent to another
Agents built:
Customer Service Agent: answers customer queries for a local paper company and can check order status.Customer Retention Agent: receives account cancellation cases and tries to retain the customer politely.
Tool built:
get_order_status(order_id): returns dummy statuses like delivered, delayed, or cancelled.
Chapter 4 focuses on giving agents external abilities through tools.
Files: model_settings.py, stop_at_tools.py, stop_on_first_tool.py, chained_tools_call.py
Concepts learned:
- Creating tools with
@function_tool - Overriding tool names and descriptions
- Forcing tool use with
ModelSettings(tool_choice="required") - Stopping after a tool call with
stop_on_first_tool - Stopping at selected tools with
StopAtTools - Chaining multiple tools in one task
Agents built:
Customer Service Agent: checks order status and creates invoices.Mortgage Advisor: calculates monthly mortgage payments.CustomerSupportAgent: gets a customer's orders, then checks each order status.
Tools built:
get_status_of_current_ordercreate_invoicecalculate_mortgageget_customer_ordersget_order_information
Files: complex_tool_input_with_pydantic.py, database_query_tool.py, multiple_coin_query.py
Concepts learned:
- Defining structured tool schemas with
pydantic.BaseModel - Passing complex objects into tools
- Querying simulated data stores
- Handling list inputs in a single tool call
Agents built:
Customer Service Agent: processes refund requests.SupportHelper: fetches support ticket history from a simulated database.CryptoTracker: fetches one or more cryptocurrency prices.
Models/tools built:
RefundRequestCustomerQueryCryptoprocess_refundget_customer_ticketsget_crypto_prices
Files: external_api_call.py, mcp_tool.py, agents_as_tool.py
Concepts learned:
- Calling external APIs from custom tools
- Using a hosted MCP tool
- Using
WebSearchTool - Using
CodeInterpreterTool - Turning agents into tools with
agent.as_tool(...) - Building an orchestrator agent that delegates subtasks
Agents built:
CryptoTracker: calls CoinGecko through a custom API tool.Crypto Agent: uses a hosted CoinGecko MCP server.LocationAgent: searches for latitude and longitude.DistanceCalculatorAgent: calculates distance using code execution.Orchestrator: combines the location and distance agents to answer distance questions.
Chapter 5 explores short term and long term memory patterns.
Files: simple_manual_memory.py, to_input_list.py
Concepts learned:
- Passing a list of messages into
Runner - Appending user and assistant messages manually
- Reusing
result.to_input_list()to continue a conversation
Agent built:
QuestionAnswer: answers follow up questions using prior conversation messages.
File: sliding_window.py
Concepts learned:
- Using
collections.deque(maxlen=...)to keep only recent messages - Preventing context from growing forever
- Running agents asynchronously with
await Runner.run(...)
Agent built:
QuestionAnswer: answers with only the latest window of conversation history.
Files: conversations_with_sessions.py, long_term_basic_persistant_memory.py
Concepts learned:
- Using
SQLiteSessionto store conversation history - Keeping state across turns without manually passing message lists
- Persisting session data to
messages.db - Using async loops for long running chat sessions
Agent built:
QuestionAnswer: a conversational Q&A agent backed by SDK sessions.
File: tool_based_structured_memory.py
Concepts learned:
- Combining
SQLiteSessionconversation memory with a separate structured memory store - Saving important facts to
memory.json - Loading memories by category through tools
- Giving the agent explicit save and load memory abilities
Agent built:
QuestionAnswer: can save and retrieve facts about the user.
Tools built:
save_memory(memory_type, memory)load_memory(memory_type)
Memory categories:
user_profileorder_preferencesother
Chapter 6 explores different ways to coordinate multiple agents.
File: basic_handoff.py
Concepts learned:
- Creating specialist agents
- Giving a triage agent a list of
handoffs - Letting the model decide which specialist should respond
Agents built:
Triage AgentComplaints AgentGeneral Inquiry Agent
Files: deterministic_approach.py, dynamic_approach.py
Concepts learned:
- Routing with normal Python control flow
- Routing dynamically by exposing agents as tools
- Comparing rule based orchestration with model driven delegation
Agents built:
Complaints AgentGeneral Inquiry AgentTriage Agent
Files: handoff_prompting.py, handoff_customization.py
Concepts learned:
- Using
RECOMMENDED_PROMPT_PREFIXfor better handoff behavior - Creating custom handoffs with
handoff(...) - Adding
on_handofflogging - Using Pydantic input for handoff metadata
- Tracking
result.last_agentso the conversation continues with the active specialist
Agents built:
Triage AgentComplaints AgentSales AgentGeneral Inquiry Agent
File: multi_agent_switching.py
Concepts learned:
- Allowing agents to hand off to each other
- Maintaining the current active agent with
last_agent - Keeping multi turn state with
SQLiteSession - Tracing a multi agent conversation with
trace(...)
Agents built:
Triage AgentComplaints AgentSales Agent
File: hierarchical _system.py
Concepts learned:
- Building a hierarchy of manager agents and specialist agents
- Routing first by broad domain, then by subdomain
- Continuing conversation with the last active agent
Agents built:
Research Triage AgentScience ManagerHistory ManagerPhysics AgentChemistry AgentMedical AgentPolitics AgentWarfare AgentCulture Agent
File: decentrailized_system.py
Concepts learned:
- Simulating a back and forth debate between agents
- Maintaining shared conversation history
- Summarizing multi agent output with a separate agent
Agents built:
Landlord AgentTenant AgentSummarizer Agent
File: swarm_system.py
Concepts learned:
- Running many agents with different roles on the same prompt
- Collecting their outputs
- Aggregating many responses into one final answer
Agents built:
- Role agents: Urban Planner, Artist, Chef, Engineer, Teacher, Doctor, Mechanic, Lawyer, Historian, Environmentalist
City Design Aggregator: combines all role agent ideas into one city plan.
- An
Agentcombines instructions, a model, tools, and optional handoffs. Runner.run_sync(...)is useful for simple scripts;await Runner.run(...)is useful for async apps.- Tools let agents access code, APIs, databases, MCP servers, web search, and code execution.
- Pydantic models make tool inputs structured and reliable.
- Sessions such as
SQLiteSessionprovide conversation memory without manually managing message lists. - Separate memory stores like
memory.jsonare useful for structured long term facts. - Handoffs, agents as tools, and orchestration logic allow multiple agents to collaborate.