> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://respan.ai/docs/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://respan.ai/docs/_mcp/server.

# Agno (tracing)

> Trace Agno agents and teams with Respan using native respan-tracing instrumentation and optional gateway routing.

[Agno](https://docs.agno.com/) is a Python framework for building agents and teams with model calls, tools, streaming runs, and multi-agent coordination. Respan's Agno integration patches Agno's native `Agent.run`, `Agent.arun`, `Team.run`, and `Team.arun` methods and sends agent, team, chat, tool, and event spans through `respan-tracing`.

#### Set up Respan

Create an account at [platform.respan.ai](https://platform.respan.ai) and grab an [API key](https://platform.respan.ai/platform/gateway/api-keys).

Run `npx @respan/cli setup` to set up with your coding agent.

#### Use Respan Gateway

See [Agno gateway setup](/docs/gateway/agno) to route this integration through the Respan gateway.

#### Example projects

* Example repo root: `respan-example-projects/python/tracing/agno`

## Setup

#### Install packages

```bash
pip install respan-ai respan-instrumentation-agno agno openai
```

#### Set environment variables

```bash
export OPENAI_API_KEY="YOUR_OPENAI_API_KEY"
export RESPAN_API_KEY="YOUR_RESPAN_API_KEY"
```

`RESPAN_API_KEY` exports traces to Respan. `OPENAI_API_KEY` is used by Agno's OpenAI model client in this tracing-only setup.

#### Initialize and run

```python
from agno.agent import Agent
from agno.models.openai import OpenAIChat
from respan import Respan, workflow
from respan_instrumentation_agno import AgnoInstrumentor

respan = Respan(
    app_name="agno-quickstart",
    instrumentations=[AgnoInstrumentor()],
)

agent = Agent(
    name="Quickstart Agent",
    model=OpenAIChat(id="gpt-4o-mini"),
    instructions="Answer in one concise sentence.",
)

@workflow(name="agno_quickstart")
def run_agent() -> str:
    result = agent.run("What does Agno help developers build?")
    return str(result.content)

print(run_agent())
```

#### View your trace

Open the [Traces page](https://platform.respan.ai/platform/traces) to see the named workflow with Agno agent, chat, and tool spans. Use unique workflow names, such as `agno_01_hello_world`, so each example is easy to recognize in the trace list.

## Configuration

### Respan

| Parameter             | Type           | Default | Description                                                            |
| --------------------- | -------------- | ------- | ---------------------------------------------------------------------- |
| `api_key`             | `str \| None`  | `None`  | Falls back to `RESPAN_API_KEY` env var.                                |
| `base_url`            | `str \| None`  | `None`  | Falls back to `RESPAN_BASE_URL` env var.                               |
| `app_name`            | `str \| None`  | `None`  | Service name shown on exported Agno spans.                             |
| `instrumentations`    | `list`         | `[]`    | Plugin instrumentations to activate, for example `AgnoInstrumentor()`. |
| `customer_identifier` | `str \| None`  | `None`  | Default customer identifier for all spans.                             |
| `metadata`            | `dict \| None` | `None`  | Default metadata attached to all spans.                                |
| `environment`         | `str \| None`  | `None`  | Environment tag, for example `"production"`.                           |

### AgnoInstrumentor

| Parameter       | Type          | Default | Description                                                                                                     |
| --------------- | ------------- | ------- | --------------------------------------------------------------------------------------------------------------- |
| `agent`         | `Any \| None` | `None`  | Optional single Agno agent instance to patch. If omitted, Agno `Agent` and `Team` classes are patched globally. |
| `include_teams` | `bool`        | `True`  | Patch `Team.run` and `Team.arun` in addition to agent runs.                                                     |

## What gets traced

| Agno operation             | Respan span          | Notes                                                                                                                                 |
| -------------------------- | -------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| `Agent.run` / `Agent.arun` | `agno.agent`         | Captures run input, final output, run id, session id, agent id, and agent name.                                                       |
| Agno model request         | `agno.model_request` | Captures messages, completion, model, provider, tool definitions, tool calls, and token usage when Agno exposes metrics.              |
| Python function tools      | `agno.tool`          | Captures `{name, arguments}` as input and the tool result as output. Callable tools include a JSON schema in `llm.request.functions`. |
| `Team.run` / `Team.arun`   | `agno.team`          | Captures team input/output and keeps delegated member agent spans in the same trace tree.                                             |
| Streaming run events       | `agno.event`         | Captures intermediate Agno run events when only stream events are available.                                                          |

## Attributes

### In Respan()

Set defaults at initialization. These apply to all spans emitted by the Agno instrumentor.

```python
from respan import Respan
from respan_instrumentation_agno import AgnoInstrumentor

respan = Respan(
    app_name="agno-support-api",
    instrumentations=[AgnoInstrumentor()],
    customer_identifier="user_123",
    metadata={"service": "agno-support-api", "version": "1.0.0"},
)
```

### With propagate_attributes

Override per request using a context scope.

```python
from agno.agent import Agent
from agno.models.openai import OpenAIChat
from respan import Respan, workflow
from respan_instrumentation_agno import AgnoInstrumentor

respan = Respan(instrumentations=[AgnoInstrumentor()])
agent = Agent(name="Support Agent", model=OpenAIChat(id="gpt-4o-mini"))

@workflow(name="agno_support_request")
def answer_question(question: str) -> str:
    result = agent.run(question)
    return str(result.content)

def handle_request(user_id: str, question: str):
    with respan.propagate_attributes(
        customer_identifier=user_id,
        thread_identifier="conv_abc_123",
        trace_group_identifier="support-request",
        metadata={"plan": "pro"},
    ):
        print(answer_question(question))
```

| Attribute                | Type   | Description                                           |
| ------------------------ | ------ | ----------------------------------------------------- |
| `customer_identifier`    | `str`  | Identifies the end user in Respan analytics.          |
| `thread_identifier`      | `str`  | Groups related Agno calls into a conversation.        |
| `trace_group_identifier` | `str`  | Groups related traces for search and filtering.       |
| `metadata`               | `dict` | Custom key-value pairs. Merged with default metadata. |

## Decorators

Agno runs are auto-traced by the instrumentor. Use `@workflow` and `@task` when you want a recognizable root span around a full script or request. This is the pattern used by the example set so each result is visible by script name in the trace list.

```python
from agno.agent import Agent
from agno.models.openai import OpenAIChat
from respan import Respan, task, workflow
from respan_instrumentation_agno import AgnoInstrumentor

respan = Respan(instrumentations=[AgnoInstrumentor()])
agent = Agent(
    name="Checklist Agent",
    model=OpenAIChat(id="gpt-4o-mini"),
    instructions="Return exactly two bullets.",
)

@task(name="draft_prompt")
def draft_prompt(topic: str) -> str:
    return f"Write a two-bullet operational checklist for {topic}."

@workflow(name="agno_checklist_workflow")
def run_checklist(topic: str) -> str:
    result = agent.run(draft_prompt(topic))
    return str(result.content)

print(run_checklist("reviewing an SDK integration"))
```

## Examples

### Tool calls

```python
from agno.agent import Agent
from agno.models.openai import OpenAIChat

def lookup_shipping_status(order_id: str) -> str:
    """Look up the shipping status for an order id."""
    return f"Order {order_id} is packed and ready for pickup."

agent = Agent(
    name="Support Agent",
    model=OpenAIChat(id="gpt-4o-mini"),
    instructions="Use tools when order status is requested.",
    tools=[lookup_shipping_status],
)

result = agent.run("What is the shipping status for order A-100?")
print(result.content)
```

### Teams

```python
from agno.agent import Agent
from agno.models.openai import OpenAIChat
from agno.team import Team

researcher = Agent(
    name="Researcher",
    model=OpenAIChat(id="gpt-4o-mini"),
    instructions="Find the most relevant operational facts.",
)
writer = Agent(
    name="Writer",
    model=OpenAIChat(id="gpt-4o-mini"),
    instructions="Turn operational facts into concise prose.",
)
team = Team(
    name="Tracing Team",
    model=OpenAIChat(id="gpt-4o-mini"),
    members=[researcher, writer],
    instructions="Coordinate a concise final answer.",
)

result = team.run("Explain why tool spans are useful in one paragraph.")
print(result.content)
```

### Streaming

```python
from agno.agent import Agent
from agno.models.openai import OpenAIChat

agent = Agent(
    name="Streaming Agent",
    model=OpenAIChat(id="gpt-4o-mini"),
    instructions="Answer in one short paragraph.",
)

for event in agent.run("Explain streaming agent output.", stream=True):
    if getattr(event, "content", None):
        print(event.content, end="")
```