Claude Agents API: Building & Deploying Agents¶
Overview¶
The Claude Agents API is the production-ready way to build and deploy agents powered by Claude.
Creating Agents with SDK¶
Basic Agent¶
from anthropic import Anthropic
class ClaudeAgent:
"""Build agents with Claude SDK"""
def __init__(self, model: str = "claude-3-5-sonnet-20241022"):
self.client = Anthropic()
self.model = model
self.tools = []
def add_tool(self, name: str, description: str, input_schema: dict):
"""Register a tool"""
self.tools.append({
"name": name,
"description": description,
"input_schema": input_schema
})
def run(self, task: str):
"""Execute agent loop"""
messages = [
{"role": "user", "content": task}
]
while True:
# Get Claude's response
response = self.client.messages.create(
model=self.model,
max_tokens=4096,
tools=self.tools,
messages=messages
)
# Check if Claude wants to use tools
if response.stop_reason == "tool_use":
# Process tool calls
tool_results = self.process_tool_calls(response.content)
# Add Claude's response + tool results
messages.append({
"role": "assistant",
"content": response.content
})
messages.append({
"role": "user",
"content": tool_results
})
else:
# Claude is done
return self.extract_text(response.content)
def process_tool_calls(self, content):
"""Execute tools Claude requested"""
results = []
for block in content:
if block.type == "tool_use":
# Call tool
result = self.execute_tool(
block.name,
block.input
)
results.append({
"type": "tool_result",
"tool_use_id": block.id,
"content": result
})
return results
Deployment Options¶
REST API Endpoint¶
from fastapi import FastAPI
class DeployedAgent:
"""Deploy agent as API"""
def __init__(self):
self.app = FastAPI()
self.agent = ClaudeAgent()
@self.app.post("/agent/run")
async def run_agent(request):
"""Agent endpoint"""
try:
result = self.agent.run(request.task)
return {
"status": "success",
"result": result
}
except Exception as e:
return {
"status": "error",
"error": str(e)
}
def start(self):
"""Run API server"""
import uvicorn
uvicorn.run(self.app, host="0.0.0.0", port=8000)
State Management¶
Maintaining Context¶
class StatefulAgent:
"""Agent with persistent state"""
def __init__(self):
self.client = Anthropic()
self.conversation_history = []
self.user_context = {}
def add_context(self, user_id: str, context: dict):
"""Add user-specific context"""
self.user_context[user_id] = context
def run_with_context(self, user_id: str, task: str):
"""Execute with saved context"""
# Build system message with context
context = self.user_context.get(user_id, {})
system_prompt = self.build_system_prompt(context)
# Add to conversation
messages = [
*self.conversation_history,
{"role": "user", "content": task}
]
# Get response
response = self.client.messages.create(
model="claude-3-5-sonnet-20241022",
max_tokens=2048,
system=system_prompt,
messages=messages
)
# Save to history
self.conversation_history.append({
"role": "assistant",
"content": response.content[0].text
})
return response.content[0].text
Monitoring & Cost Optimization¶
Track Usage¶
class MonitoredAgent:
"""Agent with monitoring"""
def __init__(self):
self.client = Anthropic()
self.usage_log = []
def run_with_monitoring(self, task: str):
"""Execute with usage tracking"""
response = self.client.messages.create(
model="claude-3-5-sonnet-20241022",
max_tokens=1000,
messages=[{"role": "user", "content": task}]
)
# Log usage
self.usage_log.append({
'task': task,
'input_tokens': response.usage.input_tokens,
'output_tokens': response.usage.output_tokens,
'cost': self.calculate_cost(response.usage)
})
return response.content[0].text
def calculate_cost(self, usage):
"""Estimate API cost"""
# Claude 3.5 Sonnet pricing (2024)
input_cost = usage.input_tokens * 0.003 / 1000
output_cost = usage.output_tokens * 0.015 / 1000
return input_cost + output_cost
3 Warnings ⚠️¶
Warning 1: Unbounded Token Usage¶
# ❌ WRONG
# No token limits
response = client.messages.create(
model="claude-3-5-sonnet",
messages=messages
)
# Costs can spiral
# ✅ RIGHT
# Set max tokens
response = client.messages.create(
model="claude-3-5-sonnet",
max_tokens=1000, # Bounded!
messages=messages
)
Warning 2: No Error Handling¶
# ❌ WRONG
result = agent.run(task) # Might fail
# ✅ RIGHT
try:
result = agent.run(task)
except RateLimitError:
retry_with_backoff()
except APIError as e:
log_and_alert(e)
Warning 3: Forgotten Context Cleanup¶
# ❌ WRONG
# Conversation history grows forever
while True:
response = agent.run(task)
# Memory usage grows unbounded
# ✅ RIGHT
# Truncate old messages
if len(self.conversation_history) > 20:
# Keep last 20, drop oldest
self.conversation_history = self.conversation_history[-20:]
Last Updated: August 9, 2026