Skip to content

Agno — Le framework Python qui veut tuer LangGraph par la perf

TL;DR — Agno (anciennement Phidata) est un framework agentique Python axé performance brute : ils annoncent ~10 000× plus rapide que LangGraph côté instantiation, ~50× moins de RAM, et 0 overhead sur les LLM calls. Le DSL est minimaliste (1 classe Agent, 1 classe Team, 1 classe Workflow), batteries-included (50+ tools, 30+ vector stores, memory, knowledge/RAG, monitoring intégré via agno.com ou self-hosted). Inclut un Playground UI local + AgentOS (serveur FastAPI auto-généré) pour shipper en 1 commande. Le choix 2026 quand tu veux LangGraph-level features mais sans le poids ni la verbosité, surtout sur agents finance/recherche/BI où le RAG + tools rapides comptent. Concurrent direct : Pydantic AI, CrewAI, LangGraph.


🧠 Mental model

                  ┌─────────────────────────────────────────┐
                  │              Agent                      │
                  │  ─────────────────────                  │
                  │  model       (any LLM)                  │
                  │  tools       (Python fn / packs)        │
                  │  knowledge   (RAG, vector)              │
                  │  memory      (session + long-term)      │
                  │  storage     (Postgres/SQLite/Redis)    │
                  │  reasoning   (chain-of-thought tools)   │
                  └────────────┬────────────────────────────┘

                               ▼ compose
                  ┌─────────────────────────┐
                  │       Team              │  ← mode: route | coordinate | collaborate
                  │  agents=[a,b,c]         │
                  │  mode="coordinate"      │  (orchestrator dispatch)
                  └────────────┬────────────┘

                               ▼ compose
                  ┌─────────────────────────┐
                  │     Workflow            │  ← Python natif (pas de DSL graphe)
                  │  ┌──┐  ┌──┐  ┌──┐       │     if/while/try, state via session_state
                  │  └──┘→ └──┘→ └──┘       │
                  └────────────┬────────────┘


                  ┌─────────────────────────┐
                  │  AgentOS (FastAPI)      │  ← auto-gen API + Playground UI
                  │  /agents /teams /runs   │
                  │  monitoring → agno.com  │
                  └─────────────────────────┘

Analogie — Agno est à LangGraph ce que FastAPI est à Django : moins magique, plus rapide, plus typé, plus "Python qui se lit". Pas de graphe explicite à dessiner — un workflow Agno est juste du Python (if, for, await), avec session_state qui persiste. La philo : "tu sais déjà coder, on te file juste les primitives".

Position 2026 :

  • vs LangGraph : Agno = perf + simplicité, LangGraph = écosystème + LangSmith. Agno gagne si tu n'es pas déjà investi LangChain.
  • vs Pydantic AI : Pydantic AI = type-safety extrême + Python idiomatique. Agno = plus de batteries (knowledge, teams modes, monitoring). Pydantic AI gagne sur la pureté du DX, Agno gagne sur la richesse.
  • vs CrewAI : CrewAI = abstractions "rôle/goal/backstory" (sympa POC, casse en prod). Agno = primitives bas-niveau, contrôle total.
  • vs AutoGen : AutoGen = recherche Microsoft, surface API énorme. Agno = production-first, surface minimaliste.

🛠️ Code minimal

python
# pip install agno openai duckduckgo-search yfinance
from agno.agent import Agent
from agno.models.openai import OpenAIChat
from agno.tools.duckduckgo import DuckDuckGoTools
from agno.tools.yfinance import YFinanceTools

analyst = Agent(
    name="Market Analyst",
    model=OpenAIChat(id="gpt-4.1"),
    tools=[DuckDuckGoTools(), YFinanceTools(stock_price=True, analyst_recommendations=True)],
    description="You are a senior buy-side equity analyst.",
    instructions=[
        "Always cite sources with URL.",
        "Use tables when comparing multiple stocks.",
        "Be terse, no fluff.",
    ],
    markdown=True,
    show_tool_calls=False,
)

analyst.print_response("Quels sont les 3 principaux risques pour LVMH au S2 2026 ?", stream=True)

Team (multi-agent)

python
from agno.team import Team

researcher = Agent(name="Researcher", model=..., tools=[DuckDuckGoTools()])
writer = Agent(name="Writer", model=..., instructions=["Style: blog SEO 1200 mots"])
critic = Agent(name="Critic", model=..., instructions=["Fact-check + style review"])

