DEV-AI
smolagents v1.24.0 Publié le 4 mai 2026 Comparatif 3 frameworks

Agents IA Python : quel framework choisir en 2026 ?
smolagents vs Pydantic AI vs LangGraph

Trois façons radicalement différentes de construire des agents IA en Python. Aucune n'est universellement meilleure — mais choisir la mauvaise coûte cher en maintenance. Guide technique complet avec code Python et Ollama.

Hugging Face · MIT License · Python ≥ 3.10 · ~1 000 lignes de code core

TL;DR — 3 paradigmes

  • smolagents (code-first) — le LLM génère du code Python exécuté step by step. Variables persistantes entre étapes. ~1 000 lignes de core. Jusqu'à 30% moins d'étapes selon les benchmarks Hugging Face.
  • Pydantic AI (type-safe) — DI explicite, type checking statique mypy/pyright, TestModel déterministe. Idéal pour les APIs de production.
  • LangGraph (stateful) — graphe de nœuds, état persistant, cycles, human-in-the-loop natif. Pour les workflows orchestrés complexes.
  • Ollama : smolagents utilise LiteLLMModel (pas de classe OllamaModel native).
  • Les trois sont complémentaires — une archi hybride smolagents + LangGraph est courante en 2026.

1. Les 3 paradigmes des agents IA Python

Avant de choisir un framework, il faut comprendre que les trois approches dominant le paysage Python en 2026 ne font pas la même chose — elles répondent à des questions différentes.

smolagents — Code-first (Hugging Face)

Le LLM génère du code Python exécutable à chaque étape. Les variables persistent entre les steps. Minimaliste (~1 000 lignes), auditables, intégration native Hugging Face Hub. Question centrale : comment automatiser des tâches complexes avec le minimum de glue code ?

Pydantic AI — Type-safe (Samuel Colvin)

Injection de dépendances typée, validation compile-time mypy/pyright, TestModel déterministe, structured outputs en 3 modes. Question centrale : comment rendre les agents aussi maintenables que le reste du code Python de production ?

LangGraph — Stateful (LangChain Inc.)

Graphe de nœuds avec état partagé, cycles, checkpointing, human-in-the-loop natif, streaming. Question centrale : comment orchestrer des workflows IA complexes avec persistance d'état et contrôle précis du flux d'exécution ?

Le vrai problème des agents IA en Python

Beaucoup de développeurs choisissent leur framework d'agents comme une librairie classique — popularité GitHub, exemples rapides, promesses marketing. Mauvais réflexe. Un agent code-first, un agent type-safe et un graphe stateful ne répondent pas au même besoin. Le mauvais choix peut transformer un prototype impressionnant en système impossible à maintenir après trois semaines.

Ces trois paradigmes répondent à des niveaux d'abstraction différents, pas à des besoins identiques formulés différemment. C'est pourquoi les combiner est non seulement possible mais souvent optimal.

2. smolagents — architecture et philosophie

Si vous souhaitez d'abord approfondir l'une des deux autres approches : guide Pydantic AI Python 2026 (type-safe) et guide LangGraph 2026 (stateful). Pour les modèles locaux : démarrer avec Ollama.

smolagents a été lancé le 31 décembre 2024 par Hugging Face comme successeur de transformers.agents. Il est actuellement en version 1.24.0 (16 janvier 2026). Son argument fondateur tient en un principe : le code est un meilleur format d'action que le JSON.

Cette thèse est étayée par trois papiers de recherche :

L'argument central : le code Python est composable (boucles, conditions, fonctions imbriquées), gère naturellement les objets intermédiaires (stocker le résultat d'une image dans une variable, passer un DataFrame d'un tool au suivant), et est sur-représenté dans les données d'entraînement des LLMs — ils y excellent.

La conséquence architecturale : le core de smolagents tient en ~1 000 lignes de code (src/smolagents/agents.py). Pas de surcharge d'abstraction, auditabilité complète, fork possible en une journée.

Résultat GAIA benchmark

L'architecture multi-agents Hugging Face basée sur smolagents a atteint 44,2% sur GAIA validation (Human Avg : ~92%, GPT-4 Turbo seul : ~7%). Ce résultat a été obtenu avec l'ancienne architecture transformers.agents migrée vers smolagents — les scores sont indicatifs d'une capacité réelle, pas d'une comparaison directe entre frameworks.

3. Installation

smolagents est organisé en extras PyPI selon les backends utilisés :

bash
# Base (CodeAgent + ToolCallingAgent + outils natifs)
pip install smolagents

