Building AI Agents with GPT-5 and Python
RELEASES Nov. 30, 2025, 11:31 a.m.

Building AI Agents with GPT-5 and Python

Imagine having a personal AI sidekick that doesn't just chat but actually gets things done—researching topics, crunching numbers, or even drafting emails for you. That's the magic of AI agents powered by GPT-5 and Python. In this hands-on guide, we'll build intelligent agents step-by-step, from simple responders to sophisticated multi-tool powerhouses.

With GPT-5's superior reasoning and tool-use capabilities, creating autonomous agents has never been easier. You'll end up with deployable code you can run today (using the latest OpenAI models like gpt-4o, prepped for GPT-5). Let's dive in and turn your ideas into action-oriented AI.

What Are AI Agents?

AI agents are more than chatbots—they're autonomous systems that perceive their environment, reason about goals, and take actions using tools. Think of them as digital butlers: given a task like "plan my week," they break it down, query calendars, suggest schedules, and confirm with you.

GPT-5 supercharges this with advanced planning, memory, and error correction. Unlike basic LLMs, agents loop through observation, thought, and action (the ReAct pattern), making them ideal for real-world tasks.

  • Reactive agents: Respond to inputs with tools (e.g., math solver).
  • Planning agents: Decompose complex goals into steps.
  • Multi-agent systems: Teams of specialized agents collaborating.

Pro Tip: Start simple—over-engineer early and you'll get tangled in state management. Prototype with OpenAI's Assistants API before custom frameworks.

Setting Up Your Environment

Before coding, grab your tools. You'll need Python 3.10+, an OpenAI API key (free tier works for testing), and a few libraries.

  1. Create a virtual environment: python -m venv agent_env and activate it.
  2. Install dependencies: pip install openai python-dotenv streamlit.
  3. Set your API key: Create a .env file with OPENAI_API_KEY=your_key_here.

This setup uses OpenAI's Python SDK for GPT-5-level models (specify gpt-4o now, swap to gpt-5 later). Streamlit lets us demo agents in a web UI quickly.

import os
from dotenv import load_dotenv
from openai import OpenAI

load_dotenv()
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))

print("Ready to build agents!")

Pro Tip: Monitor costs—GPT-5 will be pricey for heavy tool calls. Use cheaper models like gpt-4o-mini for prototyping.

Building Your First AI Agent: A Task Planner

Let's create our first agent using OpenAI's Assistants API. This handles conversation state, tools, and runs automatically—no manual loops needed.

Our agent will plan daily tasks. It reasons step-by-step and suggests actions. Run this code to see it in action.

from openai import OpenAI

client = OpenAI()

# Create a reusable assistant
assistant = client.beta.assistants.create(
    name="Task Planner",
    instructions="You are a helpful task planner. Break down user goals into actionable steps, prioritize, and suggest timelines.",
    model="gpt-4o",  # Swap to 'gpt-5' when available
    tools=[]
)

# Start a thread (conversation)
thread = client.beta.threads.create()

# Add a message
message = client.beta.threads.messages.create(
    thread_id=thread.id,
    role="user",
    content="Plan my week: gym 3x, finish report, call mom."
)

# Run the assistant
run = client.beta.threads.runs.create(thread_id=thread.id, assistant_id=assistant.id)

# Poll for completion
import time
while run.status != "completed":
    run = client.beta.threads.runs.retrieve(thread_id=thread.id, run_id=run.id)
    time.sleep(1)

# Get response
messages = client.beta.threads.messages.list(thread_id=thread.id)
print(messages.data[0].content[0].text.value)

This outputs a detailed plan like: "Monday: Gym (30min), start report outline..." Magic! The agent maintains context across runs.

Real-World Use Case: Personal Productivity Booster

Integrate this into a calendar app. Users say "Schedule meetings around deadlines," and the agent syncs with Google Calendar via tools (more on that soon). Teams at startups use similar for project management, saving hours weekly.

Supercharging with Tools: Math and Search Agent

Plain reasoning is cool, but tools make agents unstoppable. GPT-5 excels at function calling—let's add a calculator and mock web search.

Custom tools are Python functions decorated for OpenAI. Our agent will solve math and "research" facts.

from openai import OpenAI
import json