content_team = Team(
    members=[researcher, writer, critic],
    mode="coordinate",  # un leader dispatch les tâches
    model=OpenAIChat(id="gpt-4.1"),
    instructions=["Goal: produire un article SEO factuellement correct."],
    success_criteria="Article ≥ 1000 mots, ≥ 3 sources, 0 fact-check failure.",
)
content_team.print_response("Article: Loi DDADUE 2026 et impact RGPD pour PME", stream=True)

Workflow

python
from agno.workflow import Workflow, RunResponse

class BlogPipeline(Workflow):
    description = "Recherche → Draft → Fact-check → Publish"

    researcher: Agent = Agent(...)
    writer: Agent = Agent(...)
    critic: Agent = Agent(...)

    def run(self, topic: str) -> RunResponse:
        if topic in self.session_state.get("published", []):
            return RunResponse(content="Already published.")
        research = self.researcher.run(f"Recherche: {topic}").content
        draft = self.writer.run(f"Article sur {topic}\nSources:\n{research}").content
        review = self.critic.run(f"Fact-check:\n{draft}").content
        if "REJECTED" in review:
            draft = self.writer.run(f"Corrige:\n{draft}\nIssues:\n{review}").content
        self.session_state.setdefault("published", []).append(topic)
        return RunResponse(content=draft)

🎬 Cas d'usage concrets (France 2026)

1. Recherche financière buy-side (asset manager Paris)

Contexte — Boutique de gestion 8 gérants, 200 M€ AUM. Veulent un agent qui : (1) crawl SEC/AMF + transcripts earnings, (2) extrait métriques + sentiment, (3) génère thèse d'investissement 2 pages avec sources, (4) cross-check via critic agent. Aujourd'hui : 1 analyst junior = 60 k€/an pour produire 2 thèses/semaine. Objectif : 5 thèses/jour.

Pourquoi Agno — Performance (instantiate fast, scale workers), knowledge base ad-hoc par ticker, monitoring intégré (audit trail réglementaire AMF), Python = compatible avec le notebook de risque existant.

Mission — 35 j @ 1 500 € = 52 500 €.

2. Équipe rédaction blog SEO (PME e-commerce Toulouse)

Contexte — PME mode éco-responsable, fait 1,5 M€ CA en ligne. Veut publier 30 articles SEO/mois (catégorie produit, comparatifs, guides). Avant : agence 2 500 €/mois pour 8 articles, qualité moyenne. Objectif : 30 articles/mois pour < 1 500 €/mois.

Stack — Team Agno (researcher SerpAPI, writer GPT-4.1, SEO-critic avec brief AhrefsTools, editor humain). Workflow : input keyword → outline → draft → optimize → human approval → publish WordPress.

Pourquoi Agno — Mode coordinate propre pour ce flow, Knowledge base = brand guidelines + articles précédents (cohérence ton), Storage Postgres = audit ce qui a été publié.

Mission — 18 j @ 1 200 € = 21 600 € + mensuel 800 €/mois pour ops.

3. ChatBI sur dashboards e-commerce (DNVB beauté Marseille)

Contexte — Marque cosmétique D2C, 8 M€ CA, stack Shopify + Klaviyo + Meta Ads + GA4. Direction veut poser des questions en langage naturel ("CA cette semaine vs S-1 par catégorie", "quel produit a le meilleur retention 90 j", "ROAS Meta sur audience X vs Y").

Pourquoi Agno — Tools SQL natifs (SQLTools), knowledge base = schéma BigQuery + glossaire métier, agent reasoning (CoT explicit) pour transparence des calculs, AgentOS pour exposer un endpoint Slack bot.

Mission — Forfait 28 k€ + 600 €/mois maintenance.


🛠️ Exemple end-to-end — Équipe "Finance Research" Agno + FastAPI

Pipeline ~190 lignes. Team de 3 agents : data_analyst (yfinance + EDGAR), narrative_writer (thèse), fact_checker (critic). Deploy via AgentOS (FastAPI auto-généré).

python
# file: finance_research/app.py
# pip install agno[all] openai yfinance edgar httpx fastapi uvicorn pgvector psycopg2-binary
from __future__ import annotations
from datetime import date
from typing import Literal