# + LiteLLM (Ollama, Anthropic, OpenAI, 100+ providers)
pip install 'smolagents[litellm]'

# + DuckDuckGoSearch + Whisper transcriber (outils courants)
pip install 'smolagents[toolkit]'

# + Interface Gradio
pip install 'smolagents[gradio]'

# + Sandbox E2B cloud (exécution sécurisée)
pip install 'smolagents[e2b]'

# + Inférence locale via Transformers
pip install 'smolagents[transformers]'

# Tout en une commande (dev)
pip install 'smolagents[litellm,toolkit,gradio]'

4. CodeAgent — agents code-first

CodeAgent est le cœur de smolagents. À chaque step, le LLM génère un bloc de code Python entre balises — ce code est exécuté, son output est observé, et le LLM décide du step suivant. Le cycle s'arrête quand le LLM appelle final_answer() — une fonction Python standard injectée automatiquement dans l'environnement.

python
from smolagents import CodeAgent, InferenceClientModel, DuckDuckGoSearchTool

# Modèle via Hugging Face Inference API (Qwen3-Next par défaut)
model = InferenceClientModel()

# Agent avec outils natifs (web search + calcul + code Python)
agent = CodeAgent(
    tools=[DuckDuckGoSearchTool()],
    model=model,
    add_base_tools=True,  # Ajoute PythonInterpreterTool, FinalAnswerTool
    max_steps=10,
)

result = agent.run("Quelle est la racine carrée de la population de Paris en 2025 ?")
print(result)

Ce que le LLM génère à chaque step

python — output LLM interne
# Step 1 : Le LLM génère ce code
results = web_search("population Paris 2025")
print(results)

# Observation : "Paris compte environ 2,1 millions d'habitants en 2025"

# Step 2 : Le LLM génère ce code (réutilise les variables du step 1)
import math
population = 2_100_000
racine = math.sqrt(population)
final_answer(f"La racine carrée de {population:,} est {racine:.1f}")

État stateful entre les steps

Les variables Python définies au step N sont disponibles au step N+1. C'est ce qui permet à un CodeAgent d'enchaîner des opérations complexes — charger un DataFrame, le filtrer, faire un calcul, générer un graphique — sans perdre les objets intermédiaires entre chaque appel LLM.

Paramètres clés du CodeAgent

python
agent = CodeAgent(
    tools=[...],
    model=model,
    additional_authorized_imports=["pandas", "matplotlib", "numpy"],
    # ^ Imports autorisés en plus de la liste blanche par défaut
    use_structured_outputs_internally=True,
    # ^ LLM génère {"thoughts": "...", "code": "..."} → 2-7 pts de gain
    planning_interval=3,
    # ^ Replanning tous les 3 steps : le LLM met à jour sa stratégie
    max_steps=15,
    executor_type="local",  # ou "e2b", "docker", "modal", "wasm"
    stream_outputs=True,    # Affiche les prints en temps réel
)

5. ToolCallingAgent — agents JSON

ToolCallingAgent utilise le format standard OpenAI function-calling : le LLM génère un JSON structuré indiquant quel outil appeler et avec quels arguments. Aucun code Python n'est exécuté — c'est le framework qui dispatch l'appel.

python
from smolagents import ToolCallingAgent, InferenceClientModel

agent = ToolCallingAgent(
    tools=[search_tool, calculator_tool],
    model=model,
    max_tool_threads=4,  # Appels parallèles via ThreadPoolExecutor
)

result = agent.run("Compare les prix de l'or et de l'argent aujourd'hui")
# → Les deux recherches sont lancées en parallèle

CodeAgent vs ToolCallingAgent — quand choisir quoi

CritèreCodeAgentToolCallingAgent
Format d'actionCode Python exécutableJSON structuré (function calling)
ComposabilitéMaximale (boucles, conditions, objets)Nulle — chaque appel est atomique
Objets intermédiairesVariables Python persistantesImpossible nativement
Appels parallèlesNonOui via max_tool_threads
Exécution de codeRequis (executor)Aucune exécution
Nombre d'étapes (benchmark)Jusqu'à 30% moins (benchmarks HF)Baseline
Risque sécuritéExécution arbitraire possiblePas d'exécution de code
Idéal pourAnalyse de données, automation, scienceChatbots, RAG, APIs structurées

6. Définir des outils

Un outil smolagents est une fonction Python décorée — le framework génère automatiquement le schéma JSON depuis les type hints et la docstring.