client = OpenAI()

# Define tools
tools = [
    {
        "type": "function",
        "function": {
            "name": "calculate",
            "description": "Solve math expressions",
            "parameters": {
                "type": "object",
                "properties": {
                    "expression": {"type": "string", "description": "Math expression e.g., '2+2*3'"}
                },
                "required": ["expression"]
            }
        }
    },
    {
        "type": "function",
        "function": {
            "name": "search_knowledge",
            "description": "Search internal knowledge base",
            "parameters": {
                "type": "object",
                "properties": {
                    "query": {"type": "string"}
                },
                "required": ["query"]
            }
        }
    }
]

assistant = client.beta.assistants.create(
    name="Math & Research Agent",
    instructions="Use tools for calculations and facts. Reason step-by-step.",
    model="gpt-4o",
    tools=tools
)

def calculate(expression):
    try:
        return str(eval(expression))
    except:
        return "Error in calculation"

def search_knowledge(query):
    # Mock DB - replace with real search (e.g., Tavily, Pinecone)
    knowledge = {"python": "Python is a programming language created by Guido van Rossum.", "gpt5": "GPT-5 is OpenAI's next flagship model with enhanced reasoning."}
    return knowledge.get(query.lower(), "No info found.")

# Tool executor
def run_tool(tool_call):
    if tool_call.function.name == "calculate":
        args = json.loads(tool_call.function.arguments)
        return calculate(args["expression"])
    elif tool_call.function.name == "search_knowledge":
        args = json.loads(tool_call.function.arguments)
        return search_knowledge(args["query"])

# Create thread and message
thread = client.beta.threads.create()
message = client.beta.threads.messages.create(
    thread_id=thread.id,
    role="user",
    content="What's 15% of 200? And tell me about GPT-5."
)

run = client.beta.threads.runs.create(thread_id=thread.id, assistant_id=assistant.id)

# Handle tool calls
while run.status == "requires_action":
    tool_calls = run.required_action.submit_tool_outputs.tool_calls
    tool_outputs = []
    for tool_call in tool_calls:
        output = run_tool(tool_call)
        tool_outputs.append({
            "tool_call_id": tool_call.id,
            "output": output
        })
    run = client.beta.threads.runs.submit_tool_outputs(
        thread_id=thread.id,
        run_id=run.id,
        tool_outputs=tool_outputs
    )
    while run.status not in ["completed", "failed"]:
        run = client.beta.threads.runs.retrieve(thread_id=thread.id, run_id=run.id)
        time.sleep(1)

messages = client.beta.threads.messages.list(thread_id=thread.id)
print(messages.data[0].content[0].text.value)

Output: "15% of 200 is 30 (calculated). GPT-5 is OpenAI's next model..." The agent calls tools seamlessly, chaining if needed.

Pro Tip: Always validate tool inputs/outputs—LLMs can hallucinate args. Use Pydantic for schema safety in production.

Real-World Use Case: Data Analyst Agent

Finance teams deploy these for queries like "Forecast Q3 revenue from this CSV." Add file upload tools (Assistants support retrieval), and it crunches numbers, plots charts. Beats manual Excel by 10x speed.

Advanced Agent: Multi-Step Automation with Memory

For complex workflows, build a ReAct-style agent with persistent memory. We'll create an email drafter that researches, calculates ROI, and composes.

Use threads for memory. Add more tools: email sender (mocked), web scraper.

from openai import OpenAI
import json
import time

client = OpenAI()

# Expanded tools
tools = [
    {
        "type": "function",
        "function": {
            "name": "get_weather",
            "description": "Get current weather for a city",
            "parameters": {
                "type": "object",
                "properties": {"city": {"type": "string"}},
                "required": ["city"]
            }
        }
    },
    {
        "type": "function",
        "function": {
            "name": "draft_email",
            "description": "Draft professional email",
            "parameters": {
                "type": "object",
                "properties": {
                    "to": {"type": "string"},
                    "subject": {"type": "string"},
                    "body": {"type": "string"}
                },
                "required": ["to", "subject", "body"]
            }
        }
    }
]

assistant = client.beta.assistants.create(
    name="Email Automation Agent",
    instructions="You plan emails: research context (use tools), draft, confirm before send. Remember past interactions.",
    model="gpt-4o",
    tools=tools
)