from agno.agent import Agent
from agno.team import Team
from agno.models.openai import OpenAIChat
from agno.models.anthropic import Claude
from agno.tools.yfinance import YFinanceTools
from agno.tools.duckduckgo import DuckDuckGoTools
from agno.tools.python import PythonTools
from agno.knowledge.url import UrlKnowledge
from agno.vectordb.pgvector import PgVector, SearchType
from agno.memory.v2.db.postgres import PostgresMemoryDb
from agno.memory.v2.memory import Memory
from agno.storage.postgres import PostgresStorage
from agno.os import AgentOS
from pydantic import BaseModel, Field

DB_URL = "postgresql+psycopg://ai:ai@localhost:5532/ai"

# ---------- Knowledge base ----------
# SEC EDGAR + AMF + Bloomberg primers — chargé une fois, réutilisé
knowledge = UrlKnowledge(
    urls=[
        "https://www.sec.gov/cgi-bin/browse-edgar?action=getcompany&CIK=LVMUY",
        "https://www.amf-france.org/fr/listes/societes",
    ],
    vector_db=PgVector(
        table_name="finance_kb",
        db_url=DB_URL,
        search_type=SearchType.hybrid,
        embedder=None,  # default OpenAI small
    ),
)

# ---------- Output schema ----------
class InvestmentThesis(BaseModel):
    ticker: str
    company: str
    sector: str
    recommendation: Literal["BUY", "HOLD", "SELL"]
    target_price_eur: float = Field(gt=0)
    horizon_months: int = Field(ge=1, le=36)
    summary: str = Field(max_length=400)
    bull_case: list[str] = Field(min_length=2, max_length=5)
    bear_case: list[str] = Field(min_length=2, max_length=5)
    key_metrics: dict[str, float]
    sources: list[str] = Field(min_length=3)

# ---------- Agents ----------
data_analyst = Agent(
    name="Data Analyst",
    role="Pull quantitative data: financials, ratios, peer comps.",
    model=OpenAIChat(id="gpt-4.1"),
    tools=[
        YFinanceTools(
            stock_price=True,
            analyst_recommendations=True,
            stock_fundamentals=True,
            company_news=True,
            historical_prices=True,
        ),
        PythonTools(run_code=True, save_and_run=True),  # calculs maison
    ],
    instructions=[
        "Always fetch latest fundamentals and 5y price history.",
        "Compute PE, PEG, EV/EBITDA, FCF yield. Show formulas.",
        "Compare with 3 sector peers.",
    ],
    storage=PostgresStorage(table_name="data_analyst_sessions", db_url=DB_URL),
    reasoning=True,  # active chain-of-thought tool
    show_tool_calls=False,
    markdown=True,
)

narrative_writer = Agent(
    name="Narrative Writer",
    role="Synthesize quant + qual into an investment thesis.",
    model=Claude(id="claude-sonnet-4-6"),
    tools=[DuckDuckGoTools()],
    knowledge=knowledge,
    instructions=[
        "Write in French, professional tone, no marketing fluff.",
        "Bull/Bear case: 3 bullets each, evidence-based.",
        "Cite each fact with [source: URL].",
    ],
    response_model=InvestmentThesis,  # Pydantic enforced
    structured_outputs=True,
    storage=PostgresStorage(table_name="writer_sessions", db_url=DB_URL),
    markdown=True,
)

fact_checker = Agent(
    name="Fact Checker",
    role="Verify every quantitative claim and source.",
    model=Claude(id="claude-opus-4-8"),  # plus cher mais critic ≥ writer (flagship 5/25 $/Mtok)
    tools=[DuckDuckGoTools(), YFinanceTools(stock_price=True, stock_fundamentals=True)],
    instructions=[
        "For each claim with number, re-check via tools.",
        "Reply ONLY with: 'APPROVED' or 'REJECTED: <reason1>; <reason2>; ...'",
        "Reject if any source URL returns 404 or paywall.",
    ],
    storage=PostgresStorage(table_name="critic_sessions", db_url=DB_URL),
)

# ---------- Memory shared across team ----------
shared_memory = Memory(
    db=PostgresMemoryDb(table_name="team_memory", db_url=DB_URL),
    model=OpenAIChat(id="gpt-4.1-mini"),
)