python
from smolagents import tool

@tool
def get_stock_price(ticker: str, currency: str = "EUR") -> float:
    """
    Retourne le prix actuel d'une action boursière.

    Args:
        ticker: Le symbole boursier (ex: AAPL, NVDA, MSFT).
        currency: La devise de retour (EUR, USD, GBP).
    """
    # type hints + docstring Args: obligatoires
    return fetch_price_api(ticker, currency)

# Vérification de la définition générée
print(get_stock_price.inputs)
# {'ticker': {'type': 'string', 'description': 'Le symbole boursier (ex: AAPL, NVDA, MSFT).'},
#  'currency': {'type': 'string', 'description': 'La devise de retour (EUR, USD, GBP).'}}

Classe Tool (pour les outils lourds)

python
from smolagents import Tool

class EmbeddingSearchTool(Tool):
    name = "embedding_search"
    description = "Recherche sémantique dans la base de connaissances."
    inputs = {
        "query": {"type": "string", "description": "La requête de recherche."},
        "k": {"type": "integer", "description": "Nombre de résultats à retourner."}
    }
    output_type = "string"

    def setup(self):
        # Appelé au premier usage — lazy init des ressources lourdes
        self.index = load_vector_index("knowledge_base.faiss")
        self.embedder = load_embedder()

    def forward(self, query: str, k: int = 3) -> str:
        vec = self.embedder.encode(query)
        results = self.index.search(vec, k)
        return "\n".join(results)

Outils depuis le Hub et MCP

python
from smolagents import ToolCollection
from mcp import StdioServerParameters

# Charger des outils depuis Hugging Face Hub
coll = ToolCollection.from_hub("huggingface-tools/diffusion-tools-6")
agent = CodeAgent(tools=[*coll.tools], model=model)

# Charger des outils depuis un serveur MCP (stdio)
server = StdioServerParameters(command="uvx", args=["pubmedmcp@0.1.3"])
with ToolCollection.from_mcp(server, trust_remote_code=True) as tools:
    agent = CodeAgent(tools=[*tools.tools], model=model)
    result = agent.run("Résume les 3 dernières publications sur les vaccins ARNm")

# Depuis un serveur MCP HTTP Streamable (production)
with ToolCollection.from_mcp({"url": "http://mcp-service:8000/mcp", "transport": "streamable-http"}) as tools:
    agent = CodeAgent(tools=[*tools.tools], model=model)

7. Intégration Ollama

smolagents n'a pas de classe OllamaModel native — c'est une erreur fréquente dans les blogs et tutoriels. L'intégration Ollama passe par LiteLLMModel avec le préfixe ollama_chat/.

python
from smolagents import CodeAgent, LiteLLMModel, DuckDuckGoSearchTool
from smolagents.tools import PythonInterpreterTool

model = LiteLLMModel(
    model_id="ollama_chat/qwen3:14b",
    api_base="http://localhost:11434",
    # api_key non requis pour Ollama local
    num_ctx=8192,   # CRITIQUE — défaut Ollama = 2048, insuffisant pour les agents
)

agent = CodeAgent(
    tools=[DuckDuckGoSearchTool(), PythonInterpreterTool()],
    model=model,
    additional_authorized_imports=["pandas", "numpy", "matplotlib"],
    max_steps=8,
)

result = agent.run(
    "Télécharge les données EUR/USD des 30 derniers jours et calcule la volatilité"
)
print(result)

num_ctx=8192 — le paramètre critique avec Ollama

Le contexte par défaut d'Ollama est 2 048 tokens — largement insuffisant pour un agent qui accumule l'historique des steps. Avec num_ctx=8192 minimum (32 768 pour les tâches longues), les agents fonctionnent correctement. Sans ce paramètre, l'agent "oublie" ses steps précédents et boucle.

Pour aller plus loin avec les modèles locaux, voir notre guide Ollama Python complet et le guide RAG avec Ollama et ChromaDB.

LiteLLMModel active automatiquement flatten_messages_as_text=True pour les identifiants commençant par "ollama" — cela gère les limitations de format de certains modèles Ollama qui ne supportent pas nativement les rôles multiples dans l'historique.

8. Exécution sécurisée du code

L'exécution de code généré par un LLM est le risque principal du paradigme code-first. smolagents offre une progression en 3 niveaux.

Niveau 1 — LocalPythonExecutor (défaut)

Le LocalPythonExecutor ne fait pas d'eval() ou d'exec(). Il parse l'AST (Abstract Syntax Tree) et évalue chaque nœud indépendamment — ce qui permet de compter les opérations, intercepter les imports et détecter les abus.