def get_weather(city):
    # Mock API
    return f"Weather in {city}: Sunny, 22°C"

def draft_email(to, subject, body):
    return f"Email drafted to {to}\nSubject: {subject}\nBody: {body}\n[Send? Y/N]"

thread = client.beta.threads.create()  # Persistent memory

# Multi-turn example
messages = [
    "Draft an email to boss about project delay due to weather in NYC.",
    "Ok, send it."
]

for msg in messages:
    client.beta.threads.messages.create(thread_id=thread.id, role="user", content=msg)
    run = client.beta.threads.runs.create(thread_id=thread.id, assistant_id=assistant.id)
    
    # Tool loop
    while run.status == "requires_action":
        tool_calls = run.required_action.submit_tool_outputs.tool_calls
        tool_outputs = []
        for tc in tool_calls:
            if tc.function.name == "get_weather":
                args = json.loads(tc.function.arguments)
                out = get_weather(args["city"])
            elif tc.function.name == "draft_email":
                args = json.loads(tc.function.arguments)
                out = draft_email(args["to"], args["subject"], args["body"])
            tool_outputs.append({"tool_call_id": tc.id, "output": out})
        run = client.beta.threads.runs.submit_tool_outputs(
            thread_id=thread.id, run_id=run.id, tool_outputs=tool_outputs
        )
    while run.status not in ["completed", "failed"]:
        run = client.beta.threads.runs.retrieve(thread_id=thread.id, run_id=run.id)
        time.sleep(1)

# Final messages
msgs = client.beta.threads.messages.list(thread_id=thread.id)
for m in msgs.data:
    print(f"{m.role}: {m.content[0].text.value}")

This agent remembers context, researches weather, drafts, and "sends." Extend with SMTP for real emails.

Real-World Use Case: Sales Outreach Agent

Sales reps use these to personalize 100s of emails: "Research prospect's latest tweet, calculate deal value, draft pitch." Conversion rates jump 20-30%. Or automate support: triage tickets, query DBs, respond.

Pro Tip: For production, add human-in-loop approval for actions like emails. Use LangGraph for custom flows beyond Assistants API.

Deployment: From Script to Web App

Scripts are great, but users want UIs. Wrap your agent in Streamlit for instant demos.

# app.py - Run with: streamlit run app.py
import streamlit as st
from openai import OpenAI
import os
from dotenv import load_dotenv

load_dotenv()
client = OpenAI()

# Reuse your assistant ID (create once)
ASSISTANT_ID = "your_assistant_id_here"  # From previous create

st.title("🤖 GPT-5 Task Agent")

if "thread_id" not in st.session_state:
    st.session_state.thread_id = client.beta.threads.create().id

user_input = st.chat_input("Ask your agent...")

if user_input:
    st.chat_message("user").write(user_input)
    client.beta.threads.messages.create(
        thread_id=st.session_state.thread_id,
        role="user",
        content=user_input
    )
    
    run = client.beta.threads.runs.create(
        thread_id=st.session_state.thread_id,
        assistant_id=ASSISTANT_ID
    )
    
    # Stream response (simplified)
    with st.chat_message("assistant"):
        while run.status not in ["completed"]:
            run = client.beta.threads.runs.retrieve(
                thread_id=st.session_state.thread_id, run_id=run.id
            )
            time.sleep(1)
        messages = client.beta.threads.messages.list(st.session_state.thread_id)
        st.write(messages.data[0].content[0].text.value)

Share via Streamlit Cloud. Scale to FastAPI for APIs.

Scaling Tips

  • Vector stores (Pinecone) for long-term memory.
  • Multi-agent: Use CrewAI for teams (researcher + writer).
  • Monitor with LangSmith.

Pro Tip: Rate limits kill demos—implement async runs and caching. Test edge cases like tool failures.

Conclusion

You've now built AI agents that plan, calculate, research, and automate—from zero to hero with GPT-5 and Python. These aren't toys; they're productivity multipliers for devs, analysts, and businesses.

Experiment: Add your tools (CRM queries, image gen). When GPT-5 drops, swap models and watch reasoning soar. Share your agents on Codeyaan—happy building!

Share this article