# ---------- Team ----------
finance_team = Team(
    name="Finance Research Team",
    members=[data_analyst, narrative_writer, fact_checker],
    mode="coordinate",  # orchestrator dispatches
    model=Claude(id="claude-sonnet-4-6"),
    description="Senior buy-side research team producing investment theses.",
    instructions=[
        "Workflow: data_analyst pulls data → narrative_writer drafts thesis → fact_checker validates.",
        "If fact_checker returns REJECTED, send back to narrative_writer with the issues.",
        "Max 2 revision loops.",
        "Final output: validated InvestmentThesis JSON + 1-paragraph executive summary.",
    ],
    success_criteria="Fact-checker returns APPROVED and thesis matches schema.",
    storage=PostgresStorage(table_name="team_sessions", db_url=DB_URL),
    memory=shared_memory,
    enable_agentic_context=True,
    share_member_interactions=True,
    show_members_responses=False,
    markdown=True,
)

# ---------- AgentOS (FastAPI) ----------
agent_os = AgentOS(
    description="Finance Research API",
    agents=[data_analyst, narrative_writer, fact_checker],
    teams=[finance_team],
)
app = agent_os.get_app()

if __name__ == "__main__":
    # 1. Load knowledge (one-shot)
    # knowledge.load(recreate=False)
    # 2. Serve
    agent_os.serve(app="app:app", reload=True, port=8000)

Appel

bash
# Local
python app.py
# → Playground UI: http://localhost:8000
# → REST API:    POST http://localhost:8000/v1/teams/finance-research-team/runs
#                body: { "message": "Thèse sur AIR.PA horizon 12 mois" }

Réponse type (JSON)

json
{
  "ticker": "AIR.PA",
  "company": "Airbus SE",
  "sector": "Aerospace & Defense",
  "recommendation": "BUY",
  "target_price_eur": 195.0,
  "horizon_months": 12,
  "summary": "Cycle commercial record (backlog ≈ 8000 avions), discipline cash, ...",
  "bull_case": [
    "Backlog 8000+ avions = ~10 ans de production [source: https://...]",
    "Marge EBIT Commercial Aircraft passe de 9% → 12% guidance 2026 [source: ...]",
    "..."
  ],
  "bear_case": ["...", "..."],
  "key_metrics": { "pe_forward": 22.4, "ev_ebitda": 14.1, "fcf_yield": 0.045 },
  "sources": ["https://www.airbus.com/en/investors", "https://www.sec.gov/...", "..."]
}

Ce que ce pipeline montre :

  • 3 agents avec modèles hétérogènes (GPT-4.1 pour data, Claude Sonnet 4.6 pour writing, Claude Opus 4.8 pour critic)
  • response_model=Pydantic force le format thèse
  • Memory partagée au niveau team → les agents voient les interactions des autres
  • AgentOS = FastAPI auto-généré + Playground = 0 boilerplate
  • reasoning=True sur l'analyst → traces CoT loggées (audit-friendly AMF)

🎯 Patterns courants

1. Team modes — quand utiliser quoi

ModeComportementCas d'usage
routeLeader décide quel agent unique appeler (1 fois)Triage support, dispatcher
coordinateLeader orchestre, peut appeler plusieurs agents séquentielResearch, content pipeline
collaborateTous les agents voient le contexte, parlent à tour de rôleBrainstorm, debate, peer review

2. Knowledge base hybride (vector + keyword)

python
PgVector(
    table_name="kb",
    db_url=DB_URL,
    search_type=SearchType.hybrid,   # BM25 + dense vector
    distance=Distance.cosine,
    embedder=OpenAIEmbedder(id="text-embedding-3-small"),
)

3. Memory v2 (faits structurés extraits)

python
agent = Agent(
    ...,
    memory=Memory(db=PostgresMemoryDb(...), model=OpenAIChat(id="gpt-4.1-mini")),
    enable_user_memories=True,   # extrait des facts depuis chaque conv
    enable_session_summaries=True,
)
# Après quelques convs:
agent.memory.get_user_memories(user_id="achref")
# → ["Achref est freelance AI engineer", "préfère TJM 1200-1500", ...]

4. Async + batch (perf Agno briller)

python
import asyncio
results = await asyncio.gather(*[
    analyst.arun(f"Thèse {ticker}") for ticker in tickers
])

Sur 50 tickers, Agno tient avec ~50 Mo RAM total (vs 2-3 Go LangGraph dans le même use case selon leurs benchmarks).

