# Opper AI Opper Skills Opper Python Agents

> Opper Python Agents

- Skill: `tomevault-io/opper-ai-opper-skills-opper-python-agents` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds@latest add tomevault-io/opper-ai-opper-skills-opper-python-agents`
- Raw SKILL.md: https://api.skillmd.com/api/skills/tomevault-io/opper-ai-opper-skills-opper-python-agents/raw
- Safety review: pending (external: skill-scanner PASS, skillspector PASS)
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: tomevault-io (https://skillmd.com/u/tomevault-io)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/tomevault-io/opper-ai-opper-skills-opper-python-agents

---


# Opper Python Agents

Build AI agents with think-act reasoning loops, typed tools, multi-agent composition, memory, and full observability.

## Installation

```bash
pip install opper-agents
```

Set your API key:

```bash
export OPPER_API_KEY="your-api-key"
```

Get your API key from [platform.opper.ai](https://platform.opper.ai).

## Core Pattern: Agent with Tools

Define tools with the `@tool` decorator, create an agent, and run it:

```python
from opper_agents import Agent, tool

@tool
def get_weather(city: str) -> str:
    """Get the current weather for a city."""
    return f"The weather in {city} is 22°C and sunny"

@tool
def get_population(city: str) -> int:
    """Get the population of a city."""
    populations = {"Paris": 2_161_000, "London": 8_982_000}
    return populations.get(city, 0)

agent = Agent(
    name="CityBot",
    instructions="Help users with city information using available tools.",
    tools=[get_weather, get_population],
)

result = await agent.process("What's the weather and population of Paris?")
print(result)
# "Paris has a population of 2,161,000 and the weather is 22°C and sunny."
```

## How the Agent Loop Works

The agent follows a Think-Act-Observe loop:

1. **Think**: The LLM analyzes the goal and available tools
2. **Act**: It selects and executes a tool
3. **Observe**: Results are added to the conversation history
4. **Loop/Return**: Repeat until the goal is met, then return the final answer

The loop runs up to `max_iterations` times (default: 25).

## Structured Output

Use Pydantic models to get typed, validated results:

```python
from pydantic import BaseModel, Field
from typing import List

class CityReport(BaseModel):
    city: str
    temperature_c: float
    population: int
    summary: str = Field(description="One-sentence summary")

agent = Agent(
    name="CityReporter",
    instructions="Generate a city report using available tools.",
    tools=[get_weather, get_population],
    output_schema=CityReport,
)

result = await agent.process("Report on London")
# result is a CityReport instance
print(result.city)          # "London"
print(result.temperature_c) # 18.0
print(result.population)    # 8982000
```

## Model Selection

Specify which LLM the agent uses for reasoning:

```python
agent = Agent(
    name="SmartAgent",
    instructions="You are a helpful assistant.",
    tools=[my_tool],
    model="anthropic/claude-4-sonnet",
)

# With fallback chain
agent = Agent(
    name="ResilientAgent",
    instructions="You are a helpful assistant.",
    tools=[my_tool],
    model=["anthropic/claude-4-sonnet", "openai/gpt-4o"],
)
```

## Async Tools

For I/O-bound operations, define async tools:

```python
import httpx

@tool
async def fetch_url(url: str) -> str:
    """Fetch content from a URL."""
    async with httpx.AsyncClient() as client:
        response = await client.get(url)
        return response.text[:1000]
```

## Multi-Agent Composition

Use agents as tools within other agents for delegation:

```python
math_agent = Agent(
    name="MathAgent",
    instructions="Solve math problems step by step.",
    tools=[add, multiply],
)

research_agent = Agent(
    name="ResearchAgent",
    instructions="Answer factual questions.",
    tools=[search_web],
)

coordinator = Agent(
    name="Coordinator",
    instructions="Delegate tasks to specialist agents.",
    tools=[math_agent.as_tool(), research_agent.as_tool()],
)

result = await coordinator.process("What is 15 * 23, and who invented calculus?")
```

## MCP Integration

Connect to MCP servers for external tool access:

```python
from opper_agents import mcp, MCPServerConfig

filesystem_server = MCPServerConfig(
    name="filesystem",
    transport="stdio",
    command="npx",
    args=["-y", "@modelcontextprotocol/server-filesystem", "/tmp"],
)

agent = Agent(
    name="FileAgent",
    instructions="Use filesystem tools to manage files.",
    tools=[mcp(filesystem_server)],
)
```

## Hooks

Monitor agent lifecycle events:

```python
from opper_agents import hook
from opper_agents.base.context import AgentContext

@hook("agent_start")
async def on_start(context: AgentContext, agent):
    print(f"Agent {agent.name} starting: {context.goal}")

@hook("tool_result")
async def on_tool(context: AgentContext, tool_name: str, result):
    print(f"Tool {tool_name} returned: {result}")

agent = Agent(
    name="ObservedAgent",
    instructions="Do the task.",
    tools=[my_tool],
    hooks=[on_start, on_tool],
)
```

## Execution Stats

Access usage information after running:

```python
result = await agent.process("Solve this problem")

# Access stats from the agent context
print(f"Iterations: {agent.context.iteration}")
print(f"Total tokens: {agent.context.usage.total_tokens}")
```

## Common Mistakes

- **Forgetting `await`**: `agent.process()` is async. Always use `await`.
- **Missing tool docstrings**: The agent uses docstrings to understand what tools do. Always provide descriptive docstrings.
- **Too many tools**: Agents work best with 5-10 focused tools. Use multi-agent composition for more.
- **No `output_schema`**: Without it, results are unstructured strings. Use Pydantic models for reliable parsing.
- **Infinite loops**: Set `max_iterations` to prevent runaway agents.

## Additional Resources

- For advanced tool patterns and context, see [references/TOOLS.md](references/TOOLS.md)
- For MCP server configuration, see [references/MCP.md](references/MCP.md)
- For multi-agent composition patterns, see [references/COMPOSITION.md](references/COMPOSITION.md)
- For lifecycle hooks reference, see [references/HOOKS.md](references/HOOKS.md)
- For persistent memory, see [references/MEMORY.md](references/MEMORY.md)
- For migrating from OpenRouter, see [references/MIGRATION.md](references/MIGRATION.md)

## Related Skills

- **opper-python-sdk**: Use for single-shot task completion without agent loops — simpler when you don't need multi-step reasoning.
- **opper-node-agents**: Use when building agents in TypeScript instead of Python.

## Upstream Sources

When this skill's content may be outdated, resolve using this priority:

1. **Installed package source** — check the user's project first, as it reflects the exact version in use: `.venv/**/site-packages/opper_agents/` or `**/site-packages/opper_agents/`
2. **Source code**: https://github.com/opper-ai/opperai-agent-sdk
3. **Documentation**: https://docs.opper.ai

---
> Converted and distributed by [TomeVault](https://tomevault.io/claim/opper-ai) — claim your Tome and manage your conversions.
<!-- tomevault:4.0:skill_md:2026-04-13 -->

