Section 6: Agents! - calisley/dpi-681 GitHub Wiki

Set Up

  1. Install the openai-agents package

    # macOS / Linux
    pip3 install openai-agents
    
    # Windows (or if you use plain `pip`)
    pip install openai-agents
    
  2. Pull the latest code

    git pull
    
  3. Export your OpenAI API key
    In your terminal (bash, zsh, PowerShell, etc.), run:

    export OPENAI_API_KEY="your_openai_api_key"
    

    This environment variable is required for the script to authenticate with OpenAI.


Activity 1: Build & Run a Simple Agent

In this activity you’ll use the agents framework and the Runner to:

  • Install and import the OpenAI Agents SDK
  • Wire up a built-in WebSearchTool plus a custom square function
  • Observe how the agent chooses and executes tools at runtime

Script Walkthrough

  1. Tool Definitions

    • @function_tool wraps square(x) so the agent can call it.
    • WebSearchTool() is registered to fetch live data.
  2. Agent Configuration

    agent = Agent(
        name="Agent",
        tools=[ WebSearchTool(), square ],
        model="gpt-4.1"
    )
    
    • The agent knows which tools are available and how to call them.
    • It uses your OpenAI key to power the LLM reasoning over prompts and tool calls.
  3. Runner Orchestration

    result = await Runner.run(agent, prompt)
    print(result.final_output)
    
    • Runner.run(...) sends your prompt to the agent,
    • The agent decides “search” vs. “square” under the hood,
    • Executes the chosen tool, then returns the final output.
  4. Interactive Prompts

    • “What’s the weather in Paris today?” → triggers WebSearchTool.
    • “What is the square of 3.7545624?” → triggers square(...).

Extension: Uncomment and try the multi-step prompt to see how the agent decomposes complex instructions.


Activity 2: Multi-Agent Workflows, Guardrails, Handoffs, oh my!

Script Walkthrough

Below is a high-level tour of the key parts of the script. We’ll highlight:

  1. Structured guardrail output

    class HomeworkOutput(BaseModel):
        is_homework: bool
        reasoning: str
    
    • Defines a Pydantic model for the guardrail’s output.
    • is_homework flags whether the input looks like a homework question.
    • reasoning gives the agent’s internal rationale.
  2. Guardrail agent

    guardrail_agent = Agent(
        name="Guardrail check",
        instructions="Check if the user is asking about homework.",
        output_type=HomeworkOutput,
    )
    
    • This agent’s sole job is to classify inputs as homework or not.
  3. Tutor agent (example: Math Tutor)

    math_tutor_agent = Agent(
        name="Math Tutor",
        handoff_description="Specialist agent for math questions",
        instructions="You provide help with math problems. Explain your reasoning at each step and include examples",
    )
    
    • A “specialist” agent that knows how to walk through math problems step by step.
  4. Guardrail function

    async def homework_guardrail(ctx, agent, input_data):
        result = await Runner.run(guardrail_agent, input_data, context=ctx.context)
        final_output = result.final_output_as(HomeworkOutput)
        return GuardrailFunctionOutput(
            output_info=final_output,
            tripwire_triggered=not final_output.is_homework,
        )
    
    • Runs the guardrail_agent and parses its output into our HomeworkOutput model.
    • If is_homework is False, we trigger the “tripwire,” preventing the main agent from firing.
  5. Triage agent

    triage_agent = Agent(
        name="Triage Agent",
        instructions="You determine which agent to use based on the user's homework question",
        handoffs=[history_tutor_agent, math_tutor_agent],
        input_guardrails=[ InputGuardrail(guardrail_function=homework_guardrail) ],
    )
    
    • Listens for user queries: if the guardrail says “not homework,” it trips and the triage agent won’t hand off.
    • Otherwise, it picks the appropriate tutor (history or math) based on your instructions.

Running the Script

  1. Save the code above to, e.g., triage_demo.py.
  2. In your terminal, run:
    # macOS / Linux
    python3 section-6/basic-agent.py
    # Windows 
    python section-6/basic-agent.py
    
  3. Observe the two example runs:
    >>> How did the first president of the United States get elected?
    <HistoryTutor’s answer with context and events…>
    
    >>> what is life
    <Guardrail tripwire triggered; no tutor handoff>
    
  4. Discussion: What differences do you see between the two outputs?
    • Which input got routed to a tutor?
    • What happens when the guardrail trips?

Viewing Traces

  1. Go to https://platform.openai.com/traces
  2. Find your recent requests for triage_demo.py.
  3. Click through the trace for each run to see:
    • The guardrail agent’s classification
    • The triage decision
    • The specialist tutor’s response (if it ran)

Tip: Traces give you a step-by-step “waterfall” of each agent call, inputs, and outputs.


Activity

Now it’s your turn to vibe-code! Pick at least one of these challenges:

  1. Add another tutor
    • e.g., a Science Tutor for chemistry or biology questions.
  2. “Hint” guardrail
    • Prevent tutors from giving full solutions — only hints and guiding questions.
  3. Academic Integrity guardrail
    • Detect “please solve my entire assignment” requests and either refuse or provide high-level guidance only.

Function Calling Experiments

  • Write a new @function_tool for a small utility (e.g., summarize_text, translate_text) and register it with the triage agent.
  • Observe how the agent selects between tools when you ask combined queries (e.g., “Summarize this article, then square the word count”).
  • Chain your new tool call after existing ones in your guardrail or handoff functions to see multi-step function calling in action.
  • Challenge: Implement conditional tool invocation inside a custom @function_tool definition and test its behavior.

Bonus: Combine two or more ideas.
When you’re done, rerun the script, re-visit your traces, and share what you built!