5. Reasoning tools (chain-of-thought explicit)

python
agent = Agent(..., reasoning=True, reasoning_model=OpenAIChat(id="o3-mini"))
# L'agent appelle un "tool" interne think() qui log chaque étape — auditable

6. Monitoring (agno.com ou self-hosted)

python
agent = Agent(..., monitoring=True)  # → traces uploadées sur app.agno.com
# Ou self-host AgentOS dashboard intégré

7. Model routing hétérogène — la vraie décision senior

Agno est model-agnostique : chaque Agent peut tourner sur un provider différent. C'est le levier coût/qualité d'un système multi-agent. Le raisonnement staff : on n'achète pas le flagship partout, on le réserve aux rôles où une erreur coûte cher (critic, fact-check, code review) et on pousse le volume vers le cheap tier.

Rôle dans la teamTier recommandéModèle exemplePourquoi
Data puller / tool-callercheap, rapideclaude-haiku-4-5 (1/5 $/Mtok)beaucoup d'appels, peu de raisonnement
Writer / synthétiseurmidclaude-sonnet-4-6 (3/15 $/Mtok)qualité de prose, coût maîtrisé
Critic / fact-checkerflagshipclaude-opus-4-8 (5/25 $/Mtok à 1M ctx)une erreur non rattrapée = faute réglementaire
Memory summarizercheapclaude-haiku-4-5 ou gpt-4.1-minitâche mécanique, volume élevé
python
from agno.models.anthropic import Claude

data_analyst   = Agent(model=Claude(id="claude-haiku-4-5"),  ...)   # cheap, haut volume tool calls
narrative_writer = Agent(model=Claude(id="claude-sonnet-4-6"), ...)  # mid, qualité prose
fact_checker   = Agent(model=Claude(id="claude-opus-4-8"),   ...)   # flagship, critic ≥ writer

Règle d'or : le critic doit être ≥ au writer en capacité. Un critic moins fort que le writer ne détecte pas les erreurs subtiles — il valide du faux. C'est l'erreur d'archi #1 sur les pipelines "writer + reviewer".

Côté Anthropic 4.8 : pas de budget_tokens (supprimé, renvoie HTTP 400) — le contrôle du raisonnement se fait via thinking adaptatif (thinking type=adaptive) + output_config.effort (low/medium/high). Si Agno expose un thinking= ou un knob d'effort sur le Claude(...) model, mappe-le là-dessus ; ne bricole jamais un budget de tokens de thinking en dur.


🔄 Versions & écosystème 2026

PackageVersion mai 2026Note
agno2.xRefactor v2 (memory v2, knowledge v2, AgentOS)
Python≥ 3.103.12 recommandé
StockagesPostgres / SQLite / Redis / Mongo / DynamoDBtous officiels
Vector DBspgvector, Qdrant, Chroma, LanceDB, Weaviate, Milvus, Pinecone, Cassandra, ClickHouse, MongoDB Atlas15+
ModèlesOpenAI, Anthropic, Google, Mistral, Cohere, Groq, Together, Ollama, vLLM, Bedrock, Azure, Vertex, Cerebras, DeepSeek, xAI30+
Tools80+ packs intégrés (Slack, Linear, Notion, Jira, Stripe, Hubspot, SQL, Browser, …)

Tendances 2026 :

  • AgentOS est devenu le différenciateur — déploiement 1-commande, dashboards inclus.
  • Memory v2 rivalise sérieusement avec MemGPT / Letta sur la qualité.
  • Agno + DSPy combo qui monte : DSPy optimise les prompts Agno → +15-25 % qualité.
  • Communauté ≈ 30k stars GitHub, gros push marketing depuis l'IPO du parent (Phidata Inc.).
  • Compatible OpenTelemetry → traces vers Langfuse / Braintrust / Arize.

