Construire un seul agent d'IA est facile. Construire un système d'agents qui planifient, délèguent, mémorisent et tournent de façon fiable en production, c'est là que la plupart des projets calent. Le framework Agno — autrefois connu sous le nom de Phidata — a été conçu précisément pour combler ce vide. Les agents s'instancient en quelques microsecondes, consomment une fraction de la mémoire des frameworks plus lourds et arrivent tout équipés : mémoire, bases de connaissances, sorties structurées et un runtime de production appelé AgentOS qui encapsule le tout derrière un serveur FastAPI.
Dans ce tutoriel, vous construirez un assistant de recherche qui grandit d'un seul agent vers une équipe coordonnée, puis vers un workflow multi-étapes, et enfin vers une API déployable. À la fin, vous comprendrez les quatre primitives fondamentales d'Agno — l'Agent, l'Équipe (Team), le Workflow et AgentOS — et comment elles se composent.
Prérequis
Avant de commencer, assurez-vous d'avoir :
- Python 3.10+ installé (
python --version) - Une familiarité de base avec Python et
async/await - Une clé d'API OpenAI (ou Anthropic — Agno est agnostique vis-à-vis des modèles)
- Un terminal et un éditeur de code (VS Code recommandé)
Vous devriez être à l'aise avec les environnements virtuels et la lecture des modèles Pydantic. Aucune expérience préalable des frameworks d'agents n'est requise.
Ce que vous allez construire
Un assistant de recherche progressivement plus riche :
- Un seul agent qui cherche sur le web et répond aux questions avec ses sources.
- Une équipe où un chef délègue à des agents spécialistes (recherche web + analyse).
- Un workflow qui exécute la recherche et l'analyse en parallèle, boucle jusqu'à réunir assez de matière, puis rédige un rapport.
- Un déploiement AgentOS exposant tout cela sous forme d'API REST avec des sessions persistantes.
Étape 1 : Mise en place du projet
Créez un dossier de projet et un environnement virtuel :
mkdir agno-research && cd agno-research
python -m venv .venv
source .venv/bin/activate # Sous Windows : .venv\Scripts\activateInstallez Agno avec un fournisseur de modèle et les outils que nous utiliserons :
pip install -U agno openai ddgs lancedb tantivyUne note rapide sur le rôle de chaque paquet :
agno— le framework lui-mêmeopenai— le client du fournisseur de modèleddgs— alimenteWebSearchTools(recherche DuckDuckGo, sans clé d'API)lancedbettantivy— la base de données vectorielle embarquée pour les bases de connaissances (Étape 5)
Exportez votre clé d'API :
export OPENAI_API_KEY="sk-..."Astuce : Agno est réellement agnostique vis-à-vis des modèles. Pour utiliser Claude à la place, exécutez
pip install anthropic, définissezANTHROPIC_API_KEYet remplacezOpenAIChat(id="gpt-4o-mini")parClaude(id="claude-sonnet-4-0"). Tout le reste de ce tutoriel demeure identique.
Étape 2 : Votre premier agent
Un Agent Agno est l'unité atomique : un modèle, un jeu d'instructions et, éventuellement, des outils. Créez agent.py :
from agno.agent import Agent
from agno.models.openai import OpenAIChat
from agno.tools.websearch import WebSearchTools
web_agent = Agent(
name="Web Researcher",
model=OpenAIChat(id="gpt-4o-mini"),
tools=[WebSearchTools()],
instructions=[
"You are a meticulous research assistant.",
"Always search the web before answering factual questions.",
"Cite your sources as a bulleted list at the end.",
],
add_datetime_to_context=True,
markdown=True,
)
web_agent.print_response(
"What were the biggest open-source AI agent frameworks released in 2026?",
stream=True,
)Exécutez-le :
python agent.pyVous verrez l'agent raisonner, appeler l'outil de recherche et diffuser en flux une réponse formatée et sourcée vers votre terminal. Quelques points méritent d'être soulignés :
instructionsest une liste de directives courtes. Agno les assemble dans le prompt système — gardez-les impératives et précises.toolsn'est qu'une liste d'objets outils. Le modèle décide quand les appeler ; vous n'écrivez jamais la logique d'orchestration à la main.add_datetime_to_context=Trueinjecte la date courante, ce qui ancre les requêtes du type « les plus récents ».print_response(..., stream=True)est le moyen le plus rapide de voir la sortie pendant le développement.
Exécuter les agents par programmation
print_response est destinée aux humains. Dans du vrai code, utilisez run() pour récupérer un objet de réponse :
response = web_agent.run("Summarize the Agno framework in two sentences.")
print(response.content) # la réponse textuellePour les services à fort débit, chaque méthode a son jumeau asynchrone — arun() et aprint_response() — afin d'attendre plusieurs agents en parallèle.
Étape 3 : Sortie structurée avec Pydantic
Le texte d'un LLM est difficile à consommer par programmation. Agno peut forcer un agent à renvoyer un objet typé en passant un modèle Pydantic via output_schema. Créez structured.py :
from typing import List
from pydantic import BaseModel, Field
from agno.agent import Agent
from agno.models.openai import OpenAIChat
from agno.tools.websearch import WebSearchTools
class TopicBriefing(BaseModel):
topic: str = Field(..., description="The subject being researched")
summary: str = Field(..., description="A two-sentence overview")
key_points: List[str] = Field(..., description="3-5 essential takeaways")
sources: List[str] = Field(..., description="URLs used for the research")
briefing_agent = Agent(
model=OpenAIChat(id="gpt-4o-mini"),
tools=[WebSearchTools()],
output_schema=TopicBriefing,
)
response = briefing_agent.run("Research the rise of small language models in 2026")
briefing: TopicBriefing = response.content
print(briefing.topic)
for point in briefing.key_points:
print(f"- {point}")
print("Sources:", ", ".join(briefing.sources))Comme response.content est désormais une véritable instance de TopicBriefing, vous obtenez l'autocomplétion, la validation et zéro analyse de chaîne fragile. Cette seule fonctionnalité rend les agents Agno sûrs à intégrer au sein d'applications plus vastes.
Étape 4 : Coordonner une équipe
Un seul agent est limité. Une Équipe (Team) permet à un modèle chef de déléguer à des membres spécialistes, chacun avec son rôle et ses outils. Le chef décide qui traite quoi et synthétise la réponse finale.
Créez team.py :
from agno.agent import Agent
from agno.models.openai import OpenAIChat
from agno.team import Team
from agno.tools.websearch import WebSearchTools
from agno.tools.hackernews import HackerNewsTools
web_agent = Agent(
name="Web Agent",
role="Search the broad web for background and context",
model=OpenAIChat(id="gpt-4o-mini"),
tools=[WebSearchTools()],
instructions="Always include sources.",
)
tech_pulse_agent = Agent(
name="Tech Pulse Agent",
role="Gauge developer sentiment from Hacker News discussions",
model=OpenAIChat(id="gpt-4o-mini"),
tools=[HackerNewsTools()],
instructions="Summarize what practitioners actually think, not just headlines.",
)
research_team = Team(
name="Research Team",
model=OpenAIChat(id="gpt-4o"),
members=[web_agent, tech_pulse_agent],
instructions=[
"You coordinate a research team.",
"Delegate broad context to the Web Agent.",
"Delegate community sentiment to the Tech Pulse Agent.",
"Combine both into a balanced briefing with a clear verdict.",
],
show_members_responses=True,
markdown=True,
)
research_team.print_response(
"Should a startup adopt Agno for its agent stack in 2026?",
stream=True,
)Idées clés :
- Chaque membre possède un
role— une description d'une ligne que le chef utilise pour router le travail. Rédigez les rôles comme des fiches de poste, pas comme des instructions. - Le chef (
research_team) reçoit généralement un modèle plus puissant que les membres, car la coordination et la synthèse sont plus difficiles que les recherches individuelles. show_members_responses=Truefait remonter la contribution de chaque membre, ce qui est inestimable pour déboguer la délégation.
Exécutez-le et observez le chef se répartir vers les deux spécialistes, puis fusionner leurs résultats en un verdict unique. Vous n'avez écrit aucun code de routage — le chef d'équipe gère la délégation via des appels d'outils en coulisses.
Étape 5 : Ajouter mémoire et connaissances
Les vrais assistants se souviennent des conversations passées et peuvent ancrer leurs réponses dans vos propres documents. Agno gère les deux via une base de données (pour la mémoire et les sessions) et une base de Connaissances (Knowledge) (pour la récupération).
Créez memory_knowledge.py :
from agno.agent import Agent
from agno.models.openai import OpenAIChat
from agno.db.sqlite import SqliteDb
from agno.knowledge.knowledge import Knowledge
from agno.knowledge.embedder.openai import OpenAIEmbedder
from agno.vectordb.lancedb import LanceDb, SearchType
# Stockage persistant pour les sessions et la mémoire utilisateur de long terme
db = SqliteDb(db_file="tmp/research.db")
# Une base de connaissances adossée à un magasin vectoriel LanceDB embarqué
knowledge = Knowledge(
vector_db=LanceDb(
uri="tmp/lancedb",
table_name="research_docs",
search_type=SearchType.hybrid,
embedder=OpenAIEmbedder(id="text-embedding-3-small"),
),
)
# Ingérez un document une seule fois ; il est découpé, vectorisé et indexé automatiquement
knowledge.insert(url="https://www.paulgraham.com/read.html")
assistant = Agent(
name="Grounded Assistant",
model=OpenAIChat(id="gpt-4o-mini"),
db=db,
knowledge=knowledge,
search_knowledge=True, # autorise l'agent à récupérer depuis la base de connaissances
add_history_to_context=True, # inclut les tours récents dans le prompt
num_history_runs=3, # combien d'échanges passés inclure
update_memory_on_run=True, # apprend des faits durables sur l'utilisateur
markdown=True,
)
# Passez un user_id et un session_id stables pour relier la mémoire entre les exécutions
assistant.print_response(
"According to the essay I added, why does reading matter?",
user_id="anis@example.com",
session_id="session-1",
)Ce que fait chaque élément :
SqliteDbpersiste les sessions et les mémoires dans un fichier local. En production, vous le remplaceriez parPostgresDb— le code de l'agent ne change pas.Knowledge+LanceDbvous offre une recherche hybride (vectorielle + mots-clés) sur le contenu ingéré.search_knowledge=Trueindique à l'agent qu'il peut y récupérer des informations.add_history_to_contextetnum_history_runscontrôlent la mémoire conversationnelle au sein d'une session.update_memory_on_runpermet à l'agent d'extraire des faits durables (« l'utilisateur préfère des réponses concises ») et de les rappeler dans de futures sessions liées au mêmeuser_id.
C'est le moment où une démo devient un assistant : il se souvient de son interlocuteur et peut citer vos documents.
Étape 6 : Orchestrer un workflow
Les équipes sont parfaites quand vous voulez que le modèle décide qui fait quoi. Mais parfois, il vous faut un flux de contrôle déterministe — exécuter ces étapes en parallèle, boucler jusqu'à atteindre un seuil de qualité, brancher selon une condition. C'est à cela que sert un Workflow.
Créez workflow.py :
from typing import List
from agno.agent import Agent
from agno.models.openai import OpenAIChat
from agno.tools.websearch import WebSearchTools
from agno.tools.hackernews import HackerNewsTools
from agno.workflow import Loop, Parallel, Step, Workflow
from agno.workflow.types import StepOutput
# --- Agents ---
web_researcher = Agent(
name="Web Researcher",
model=OpenAIChat(id="gpt-4o-mini"),
tools=[WebSearchTools()],
instructions="Research the topic thoroughly from web sources.",
)
hn_researcher = Agent(
name="HN Researcher",
model=OpenAIChat(id="gpt-4o-mini"),
tools=[HackerNewsTools()],
instructions="Surface what developers are saying about the topic.",
)
writer = Agent(
name="Report Writer",
model=OpenAIChat(id="gpt-4o"),
instructions="Write a concise, well-structured report from the research provided.",
markdown=True,
)
# --- Étapes ---
research_web = Step(name="Research Web", agent=web_researcher)
research_hn = Step(name="Research HN", agent=hn_researcher)
write_report = Step(name="Write Report", agent=writer)
# --- Condition de sortie de boucle : continuer jusqu'à réunir assez de matière ---
def enough_research(outputs: List[StepOutput]) -> bool:
total = sum(len(o.content or "") for o in outputs)
return total > 1500
# --- Workflow : recherche parallèle dans une boucle, puis rédaction ---
workflow = Workflow(
name="Deep Research Workflow",
description="Research a topic in parallel until sufficient, then write a report",
steps=[
Loop(
name="Research Loop",
steps=[Parallel(research_web, research_hn, name="Parallel Research")],
end_condition=enough_research,
max_iterations=3,
),
write_report,
],
)
if __name__ == "__main__":
workflow.print_response(
input="The state of TypeScript-first AI agent frameworks in 2026",
stream=True,
)Les briques de base qu'Agno vous fournit pour les workflows :
| Primitive | Rôle |
|---|---|
Step | Exécuter un agent (ou une fonction) comme une unité |
Parallel | Exécuter plusieurs étapes simultanément |
Loop | Répéter des étapes jusqu'à ce que end_condition soit vrai ou que max_iterations soit atteint |
Router | Choisir une branche dynamiquement via une fonction de sélection |
Condition | Exécuter des étapes seulement si une expression est vraie (avec else_steps optionnel) |
Ici, les deux chercheurs s'exécutent en même temps à l'intérieur d'une Loop qui continue jusqu'à ce que la sortie combinée dépasse 1500 caractères (ou que trois itérations passent), après quoi le rédacteur produit le rapport final. Contrairement à une équipe, le flux de contrôle est entièrement déterministe et testable — vous pouvez tester unitairement enough_research() de manière isolée.
Brancher avec Condition
Pour le routage, Agno prend même en charge des conditions basées sur des expressions :
from agno.workflow import Condition, Step, Workflow
workflow = Workflow(
name="Classify and Route",
steps=[
Step(name="Classify", agent=classifier),
Condition(
name="Route by Type",
evaluator='previous_step_content.contains("TECHNICAL")',
steps=[Step(name="Technical Help", agent=technical_agent)],
else_steps=[Step(name="General Help", agent=general_agent)],
),
],
)Le classificateur étiquette la requête, et la Condition l'envoie dans la bonne branche — sans aucun code de liaison au milieu.
Étape 7 : Déployer avec AgentOS
Un script fonctionnel n'est pas un produit. AgentOS encapsule vos agents, équipes et workflows dans une application FastAPI prête à l'emploi — avec stockage des sessions, historique des conversations et points de terminaison de surveillance — que vous exécutez dans votre propre infrastructure.
Créez serve.py :
from agno.agent import Agent
from agno.team import Team
from agno.workflow import Step, Workflow
from agno.models.openai import OpenAIChat
from agno.db.sqlite import SqliteDb
from agno.tools.websearch import WebSearchTools
from agno.os import AgentOS
db = SqliteDb(db_file="tmp/agentos.db")
researcher = Agent(
name="Researcher",
model=OpenAIChat(id="gpt-4o-mini"),
db=db,
tools=[WebSearchTools()],
instructions="Research thoroughly and cite sources.",
add_history_to_context=True,
markdown=True,
)
research_team = Team(
name="Research Team",
model=OpenAIChat(id="gpt-4o"),
db=db,
members=[researcher],
instructions="Coordinate research and deliver a clear briefing.",
)
qa_workflow = Workflow(
name="QA Workflow",
description="Answer a question using the researcher agent",
db=db,
steps=[Step(name="Answer", agent=researcher)],
)
agent_os = AgentOS(
description="Research AgentOS",
agents=[researcher],
teams=[research_team],
workflows=[qa_workflow],
)
# Instance d'application FastAPI — uvicorn recherche `app`
app = agent_os.get_app()
if __name__ == "__main__":
agent_os.serve(app="serve:app", reload=True)Démarrez le serveur :
python serve.pyAgentOS démarre un serveur FastAPI (par défaut http://localhost:7777) avec des points de terminaison REST générés automatiquement pour chaque agent, équipe et workflow enregistré, ainsi qu'une documentation interactive sur /docs. Comme chaque composant partage la même db, les sessions et la mémoire sont persistées automatiquement — vos agents se souviennent des conversations d'une requête HTTP à l'autre.
Le runtime est sans état et horizontalement scalable : exécutez plusieurs instances derrière un répartiteur de charge et pointez-les vers une base de données Postgres partagée. C'est la « pièce manquante » autour de laquelle Agno est conçu — le pont entre un prototype fonctionnel et un produit déployé.
Tester votre implémentation
Vérifiez chaque couche dans l'ordre :
- Agent —
python agent.pydiffuse une réponse sourcée. - Sortie structurée —
python structured.pyaffiche des champs typés sans erreur. - Équipe —
python team.pymontre la contribution des deux membres, puis un verdict fusionné. - Mémoire — exécutez
memory_knowledge.pydeux fois avec le mêmeuser_id; la seconde exécution devrait rappeler le contexte. - Workflow —
python workflow.pyexécute une recherche parallèle dans une boucle avant la rédaction. - AgentOS — ouvrez
http://localhost:7777/docset appelez un point de terminaison ; confirmez la réponse et l'apparition d'une ligne de session danstmp/agentos.db.
Dépannage
ModuleNotFoundError: No module named 'ddgs' — WebSearchTools a besoin du moteur de recherche. Exécutez pip install ddgs.
Appels d'outils vides ou refusés — votre modèle est peut-être trop petit pour raisonner sur les outils de façon fiable. Faites passer le chef/orchestrateur à un modèle plus puissant (gpt-4o, claude-sonnet-4-0) et réservez le modèle bon marché aux rôles de membres simples.
La base de connaissances ne renvoie rien — vérifiez que search_knowledge=True est défini sur l'agent et que knowledge.insert(...) s'est exécuté avec succès avant la requête. La recherche hybride nécessite aussi l'installation de tantivy.
La mémoire ne persiste pas — assurez-vous de passer un user_id et un session_id stables, que l'agent possède une db, et que update_memory_on_run=True et/ou add_history_to_context=True sont définis.
AgentOS ne démarre pas avec serve() — la chaîne app= doit être "<module>:app" correspondant au nom de votre fichier. Dans serve.py, c'est "serve:app".
Prochaines étapes
- Remplacez
SqliteDbparPostgresDbet déployez AgentOS derrière un répartiteur de charge. - Ajoutez des étapes
Routerpour choisir dynamiquement les stratégies de recherche selon le sujet. - Connectez des outils externes via MCP grâce à la classe
MCPToolsd'Agno. - Ajoutez de l'évaluation avec
ReliabilityEvald'Agno pour détecter les régressions dans le comportement des agents. - Explorez des tutoriels connexes sur notre site : systèmes multi-agents CrewAI, agents type-safe Pydantic AI et agents orientés code smolagents.
Conclusion
Vous avez fait passer un assistant de recherche d'un simple agent utilisant un outil jusqu'à une API horizontalement scalable. En chemin, vous avez rencontré les quatre primitives d'Agno qui se composent pour former presque n'importe quel système agentique : l'Agent pour la capacité individuelle, l'Équipe pour la délégation pilotée par le modèle, le Workflow pour l'orchestration déterministe, et AgentOS pour le déploiement en production. Les forces qui définissent Agno — instanciation en microsecondes, faible empreinte mémoire et runtime tout équipé — signifient que le système prototypé cet après-midi est exactement celui que vous livrerez. Commencez petit avec un seul agent, et ne recourez aux équipes et aux workflows que lorsque le problème l'exige réellement.