Protections actives par défaut :

Limite du sandbox local

Aucun sandbox local ne peut être 100% sûr. Exemple documenté par Hugging Face : si PIL est autorisé, un LLM mal aligné pourrait générer des milliers d'images pour saturer le disque. Pour du code non fiable en production, utiliser les sandboxes distants.

Niveau 2 — Sandboxes distants

python
# E2B cloud sandbox — une ligne de changement
with CodeAgent(model=model, tools=tools, executor_type="e2b") as agent:
    agent.run("Analyse ce CSV et génère un graphique")
# Le code s'exécute dans une VM isolée, pas sur le serveur local

# Docker local (nécessite Docker installé)
agent = CodeAgent(model=model, tools=tools, executor_type="docker")

# Modal cloud (scale-to-zero automatique)
agent = CodeAgent(model=model, tools=tools, executor_type="modal")

# WebAssembly via Pyodide (zéro installation cloud, via Deno)
agent = CodeAgent(model=model, tools=tools, executor_type="wasm")

Limite des sandboxes distants avec multi-agents

L'approche sandbox simple (executor_type seul) ne supporte pas le multi-agents car les clés API ne sont pas transférées dans le sandbox. Pour le multi-agents sécurisé, il faut déployer l'ensemble du système agent dans E2B ou Docker — plus complexe mais complet.

9. Multi-agents avec smolagents

Le système multi-agents de smolagents repose sur un principe élégant : tout agent avec name et description peut être passé dans managed_agents d'un agent parent. Il n'existe pas de classe ManagedAgent séparée dans l'API actuelle.

python
from smolagents import CodeAgent, ToolCallingAgent, InferenceClientModel, WebSearchTool

model = InferenceClientModel()

# Agent spécialisé (ToolCallingAgent pour les recherches JSON-structurées)
web_agent = ToolCallingAgent(
    tools=[WebSearchTool()],
    model=model,
    name="web_search_agent",       # Requis
    description="Effectue des recherches web. Passe la requête complète en argument.",
    max_steps=5,
)

# Agent spécialisé analyse données
data_agent = CodeAgent(
    tools=[],
    model=model,
    name="data_analyst",
    description="Analyse des données, calcule des statistiques, génère des graphiques.",
    additional_authorized_imports=["pandas", "matplotlib", "scipy"],
)

# Agent manager — voit web_agent et data_agent comme des fonctions Python
manager = CodeAgent(
    tools=[],
    model=model,
    managed_agents=[web_agent, data_agent],
    planning_interval=2,  # Replanning tous les 2 steps
)

manager.run("Collecte les prix des actions NVDA sur 30 jours et analyse leur volatilité")

Du point de vue du LLM manager, appeler un agent géré est strictement identique à appeler un outil. Dans le system prompt du manager, les agents gérés apparaissent comme des fonctions Python :

python — system prompt injecté automatiquement
def web_search_agent(task: str, additional_args: dict[str, Any]) -> str:
    """Effectue des recherches web. Passe la requête complète en argument.

    Args:
        task: Description détaillée de la tâche.
        additional_args: Variables supplémentaires (images, DataFrames...).
    """

10. Système de mémoire — ActionStep et AgentMemory

Chaque interaction est enregistrée dans un objet ActionStep. La mémoire complète de l'agent est accessible via agent.memory.

python
# Après un run, inspecter la mémoire
result = agent.run("Analyse ce fichier CSV", reset=False)

for step in agent.memory.steps:
    if hasattr(step, 'code_action'):
        print(f"Step {step.step_number} — Code généré :")
        print(step.code_action)
        print(f"Observation : {step.observations}")
        print(f"Tokens : {step.token_usage}")

# Récupérer tout le code généré en un seul script
full_script = agent.memory.return_full_code()

# Rejouer la session en mode debug
agent.memory.replay(agent.logger, detailed=True)

# Continuer une conversation (reset=False conserve l'historique)
result2 = agent.run("Maintenant génère un graphique de ce résultat", reset=False)

11. Interface Gradio en une ligne

python
from smolagents import CodeAgent, InferenceClientModel, GradioUI

agent = CodeAgent(
    tools=[DuckDuckGoSearchTool()],
    model=InferenceClientModel(),
    add_base_tools=True,
)