⚠️ Pitfalls

  1. response_model= + structured_outputs=True requiert un modèle qui supporte JSON mode/tools strict — GPT-4.1, Claude Opus 4.8 / Sonnet 4.6 / Haiku 4.5, Mistral Large 3. Côté Anthropic, Agno mappe ça sur le native output_config.format (structured outputs) — pas de prompt XML/JSON bricolé. Sur les modèles qui ne supportent pas le strict mode : utilise parser_model= pour parser en deuxième passe (un Haiku 4.5 à 1/5 $/Mtok fait un excellent parser bon marché).
  2. Knowledge load(recreate=True) recharge tout — sur de gros corpus, coûte cher en embeddings. Utilise recreate=False + diff manuel ou upsert=True.
  3. Mode collaborate peut diverger — 3 agents qui se parlent en boucle → loop. Toujours mettre max_loops ou success_criteria clair.
  4. Postgres storage non-versionné — si tu modifies le schéma Agent, les sessions stockées peuvent casser au reload. Sépare le storage par env (dev/staging/prod) et migrate proprement.
  5. reasoning=True × 3-5 LLM calls supplémentaires par run — sur agents à haut volume, ça double la facture. Active uniquement sur agents critiques (finance, médical, légal).
  6. AgentOS = FastAPI mais pas d'auth par défaut — n'expose JAMAIS sur Internet sans middleware auth (JWT, OAuth, API key). Tu peux passer app.add_middleware(...).
  7. Async + tools sync : analyst.arun() mais tool synchrone → bloque l'event loop. Utilise agno.tools.toolkit.Toolkit avec méthodes async def.
  8. Team share_member_interactions=True : explose le context window sur runs longs. Désactive après debug.
  9. Reasoning model différent du model principalreasoning_model=o3-mini mais agent principal sur Claude → 2 providers, 2 quotas, 2 latences. Cohérence à choisir.
  10. enable_user_memories=True stocke des facts depuis chaque conv — vérifie RGPD avant prod. Ajoute un endpoint d'effacement.

💰 Pricing / ROI client

Coût infra Agno (production typique)

ComposantChoix recommandéCoût/mois (1k users actifs)
ComputeFly.io / Railway 2 vCPU 4GB25-40 €
Postgres + pgvectorNeon Pro 8GB35 €
LLM (mix GPT-4.1 + Claude Sonnet 4.6)~500 tokens-équiv/user/jour400-900 €
Embeddings (OpenAI small)0,02 $/1M tokens15-40 €
Monitoring (agno.com Pro)inclus tier paid49 €
TOTAL infra~550-1 100 €/mois

Pricing freelance senior Agno

MissionDuréeTJMTotal
POC team Agno (3 agents + 1 workflow)6-8 j1 200 €8 000 €
Migration LangGraph → Agno + perf benchmark12 j1 400 €16 800 €
Plateforme finance research complète (cf. exemple)35 j1 500 €52 500 €
ChatBI sur stack data PME25 j1 300 €32 500 €
Forfait packagé "Team de rédaction SEO"18-28 k€

Argument commercial vs LangGraph : "Même features, 80 % moins de RAM, instantiation quasi-instantanée, monitoring inclus. On gagne 30-40 % sur le coût infra à charge égale, et on évite la dette LangChain."


🧪 Testing / Eval

Tests unitaires d'agents

python
import pytest
from finance_research.app import data_analyst

def test_data_analyst_fetches_yfinance():
    res = data_analyst.run("Prix actuel AAPL")
    assert any("yfinance" in str(c.tool_name).lower() for c in res.tool_calls)
    assert "$" in res.content or "USD" in res.content

Evals (Agno eval framework)

python
from agno.eval.accuracy import AccuracyEval
from agno.eval.performance import PerformanceEval
from agno.eval.reliability import ReliabilityEval

acc = AccuracyEval(
    agent=narrative_writer,
    input="Thèse Total Energies",
    expected_output="Doit mentionner: transition énergétique, dividend, CapEx",
    iterations=5,
)
res = acc.run(print_results=True)
assert res.avg_score > 0.7

perf = PerformanceEval(func=lambda: data_analyst.run("AAPL"), num_iterations=10)
perf.run(print_results=True)  # → latency p50/p95, memory delta

Reliability (taux de succès tools)

python
rel = ReliabilityEval(
    agent=fact_checker,
    test_cases=[...],  # input + expected tool calls
    iterations=20,
)
rel.run(print_results=True)
# → % runs où l'agent appelle les bons tools dans le bon ordre

Production metrics (via monitoring)

  • Tool call success rate par agent / par tool
  • Avg latency par agent
  • Token cost par run (rapport coût/qualité)
  • Memory recall hit (% queries où la memory apporte du contexte utile)
  • Revision loops moyens en team mode (target < 2)

🔁 Quand utiliser / éviter

