building-with-openai-agents by panaversity
Use when building AI agents with OpenAI's Agents SDK. Triggers include creating agents, implementing tools, multi-agent handoffs, guardrails, MCP integration, tracing. Also for using LiteLLM to run agents on free/alternative models (Anthropic, Gemini). NOT for general OpenAI API usage (use openai-python SDK docs instead).
Content & Writing
107 Stars
95 Forks
Updated Jan 17, 2026, 05:30 AM
Why Use This
This skill provides specialized capabilities for panaversity's codebase.
Use Cases
- Developing new features in the panaversity repository
- Refactoring existing code to follow panaversity standards
- Understanding and working with panaversity's codebase structure
Install Guide
2 steps- 1
Skip this step if Ananke is already installed.
- 2
Skill Snapshot
Auto scan of skill assets. Informational only.
Valid SKILL.md
Checks against SKILL.md specification
Source & Community
Skill Stats
SKILL.md 531 Lines
Total Files 1
Total Size 0 B
License NOASSERTION
---
name: building-with-openai-agents
description: Use when building AI agents with OpenAI's Agents SDK. Triggers include creating agents, implementing tools, multi-agent handoffs, guardrails, MCP integration, tracing. Also for using LiteLLM to run agents on free/alternative models (Anthropic, Gemini). NOT for general OpenAI API usage (use openai-python SDK docs instead).
---
# Building with OpenAI Agents SDK
Production-ready agent framework with minimal abstractions, released March 2025.
## Persona
You are an OpenAI Agents SDK expert with production experience. You understand:
- Official SDK patterns from openai-agents-python
- LiteLLM integration for alternative model providers
- MCP (Model Context Protocol) integration patterns
- Multi-agent orchestration with handoffs
- Production guardrails and safety patterns
## Quick Start
### Installation
```bash
pip install openai-agents
export OPENAI_API_KEY=sk-...
```
For alternative models (free/low-cost):
```bash
pip install "openai-agents[litellm]"
```
### Hello World
```python
from agents import Agent, Runner
agent = Agent(
name="Assistant",
instructions="You are a helpful assistant."
)
result = Runner.run_sync(agent, "Hello!")
print(result.final_output)
```
### With LiteLLM (Free Models)
```python
from agents import Agent, Runner
from agents.extensions.models.litellm_model import LitellmModel
# Use any of 100+ models via LiteLLM
agent = Agent(
name="Assistant",
instructions="You are a helpful assistant.",
model=LitellmModel(
model="anthropic/claude-3-5-sonnet-20240620",
api_key="your-anthropic-key"
)
)
result = await Runner.run(agent, "Hello!")
```
Supported prefixes: `anthropic/`, `gemini/`, `bedrock/`, `azure/`, `mistral/`
## Core Primitives
| Primitive | Purpose |
|-----------|---------|
| **Agent** | LLM with instructions, tools, handoffs |
| **Tool** | Python function the agent can call |
| **Handoff** | Transfer control to another agent |
| **Guardrail** | Validate input/output before processing |
| **Session** | Automatic conversation history |
| **Runner** | Executes the agent loop |
## Creating Agents
```python
from agents import Agent
agent = Agent(
name="Customer Support",
instructions="You help customers with their orders.",
model="gpt-4o", # or use LitellmModel
tools=[get_order_status, create_refund],
handoffs=[billing_agent, shipping_agent],
output_type=OrderResponse, # Structured output
)
```
### Dynamic Instructions
```python
def dynamic_instructions(context, agent):
user = context.context.user_name
return f"You are helping {user} with their account."
agent = Agent(
name="Support",
instructions=dynamic_instructions
)
```
## Function Tools
### Basic Tool
```python
from agents import function_tool
@function_tool
def get_weather(city: str) -> str:
"""Get weather for a city.
Args:
city: The city name.
"""
return f"Weather in {city}: Sunny, 72F"
```
### Async Tool
```python
@function_tool
async def fetch_order(order_id: str) -> dict:
"""Fetch order details from database."""
order = await db.orders.get(order_id)
return order.dict()
```
### Tool with Pydantic
```python
from pydantic import BaseModel
class Location(BaseModel):
city: str
country: str = "USA"
@function_tool
def search_restaurants(location: Location, cuisine: str) -> list:
"""Search restaurants by location and cuisine."""
return [...]
```
### Tool Error Handling
```python
def custom_error(e: Exception) -> str:
return f"Tool failed: {str(e)}. Try a different approach."
@function_tool(failure_error_function=custom_error)
def risky_operation(data: str) -> str:
"""Perform risky operation."""
...
```
## Multi-Agent Handoffs
### Basic Handoff
```python
from agents import Agent, handoff
billing_agent = Agent(
name="Billing Agent",
instructions="Handle billing questions."
)
support_agent = Agent(
name="Support Agent",
instructions="Handle general support.",
handoffs=[billing_agent] # Can hand off to billing
)
```
### Handoff with Callback
```python
from pydantic import BaseModel
from agents import handoff, RunContextWrapper
class EscalationData(BaseModel):
reason: str
priority: str
async def on_escalate(ctx: RunContextWrapper, data: EscalationData):
await log_escalation(data.reason, data.priority)
escalation_handoff = handoff(
agent=escalation_agent,
on_handoff=on_escalate,
input_type=EscalationData,
tool_name_override="escalate_to_human"
)
```
### Two Multi-Agent Patterns
**Pattern 1: Manager (Agents as Tools)**
- Central orchestrator invokes sub-agents as tools
- Orchestrator retains control
- Best for: predictable workflows, classification
```python
# Sub-agent as tool
research_agent = Agent(name="Researcher", ...)
writer_agent = Agent(name="Writer", ...)
manager = Agent(
name="Manager",
tools=[
research_agent.as_tool(
tool_name="do_research",
tool_description="Research a topic"
),
writer_agent.as_tool(
tool_name="write_content",
tool_description="Write content"
)
]
)
```
**Pattern 2: Handoffs (Peer Agents)**
- Specialized agents hand off to each other
- Receiving agent takes full control
- Best for: customer support flows, expert routing
```python
triage_agent = Agent(
name="Triage",
instructions="Route to appropriate specialist.",
handoffs=[billing_agent, technical_agent, sales_agent]
)
```
## Guardrails
### Input Guardrail
```python
from agents import Agent, input_guardrail, GuardrailFunctionOutput
@input_guardrail
async def check_no_pii(ctx, agent, input: str) -> GuardrailFunctionOutput:
has_pii = detect_pii(input)
return GuardrailFunctionOutput(
output_info={"has_pii": has_pii},
tripwire_triggered=has_pii
)
agent = Agent(
name="Support",
input_guardrails=[check_no_pii]
)
```
### Output Guardrail
```python
from agents import output_guardrail
@output_guardrail
async def check_no_secrets(ctx, agent, output: str) -> GuardrailFunctionOutput:
has_secrets = scan_for_secrets(output)
return GuardrailFunctionOutput(
output_info={"scanned": True},
tripwire_triggered=has_secrets
)
agent = Agent(
name="CodeHelper",
output_guardrails=[check_no_secrets]
)
```
### Handle Guardrail Failures
```python
from agents import InputGuardrailTripwireTriggered
try:
result = await Runner.run(agent, user_input)
except InputGuardrailTripwireTriggered as e:
print(f"Blocked: {e.guardrail_result.output_info}")
```
## MCP Integration
### Stdio Server (Local Process)
```python
from agents import Agent
from agents.mcp import MCPServerStdio
async with MCPServerStdio(
name="Filesystem",
params={
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/path"]
}
) as mcp_server:
agent = Agent(
name="FileHelper",
mcp_servers=[mcp_server]
)
result = await Runner.run(agent, "List files in /path")
```
### HTTP Server (Remote)
```python
from agents.mcp import MCPServerStreamableHttp
async with MCPServerStreamableHttp(
name="Remote Tools",
params={
"url": "https://mcp.example.com/mcp",
"headers": {"Authorization": f"Bearer {token}"}
}
) as server:
agent = Agent(mcp_servers=[server])
```
### Tool Filtering
```python
from agents.mcp import MCPServerStdio, create_static_tool_filter
server = MCPServerStdio(
params={...},
tool_filter=create_static_tool_filter(
allowed_tool_names=["read_file", "list_directory"]
)
)
```
## Sessions (Conversation Memory)
### SQLite (Simple)
```python
from agents import SQLiteSession
# In-memory (lost on restart)
session = SQLiteSession("user_123")
# File-based (persistent)
session = SQLiteSession("user_123", "conversations.db")
result = await Runner.run(agent, "Hello", session=session)
# Next run automatically includes history
result = await Runner.run(agent, "What did I say?", session=session)
```
### SQLAlchemy (Production)
```python
from agents import SQLAlchemySession
session = SQLAlchemySession.from_url(
"user_123",
url="postgresql+asyncpg://user:pass@localhost/db",
create_tables=True
)
```
## Streaming
```python
result = await Runner.run_streamed(agent, "Tell me a story")
async for event in result.stream_events():
if event.type == "raw_response_event":
print(event.data, end="", flush=True)
```
## Structured Outputs
```python
from pydantic import BaseModel
class OrderAnalysis(BaseModel):
sentiment: str
urgency: int
action_required: bool
agent = Agent(
name="Analyzer",
instructions="Analyze customer orders.",
output_type=OrderAnalysis
)
result = await Runner.run(agent, "My order is late!")
analysis: OrderAnalysis = result.final_output
print(f"Urgency: {analysis.urgency}")
```
## Tracing
Tracing is enabled by default. View in OpenAI Dashboard.
### Custom Spans
```python
from agents import trace
with trace("Customer Support Flow"):
result1 = await Runner.run(triage, query)
result2 = await Runner.run(specialist, query)
```
### Disable Tracing (for non-OpenAI models)
```python
from agents import set_tracing_disabled
set_tracing_disabled(True)
```
## Decision Logic
| Situation | Pattern |
|-----------|---------|
| Single agent, simple task | Basic Agent |
| Need conversation history | Add Session |
| Multiple specialized tasks | Handoffs between agents |
| Predictable routing | Manager with agents-as-tools |
| User-facing validation | Input guardrails |
| Output safety checks | Output guardrails |
| External tool ecosystem | MCP integration |
| Non-OpenAI models | LiteLLM |
## TaskManager Example
Complete example building a task management agent:
```python
from agents import Agent, Runner, function_tool
from pydantic import BaseModel
from typing import Optional
# Task model
class Task(BaseModel):
id: str
title: str
completed: bool = False
# In-memory storage
tasks: dict[str, Task] = {}
@function_tool
def add_task(title: str) -> str:
"""Add a new task."""
task_id = f"task_{len(tasks) + 1}"
tasks[task_id] = Task(id=task_id, title=title)
return f"Created task {task_id}: {title}"
@function_tool
def list_tasks() -> str:
"""List all tasks."""
if not tasks:
return "No tasks yet."
return "\n".join(
f"[{'x' if t.completed else ' '}] {t.id}: {t.title}"
for t in tasks.values()
)
@function_tool
def complete_task(task_id: str) -> str:
"""Mark a task as completed."""
if task_id not in tasks:
return f"Task {task_id} not found."
tasks[task_id].completed = True
return f"Completed: {tasks[task_id].title}"
# Create agent
task_agent = Agent(
name="TaskManager",
instructions="""You help users manage their tasks.
Use add_task to create tasks, list_tasks to show them,
and complete_task to mark them done.""",
tools=[add_task, list_tasks, complete_task]
)
# Run
async def main():
result = await Runner.run(
task_agent,
"Add a task to buy groceries, then list all tasks"
)
print(result.final_output)
if __name__ == "__main__":
import asyncio
asyncio.run(main())
```
## Safety
### NEVER
- Expose API keys in code or logs
- Skip error handling for API calls
- Trust user input without validation
- Ignore rate limits
### ALWAYS
- Use environment variables for secrets
- Wrap API calls in try/except
- Implement input guardrails for user-facing agents
- Use output guardrails for sensitive content
- Test with tracing enabled
## Common Errors
| Error | Cause | Fix |
|-------|-------|-----|
| `MaxTurnsExceeded` | Agent loops too long | Increase `max_turns` in RunConfig |
| `ModelBehaviorError` | Invalid LLM output | Check model compatibility |
| `InputGuardrailTripwireTriggered` | Input blocked | Handle exception, provide feedback |
## References
- [Official Docs](https://openai.github.io/openai-agents-python/)
- [GitHub Repo](https://github.com/openai/openai-agents-python)
- [LiteLLM Providers](https://docs.litellm.ai/docs/providers)
- [Customer Service Demo](https://github.com/openai/openai-cs-agents-demo)
Name Size