# Interface chat complète avec upload de fichiers
GradioUI(
    agent,
    file_upload_folder="uploads",   # Dossier pour les fichiers uploadés
    reset_agent_memory=False,        # Conserve l'historique entre messages
).launch(share=True)  # share=True → URL publique temporaire

# Publier sur Hugging Face Hub comme Space
agent.push_to_hub("user/mon-agent-ia")
agent2 = CodeAgent.from_hub("user/mon-agent-ia", trust_remote_code=True)

12. smolagents vs Pydantic AI vs LangGraph — comparaison complète

CritèresmolagentsPydantic AILangGraph
ParadigmeCode-first (Python exec)Type-safe (DI + Pydantic)Graph stateful
Type safetyNonNative, compilateurPartielle
Structured outputVia tool appel3 modes, auto-retryVia Pydantic
État agentVariables Python statefulMessage historyState dict partagé
Cycles / bouclesNatif (code Python)Via output_retriesNatif (graphe)
Human-in-the-loopVia step_callbacksrequires_approvalNatif (interrupt())
TestingMocks manuelsTestModel, FunctionModelMocks manuels
ObservabilitéAgentMemory + Logfire optionnelOpenTelemetry standardLangSmith
OllamaVia LiteLLMModelVia OllamaModel + OllamaProviderVia OllamaChatModel
Interface UIGradioUI natifagent.to_web()Non intégré
Lines of code core~1 000~15 000~8 000
Courbe d'entréeFacileRaide (generics)Intermédiaire

13. Quand utiliser quoi

smolagents

  • Automation de tâches exploratoires
  • Analyse de données ad hoc
  • Agents scientifiques / calcul
  • Prototype rapide
  • Intégration Hugging Face Hub
  • Interface Gradio rapide

Pydantic AI

  • APIs de production (FastAPI)
  • Codebase grande équipe
  • Structured output fiable
  • Tests unitaires déterministes
  • DI avec DB/HTTP pools
  • Type checking CI/CD

LangGraph

  • Workflows multi-étapes complexes
  • État persistant cross-sessions
  • Human-in-the-loop frequent
  • Routing conditionnel complexe
  • Self-RAG avec rebouclage
  • Checkpointing / reprise

Architecture hybride — le pattern 2026

Une combinaison qui émerge sur les projets production : smolagents pour les agents exploratoires et l'analyse de données (code-first, rapide à prototyper) + Pydantic AI pour les micro-services IA (type safety, DI, tests) + LangGraph pour l'orchestration globale (routing, état, human-in-the-loop). Les trois s'appellent mutuellement — un nœud LangGraph peut instancier un CodeAgent smolagents.

14. Exemple complet — agent d'analyse CSV avec smolagents + Ollama

Un cas concret : un agent qui lit un fichier CSV, calcule des statistiques descriptives, détecte les valeurs aberrantes et produit une conclusion textuelle — entièrement local avec Ollama.

python
from smolagents import CodeAgent, LiteLLMModel, tool
import os

model = LiteLLMModel(
    model_id="ollama_chat/qwen3:14b",
    api_base="http://localhost:11434",
    num_ctx=16384,
)

@tool
def read_csv_summary(filepath: str) -> str:
    """
    Lit un fichier CSV et retourne un résumé de ses colonnes et premières lignes.

    Args:
        filepath: Chemin absolu vers le fichier CSV à analyser.
    """
    import pandas as pd
    df = pd.read_csv(filepath)
    return f"Shape: {df.shape}\nColumns: {list(df.columns)}\nHead:\n{df.head(3).to_string()}\nDtypes:\n{df.dtypes.to_string()}"

agent = CodeAgent(
    tools=[read_csv_summary],
    model=model,
    additional_authorized_imports=["pandas", "numpy", "scipy"],
    max_steps=6,
)

result = agent.run(
    """Analyse le fichier /data/ventes_2025.csv :
    1. Calcule les statistiques descriptives des colonnes numériques
    2. Détecte les valeurs aberrantes (IQR method)
    3. Identifie les 3 produits avec la plus forte variance de ventes
    4. Rédige une conclusion en 3 points"""
)
print(result)
# L'agent génère et exécute du code pandas/numpy à chaque étape
# Les variables (df, stats, outliers...) persistent entre les steps

Ce qui se passe en interne : le CodeAgent génère du pandas au step 1 (load + describe), réutilise le DataFrame au step 2 (IQR outliers), puis au step 3 (variance par produit), et synthétise au step 4 avec final_answer(). Les variables df, stats, etc. sont disponibles tout au long du run — c'est l'avantage central du paradigme code-first sur le JSON tool-calling.