✅ Utiliser Agno

  • Python, équipe à l'aise sans framework lourd
  • Besoin agents + teams + RAG + memory sans coller 4 libs ensemble
  • Tu veux shipper rapide (AgentOS = API + UI clé en main)
  • Perf / coût infra critiques (scale 1k+ agents concurrent)
  • Migrer depuis CrewAI / LangGraph sans tout réécrire
  • Domain : finance, recherche, BI, content (sweet spot Agno)

❌ Éviter Agno

  • Stack TypeScript → Mastra
  • Tu veux type-safety extrême Pydantic-first → Pydantic AI
  • Écosystème LangSmith déjà adopté + équipe formée → reste sur LangGraph
  • Notebooks / recherche académique → LlamaIndex / LangChain
  • Tooling propriétaire (LLM custom on-prem sans HTTP) → SDK natif + orchestrator maison
  • Voice agents temps réel → Pipecat / Livekit Agents plus matures que Agno voice

Decision tree Python AI 2026

Python AI app à shipper ?
├─ POC extraction simple                  → Instructor seul
├─ Agents complexes + monitoring          → Agno ★
├─ Type-safety extrême, agents purs       → Pydantic AI
├─ Écosystème LangChain déjà en place     → LangGraph
├─ Rôles "agent persona" friendly POC     → CrewAI (attention prod)
└─ Heavy RAG documents corpus              → LlamaIndex (+ Agno pour les agents)

🏋️ Exercices

Progression : du "fais marcher" au "casse-le puis rends-le production-grade". Code en Python, tout en async là où ça compte.

Exercice 1 — Team coordinate avec output Pydantic strict

Objectif : construire une Team de 3 agents (researcher DuckDuckGo, writer, critic) qui produit un BlogPost Pydantic validé (titre, ≥ 1000 mots, ≥ 3 sources avec URL, score SEO), avec success_criteria qui bloque tant que le schéma n'est pas respecté.

Indice/Solution : mode coordinate, response_model=BlogPost sur le writer + structured_outputs=True. Le critic renvoie APPROVED/REJECTED: <raisons>. Boucle de révision max 2 dans les instructions de la team. Pour la garantie de format côté Anthropic, c'est output_config.format natif sous le capot — pas de prompt JSON manuel.

Exercice 2 — Routing coût/qualité et défends le chiffre

Objectif : prendre le pipeline de l'exercice 1 et router chaque rôle sur le bon tier (haiku-4-5 pour le researcher tool-caller, sonnet-4-6 pour le writer, opus-4-8 pour le critic). Logge resp.usage par agent et calcule le coût €/article. Puis : un VP te dit "passe tout sur opus-4-8 pour la qualité". Chiffre l'impact et défends ta position.

Indice/Solution : avec ~8k tokens in / 2k out par article et le critic à 5/25 $/Mtok vs haiku à 1/5 $/Mtok, montre que le researcher (haut volume tool calls, peu de raisonnement) ne gagne rien à passer flagship — tu paies 5× l'input pour zéro gain de qualité mesurable. La défense senior : "le flagship sur le critic, oui ; sur le tool-caller, c'est brûler du budget sans bouger l'eval". Appuie-toi sur un eval AccuracyEval qui prouve que le score ne bouge pas.

Exercice 3 — Async + 50 tickers sans exploser la RAM ni le rate limit

Objectif : lancer une thèse d'investissement sur 50 tickers en parallèle via asyncio.gather(*[agent.arun(...) for ...]). Mesure la RAM (tracemalloc) et le wall-time. Puis ajoute un Semaphore pour borner la concurrence et gérer les 429.

Indice/Solution : asyncio.gather brut sur 50 LLM calls va se prendre des RateLimitError (429). Borne avec asyncio.Semaphore(8) et un wrapper qui retry avec backoff exponentiel sur 429/529. Côté Anthropic, le SDK retry déjà 429/5xx (typed exceptions RateLimitError/OverloadedError) — vérifie qu'Agno ne court-circuite pas ce retry. Le point que vérifie l'exo : un tool synchrone dans un agent async bloque l'event loop → tes 50 "parallèles" deviennent séquentiels. Profile-le pour le voir.

Exercice 4 — Casse-le : la boucle infinie en mode collaborate

Objectif : monter une team collaborate de 3 agents en debate, sans max_loops ni success_criteria, et observer la divergence (boucle, explosion du context window, facture qui grimpe). Puis répare : ajoute un critère d'arrêt, un cap de tours, et un budget de coût hard.

