
Creating an AI agent can be complex, and all the concepts, frameworks, and practices you need to follow can be a bit overwhelming.
The good news is that adding agents to your application can be easy, and I’ll show you how.
What are AI agents?
AI agents are like really smart assistants. You just tell them what you need, and they figure out how to get it done!!
The LLM acts as the brain of the system. When an AI has to communicate with the outside world, obtain data, or carry out particular tasks, it can utilize tools, which are external resources or APIs.
They can plan, make decisions, and even get better over time. Think of it as a digital entity that can observe, think, and act, much like how humans interact with their surroundings, but in a programmed and purposeful manner.
Key Features and Benefits
I will guide you through the OpenAI Agents SDK, a powerful tool designed to simplify the creation of AI agents. The SDK offers several key features that make building and managing agents more efficient:
- Simplified Multi-Agent Handoff: Easily manage interactions between multiple agents, allowing for seamless task transitions.
- Built-in Guardrails: Implement safety and control mechanisms to ensure responsible agent behavior.
- Easy Lifecycle Hooks: Access and interact with agents at different stages of their execution, enabling custom actions and monitoring.
- Seamless Tool Integration: Integrate tools like web search and computer use effortlessly, expanding agent capabilities.
- By the end of this guide, you’ll understand the fundamental concepts and start Build Your First AI Agent.
Step 1: Setting Up Your Environment
First, let’s set up our project and install the necessary dependencies:
# Create a virtual environment using uv (you can also use pip)
uv venv
source .venv/bin/activate # On Windows: .venv\Scripts\activate
# Install required packages
pip install openai openai-agents pydantic python-dotenv agentops
Create a .env file in your project directory to store your API keys:
OPENAI_API_KEY=your_openai_api_key
AGENTOPS_API_KEY=your_agentops_api_key
What’s happening here?
We’re creating a dedicated folder for our project
A virtual environment isolates our project’s dependencies from other Python projects
We’re installing the libraries we need:
- openai: To access OpenAI’s API
- openai-agents: OpenAI’s Agents SDK
- pydantic: For data validation and settings management
- python-dotenv: To load environment variables from a .env file
- agentops: For monitoring and tracking our agents’ performance
Step 2: Defining Data Models Using Pydantic
Let’s create a file called health_and_wellness_agent.py and start by defining Pydantic models for structured outputs. These models help ensure our agent returns consistent, well-formatted information:
from pydantic import BaseModel, Field
from typing import List, Optional
class NutritionInfo(BaseModel):
foods: List[str] = Field(..., description="List of foods identified in the meal")
total_calories: Optional[int] = Field(None, description="Estimated total calories")
recommendations: Optional[List[str]] = Field(None, description="Nutritional recommendations")
class WorkoutPlan(BaseModel):
exercises: List[str] = Field(..., description="List of recommended exercises")
duration: str = Field(..., description="Recommended workout duration")
intensity: str = Field(..., description="Recommended intensity level")
class BMIResult(BaseModel):
bmi: Optional[float] = Field(None, description="Calculated BMI value")
category: Optional[str] = Field(None, description="BMI category")
advice: Optional[str] = Field(None, description="Health advice based on BMI")
class SleepRecommendation(BaseModel):
bedtime: Optional[str] = Field(None, description="Recommended bedtime")
tips: Optional[List[str]] = Field(None, description="Sleep hygiene tips")
What are we doing here?
- We’re using Pydantic, a data validation library, to define structured data models
- Each model represents a specific type of information our agent might return
- BaseModel is the base class for all Pydantic models
- Field lets us add metadata like descriptions to our fields
- List[str] means a list of strings
- Optional[int] means an integer that might be None
- These models help ensure our agent returns consistent, well-formatted information
Step 3: Use OpenAI Agent SDK’s inbuilt web_search tool
Next, we’ll define tools that our agent can use. For this example, we’ll create a web search tool:
from agents import function_tool
@function_tool
def web_search(query: str) -> str:
"""
Search the web for information.
Args:
query: The search query
Returns:
Search results from the web
"""
# Use OpenAI's built-in web search
response = client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": query}],
tools=[{"type": "web_search"}]
)
# Extract the search results from the response
tool_calls = response.choices[0].message.tool_calls
if tool_calls:
search_results = tool_calls[0].function.arguments
return f"Web search results for: {query}\n\n{search_results}"
else:
return f"No search results found for: {query}"
What’s happening here?
- We’re defining a function that our agent can call to search the web
- @function_tool is a decorator that turns a regular Python function into a tool for our agent
- We’re leveraging OpenAI’s built-in web search capability
- The function makes an API call to OpenAI with the web search tool enabled
- It extracts the search results from the response and formats them for the agent to use
- This approach eliminates the need for separate search API keys and implementations
Step 4: Creating Specialized Agents
Now, let’s create specialized agents for different health domains:
from agents import Agent
nutrition_agent = Agent(
name="nutrition_agent",
instructions="""You are a nutrition specialist.
When asked about food or meals, use the web_search tool to find nutritional information.
Return the information in a clear, structured format.
Always include:
- Identified foods
- Estimated calories (when possible)
- Nutritional recommendations
After providing your recommendations, ask ONE specific follow-up question to learn more about the user's
dietary preferences, restrictions, or habits. This will help you provide more personalized nutrition advice.
""",
tools=[web_search]
)
workout_agent = Agent(
name="workout_agent",
instructions="""You are a fitness trainer.
When asked about workouts or exercises, use the web_search tool to find appropriate workout plans.
Consider the user's fitness level, available equipment, and goals.
Always include:
- List of recommended exercises
- Recommended duration
- Intensity level
After providing your workout recommendations, ask ONE specific follow-up question to learn more about the
user's fitness level, available equipment, or exercise preferences. This will help you tailor future workout suggestions.
""",
tools=[web_search]
)
bmi_agent = Agent(
name="bmi_agent",
instructions="""You are a BMI calculator and advisor.
Calculate BMI using the formula: weight(kg) / height(m)².
Provide the BMI category and appropriate health advice.
Use web_search to find additional information if needed.
After providing BMI information, ask ONE specific follow-up question about the user's health goals or
current lifestyle to help provide more personalized health recommendations.
""",
tools=[web_search]
)
sleep_agent = Agent(
name="sleep_agent",
instructions="""You are a sleep specialist.
Provide sleep recommendations based on the user's wake-up time and sleep needs.
Use web_search to find sleep hygiene tips and other relevant information.
After providing sleep advice, ask ONE specific follow-up question about the user's current sleep habits,
bedtime routine, or sleep environment to help provide more tailored recommendations.
""",
tools=[web_search]
)
What’s happening here?
- We’re creating four specialized agents, each with expertise in a specific health domain
- Each agent is an instance of the Agent class from the Agents SDK
- The name parameter gives each agent a unique identifier for reference
- The instructions parameter provides detailed guidance on how the agent should behave
- Each agent has access to the web_search tool we defined earlier
- The instructions include specific formatting requirements for responses
- Each agent is instructed to ask a follow-up question to personalize future interactions
- This specialized approach allows for more detailed and accurate responses in each domain
Step 5: Creating the Main Health Coach Agent
Now, let’s create our main health coach agent that can hand off to specialized agents:
health_coach = Agent(
name="health_coach",
instructions="""You are a helpful health and wellness coach.
Your job is to help users improve their physical health, nutrition, sleep, and overall wellness.
For nutrition questions, hand off to the nutrition_agent.
For workout questions, hand off to the workout_agent.
For BMI calculations, hand off to the bmi_agent.
For sleep recommendations, hand off to the sleep_agent.
For general health questions, use web_search to find relevant information.
IMPORTANT: Always personalize your advice. After answering a user's question, ask ONE specific follow-up
question to learn more about their personal situation, preferences, or health metrics. This will help you
provide more tailored recommendations in future interactions.
Examples of good follow-up questions:
- "What foods do you typically enjoy for breakfast?"
- "How much time can you realistically dedicate to exercise each day?"
- "Do you have any dietary restrictions I should be aware of?"
- "What time do you usually wake up in the morning?"
Be supportive, encouraging, and non-judgmental. Focus on sustainable habits rather than quick fixes.
""",
tools=[web_search],
handoffs=[nutrition_agent, workout_agent, bmi_agent, sleep_agent]
)
What’s happening here?
- We’re creating a main coordinator agent that serves as the primary interface for users
- This agent can handle general health questions using the web_search tool
- The handoffs parameter lists the specialized agents this main agent can delegate to
- When a user asks about a specific domain (nutrition, workouts, BMI, sleep), the main agent will hand off to the appropriate specialized agent
- This creates a hierarchical structure where the main agent acts as a router
- The instructions emphasize personalization and follow-up questions
- The agent is guided to be supportive and focus on sustainable habits
- This approach combines the benefits of specialized knowledge with a unified user experience
Step 6: Integrating AgentOps for Monitoring
Let’s add AgentOps to track and monitor our agents’ performance:
import os
from dotenv import load_dotenv
import agentops
# Load environment variables from .env file
load_dotenv()
# Get API key from environment variables
AGENTOPS_API_KEY = os.getenv("AGENTOPS_API_KEY")
# Initialize AgentOps - this is all you need for automatic instrumentation
agentops.init(api_key=AGENTOPS_API_KEY, default_tags=["wellness_coach"])
What’s happening here?
- We’re setting up AgentOps to monitor and track our agents’ performance
- load_dotenv() loads environment variables from a .env file, including API keys
- os.getenv() retrieves the AgentOps API key from the environment variables
- agentops.init() initializes AgentOps with our API key and default tags
- The tag “wellness_coach” helps categorize this agent in the AgentOps dashboard
Step 7: Creating the Main Function
Finally, let’s create a main function to run our agent:
import asyncio
from agents import Runner
async def main():
print("Welcome to the Health and Wellness Coach!")
print("I can help you with workouts, nutrition, sleep, and general wellness advice.")
print("Type 'exit' at any time to end the conversation.\n")
query = input("How can I help with your health and wellness goals today? ")
while query.lower() != 'exit':
try:
# Run the agent - AgentOps will automatically track this
result = await Runner.run(health_coach, query)
# Print the response to the user
print(f"\nHealth Coach: {result.final_output}\n")
except Exception as e:
print(f"\nAn error occurred: {str(e)}\n")
# Get the next query
query = input("You: ")
if __name__ == "__main__":
asyncio.run(main())
What’s happening here?
- We’re creating an asynchronous function called main() to run our agent
- Asynchronous functions use async and await to handle operations that might take time
- We display a welcome message to orient the user
- We use a while loop to maintain a conversation until the user types ‘exit’
- Runner.run() executes our agent with the user’s query and returns the result
- input() gets text input from the user for the next query
- asyncio.run(main()) runs our asynchronous main function
Running Your Health & Wellness Coach
Once you’ve built your health and wellness coach using the OpenAI Agents SDK and AgentOps, you’ll need to know how to run it. Here are the steps to get your agent up and running:
Step 1: Save your code
Save all your code in a file named health_and_wellness_agent.py.
Step 2: Run the script
Open your terminal or command prompt, navigate to the directory containing your script, and run:
python health_and_wellness_agent.py
Step 3: Interact with your agent
Once the script is running, you’ll see a welcome message and a prompt asking how the agent can help with your health and wellness goals. Type your questions or requests, and the agent will respond.
Example interaction:
Welcome to the Health and Wellness Coach!
I can help you with workouts, nutrition, sleep, and general wellness advice.
Type 'exit' at any time to end the conversation.
How can I help with your health and wellness goals today? I want to improve my sleep quality
Health Coach: Based on your interest in improving sleep quality, here are some recommendations...
You: What foods should I avoid before bedtime?
Health Coach: When it comes to foods to avoid before bedtime...
You: exit