Overview
The RetryConfig class configures automatic retry behavior for agent operations, particularly useful when using structured output that may fail validation.
Class Definition
from pydantic import BaseModel, Field
class RetryConfig(BaseModel):
"""Configuration for retry behavior in agent execution."""
max_retries: int = Field(default=3, ge=0)
retry_on_validation_error: bool = Field(default=True)
retry_on_tool_error: bool = Field(default=False)
backoff_base_seconds: float = Field(default=1.0, ge=0)
model_config = {"frozen": True} # Immutable
Properties
Maximum number of retry attempts for a failed operation. Set to 0 to disable retries entirely.
- Minimum value: 0
- Each retry includes the error message as feedback to the LLM
retry_on_validation_error
When True, the agent will automatically retry if structured output validation fails.This handles:
JSONDecodeError when the LLM returns invalid JSON
ValidationError when JSON doesn’t match the Pydantic schema
When True, the agent will retry if a tool execution fails with an exception.Use with caution—some tool errors are not recoverable by retry (e.g., authentication failures).
Base delay in seconds for exponential backoff between retries.The actual delay is: backoff_base_seconds * retry_attempt
- Retry 1: 1.0s delay
- Retry 2: 2.0s delay
- Retry 3: 3.0s delay
Creating RetryConfig
from tyler import RetryConfig
# Default configuration (3 retries, validation retry enabled)
config = RetryConfig()
# Custom configuration
config = RetryConfig(
max_retries=5,
retry_on_validation_error=True,
retry_on_tool_error=True,
backoff_base_seconds=2.0
)
# Disable retries
config = RetryConfig(max_retries=0)
Usage with Agent
At Agent Creation
from tyler import Agent, RetryConfig
agent = Agent(
name="DataExtractor",
model_name="gpt-4o",
purpose="To extract structured data from documents",
retry_config=RetryConfig(
max_retries=3,
retry_on_validation_error=True
)
)
At Runtime
The agent’s retry_config is used automatically when response_type is provided:
from pydantic import BaseModel
class Invoice(BaseModel):
vendor: str
total: float
items: list[str]
# Retry config is used if structured output validation fails
result = await agent.run(thread, response_type=Invoice)
Retry Flow
When a retry occurs:
- Error Detection: The agent catches
JSONDecodeError or ValidationError
- Feedback Message: An error message is added to the thread explaining what went wrong
- Backoff Delay: The agent waits
backoff_base_seconds * attempt_number seconds
- Retry Attempt: A new LLM call is made with the feedback in context
- Repeat or Fail: Steps 1-4 repeat until success or
max_retries is exhausted
# Example retry flow with max_retries=2
#
# Attempt 1: LLM returns invalid JSON → JSONDecodeError
# → Add error feedback to thread
# → Wait 1.0s
#
# Attempt 2: LLM returns JSON but wrong schema → ValidationError
# → Add error feedback to thread
# → Wait 2.0s
#
# Attempt 3: LLM returns valid structured output → Success!
Error Handling
When all retries are exhausted, StructuredOutputError is raised:
from tyler import Agent, RetryConfig, StructuredOutputError
agent = Agent(
name="extractor",
retry_config=RetryConfig(max_retries=2)
)
try:
result = await agent.run(thread, response_type=MyModel)
except StructuredOutputError as e:
print(f"Failed: {e.message}")
print(f"Validation errors: {e.validation_errors}")
print(f"Last response: {e.last_response}")
Immutability
RetryConfig instances are immutable (frozen). Create a new instance to change values:
config = RetryConfig(max_retries=3)
# ❌ This will raise an error
config.max_retries = 5
# ✅ Create a new instance instead
new_config = RetryConfig(
max_retries=5,
retry_on_validation_error=config.retry_on_validation_error,
retry_on_tool_error=config.retry_on_tool_error,
backoff_base_seconds=config.backoff_base_seconds
)
Best Practices
Choosing max_retries
# Simple schemas - fewer retries needed
RetryConfig(max_retries=2)
# Complex schemas - may need more attempts
RetryConfig(max_retries=5)
# Critical operations - more retries with longer backoff
RetryConfig(max_retries=5, backoff_base_seconds=2.0)
# ✅ Good candidates for tool retry
# - Network timeouts
# - Rate limiting
# - Transient API errors
# ❌ Bad candidates (won't help)
# - Authentication failures
# - Invalid parameters
# - Permission denied
Production Configuration
# Development - fast iteration
dev_config = RetryConfig(
max_retries=1,
backoff_base_seconds=0.5
)
# Production - reliability focused
prod_config = RetryConfig(
max_retries=3,
retry_on_validation_error=True,
retry_on_tool_error=False, # Only retry known-recoverable errors
backoff_base_seconds=1.0
)
See Also