Indice/Solution : sans garde-fou, les 3 agents se relancent indéfiniment. Le fix en 3 couches : (1) success_criteria clair + cap de tours, (2) un compteur de coût qui somme resp.usage et coupe au-delà d'un seuil €, (3) share_member_interactions=False après debug pour ne pas exploser le context. Le piège production : le coût d'une boucle collaborate non bornée est non déterministe — c'est inacceptable en prod, il faut un kill-switch budgétaire.

Exercice 5 — AgentOS exposé : sécurise l'endpoint avant de shipper

Objectif : prendre l'app AgentOS de l'exemple end-to-end et la rendre safe pour exposition Internet : auth (API key / JWT), rate limiting, et masquage des erreurs internes. Vérifie qu'un appel non authentifié sur /v1/teams/.../runs renvoie 401.

Indice/Solution : AgentOS = FastAPI mais zéro auth par défaut. Ajoute app.add_middleware(...) pour une vérif API key/JWT, un rate limiter (slowapi), et un exception handler qui ne fuite pas les stack traces. Bonus RGPD : si enable_user_memories=True, expose un endpoint d'effacement des memories par user_id (droit à l'oubli). Le réflexe senior : ne jamais exposer un AgentOS brut — c'est un agent qui peut appeler des tools (SQL, browser), donc une surface d'attaque (prompt injection → exfiltration).

Exercice 6 — Migration LangGraph → Agno avec benchmark défendable

Objectif : porter un graphe LangGraph de 4 nœuds (research → draft → review → publish) vers un Workflow Agno natif Python. Benchmark instantiation time + RAM sur 100 runs et produis un tableau comparatif honnête.

Indice/Solution : le workflow Agno est du Python pur (if/while/await) avec session_state — pas de DSL graphe. Le piège du benchmark : Agno annonce ~10 000× sur l'instantiation, pas sur le temps total (les LLM calls dominent). Un benchmark honnête sépare instantiation (où Agno gagne énormément) du wall-time end-to-end (où c'est l'identique, le LLM domine). Défends le chiffre : "Agno gagne sur le cold-start et la RAM à scale, pas sur la latence d'un run unique — donc le gain réel est sur le coût infra à 1k+ agents concurrent, pas sur le P50 d'une requête".


🎤 En entretien

Q : Tu as un pipeline "writer + reviewer". Quel modèle mets-tu sur chacun et pourquoi ? Le reviewer/critic doit être ≥ au writer en capacité (ex. writer sur claude-sonnet-4-6, critic sur claude-opus-4-8) — un critic plus faible valide du faux et ne détecte pas les erreurs subtiles, c'est pire que pas de critic.

Q : Agno annonce 10 000× plus rapide que LangGraph. Tu y crois ? Comment tu le vérifies ? C'est sur l'instantiation des agents, pas sur le wall-time end-to-end (les LLM calls dominent) — donc le gain réel est sur le cold-start et la RAM à scale (1k+ agents concurrent), pas sur le P50 d'une requête ; je le prouve avec un benchmark qui sépare instantiation du temps total.

Q : Comment tu contrôles le coût d'une team multi-agent en production ? Routing hétérogène par tier (cheap sur les tool-callers, flagship sur le critic), resp.usage loggé par agent pour le coût réel, cap de tours + budget hard sur les modes collaborate/coordinate, et prompt caching sur le préfixe system+tools stable pour les agents à fort volume.

Q : Un junior met thinking budget_tokens=8000 sur un agent Claude Opus 4.8. Que se passe-t-il ? HTTP 400 — budget_tokens est supprimé sur 4.7/4.8. Le contrôle du raisonnement passe par le thinking adaptatif (thinking type=adaptive) plus output_config.effort (low/medium/high) ; le budget de tokens fixe n'existe plus.

Q : AgentOS te donne une API FastAPI en 1 commande. Quel est le premier truc que tu fais avant de l'exposer ? Auth — AgentOS n'a aucune auth par défaut, et c'est un agent qui peut appeler des tools (SQL, browser, code), donc une surface d'attaque par prompt injection. Middleware JWT/API-key, rate limiting, masquage des stack traces, et endpoint d'effacement RGPD si les user memories sont activées.


🔗 Liens

Bibliothèque tech perso — Achref