15. Limites de smolagents

Pour un article honnête, les limites méritent d'être nommées :

16. FAQ

Quelle différence entre CodeAgent et ToolCallingAgent ?

CodeAgent génère du code Python exécutable — composable, stateful (variables persistantes entre steps), jusqu'à 30% moins d'étapes selon les benchmarks Hugging Face. ToolCallingAgent génère des JSON tool calls — plus prévisible, pas d'exécution de code, supporte les appels parallèles via max_tool_threads. Pour l'analyse de données ou les tâches multi-étapes complexes → CodeAgent. Pour les chatbots et RAG simples → ToolCallingAgent.

smolagents fonctionne-t-il avec Ollama ?

Oui — via LiteLLMModel avec le préfixe ollama_chat/. Il n'existe pas de classe OllamaModel native dans smolagents (contrairement à Pydantic AI). Le paramètre num_ctx est critique :

from smolagents import LiteLLMModel
model = LiteLLMModel("ollama_chat/qwen3:14b", api_base="http://localhost:11434", num_ctx=8192)
Le code généré par smolagents est-il sûr ?

Par défaut, le LocalPythonExecutor parse l'AST (pas d'eval), restreint les imports et limite les itérations. C'est insuffisant pour du code non fiable en production — utiliser executor_type="e2b" ou "docker" pour une isolation complète. Hugging Face documente explicitement qu'aucun sandbox local n'est 100% sûr.

smolagents vs LangChain — pourquoi choisir smolagents ?

smolagents a ~1 000 lignes de core vs des milliers dans LangChain — auditabilité et debuggabilité bien meilleures. Le paradigme code-first élimine le besoin de définir des chaînes d'outils JSON complexes. LangChain reste pertinent pour son écosystème d'intégrations (1000+) et sa courbe d'entrée plus douce. smolagents n'est pas "LangChain en mieux" — c'est un paradigme différent.

Comment faire des agents multi-niveaux avec smolagents ?

Passer n'importe quel agent (avec name et description) dans managed_agents=[...] de l'agent parent. Le manager voit les agents gérés comme des fonctions Python ordinaires — aucune classe ManagedAgent séparée n'est nécessaire. Différents agents peuvent utiliser différents modèles LLM.

Peut-on combiner smolagents, Pydantic AI et LangGraph dans le même projet ?

Oui — les trois sont interopérables. Un nœud LangGraph peut instancier un CodeAgent smolagents pour une tâche d'analyse de données. Un agent Pydantic AI peut appeler un ToolCallingAgent smolagents via son interface agent.run(). L'architecture hybride est courante : smolagents pour les tâches exploratoires, Pydantic AI pour les micro-services API, LangGraph pour l'orchestration globale.

LangChain est-il encore utile en 2026 ?

Oui — pour son écosystème d'intégrations (1000+ connecteurs). Si vous avez besoin d'un connecteur spécifique (Pinecone, Weaviate, HubSpot, Salesforce...) qui n'existe pas dans smolagents ou Pydantic AI, LangChain reste la solution la plus rapide. Il est moins pertinent pour les nouvelles architectures agents où la type safety et l'auditabilité priment.

smolagents est-il adapté à la production ?

Oui, avec les bons garde-fous. Pour la production : (1) utiliser executor_type="e2b" ou "docker" pour isoler l'exécution de code, (2) limiter additional_authorized_imports au strict nécessaire, (3) utiliser ToolCallingAgent plutôt que CodeAgent quand l'exécution de code n'est pas requise. smolagents est notamment utilisé en production pour des pipelines d'analyse de données et de traitement documentaire.

Conclusion

smolagents v1.24 est le choix le plus direct pour des agents code-first : minimal, auditable, intégré à l'écosystème Hugging Face. Pydantic AI est la référence pour les APIs de production qui exigent type safety et testabilité. LangGraph pour les workflows avec état persistant et orchestration complexe.

Le vrai take-away 2026 : ces trois frameworks ne se remplacent pas — ils se complètent. L'architecture hybride (smolagents pour l'exploration + Pydantic AI pour la prod + LangGraph pour l'orchestration) est ce qui émerge sur les projets sérieux.

Articles liés

Type-safe

Pydantic AI Python 2026 : agents type-safe et structured output

Stateful

LangGraph 2026 : agents stateful avec mémoire et Ollama

Ollama + RAG

RAG avec Ollama en Python : connectez vos documents

Serving

vLLM Python 2026 : PagedAttention et serving en production