# Agno User Guide

Agno is a Python SDK for building, running, and managing **agent platforms**. You use it to create AI agents in a handful of lines, compose them into multi-agent teams and deterministic workflows, give them tools, memory, and knowledge, and then run the whole thing as a production HTTP service with tracing, scheduling, human approvals, and role-based access control — all in your own infrastructure.

This guide is task-oriented: it shows you how to install Agno, build your first agent, and progressively add every capability the framework offers. Architecture, deployment internals, security hardening, and the full configuration reference live in the companion **Admin Guide**.

> [!NOTE]
> Agno is an **SDK and library**, not a command-line application. You build agents in Python and run them as scripts or services. The only shipped CLI (`ag` / `agno`) belongs to the separate `agno-infra` package and is used for scaffolding and deploying AgentOS projects — see [Deploying with the `ag` CLI](#deploying-with-the-ag-cli).

---

## Table of Contents

1. [What Is Agno](#1-what-is-agno)
2. [Quick Start](#2-quick-start)
3. [Installation](#3-installation)
4. [Core Concepts](#4-core-concepts)
5. [Building Agents](#5-building-agents)
6. [Models and Providers](#6-models-and-providers)
7. [Tools and Toolkits](#7-tools-and-toolkits)
8. [Knowledge and RAG](#8-knowledge-and-rag)
9. [Memory](#9-memory)
10. [Sessions, State, and History](#10-sessions-state-and-history)
11. [Structured Input and Output](#11-structured-input-and-output)
12. [Reasoning](#12-reasoning)
13. [Guardrails, Hooks, and Human-in-the-Loop](#13-guardrails-hooks-and-human-in-the-loop)
14. [Multi-Agent Teams](#14-multi-agent-teams)
15. [Workflows](#15-workflows)
16. [Running as a Service: AgentOS](#16-running-as-a-service-agentos)
17. [Deploying with the `ag` CLI](#17-deploying-with-the-ag-cli)
18. [Common Recipes](#18-common-recipes)
19. [Troubleshooting](#19-troubleshooting)
20. [Frequently Asked Questions](#20-frequently-asked-questions)
21. [Reference](#21-reference)

---

## 1. What Is Agno

Agno lets you own your entire agent stack. You keep control of your data, context, tools, permissions, memory, and human-review loops; you run the platform in your own cloud; and you manage it through a single control plane.

At its heart, Agno gives you three composable primitives:

| Primitive | Import | What it does |
|-----------|--------|--------------|
| **Agent** | `from agno.agent import Agent` | A single model + instructions + tools + memory + knowledge. The fundamental unit. |
| **Team** | `from agno.team import Team` | A group of agents (or nested teams) coordinated by a leader, in one of four execution modes. |
| **Workflow** | `from agno.workflow import Workflow` | A deterministic, step-based pipeline (sequences, loops, branches, parallel fan-out) over agents and functions. |

Around those primitives, Agno provides everything a production agent platform needs:

- **50+ model providers** behind one `Model` interface — OpenAI, Anthropic, Google, Groq, Mistral, Ollama, AWS Bedrock, Azure, and dozens more.
- **~130 pre-built toolkits** — web search, finance data, code execution, databases, Slack, GitHub, Gmail, and many others.
- **Knowledge / RAG** with readers, chunkers, embedders, rerankers, and 18+ vector databases.
- **Memory** that persists user facts across sessions.
- **Storage** for sessions, runs, memory, knowledge, and traces in your own database (PostgreSQL, MySQL, SQLite, MongoDB, Redis, DynamoDB, and more).
- **AgentOS** — a FastAPI runtime that exposes your agents as a production API with SSE/WebSocket streaming, JWT-based RBAC, OpenTelemetry tracing, cron scheduling, human-approval gates, and chat interfaces for Slack, Telegram, WhatsApp, AG-UI, and A2A.

> [!TIP]
> If you only want a chatbot in a script, you need just the `agno` package and one model provider. If you want to serve agents over HTTP for a product, add `agno[os]`. If you want to deploy that to a cloud, add `agno-infra`. Each layer is opt-in.

---

## 2. Quick Start

### Install Agno with a model provider

=== "OpenAI"

    ```bash
    pip install -U agno openai
    export OPENAI_API_KEY=sk-...
    ```

=== "Anthropic"

    ```bash
    pip install -U "agno[anthropic]"
    export ANTHROPIC_API_KEY=sk-ant-...
    ```

=== "Google Gemini"

    ```bash
    pip install -U "agno[google]"
    export GOOGLE_API_KEY=...
    ```

### Your first agent

Create `finance_agent.py`:

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

agent = Agent(
    model=OpenAIChat(id="gpt-4o"),
    instructions="You are a concise financial analyst. Facts only, no speculation.",
    markdown=True,
)

agent.print_response("Explain what a P/E ratio is in two sentences.", stream=True)
```

Run it:

```bash
python finance_agent.py
```

```text
The price-to-earnings (P/E) ratio measures a company's current share price
relative to its earnings per share. A higher P/E suggests investors expect
higher future growth, while a lower P/E may indicate a more conservatively
valued or slower-growing company.
```

> [!NOTE]
> `print_response()` renders the answer to your terminal (with live streaming when `stream=True`). For programmatic use, call `agent.run(...)`, which returns a `RunOutput` object you can inspect — see [Building Agents](#5-building-agents).

### Add a tool

Tools let the model fetch live data or take actions. Here the agent uses real Yahoo Finance data:

```python
from agno.agent import Agent
from agno.models.openai import OpenAIChat
from agno.tools.yfinance import YFinanceTools

agent = Agent(
    model=OpenAIChat(id="gpt-4o"),
    tools=[YFinanceTools(all=True)],
    instructions="You are a finance analyst. Always note the data timestamp.",
    add_datetime_to_context=True,
    markdown=True,
)

agent.print_response("Give me a quick investment brief on NVIDIA", stream=True)
```

```bash
pip install yfinance   # or: pip install "agno[yfinance]"
python finance_agent.py
```

That is the whole loop: a model, instructions, and tools. Everything else in this guide builds on this pattern.

---

## 3. Installation

### Requirements

| Requirement | Detail |
|-------------|--------|
| Python | 3.7+ (`requires-python = ">=3.7,<4"`). Type hints target 3.9+; 3.10+ recommended. |
| OS | OS-independent (Linux, macOS, Windows). |
| Core dependencies | `pydantic`, `pydantic-settings`, `httpx`, `typer`, `rich`, `gitpython`, `pyyaml`, `python-dotenv` (installed automatically). |
| Model provider | At least one (e.g. `openai`, `anthropic`, `google-genai`) — installed via extras. |

The base `agno` package is intentionally lightweight. Model providers, tools, databases, vector stores, and the server runtime are all **optional extras** you add as needed.

### Install the base package

```bash
pip install -U agno
```

### Extras matrix

Install extras with `pip install "agno[<extra>]"`. You can combine them: `pip install "agno[openai,os,pgvector]"`.

#### Model providers

| Extra | Installs | Provider |
|-------|----------|----------|
| `agno[openai]` | `openai` | OpenAI |
| `agno[anthropic]` | `anthropic` | Anthropic Claude |
| `agno[google]` | `google-genai` | Google Gemini |
| `agno[groq]` | `groq` | Groq |
| `agno[mistral]` | `mistralai` | Mistral |
| `agno[ollama]` | `ollama` | Ollama (local) |
| `agno[aws-bedrock]` | `boto3`, `aioboto3` | AWS Bedrock |
| `agno[azure]` | `azure-ai-inference` | Azure AI |
| `agno[cohere]` | `cohere` | Cohere |
| `agno[ibm]` | `ibm-watsonx-ai` | IBM watsonx |
| `agno[litellm]` | `litellm` | LiteLLM gateway |
| `agno[meta]` | `llama-api-client` | Meta Llama API |
| `agno[lmstudio]` | `lmstudio` | LM Studio |
| `agno[portkey]` | `portkey-ai` | Portkey |
| `agno[models]` | all of the above (curated set) | Everything |

> [!WARNING]
> As of this writing, the `agno[models]` meta-extra temporarily excludes `litellm` and `mistralai` because of upstream PyPI supply-chain incidents (see the Admin Guide's security section). Install them individually only if you have verified the upstream package.

#### Server runtime, storage, and infrastructure

| Extra | Installs | Purpose |
|-------|----------|---------|
| `agno[os]` | `fastapi[standard]`, `uvicorn`, `sqlalchemy`, `PyJWT`, `opentelemetry-sdk`, `croniter`, `pytz` | The AgentOS FastAPI runtime |
| `agno[scheduler]` | `croniter`, `pytz` | Cron scheduling |
| `agno[sql]` / `agno[postgres]` / `agno[sqlite]` / `agno[mysql]` | SQLAlchemy + driver | Relational session/run storage |
| `agno[async_postgres]` / `agno[async_mongo]` | `asyncpg` / `motor` | Async storage drivers |
| `agno[redis]` | `redis`, `redisvl` | Redis storage |
| `agno[gcs]` / `agno[firestore]` | Google Cloud storage backends |
| `agno[infra]` / `agno[docker]` / `agno[aws]` | `agno-infra` (+ extras) | Deployment tooling |

#### Vector databases (`agno[vectordbs]` for all)

`agno[pgvector]`, `agno[chromadb]`, `agno[lancedb]`, `agno[qdrant]`, `agno[milvusdb]`, `agno[weaviate]`, `agno[mongodb]`, `agno[pinecone]`, `agno[couchbase]`, `agno[cassandra]`, `agno[clickhouse]`, `agno[singlestore]`, `agno[surrealdb]`, `agno[upstash]`, `agno[redis]`.

#### Knowledge / document readers (`agno[knowledge]` for all)

`agno[pdf]`, `agno[docx]`, `agno[pptx]`, `agno[csv]`, `agno[excel]`, `agno[text]`, `agno[markdown]`, `agno[docling]`, `agno[chonkie]` (chunking).

#### Interfaces and integrations

| Extra | Purpose |
|-------|---------|
| `agno[slack]` | Slack chat interface |
| `agno[telegram]` | Telegram interface |
| `agno[whatsapp-crypto]` | WhatsApp encryption support |
| `agno[agui]` | AG-UI protocol integration |
| `agno[a2a]` | Agent-to-Agent (A2A) protocol |
| `agno[mcp]` | Model Context Protocol tools |

#### Observability

`agno[opentelemetry]`, `agno[langfuse]`, `agno[arize]`, `agno[weave]`, `agno[openlit]`.

> [!TIP]
> Tool extras follow the same pattern — `agno[exa]`, `agno[github]`, `agno[gmail]`, `agno[duckdb]`, `agno[firecrawl]`, and many more. Install `agno[tools]` to pull a curated bundle, or add individual tool extras as you adopt them.

### Set provider credentials

Most providers read an API key from an environment variable. Agno loads a `.env` file automatically (via `python-dotenv`):

```bash
# .env
OPENAI_API_KEY=sk-...
ANTHROPIC_API_KEY=sk-ant-...
GOOGLE_API_KEY=...
```

---

## 4. Core Concepts

| Concept | Description |
|---------|-------------|
| **Agent** | The atomic unit: one `Model`, instructions, optional tools, memory, knowledge, and a database for persistence. Runs via `run()` / `arun()` / `print_response()`. |
| **Model** | A provider-backed LLM wrapper (`OpenAIChat`, `Claude`, `Gemini`, …). Implements a common interface so agents are provider-agnostic. |
| **Tool / Toolkit** | A function (or class of functions) the model can call. Toolkits bundle related functions (e.g. `YFinanceTools`). |
| **Team** | A leader agent plus members, run in `coordinate`, `route`, `broadcast`, or `tasks` mode. |
| **Workflow** | A deterministic graph of `Step`s with control-flow primitives (`Loop`, `Parallel`, `Condition`, `Router`, `Steps`). |
| **Knowledge** | A searchable corpus (RAG): documents → chunks → embeddings → vector DB, queried at run time. |
| **Memory** | Long-lived facts about a user, captured and recalled across sessions. |
| **Session** | A conversation thread, identified by `session_id`, persisted in a `Db`. Carries history and `session_state`. |
| **Db** | A storage backend (PostgreSQL, SQLite, MySQL, MongoDB, Redis, DynamoDB, …) for sessions, runs, memory, knowledge metadata, and traces. |
| **AgentOS** | A FastAPI app that serves your agents/teams/workflows as a production API with auth, tracing, scheduling, and chat interfaces. |

These objects compose. An `Agent` can have `knowledge`, `memory`, `tools`, and a `db`. A `Team` contains `Agent`s. A `Workflow` orchestrates `Agent`s, `Team`s, and plain functions. An `AgentOS` exposes any of them over HTTP.

---

## 5. Building Agents

The `Agent` constructor is where almost all configuration happens. It accepts roughly 150 keyword arguments, grouped by capability below. Every argument is keyword-only and optional except where noted.

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

agent = Agent(
    name="Support Agent",
    model=OpenAIChat(id="gpt-4o"),
    description="A helpful customer-support assistant.",
    instructions=[
        "Answer in plain language.",
        "If you don't know, say so.",
    ],
    markdown=True,
)
```

### Running an agent

| Method | Returns | Use |
|--------|---------|-----|
| `agent.run(input, ...)` | `RunOutput` | Synchronous run; inspect `.content`, `.messages`, `.metrics`. |
| `await agent.arun(input, ...)` | `RunOutput` | Async run. |
| `agent.print_response(input, stream=True)` | — | Pretty-print to terminal (great for demos). |
| `await agent.aprint_response(...)` | — | Async pretty-print. |
| `agent.cli_app()` | — | Launch an interactive REPL chat loop in the terminal. |
| `agent.continue_run(...)` | `RunOutput` | Resume a run that was paused (e.g. for human approval). |

```python
result = agent.run("What is the capital of France?")
print(result.content)   # "Paris"
```

> [!IMPORTANT]
> If your instructions, tools, or system message are defined as **async** callables, you must use `arun()` / `aprint_response()`. Calling `run()` will raise `Instructions function is async, use agent.arun() instead`.

### Identity and model

| Argument | Type | Default | Description |
|----------|------|---------|-------------|
| `model` | `Model \| str` | `None` | The LLM. Pass a model object or a `"provider:id"` string (e.g. `"openai:gpt-4o"`). |
| `fallback_models` | `list[Model \| str]` | `None` | Models tried in order if the primary fails. |
| `fallback_config` | `FallbackConfig` | `None` | Advanced error-specific fallback routing. |
| `name` | `str` | `None` | Human-readable agent name. |
| `id` | `str` | autogenerated | Stable agent ID. |

### Instructions and system message

| Argument | Type | Default | Description |
|----------|------|---------|-------------|
| `description` | `str` | `None` | Added to the start of the system message. |
| `instructions` | `str \| list[str] \| Callable` | `None` | The agent's task instructions. |
| `expected_output` | `str` | `None` | Describes the desired output shape. |
| `additional_context` | `str` | `None` | Extra text appended to the system message. |
| `system_message` | `str \| Callable \| Message` | `None` | Override the entire system message. |
| `markdown` | `bool` | `False` | Instruct the model to format output as Markdown. |
| `add_datetime_to_context` | `bool` | `False` | Inject the current datetime (enables "tomorrow"-style reasoning). |
| `add_location_to_context` | `bool` | `False` | Inject the current location. |
| `add_name_to_context` | `bool` | `False` | Tell the agent its own name. |
| `use_instruction_tags` | `bool` | `False` | Wrap instructions in `<instructions>` tags. |

### Tools

| Argument | Type | Default | Description |
|----------|------|---------|-------------|
| `tools` | `list[Toolkit \| Callable \| Function \| dict] \| Callable` | `None` | Tools the model may call. Can be a factory returning tools at run time. |
| `tool_call_limit` | `int` | `None` | Max tool calls per run. |
| `tool_choice` | `str \| dict` | `None` | `"auto"`, `"none"`, or force a specific function. |
| `tool_hooks` | `list[Callable]` | `None` | Middleware wrapped around each tool call. |

See [Tools and Toolkits](#7-tools-and-toolkits).

### Knowledge (RAG)

| Argument | Type | Default | Description |
|----------|------|---------|-------------|
| `knowledge` | `Knowledge` | `None` | A knowledge base to search. |
| `search_knowledge` | `bool` | `True` | Give the agent a tool to search knowledge (Agentic RAG). Active only when `knowledge` is set. |
| `add_knowledge_to_context` | `bool` | `False` | Inject retrieved references directly into the prompt. |
| `knowledge_filters` | `dict \| list[FilterExpr]` | `None` | Metadata filters applied to searches. |
| `enable_agentic_knowledge_filters` | `bool` | `False` | Let the agent choose filters itself. |
| `knowledge_retriever` | `Callable` | `None` | Custom retrieval function replacing the default search. |

See [Knowledge and RAG](#8-knowledge-and-rag).

### Memory

| Argument | Type | Default | Description |
|----------|------|---------|-------------|
| `memory_manager` | `MemoryManager` | `None` | Custom memory manager. |
| `enable_agentic_memory` | `bool` | `False` | Let the agent manage user memories via tools. |
| `update_memory_on_run` | `bool` | `False` | Create/update user memories at the end of each run. |
| `add_memories_to_context` | `bool` | `None` | Inject stored memories into the prompt. |

See [Memory](#9-memory).

### Sessions, state, and history

| Argument | Type | Default | Description |
|----------|------|---------|-------------|
| `db` | `BaseDb \| AsyncBaseDb` | `None` | Database for persisting sessions, runs, and memory. |
| `session_id` | `str` | autogenerated | Conversation thread identifier. |
| `user_id` | `str` | `None` | Default user for this agent. |
| `session_state` | `dict` | `None` | Mutable state persisted across runs in the session. |
| `add_session_state_to_context` | `bool` | `False` | Include `session_state` in the prompt. |
| `enable_agentic_state` | `bool` | `False` | Give the agent tools to update `session_state`. |
| `add_history_to_context` | `bool` | `False` | Include prior messages from the session. |
| `num_history_runs` | `int` | `None` | How many past runs to include. |
| `search_past_sessions` | `bool` | `False` | Add a tool to search previous sessions. |
| `enable_session_summaries` | `bool` | `False` | Generate session summaries at run end. |

See [Sessions, State, and History](#10-sessions-state-and-history).

### Structured output

| Argument | Type | Default | Description |
|----------|------|---------|-------------|
| `input_schema` | `Type[BaseModel]` | `None` | Validate the run input against a Pydantic model. |
| `output_schema` | `Type[BaseModel] \| dict` | `None` | Coerce the response into a Pydantic model / JSON schema. |
| `parse_response` | `bool` | `True` | Convert the model output into `output_schema`. |
| `structured_outputs` | `bool` | `None` | Use the provider's native structured-output mode. |
| `use_json_mode` | `bool` | `False` | Describe the schema in the prompt instead of native enforcement. |
| `parser_model` | `Model` | `None` | A secondary model that parses the primary model's output. |

See [Structured Input and Output](#11-structured-input-and-output).

### Reasoning

| Argument | Type | Default | Description |
|----------|------|---------|-------------|
| `reasoning` | `bool` | `False` | Enable step-by-step reasoning. |
| `reasoning_model` | `Model` | `None` | A dedicated model for the reasoning phase. |
| `reasoning_min_steps` / `reasoning_max_steps` | `int` | `1` / `10` | Bounds on reasoning steps. |

See [Reasoning](#12-reasoning).

### Hooks and guardrails

| Argument | Type | Default | Description |
|----------|------|---------|-------------|
| `pre_hooks` | `list[Callable \| BaseGuardrail \| BaseEval]` | `None` | Run after the session loads, before processing. |
| `post_hooks` | `list[Callable \| BaseGuardrail \| BaseEval]` | `None` | Run after output is generated, before it returns. |

See [Guardrails, Hooks, and Human-in-the-Loop](#13-guardrails-hooks-and-human-in-the-loop).

### Streaming and retries

| Argument | Type | Default | Description |
|----------|------|---------|-------------|
| `stream` | `bool` | `None` | Stream the response token-by-token. |
| `stream_events` | `bool` | `None` | Stream intermediate events (tool calls, reasoning steps). |
| `retries` | `int` | `0` | Retry attempts on failure. |
| `delay_between_retries` | `int` | `1` | Seconds between retries. |
| `exponential_backoff` | `bool` | `False` | Double the delay each retry. |

### Telemetry and debug

| Argument | Type | Default | Description |
|----------|------|---------|-------------|
| `telemetry` | `bool` | `True` | Send minimal anonymous usage telemetry. Disable per-agent or globally with `AGNO_TELEMETRY=false`. |
| `debug_mode` | `bool` | `False` | Verbose debug logging. |
| `debug_level` | `1 \| 2` | `1` | Debug verbosity. |

> [!CAUTION]
> Telemetry is currently **synchronous** and can add latency to `agent.run()`. If you need the lowest possible per-call latency, set `telemetry=False` (or `AGNO_TELEMETRY=false`). See [Troubleshooting](#19-troubleshooting).

---

## 6. Models and Providers

Agno wraps every provider behind a common `Model` interface. Import the class for your provider and pass it as `model=`:

```python
from agno.models.openai import OpenAIChat
from agno.models.anthropic import Claude
from agno.models.google import Gemini

agent = Agent(model=Claude(id="claude-sonnet-4-5"))
```

### Provider class reference

| Provider | Import | Class(es) |
|----------|--------|-----------|
| OpenAI | `agno.models.openai` | `OpenAIChat`, `OpenAIResponses`, `OpenAILike` |
| Anthropic | `agno.models.anthropic` | `Claude` |
| Google | `agno.models.google` | `Gemini` |
| Groq | `agno.models.groq` | `Groq` |
| Mistral | `agno.models.mistral` | `MistralChat` |
| Ollama (local) | `agno.models.ollama` | `Ollama`, `OllamaResponses` |
| AWS Bedrock | `agno.models.aws` | `AwsBedrock`, `Claude` |
| Azure | `agno.models.azure` | `AzureOpenAI`, `AzureAIFoundry` |
| Cohere | `agno.models.cohere` | `Cohere` |
| DeepSeek | `agno.models.deepseek` | `DeepSeek` |
| xAI | `agno.models.xai` | `xAI` |
| Vertex AI | `agno.models.vertexai` | `Claude` |

Agno additionally ships providers for Cerebras, Cloudflare, Fireworks, Hugging Face, IBM watsonx, LiteLLM, LM Studio, llama.cpp, Meta, NVIDIA, Nebius, OpenRouter, Perplexity, Portkey, Requesty, SambaNova, Together, vLLM, and more — over 45 in total. Each lives under `agno.models.<provider>`.

### The `provider:id` shorthand

Instead of importing a class, you can pass a model string. Agno resolves the provider and instantiates the right class:

```python
agent = Agent(model="openai:gpt-4o")
agent = Agent(model="anthropic:claude-sonnet-4-5")
```

> [!WARNING]
> The string **must** be `"<provider>:<model_id>"`. A bare model name raises:
> `ValueError: Invalid model string format: 'gpt-4o'. Model strings should be in format '<provider>:<model_id>' e.g. 'openai:gpt-4o'`.

### Fallback models

Provide alternates that are tried automatically when the primary model errors:

```python
agent = Agent(
    model=OpenAIChat(id="gpt-4o"),
    fallback_models=["anthropic:claude-sonnet-4-5", "google:gemini-2.5-flash"],
)
```

---

## 7. Tools and Toolkits

Tools are functions the model can call. Agno ships ~130 pre-built toolkits and lets you write your own.

### Using a built-in toolkit

```python
from agno.agent import Agent
from agno.models.openai import OpenAIChat
from agno.tools.duckduckgo import DuckDuckGoTools

agent = Agent(
    model=OpenAIChat(id="gpt-4o"),
    tools=[DuckDuckGoTools()],
    instructions="Search the web and cite your sources.",
)
agent.print_response("What happened in tech news today?", stream=True)
```

### Toolkit catalog (selected)

| Category | Toolkits |
|----------|----------|
| Web search | `DuckDuckGoTools`, `GoogleSearchTools`, `BraveSearchTools`, `ExaTools`, `TavilyTools`, `BaiduSearchTools`, `LinkupTools` |
| Web scraping | `Crawl4aiTools`, `FirecrawlTools`, `Newspaper4kTools`, `BrowserbaseTools`, `JinaReaderTools`, `TrafilaturaTools` |
| Finance | `YFinanceTools`, `FinancialDatasetsTools`, `OpenBBTools` |
| Code & compute | `PythonTools`, `DockerTools`, `E2BTools`, `DaytonaTools`, `DuckDbTools`, `CalculatorTools` |
| Files & data | `FileTools`, `CsvTools`, `LocalFileSystemTools`, `Neo4jTools`, `GoogleBigQueryTools` |
| Productivity | `GmailTools`, `GoogleCalendarTools`, `GoogleSheetsTools`, `NotionTools`, `TodoistTools`, `LinearTools`, `JiraTools` |
| Communication | `SlackTools`, `DiscordTools`, `EmailTools`, `WebexTools` |
| Dev platforms | `GithubTools`, `GitlabTools`, `BitbucketTools`, `ConfluenceTools` |
| Media | `DalleTools`, `ElevenLabsTools`, `FalTools`, `GiphyTools`, `LumaLabTools`, `MoviePyVideoTools`, `OpenCVTools` |
| Knowledge/memory | `KnowledgeTools`, `MemoryTools`, `Mem0Tools` |
| Protocols | `MCPTools` (Model Context Protocol), `McpToolboxTools` |

> [!TIP]
> Many toolkits expose an `all=True` flag (e.g. `YFinanceTools(all=True)`) to enable every function, or accept granular flags to expose only what you need. Most require their extra: e.g. `pip install "agno[github]"` for `GithubTools`.

### Writing a custom tool

Any plain Python function with type hints and a docstring becomes a tool:

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

def get_weather(city: str) -> str:
    """Return the current weather for a city.

    Args:
        city: The city name, e.g. "London".
    """
    return f"It is 18°C and sunny in {city}."

agent = Agent(model=OpenAIChat(id="gpt-4o"), tools=[get_weather])
agent.print_response("What's the weather in Tokyo?")
```

The docstring becomes the tool description and the type hints define the JSON schema the model fills in.

### Limiting and controlling tool use

```python
agent = Agent(
    model=OpenAIChat(id="gpt-4o"),
    tools=[get_weather],
    tool_call_limit=3,          # at most 3 tool calls per run
    tool_choice="auto",          # let the model decide (default when tools present)
)
```

### Model Context Protocol (MCP)

Connect to MCP servers to expose their tools to your agent:

```python
pip install "agno[mcp]"
```

```python
from agno.tools.mcp import MCPTools

agent = Agent(model=OpenAIChat(id="gpt-4o"), tools=[MCPTools(command="npx -y @modelcontextprotocol/server-filesystem /data")])
```

> [!CAUTION]
> If MCP toolkit initialization fails, older versions could spin the CPU. Always wrap MCP setup in error handling and pin a recent Agno release (see [Troubleshooting](#19-troubleshooting)).

---

## 8. Knowledge and RAG

Knowledge gives an agent a searchable corpus. At run time the agent retrieves relevant chunks and grounds its answer in them (Retrieval-Augmented Generation).

### The pipeline

```text
Documents → Reader → Chunker → Embedder → Vector DB → (search at run time)
```

| Stage | Module | Examples |
|-------|--------|----------|
| Reader | `agno.knowledge.reader` | PDF, DOCX, PPTX, CSV, Markdown, text, web |
| Chunker | `agno.knowledge.chunking` | fixed-size, semantic, code-aware (via `chonkie`) |
| Embedder | `agno.knowledge.embedder` | OpenAI, Google, Cohere, Hugging Face, FastEmbed, Jina, Fireworks, Azure |
| Reranker | `agno.knowledge.reranker` | improve retrieval ordering |
| Vector DB | `agno.vectordb` | see below |

### Vector database support

`PgVector`, `ChromaDb`, `LanceDb`, `Qdrant`, `Milvus`, `Weaviate`, `MongoDb`, `Pinecone`, `Couchbase`, `Cassandra`, `Clickhouse`, `SingleStore`, `SurrealDb`, `UpstashDb`, `Redis`, plus LangChain and LlamaIndex adapters.

### Example: PDF knowledge with pgvector

```bash
pip install "agno[pdf,pgvector,openai]"
```

```python
from agno.agent import Agent
from agno.models.openai import OpenAIChat
from agno.knowledge.knowledge import Knowledge
from agno.vectordb.pgvector import PgVector

knowledge = Knowledge(
    vector_db=PgVector(
        table_name="docs",
        db_url="postgresql+psycopg://ai:ai@localhost:5532/ai",
    ),
)
# Load content (run once)
knowledge.add_content(path="./handbook.pdf")

agent = Agent(
    model=OpenAIChat(id="gpt-4o"),
    knowledge=knowledge,
    search_knowledge=True,        # agentic RAG: the agent searches when needed
    instructions="Answer using the handbook. Cite the relevant section.",
)
agent.print_response("What is our refund policy?", stream=True)
```

> [!NOTE]
> With `search_knowledge=True` (the default when `knowledge` is set), the agent gets a search tool and decides when to query — this is **Agentic RAG**. Set `add_knowledge_to_context=True` instead to always inject retrieved chunks into every prompt.

### Knowledge filters

Restrict searches by document metadata:

```python
agent = Agent(
    model=OpenAIChat(id="gpt-4o"),
    knowledge=knowledge,
    knowledge_filters={"department": "finance"},
)
```

Set `enable_agentic_knowledge_filters=True` to let the agent choose filters dynamically.

---

## 9. Memory

Memory captures durable facts about a user — preferences, history, context — and recalls them in future sessions. Unlike `session_state` (scoped to one conversation), memories persist across sessions for a `user_id`.

```python
from agno.agent import Agent
from agno.models.openai import OpenAIChat
from agno.db.sqlite import SqliteDb

agent = Agent(
    model=OpenAIChat(id="gpt-4o"),
    db=SqliteDb(db_file="agent.db"),
    user_id="user_123",
    enable_agentic_memory=True,     # the agent manages memories with tools
    add_memories_to_context=True,   # recall them in the prompt
)

agent.print_response("Remember that I'm vegetarian and allergic to peanuts.")
# ... later, in a new session ...
agent.print_response("Suggest a dinner recipe.")   # respects dietary facts
```

| Mode | Argument | Behaviour |
|------|----------|-----------|
| Agentic | `enable_agentic_memory=True` | The agent decides what to remember via tools. |
| Automatic | `update_memory_on_run=True` | Memories are extracted at the end of every run. |
| Recall | `add_memories_to_context=True` | Stored memories are injected into the prompt. |

> [!IMPORTANT]
> Memory requires a `db`. Without one, there is nowhere to persist memories between sessions.

---

## 10. Sessions, State, and History

### Sessions

A **session** is one conversation thread, identified by `session_id` and persisted in a `db`. Reuse a `session_id` to continue a conversation:

```python
from agno.db.sqlite import SqliteDb

agent = Agent(
    model=OpenAIChat(id="gpt-4o"),
    db=SqliteDb(db_file="agent.db"),
    session_id="chat_42",
    add_history_to_context=True,
    num_history_runs=5,
)
agent.print_response("My name is Sam.")
agent.print_response("What's my name?")   # "Sam" — history is in context
```

### Session state

`session_state` is a mutable dict persisted with the session. Use it for counters, preferences, or scratch data:

```python
agent = Agent(
    model=OpenAIChat(id="gpt-4o"),
    db=SqliteDb(db_file="agent.db"),
    session_state={"cart": []},
    add_session_state_to_context=True,
    enable_agentic_state=True,   # let the agent mutate the state via tools
)
```

| Argument | Effect |
|----------|--------|
| `session_state` | Initial state dict. |
| `add_session_state_to_context` | Include state in the prompt. |
| `enable_agentic_state` | Give the agent tools to update state. |
| `overwrite_db_session_state` | Replace stored state instead of merging (default merges). |

### History controls

| Argument | Effect |
|----------|--------|
| `add_history_to_context` | Include prior messages. |
| `num_history_runs` | Number of past runs to include. |
| `num_history_messages` | Number of past messages to include. |
| `search_past_sessions` | Add a tool to search older sessions. |
| `enable_session_summaries` | Summarize sessions for compact recall. |

---

## 11. Structured Input and Output

### Typed output

Pass a Pydantic model as `output_schema` to get validated structured data instead of free text:

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

class StockAnalysis(BaseModel):
    ticker: str
    sentiment: str
    target_price: float

agent = Agent(model=OpenAIChat(id="gpt-4o"), output_schema=StockAnalysis)

result = agent.run("Analyze NVDA")
analysis = result.content          # a StockAnalysis instance
print(analysis.ticker, analysis.target_price)
```

| Argument | Effect |
|----------|--------|
| `output_schema` | Pydantic model / JSON schema to coerce output into. |
| `structured_outputs` | Use the provider's native structured-output enforcement (e.g. OpenAI). |
| `use_json_mode` | Describe the schema in the prompt instead of native enforcement (for providers without it). |
| `parser_model` | A second model that parses the primary output into the schema. |

### Typed input

Validate inputs before the run with `input_schema`:

```python
class AnalysisRequest(BaseModel):
    ticker: str
    horizon_days: int

agent = Agent(model=OpenAIChat(id="gpt-4o"), input_schema=AnalysisRequest)
agent.run(AnalysisRequest(ticker="AAPL", horizon_days=30))
```

> [!WARNING]
> When `input_schema` is set, input is required and validated. Passing a mismatched type raises `Cannot validate <type> against input_schema. Expected dict or <Model> instance.`

---

## 12. Reasoning

Enable explicit step-by-step reasoning to improve accuracy on hard problems:

```python
agent = Agent(
    model=OpenAIChat(id="gpt-4o"),
    reasoning=True,
    reasoning_min_steps=2,
    reasoning_max_steps=8,
)
agent.print_response("If a train leaves at 3pm going 60mph...", stream=True)
```

You can dedicate a separate model to the reasoning phase (often a stronger or cheaper model):

```python
agent = Agent(
    model=OpenAIChat(id="gpt-4o"),
    reasoning_model=Claude(id="claude-sonnet-4-5"),
    reasoning=True,
)
```

---

## 13. Guardrails, Hooks, and Human-in-the-Loop

### Pre and post hooks

Hooks run custom logic around the agent's processing. Use them for validation, logging, redaction, or evaluation:

```python
def redact_pii(run_input, **kwargs):
    # mutate or inspect the input before processing
    ...

agent = Agent(
    model=OpenAIChat(id="gpt-4o"),
    pre_hooks=[redact_pii],
)
```

`pre_hooks` run after the session loads but before the model is called; `post_hooks` run after output is generated but before it is returned. Hooks may be plain callables, `BaseGuardrail` subclasses, or `BaseEval` evaluators.

### Guardrails

Subclass `BaseGuardrail` to enforce policies (e.g. block spam or off-topic requests):

```python
from agno.guardrails import BaseGuardrail

class SpamGuardrail(BaseGuardrail):
    def check(self, run_input, **kwargs):
        if "buy now" in str(run_input).lower():
            raise ValueError("Spam detected")

agent = Agent(model=OpenAIChat(id="gpt-4o"), pre_hooks=[SpamGuardrail()])
```

### Human-in-the-loop and approvals

Agno can **pause** a run to wait for human confirmation (for example, before a destructive tool call), then resume with `continue_run()`. This pattern powers approval gates in AgentOS, where the `/approvals` API surfaces pending actions. See the Admin Guide for the server-side approval workflow.

---

## 14. Multi-Agent Teams

A **Team** has a leader and a list of members (agents or nested teams). The leader coordinates the members according to the team's **mode**.

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

researcher = Agent(name="Researcher", role="Finds facts", model=OpenAIChat(id="gpt-4o"),
                   tools=[DuckDuckGoTools()])
writer = Agent(name="Writer", role="Writes prose", model=OpenAIChat(id="gpt-4o"))

team = Team(
    name="Content Team",
    members=[researcher, writer],
    model=OpenAIChat(id="gpt-4o"),
    instructions="Research the topic, then write a short article.",
)
team.print_response("Write about the James Webb Space Telescope.", stream=True)
```

### Team modes

| Mode | Behaviour |
|------|-----------|
| `coordinate` (default) | The leader picks members, crafts subtasks, and synthesizes their responses into a final answer. |
| `route` | The leader routes the request to the single best specialist and returns that member's response directly. |
| `broadcast` | The leader sends the same task to **all** members simultaneously. |
| `tasks` | Autonomous loop: the leader decomposes the goal into a shared task list, delegates, and iterates until done (bounded by `max_iterations`). |

```python
from agno.team import Team
team = Team(members=[...], mode="route")   # or "coordinate", "broadcast", "tasks"
```

### Useful Team arguments

| Argument | Default | Description |
|----------|---------|-------------|
| `members` | **required** | List of agents / nested teams. |
| `mode` | `coordinate` | Execution mode (above). |
| `respond_directly` | `False` | Leader returns member output without re-processing. |
| `delegate_to_all_members` | `False` | Delegate to every member instead of a subset. |
| `add_team_history_to_members` | `False` | Share team-level history with members. |
| `share_member_interactions` | `False` | Let members see each other's request/response. |
| `max_iterations` | `10` | Loop bound for `tasks` mode. |

Teams accept most of the same memory, knowledge, session, and db arguments as agents.

> [!NOTE]
> In `coordinate` mode with persistence, ensure your `db` is configured so member sessions survive process restarts; otherwise resuming a paused team run may fail to find a member's prior session.

---

## 15. Workflows

Workflows give you **deterministic** orchestration: explicit control flow over agents, teams, and functions. Unlike a team (where the LLM leader decides routing), a workflow's structure is code you define.

### Building blocks

| Primitive | Import | Purpose |
|-----------|--------|---------|
| `Workflow` | `from agno.workflow import Workflow` | The container. |
| `Step` | `from agno.workflow import Step` | A single unit (runs an agent, team, or function). |
| `Steps` | `from agno.workflow import Steps` | A named sequence of steps. |
| `Loop` | `from agno.workflow import Loop` | Repeat steps until a condition holds. |
| `Parallel` | `from agno.workflow import Parallel` | Run steps concurrently and fan-in. |
| `Condition` | `from agno.workflow import Condition` | Run steps only if a predicate is true. |
| `Router` | `from agno.workflow import Router` | Pick a branch dynamically. |

### Sequential workflow example

```python
from agno.agent import Agent
from agno.models.openai import OpenAIChat
from agno.workflow import Workflow, Step

researcher = Agent(name="Researcher", model=OpenAIChat(id="gpt-4o"), tools=[DuckDuckGoTools()])
writer = Agent(name="Writer", model=OpenAIChat(id="gpt-4o"))

workflow = Workflow(
    name="Article Pipeline",
    steps=[
        Step(name="research", agent=researcher),
        Step(name="write", agent=writer),
    ],
)
workflow.print_response("Write an article about black holes.", stream=True)
```

Each step receives a `StepInput` (the prior step's output plus shared context) and returns a `StepOutput`. You can mix agents, teams, and plain functions as step executors.

### Parallel and conditional flow

```python
from agno.workflow import Workflow, Step, Parallel, Condition

workflow = Workflow(
    name="Multi-source research",
    steps=[
        Parallel(
            Step(name="web", agent=web_agent),
            Step(name="news", agent=news_agent),
        ),
        Step(name="synthesize", agent=writer),
    ],
)
```

### CEL expressions

Conditions and routers can use [CEL](https://github.com/google/cel-spec) expressions for declarative logic (`pip install "agno[cel]"`). Validate them with `validate_cel_expression()`.

> [!TIP]
> Use a **Team** when you want the model to decide how to delegate; use a **Workflow** when you need a repeatable, auditable pipeline with explicit branches, loops, and parallelism.

---

## 16. Running as a Service: AgentOS

AgentOS turns your agents into a production FastAPI application — 50+ REST endpoints with SSE and WebSocket streaming, plus optional auth, tracing, scheduling, and chat interfaces.

```bash
pip install "agno[os]"
```

```python
from agno.agent import Agent
from agno.models.openai import OpenAIChat
from agno.db.sqlite import SqliteDb
from agno.os import AgentOS

agent = Agent(
    name="Assistant",
    model=OpenAIChat(id="gpt-4o"),
    db=SqliteDb(db_file="agentos.db"),
)

agent_os = AgentOS(agents=[agent])
app = agent_os.get_app()      # a FastAPI app

# Run with: uvicorn main:app --reload --port 7777
```

```bash
uvicorn main:app --port 7777
```

Visit `http://localhost:7777/docs` for the interactive OpenAPI explorer.

### What AgentOS exposes

| Domain | Endpoints (prefix) | Purpose |
|--------|--------------------|---------|
| Agents / Teams / Workflows | `/agents`, `/teams`, `/workflows` | Run and manage your components. |
| Sessions | `/sessions` | List and inspect conversations. |
| Memory | `/memory` | User memories. |
| Knowledge | `/knowledge` | Manage knowledge bases. |
| Metrics / Traces | `/metrics`, `/traces` | Observability data. |
| Evals | `/evals` | Evaluation runs. |
| Schedules | `/schedules` | Cron jobs. |
| Approvals | `/approvals` | Human-in-the-loop gates. |
| Registry | `/registry` | Discover registered components. |
| Health | `/health` | Liveness. |

### Key AgentOS options

| Argument | Default | Purpose |
|----------|---------|---------|
| `agents` / `teams` / `workflows` / `knowledge` | `None` | What to serve (at least one, or a `db`, is required). |
| `db` | `None` | Default database for components without their own. |
| `authorization` | `False` | Enable JWT-based RBAC. |
| `interfaces` | `[]` | Chat interfaces (Slack, Telegram, WhatsApp, AG-UI, A2A). |
| `tracing` | `False` | Enable OpenTelemetry tracing. |
| `scheduler` | `False` | Enable the cron scheduler. |
| `enable_mcp_server` | `False` | Expose the OS itself as an MCP server. |
| `a2a_interface` | `False` | Expose agents over the A2A protocol. |
| `cors_allowed_origins` | `None` | Additional CORS origins. |
| `config` | `None` | Path to a YAML config or an `AgentOSConfig`. |

### Chat interfaces

Expose an agent through a messaging platform:

```python
from agno.os.interfaces.slack import Slack

agent_os = AgentOS(
    agents=[agent],
    interfaces=[Slack(agent=agent)],
)
```

Available interfaces: **Slack**, **Telegram**, **WhatsApp**, **AG-UI**, **A2A**.

> [!IMPORTANT]
> AgentOS persistence, auth, scheduling, and deployment are covered in depth in the **Admin Guide**. This section is the user-facing overview.

---

## 17. Deploying with the `ag` CLI

The separate **`agno-infra`** package provides the `ag` (alias `agno`) command-line tool for scaffolding and deploying AgentOS projects to Docker and AWS.

```bash
pip install "agno-infra"          # or: pip install "agno[infra]"
```

### Commands

All deployment commands live under `ag infra`:

| Command | Purpose |
|---------|---------|
| `ag infra create` | Create a new AgentOS codebase from a starter template. |
| `ag infra up` | Create/start the infrastructure resources (containers, AWS resources). |
| `ag infra down` | Stop and remove resources. |
| `ag infra patch` | Update running resources. |
| `ag infra restart` | Restart resources. |
| `ag infra config` | Show the active infrastructure config. |
| `ag infra delete` | Delete an infrastructure configuration. |

```bash
ag infra create --name my-agentos
cd my-agentos
ag infra up
```

> [!NOTE]
> `agno-infra` targets **Docker** and **AWS** (ECS, load balancers, RDS, S3, and more). Because Agno deploys as a container, you can also run it on any platform that runs containers — Railway, GCP, Fly, etc. See the Admin Guide for deployment architecture.

---

## 18. Common Recipes

### A research agent with web search and citations

```python
from agno.agent import Agent
from agno.models.openai import OpenAIChat
from agno.tools.exa import ExaTools

agent = Agent(
    model=OpenAIChat(id="gpt-4o"),
    tools=[ExaTools()],
    instructions=["Always cite sources with URLs.", "Be concise."],
    add_datetime_to_context=True,
    markdown=True,
)
agent.print_response("Summarize recent advances in battery technology.", stream=True)
```

### A persistent chat assistant

```python
from agno.agent import Agent
from agno.models.openai import OpenAIChat
from agno.db.sqlite import SqliteDb

agent = Agent(
    model=OpenAIChat(id="gpt-4o"),
    db=SqliteDb(db_file="chat.db"),
    session_id="user-sam",
    add_history_to_context=True,
    enable_user_memories=True,
    markdown=True,
)
agent.cli_app()   # interactive REPL
```

### A structured data extractor

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

class Invoice(BaseModel):
    vendor: str
    total: float
    due_date: str

agent = Agent(model=OpenAIChat(id="gpt-4o"), output_schema=Invoice)
invoice = agent.run("Vendor: Acme, $1,250 due 2026-07-01").content
```

### A multi-agent team served over HTTP

```python
from agno.os import AgentOS
agent_os = AgentOS(teams=[content_team])
app = agent_os.get_app()
# uvicorn main:app --port 7777
```

---

## 19. Troubleshooting

### Error: `Invalid model string format: 'gpt-4o'`

**Cause:** A model passed as a string must be `"<provider>:<model_id>"`.
**Solution:** Use `"openai:gpt-4o"`, or pass a model object: `OpenAIChat(id="gpt-4o")`.
**Prevention:** Prefer model objects in code; reserve strings for config files.

### Error: `Model provider '<x>' is not supported.`

**Cause:** The provider prefix in your model string isn't recognized.
**Solution:** Check the provider name against the [provider reference](#6-models-and-providers); install the corresponding extra.

### Error: `'<package>' not installed. Please install using 'pip install agno[<extra>]'`

**Cause:** You used a tool, model, or backend whose optional dependency isn't installed (e.g. `mistralai`, `PyJWT`, `filetype`).
**Solution:** Install the named extra, e.g. `pip install "agno[mistral]"` or `pip install "agno[os]"`.
**Prevention:** Install the extras for every provider/tool/db you use up front.

### Error: `Either agents, teams, workflows, knowledge bases or a database must be provided.`

**Cause:** `AgentOS(...)` was constructed with nothing to serve.
**Solution:** Pass at least one of `agents=`, `teams=`, `workflows=`, `knowledge=`, or `db=`.

### Error: `Instructions function is async, use 'agent.arun()' instead`

**Cause:** You used an async callable for `instructions` / `system_message` / a tool, then called the sync `run()`.
**Solution:** Use `await agent.arun(...)` / `await agent.aprint_response(...)`.

### Error: `At least one JWT verification key or JWKS file is required when validate=True`

**Cause:** JWT auth is enabled in AgentOS but no verification key is configured.
**Solution:** Set `JWT_VERIFICATION_KEY` or `JWT_JWKS_FILE` (env vars), or pass `verification_keys` / `jwks_file`. See the Admin Guide.

### Error: `Input required when input_schema is set`

**Cause:** `input_schema` is configured but no input was passed to `run()`.
**Solution:** Provide an input matching the schema (a dict or a model instance).

### High latency on every `agent.run()`

**Cause:** Telemetry currently runs synchronously and can add ~1s per call.
**Solution:** Set `telemetry=False` on the agent, or globally: `export AGNO_TELEMETRY=false`.

### CPU spins to 100% after MCP setup fails

**Cause:** A failed MCP toolkit initialization could corrupt the cancel scope in older releases.
**Solution:** Upgrade to the latest Agno; wrap `MCPTools(...)` setup in try/except and ensure servers are reachable before connecting.

### Knowledge base isn't searched

**Cause:** With a pre-supplied `messages` array (rather than a single input), the knowledge search tool may not be triggered automatically.
**Solution:** Pass a natural-language query as input, ensure `search_knowledge=True`, or set `add_knowledge_to_context=True` to always inject references.

### Multi-turn conversation breaks

**Cause:** Some patch releases have regressed multi-turn handling.
**Solution:** Pin a known-good version, confirm `db` + `add_history_to_context=True` are set, and reuse the same `session_id` across turns.

---

## 20. Frequently Asked Questions

**Q: Is Agno a hosted service or a library?**
A library/SDK you run yourself. There is a companion control-plane UI and managed offering, but the framework runs entirely in your own infrastructure.

**Q: Do I need an API key?**
You need credentials for whichever model provider you use (e.g. `OPENAI_API_KEY`). Agno itself doesn't require an account to run agents locally.

**Q: How is a Team different from a Workflow?**
A Team lets the LLM leader decide how to delegate (dynamic). A Workflow is deterministic code-defined control flow (sequences, loops, branches, parallelism). Use teams for open-ended delegation, workflows for repeatable pipelines.

**Q: Can I switch model providers without rewriting my agent?**
Yes. Swap the `model=` argument (or the `"provider:id"` string). The rest of the agent definition is provider-agnostic.

**Q: Where is conversation history stored?**
In the `db` you attach to the agent (SQLite, PostgreSQL, MySQL, MongoDB, Redis, DynamoDB, and more). Without a `db`, runs are stateless.

**Q: What's the difference between session state and memory?**
`session_state` is scoped to one conversation; **memory** holds durable facts about a `user_id` recalled across sessions.

**Q: How do I disable telemetry?**
Set `telemetry=False` on the agent/AgentOS, or `export AGNO_TELEMETRY=false`.

**Q: Can agents call my own functions?**
Yes — any typed, docstringed Python function passed in `tools=` becomes a callable tool.

**Q: Does Agno support local models?**
Yes, via Ollama, LM Studio, llama.cpp, and vLLM providers.

**Q: How do I serve agents over HTTP?**
Wrap them in `AgentOS(...)` and run the returned FastAPI app with `uvicorn`. See [Running as a Service](#16-running-as-a-service-agentos).

**Q: How do I add streaming?**
Pass `stream=True` to `run()` / `print_response()`. For intermediate events (tool calls, reasoning), add `stream_events=True`.

**Q: Can I structure agent output as JSON?**
Yes — set `output_schema` to a Pydantic model. The result's `.content` will be a validated instance.

**Q: Which Python versions are supported?**
3.7+ per the package metadata; 3.10+ is recommended for the best typing experience.

---

## 21. Reference

### Import map (public API)

| You want | Import |
|----------|--------|
| An agent | `from agno.agent import Agent` |
| A team | `from agno.team import Team, TeamMode, Task` |
| A workflow | `from agno.workflow import Workflow, Step, Steps, Loop, Parallel, Condition, Router` |
| A model | `from agno.models.<provider> import <Class>` |
| A toolkit | `from agno.tools.<name> import <Toolkit>` |
| A vector DB | `from agno.vectordb.<name> import <Class>` |
| A database | `from agno.db.<backend> import <Class>` |
| Knowledge | `from agno.knowledge.knowledge import Knowledge` |
| The server | `from agno.os import AgentOS` |

> [!NOTE]
> Agno's top-level `agno` package exposes only `agno.__version__`. Public classes are imported from their submodules as shown above.

### Common environment variables

| Variable | Effect |
|----------|--------|
| `AGNO_TELEMETRY` | Set to `false` to disable usage telemetry. |
| `OPENAI_API_KEY` / `ANTHROPIC_API_KEY` / `GOOGLE_API_KEY` / … | Provider credentials. |
| `JWT_VERIFICATION_KEY` / `JWT_JWKS_FILE` | AgentOS JWT auth (see Admin Guide). |

### Team modes

| Mode | Summary |
|------|---------|
| `coordinate` | Leader delegates subtasks and synthesizes (default). |
| `route` | Leader routes to one specialist, returns its answer. |
| `broadcast` | Leader sends the same task to all members. |
| `tasks` | Autonomous task-list loop until complete. |

### Agent run methods

| Method | Sync/Async | Returns |
|--------|------------|---------|
| `run` / `arun` | sync / async | `RunOutput` |
| `print_response` / `aprint_response` | sync / async | — (prints) |
| `cli_app` | sync | — (REPL) |
| `continue_run` | sync | `RunOutput` |

### Further reading

- **Admin Guide** — architecture, the monorepo layout, AgentOS deployment, JWT/RBAC, OpenTelemetry, scheduling, storage backends, security hardening, and the complete configuration reference.
- Official docs: `https://docs.agno.com`

---

_Generated June 2026 from agno-agi/agno at 5b9cfec. AI-generated documentation. The library is checked by sampling (three repositories so far); this guide was not individually reviewed. Verify against the project before relying on it. Unofficial; not affiliated with or reviewed by the project._
