Understanding the Agent Class: Configuration, Instructions, and Models
A deep dive into every parameter of the OpenAI Agents SDK Agent class — from instructions and model settings to dynamic instructions, cloning, and advanced configuration patterns.
The Agent Class Is the Foundation
Every workflow built with the OpenAI Agents SDK starts with the Agent class. While creating a basic agent requires only a name and instructions, the class exposes a rich set of parameters that control behavior, model selection, tool usage, output format, and multi-agent handoff logic.
Understanding these parameters is essential for building agents that behave predictably in production. This post covers every major parameter with practical examples.
Core Parameters
name
The name parameter is a human-readable identifier for the agent. It appears in logs, tracing dashboards, and is used to identify agents in multi-agent handoff scenarios:
flowchart TD
START["Understanding the Agent Class: Configuration, Ins…"] --> A
A["The Agent Class Is the Foundation"]
A --> B
B["Core Parameters"]
B --> C
C["ModelSettings: Fine-Tuning Model Behavi…"]
C --> D
D["Dynamic Instructions"]
D --> E
E["The tools Parameter"]
E --> F
F["The handoffs Parameter"]
F --> G
G["The output_type Parameter"]
G --> H
H["Agent Cloning with .clone"]
H --> DONE["Key Takeaways"]
style START fill:#4f46e5,stroke:#4338ca,color:#fff
style DONE fill:#059669,stroke:#047857,color:#fff
from agents import Agent
agent = Agent(
name="Customer Support Specialist",
instructions="You handle customer support inquiries.",
)
Choose descriptive names that make it easy to identify agents in logs and traces. Names do not need to be unique, but using unique names helps with debugging.
instructions
The instructions parameter is the system prompt that defines the agent's persona, behavior rules, and response format. This is the most important parameter for controlling agent behavior:
agent = Agent(
name="Code Reviewer",
instructions="""You are a senior code reviewer. Your job is to review Python code for:
1. Correctness - Does the code do what it claims?
2. Security - Are there SQL injection, XSS, or auth bypass risks?
3. Performance - Are there N+1 queries, missing indexes, or memory leaks?
4. Readability - Is the code clear and well-structured?
Format your review as:
- SEVERITY: (critical/warning/info)
- LOCATION: (file and line reference)
- ISSUE: (what is wrong)
- FIX: (how to fix it)
Be direct. Do not pad feedback with unnecessary praise.""",
)
Instructions can also be a callable function that receives the agent and context, enabling dynamic instructions that change based on runtime state. We cover this below.
model
The model parameter specifies which language model to use. It defaults to gpt-4o but can be set to any model your API key has access to:
# Use a specific model
agent = Agent(
name="Fast Responder",
instructions="Respond quickly and concisely.",
model="gpt-4o-mini", # Faster, cheaper model
)
# Use the latest reasoning model
reasoning_agent = Agent(
name="Deep Analyst",
instructions="Analyze complex problems step by step.",
model="o3-mini",
)
Different models have different capabilities and cost profiles. Use gpt-4o-mini for simple tasks, gpt-4o for general-purpose work, and reasoning models like o3-mini for complex analysis.
ModelSettings: Fine-Tuning Model Behavior
The model_settings parameter accepts a ModelSettings object that controls generation parameters:
from agents import Agent, ModelSettings
agent = Agent(
name="Creative Writer",
instructions="Write creative fiction with vivid imagery.",
model_settings=ModelSettings(
temperature=0.9, # Higher = more creative
top_p=0.95, # Nucleus sampling threshold
max_tokens=2000, # Maximum response length
frequency_penalty=0.3, # Reduce repetition
presence_penalty=0.1, # Encourage topic diversity
),
)
Key ModelSettings parameters:
| Parameter | Type | Description |
|---|---|---|
temperature |
float | Controls randomness (0.0 = deterministic, 2.0 = very random) |
top_p |
float | Nucleus sampling — only consider tokens with cumulative probability up to this value |
max_tokens |
int | Maximum number of tokens in the response |
frequency_penalty |
float | Penalizes tokens based on how often they appear (-2.0 to 2.0) |
presence_penalty |
float | Penalizes tokens based on whether they appear at all (-2.0 to 2.0) |
parallel_tool_calls |
bool | Whether to allow the model to call multiple tools at once |
tool_choice |
str | Controls tool usage: "auto", "required", "none", or a specific tool name |
Parallel Tool Calls
By default, the model can issue multiple tool calls in a single turn. This speeds up workflows where tools are independent:
agent = Agent(
name="Research Assistant",
instructions="Research topics using available tools.",
model_settings=ModelSettings(
parallel_tool_calls=True, # Default behavior
),
tools=[search_web, search_database, search_documents],
)
Set parallel_tool_calls=False when tools have dependencies or side effects that require sequential execution.
Dynamic Instructions
Static instructions work for most cases, but sometimes you need instructions that adapt to the current user, time of day, feature flags, or other runtime state. Pass a callable instead of a string:
See AI Voice Agents Handle Real Calls
Book a free demo or calculate how much you can save with AI voice automation.
from agents import Agent, RunContextWrapper
def dynamic_instructions(
context: RunContextWrapper[UserContext],
agent: Agent[UserContext],
) -> str:
user = context.context
return f"""You are a personalized assistant for {user.name}.
Their account tier is: {user.tier}
Their preferred language is: {user.language}
If they are on the free tier, mention upgrade options naturally.
If they are on the premium tier, provide detailed analysis without upselling."""
agent = Agent(
name="Personalized Assistant",
instructions=dynamic_instructions,
)
The function receives the RunContextWrapper (which holds your custom context) and the agent itself. It must return a string that becomes the system prompt for that run.
This is powerful for multi-tenant applications where each user should experience a different agent persona.
The tools Parameter
The tools parameter accepts a list of tools the agent can call. Tools can be function tools, hosted tools, or agent-as-tool references:
flowchart TD
ROOT["Understanding the Agent Class: Configuration…"]
ROOT --> P0["Core Parameters"]
P0 --> P0C0["name"]
P0 --> P0C1["instructions"]
P0 --> P0C2["model"]
ROOT --> P1["ModelSettings: Fine-Tuning Model Behavi…"]
P1 --> P1C0["Parallel Tool Calls"]
style ROOT fill:#4f46e5,stroke:#4338ca,color:#fff
style P0 fill:#e0e7ff,stroke:#6366f1,color:#1e293b
style P1 fill:#e0e7ff,stroke:#6366f1,color:#1e293b
from agents import Agent, function_tool
@function_tool
def get_weather(city: str) -> str:
"""Get the current weather for a city."""
return f"The weather in {city} is 72F and sunny."
@function_tool
def get_time(timezone: str) -> str:
"""Get the current time in a timezone."""
from datetime import datetime
return f"Current time: {datetime.now().isoformat()}"
agent = Agent(
name="Info Agent",
instructions="Help users with weather and time queries.",
tools=[get_weather, get_time],
)
Tools are covered in depth in Post 5 of this series.
The handoffs Parameter
Handoffs enable multi-agent workflows where one agent can transfer control to another. The handoffs parameter accepts a list of agents or Handoff objects:
billing_agent = Agent(
name="Billing Specialist",
instructions="Handle billing questions, refunds, and payment issues.",
)
technical_agent = Agent(
name="Technical Support",
instructions="Handle technical issues, bugs, and configuration problems.",
)
triage_agent = Agent(
name="Triage Agent",
instructions="""You are the first point of contact. Determine the customer's
issue and hand off to the appropriate specialist:
- Billing questions -> Billing Specialist
- Technical issues -> Technical Support""",
handoffs=[billing_agent, technical_agent],
)
When the triage agent decides to hand off, the SDK switches execution to the target agent seamlessly.
The output_type Parameter
By default, agents return plain text. The output_type parameter lets you enforce structured outputs using Pydantic models:
from pydantic import BaseModel
from agents import Agent
class SentimentResult(BaseModel):
sentiment: str # "positive", "negative", or "neutral"
confidence: float
reasoning: str
agent = Agent(
name="Sentiment Analyzer",
instructions="Analyze the sentiment of the given text.",
output_type=SentimentResult,
)
Structured outputs are covered in depth in Post 6 of this series.
Agent Cloning with .clone()
The clone() method creates a copy of an agent with optional parameter overrides. This is useful for creating agent variants without repeating configuration:
base_agent = Agent(
name="Base Assistant",
instructions="You are a helpful assistant.",
model="gpt-4o",
model_settings=ModelSettings(temperature=0.7),
tools=[search_tool, calculator_tool],
)
# Create a variant with different instructions but same tools and model
formal_agent = base_agent.clone(
name="Formal Assistant",
instructions="You are a helpful assistant. Always respond in formal, professional English.",
)
# Create a cheaper variant for simple queries
lite_agent = base_agent.clone(
name="Lite Assistant",
model="gpt-4o-mini",
)
The cloned agent inherits all parameters from the original, with only the specified parameters overridden. This is especially useful in multi-agent systems where agents share common tools but have different personas.
Putting It All Together
Here is a complete example that uses most of the parameters discussed:
import asyncio
from pydantic import BaseModel
from agents import Agent, Runner, ModelSettings, function_tool, RunContextWrapper
class AnalysisResult(BaseModel):
summary: str
key_points: list[str]
risk_level: str
recommendation: str
@function_tool
def lookup_company(ticker: str) -> str:
"""Look up basic company information by stock ticker."""
data = {
"AAPL": "Apple Inc. - Technology - Market Cap: $3.4T",
"GOOGL": "Alphabet Inc. - Technology - Market Cap: $2.1T",
}
return data.get(ticker, f"No data found for {ticker}")
analyst = Agent(
name="Financial Analyst",
instructions="""You are a senior financial analyst. Analyze companies
based on available data. Be precise and data-driven.
Always structure your analysis as a formal report.""",
model="gpt-4o",
model_settings=ModelSettings(
temperature=0.3,
max_tokens=1500,
),
tools=[lookup_company],
output_type=AnalysisResult,
)
async def main():
result = await Runner.run(analyst, "Analyze Apple's current market position.")
output: AnalysisResult = result.final_output_as(AnalysisResult)
print(f"Summary: {output.summary}")
print(f"Risk Level: {output.risk_level}")
for point in output.key_points:
print(f" - {point}")
asyncio.run(main())
Best Practices
Keep instructions focused. Each agent should have a clear, single responsibility. If instructions exceed 500 words, consider splitting into multiple agents.
Use ModelSettings deliberately. Lower temperature (0.1-0.3) for factual tasks, higher (0.7-0.9) for creative tasks. Always set
max_tokensto avoid runaway responses.Prefer dynamic instructions when behavior depends on user context, feature flags, or time-sensitive data.
Use clone() for variants. Do not copy-paste agent configurations. Clone from a base and override only what changes.
Name agents descriptively. Good names make traces and logs immediately readable in production.
Written by
CallSphere Team
Expert insights on AI voice agents and customer communication automation.
Try CallSphere AI Voice Agents
See how AI voice agents work for your industry. Live demo available -- no signup required.