Lab 9: Premier Agent ADK pour Data Science

Navigation : Lab 8 << | Index | >> Lab 10

1. Objectifs d’apprentissage

À la fin de ce laboratoire, vous saurez : 1. Créer un agent Google ADK capable d’appeler des tools pandas typés 2. Analyser un DataFrame à travers des retours structurés 3. Comparer cette approche avec LangChain (create_pandas_dataframe_agent) 4. Tester différents providers via la configuration partagée

Prérequis

  • Python 3.10+
  • Fichier .env configuré avec ACTIVE_PROVIDER
  • Connaissance de base des agents (Lab 7 complété)

Durée estimée : 40-50 minutes

2. Configuration de l’Environnement

Nous utilisons la couche d’abstraction multi-provider du projet pour construire un agent Google ADK et lui exposer des tools pandas typés.

import sys
from pathlib import Path
import warnings
import nest_asyncio

# Ajout du répertoire parent pour les imports config/utils
sys.path.insert(0, str(Path().resolve().parent))

# Désactivation des warnings EXPERIMENTAL de google.adk
warnings.filterwarnings('ignore', message=r'.*EXPERIMENTAL.*', category=UserWarning, module=r'google.adk')

from config import get_settings, get_provider_config
from utils.adk_runtime import build_agent, run_agent_turn

nest_asyncio.apply()

print("Imports ADK OK")
Imports ADK OK

Chargement de la configuration du provider.

# Chargement de la configuration
config = get_provider_config(get_settings())

print(f"Provider: {config.provider.value} | Modele: {config.model}")
Provider: openrouter | Modele: openai/gpt-4.1-mini

3. Création d’un Dataset de Test

Nous créons un dataset de ventes simple pour tester notre agent.

import pandas as pd
import numpy as np

# Chargement du dataset ventes existant
df = pd.read_csv("Day4-Foundations/sales_data.csv")

print(f"Dataset chargé: {len(df)} lignes, {len(df.columns)} colonnes")
print("Colonnes:", list(df.columns))
df.head()
Dataset chargé: 100 lignes, 6 colonnes
Colonnes: ['date', 'product', 'region', 'quantity', 'price', 'revenue']
date product region quantity price revenue
0 2024-01-01 Gadget X Est 32 11.49 367.68
1 2024-01-02 Gadget Y Sud 39 56.09 2187.51
2 2024-01-03 Widget A Sud 49 30.38 1488.62
3 2024-01-04 Gadget X Ouest 32 68.07 2178.24
4 2024-01-05 Gadget X Sud 4 25.69 102.76

Lecture du dataset

Structure. 100 lignes, une par vente : une date, un produit parmi 4 (Widget A, Widget B, Gadget X, Gadget Y), une région parmi 4 (Nord, Sud, Est, Ouest), une quantité, un prix et le revenu associé. La colonne revenue est dérivée : quantity × price — vérifiez sur la première ligne du head ci-dessus : 32 × 11,49 = 367,68.

Reproductibilité. Le notebook recharge le fichier versionné sales_data.csv à chaque exécution : les outils ADK travaillent donc sur le même jeu de données et les mêmes agrégats. Les valeurs citées dans les interprétations (revenus par région et top produits) restent vérifiables directement avec pandas.

Pourquoi un CSV. L’agent ne reçoit pas le DataFrame brut dans son prompt. Les tools pandas fermés sur df effectuent les calculs puis transmettent seulement leurs retours structurés à l’agent. Le fichier matérialise le jeu de test sur disque et découple sa provenance de l’état du kernel.

Lecture de l’implémentation : trois briques, une passe unique

Le code ci-dessus repose sur trois briques fondamentales, et chacune porte une décision de conception claire :

  • build_agent — le contexte passé au LLM n’est pas seulement la question : il embarque l’instruction définie dans l’appel, plus automatiquement les docstrings de chaque tool déclaré. Le LLM « voit » donc le dataset indirectement : via la docstring de revenu_par_region, il sait que cette fonction calcule un revenu total par région et retourne un dictionnaire. C’est la description textuelle des outils qui permet au LLM de comprendre leurs capacités sans jamais manipuler le dataset lui-même. Suit dans l’instruction un bloc de directives (répondre par du code Python si nécessaire, respect des types, format de sortie) qui cadre la génération. Cette approche évite d’embarquer les données brutes dans le prompt tout en donnant au LLM toute l’information nécessaire pour agir correctement.

  • run_agent_turn — le cœur opérationnel : cette fonction déclenche l’exécution de l’agent pour un tour unique. Elle encapsule l’appel au LLM, la validation des appels de tools selon leurs signatures typées, et retourne un objet AdkRunResult contenant la réponse textuelle, les appels de tools effectués avec leurs paramètres, et les métriques d’exécution. Le contexte est passé une seule fois, sans boucle de révision : une seule passe, comme le montre concrètement l’échec étudié dans la section 5. Cette simplicité est voulue pour isoler chaque étape du pipeline.

  • AdkRunResult — la structure de retour qui matérialise le résultat : response_text pour la réponse finale du LLM, tool_calls pour la liste détaillée des invocations (avec les noms des tools, leurs arguments sérialisés, et leur statut), et tool_was_invoked pour un flag booléen indiquant si au moins un tool a été utilisé. C’est cette transparence qui permet de déboguer les échecs d’appel ou de comprendre précisément pourquoi un tool n’a pas été invoqué dans la suite du laboratoire.

Le même pipeline CodeAct, rendu sous forme de graphe. Le trait plein reprend le flux linéaire dessiné ci-dessus ; le trait tireté ajoute la boucle de révision décrite dans le repère bibliographique (« réviser ou enchaîner ses actions sur la base des résultats observés ») :

flowchart TD
    PR["Prompt<br/>question + contexte DataFrame"]
    LLM["LLM<br/>génère du code Python"]
    EX["Executor<br/>exécute de façon sécurisée"]
    OUT["Output<br/>résultat + explication"]
    PR --> LLM
    LLM --> EX
    EX --> OUT
    OUT -.->|"révision (CodeAct)"| LLM
    classDef prompt fill:#cfe2ff,stroke:#084298,color:#052c65
    classDef llm fill:#fff3cd,stroke:#b8860b,color:#5c4400
    classDef exec fill:#d1e7dd,stroke:#0f5132,color:#052e16
    classDef out fill:#e2e3e5,stroke:#41464b,color:#1b1e21
    class PR prompt
    class LLM llm
    class EX exec
    class OUT out

Lecture. Contrairement à un appel d’outil JSON figé, le paradigme CodeAct fait générer du code exécutable par le LLM : la sortie de l’Executor est ré-injectée dans le LLM (arête tiretée révision), qui peut corriger une erreur ou enchaîner l’étape suivante à partir de ce qu’il a observé. C’est cette rétroaction code ↔︎ exécution qui rend l’agent capable de s’auto-corriger, et qui sous-tend les data-science agents SOTA (Data Interpreter, CodeAct-2) évoqués dans le repère bibliographique ci-dessus.

Le pattern « tool » : deux moitiés qui doivent rester synchrones

L’ajout d’un tool à cet agent ne se joue pas à un seul endroit, mais à deux, dans deux déclarations qui doivent rester strictement synchrones :

  1. Déclarer la fonction tool avec sa signature typée et sa docstring : sans cette description, le LLM ne sait pas que la fonction existe ni comment l’utiliser ;
  2. L’inclure dans le paramètre tools de build_agent : sans cette entrée, le tool est déclaré mais injoignable, et tout appel lèvera une erreur.

Les deux moitiés se désynchronisent silencieusement : un tool présent dans le code mais non passé à build_agent est du code mort ; un tool référencé dans tools mais sans docstring claire est un piège pour le LLM. L’exercice « Tool Personnalisé » de la section 10 vous fera exécuter ce geste en entier pour detect_outliers — les deux moitiés, pas une seule.

Notez aussi deux conséquences de cette architecture ADK :

  • les fonctions tools retournent des valeurs structurées (dictionnaires, listes) : le LLM lit ces retours pour construire sa réponse finale ;
  • la docstring doit être précise et complète : c’est la seule information que le LLM a sur le comportement du tool avant de décider de l’appeler.
def revenu_par_region() -> dict:
    """
    Calcule le revenu total par région à partir du dataset ventes.
    
    Returns:
        dict: Dictionnaire avec les régions comme clés et les revenus totaux comme valeurs
    """
    global df
    return df.groupby('region')['revenue'].sum().to_dict()

def top_produits(n: int = 5) -> dict:
    """
    Retourne le top N produits par revenu total.
    
    Args:
        n (int): Nombre de produits à retourner, par défaut 5
    
    Returns:
        dict: Dictionnaire avec les noms de produits et leurs revenus totaux
    """
    global df
    return df.groupby('product')['revenue'].sum().nlargest(n).to_dict()

def get_dataset_info() -> dict:
    """
    Retourne les informations de base sur le dataset.
    
    Returns:
        dict: Informations sur la forme et les colonnes du dataset
    """
    global df
    return {
        "rows": len(df),
        "columns": list(df.columns),
        "shape": df.shape,
        "dtypes": df.dtypes.to_dict()
    }

print("Outils ADK prêts: revenu_par_region, top_produits, get_dataset_info")
Outils ADK prêts: revenu_par_region, top_produits, get_dataset_info

4. Construction de l’Agent ADK

Création d’un agent ADK avec les outils pandas définis ci-dessus.

# Construction de l'agent ADK avec outils pandas
agent = build_agent(
    name="lab9_data_analyst",
    description="Agent ADK pour analyse de données de ventes",
    instruction="Tu es un expert en analyse de données. Utilise les outils disponibles: revenu_par_region(), top_produits(n), get_dataset_info(). Réponds en français.",
    tools=(revenu_par_region, top_produits, get_dataset_info),
    config=config
)

print(f'Agent ADK créé: {agent.name}')
print(f'Outils: {len(agent.tools)}')
Agent ADK créé: lab9_data_analyst
Outils: 3
import asyncio

async def run_question(agent, question, session_id=None):
    """Execute une question avec l'agent ADK et affiche les résultats."""
    r = await run_agent_turn(agent, question, session_id=session_id)
    print(f"Réponse: {r.response_text}")
    print(f"Outils invoqués: {r.tool_was_invoked}")
    print(f"Événements: {r.event_count}")
    return r

5. Test de l’Agent

# Question 1: Revenu total par région
r1 = asyncio.run(run_question(agent, "Quel est le revenu total par région ?"))
Réponse: Le revenu total par région est le suivant :
- Région Est : 44 451,45
- Région Nord : 33 944,31
- Région Ouest : 32 673,99
- Région Sud : 40 079,60

Souhaitez-vous une autre analyse ?
Outils invoqués: True
Événements: 3

Lecture du résultat

Les chiffres. Les quatre régions totalisent des revenus du même ordre de grandeur : Est 44 451,45 en tête, puis Sud 40 079,60, Nord 33 944,31 et Ouest 32 673,99 — un écart d’environ 1,4× entre la première et la dernière. Avec 100 ventes réparties sur 4 régions, on s’attend à des totaux relativement proches : c’est exactement ce qu’affiche la réponse fraîche ci-dessus.

Le triplet de sortie ADK. La cellule affiche trois informations réellement produites par run_question : Réponse, Outils invoqués et Événements. Réponse est la formulation finale du modèle à partir du dictionnaire renvoyé par revenu_par_region; Outils invoqués: True confirme que l’agent n’a pas inventé les totaux mais a appelé un tool; Événements: 3 résume le cycle ADK observé pour ce tour. Ce triplet sépare donc le résultat destiné au lecteur de la preuve opérationnelle que l’outil a bien participé.

Pourquoi la réponse reste contrôlable. Les valeurs viennent d’un calcul pandas déterministe dans le tool, et non de code Python généré librement par le modèle. On peut les confronter directement à df.groupby('region')['revenue'].sum(). Le LLM conserve la responsabilité de choisir le tool et de présenter son retour, tandis que le calcul métier reste dans une fonction typée et testable.

Question 2 : top produits par revenu

# Question 2: Top produits par revenu
r2 = asyncio.run(run_question(agent, "Quels sont les 3 produits générant le plus de revenus ?"))
Réponse: Les 3 produits générant le plus de revenus sont :
1. Gadget Y avec un revenu de 45 784,80
2. Widget B avec un revenu de 44 180,95
3. Gadget X avec un revenu de 33 934,75

Souhaitez-vous d'autres analyses ?
Outils invoqués: True
Événements: 3

Lecture du résultat : un classement calculé par le tool

La réponse classe Gadget Y, Widget B puis Gadget X, avec les revenus affichés dans la cellule précédente. Ces valeurs proviennent de top_produits(3), qui agrège revenue par produit, trie les sommes et conserve les trois premières. Le calcul reste donc déterministe et contrôlable avec pandas.

Le paramètre est réellement interprété. La question demande trois produits et l’agent transmet cette contrainte au paramètre n du tool plutôt que de réciter la valeur par défaut. Outils invoqués: True confirme le passage par la fonction, tandis que Événements: 3 montre un cycle ADK complet comparable à celui de la première question.

Séparation des responsabilités. Le tool décide du classement numérique; le modèle transforme son dictionnaire en réponse lisible. Cette frontière limite les hallucinations arithmétiques : pour auditer le résultat, il suffit de comparer la réponse à df.groupby('product')['revenue'].sum().nlargest(3).

Question 3 : structure du dataset

# Question 3: Structure du dataset
r3 = asyncio.run(run_question(agent, "Quelle est la structure de ce dataset de ventes ?"))
Réponse: Le dataset de ventes contient 100 lignes et 6 colonnes. Les colonnes sont : date, produit, région, quantité, prix, et revenu. Les types de données sont : 
- date : chaîne de caractères (object)
- product (produit) : chaîne de caractères (object)
- region (région) : chaîne de caractères (object)
- quantity (quantité) : entier
- price (prix) : nombre à virgule flottante
- revenue (revenu) : nombre à virgule flottante

Souhaitez-vous une analyse particulière de ce dataset ?
Outils invoqués: True
Événements: 3

Lecture du résultat : une description structurée plutôt qu’une figure

La réponse ci-dessus décrit correctement les 100 lignes, les 6 colonnes et leurs types. Ici encore, Outils invoqués: True montre que l’agent a consulté get_dataset_info() avant de formuler sa réponse, et les 3 événements témoignent du même cycle ADK que pour les deux questions précédentes.

Pourquoi il n’y a plus de figure. L’ancienne version du laboratoire demandait à un agent maison d’appeler plot_pie; une ambiguïté entre noms de colonnes et données produisait alors Grouper and axis must be same length et une figure matplotlib vide. La migration ADK a intentionnellement retiré ce chemin : la troisième question appelle maintenant get_dataset_info() et retourne un dictionnaire structuré, rendu sous forme de texte par l’agent. Le symptôme de capture matplotlib n’existe donc plus dans l’artefact courant et son ancienne interprétation ne doit pas être conservée.

Leçon de conception. Un tool étroit, typé et documenté réduit l’espace d’erreur : get_dataset_info() ne prend aucun argument ambigu et renvoie une structure explicite (rows, columns, shape, dtypes). Si une visualisation devait être réintroduite, elle devrait faire l’objet d’un tool distinct dont la docstring préciserait si ses paramètres sont des noms de colonnes ou des valeurs, puis d’un test dédié de rendu.

6. Comparaison avec LangChain

Approche LangChain

from langchain_experimental.agents import create_pandas_dataframe_agent
from langchain_openai import ChatOpenAI

llm = ChatOpenAI(model="gpt-5-mini")
agent = create_pandas_dataframe_agent(llm, df, verbose=True)
agent.invoke("Quel est le revenu total par région?")

Différences clés

Aspect Agent Google ADK de ce lab LangChain Agent
Outils Fonctions pandas typées et explicitement déclarées PythonAstREPLTool autour du DataFrame
Contrôle Signatures, docstrings et calculs métier visibles Abstraction plus intégrée
Sécurité Surface bornée aux tools fournis Exécution Python à encadrer
Multi-provider Natif via la configuration partagée Nécessite des adaptateurs
Debugging Appels de tools et événements observables Traces dépendantes de l’agent configuré

Avantages de notre approche

  1. Calculs contrôlables : les agrégations restent dans des fonctions pandas testables
  2. Pédagogique : chaque capacité de l’agent correspond à un tool visible
  3. Extensible : ajouter une capacité revient à typer, documenter et enregistrer un tool
  4. Multi-provider : le même agent consomme la configuration active du projet

7. Amélioration: Ajout de Tools Supplémentaires

Étendons notre agent avec des tools spécialisés.

8. Session Multi-tours

Démonstration de la réutilisation de session_id pour maintenir le contexte.

import uuid

# Création d'une session unique
session_id = str(uuid.uuid4())
print(f"Session ID: {session_id}")

# Premier tour dans la session
r4 = asyncio.run(run_question(agent, "Bonjour, je veux analyser les données de ventes.", session_id=session_id))

# Deuxième tour dans la même session
r5 = asyncio.run(run_question(agent, "Quelle région a le revenu le plus élevé ?", session_id=session_id))
Session ID: 18888fed-4d02-497b-bfa8-6ba71a381a9f
Réponse: Bonjour ! Pour commencer, je peux vous fournir des informations générales sur le dataset de ventes, comme la structure et les colonnes disponibles. Voulez-vous que je fasse cela ? Ou avez-vous déjà une idée précise de ce que vous voulez analyser ?
Outils invoqués: False
Événements: 1
Réponse: La région ayant le revenu le plus élevé est la région Est, avec un revenu total de 44 451,45.
Outils invoqués: True
Événements: 3

Exercice : Tool Personnalisé pour l’Agent

Ajoutez un nouveau tool detect_outliers(column, method='iqr') à l’agent ADK. Ce tool doit détecter les valeurs aberrantes dans une colonne numérique et retourner le nombre d’outliers et leurs indices.

Objectifs

  1. Implémenter une fonction detect_outliers utilisant la méthode IQR (Interquartile Range)
  2. L’intégrer dans le tuple tools de build_agent(tools=[..., detect_outliers])
  3. Tester l’agent sur la colonne price du DataFrame de ventes

Indice : - IQR = Q3 - Q1. Un outlier est une valeur < Q1 - 1.5IQR ou > Q3 + 1.5IQR - Ajoutez une docstring claire à votre fonction pour que le LLM sache comment l’utiliser - Reconstruisez l’agent avec build_agent(tools=[revenu_par_region, top_produits, get_dataset_info, detect_outliers])

def detect_outliers(column: str, method: str = "iqr") -> dict:
    """
    Détecte les valeurs aberrantes dans une colonne du DataFrame.
    
    Args:
        column (str): nom de la colonne à analyser
        method (str): méthode de détection ('iqr' ou 'zscore')
    
    Returns:
        dict: dictionnaire avec le nombre d'outliers, leurs indices et les bornes
    """
    # TODO: Implémentez la détection d'outliers
    # Étape 1: Récupérez les données de la colonne depuis df
    # data = df[column]
    
    # Étape 2: Calculez Q1, Q3 et l'IQR
    # Q1 = data.quantile(0.25)
    # Q3 = data.quantile(0.75)
    # IQR = Q3 - Q1
    
    # Étape 3: Identifiez les outliers
    # lower = Q1 - 1.5 * IQR
    # upper = Q3 + 1.5 * IQR
    # outliers_mask = (data < lower) | (data > upper)
    
    # Étape 4: Retournez les résultats
    # return {"count": int(outliers_mask.sum()), "indices": data[outliers_mask].index.tolist()}
    
    return None  # TODO étudiant

print("Exercice à compléter : tool detect_outliers pour l'agent")
Exercice à compléter : tool detect_outliers pour l'agent

Test de l’agent etendu avec des requêtes plus complexes.

# TODO: Construisez l'agent avec detect_outliers
# outlier_agent = build_agent(
#     name="lab9_outlier_detector",
#     description="Agent ADK avec détection d'outliers",
#     instruction="Tu es un expert en détection d'outliers. Utilise detect_outliers(column, method).",
#     tools=(revenu_par_region, top_produits, get_dataset_info, detect_outliers),
#     config=config
# )

# TODO: Testez l'agent
# r6 = asyncio.run(run_question(outlier_agent, "Y a-t-il des valeurs aberrantes dans les prix ?"))

print("TODO: Construisez et testez l'agent outlier_agent")
TODO: Construisez et testez l'agent outlier_agent

9. Résumé et Points Clés

Ce que nous avons appris

  1. Runtime ADK réel : utilisation de build_agent, run_agent_turn et AdkRunResult
  2. Architecture d’un agent : modèle, instruction, tools typés et session dans le cadre ADK
  3. Calcul métier contrôlé : les tools pandas produisent les agrégats; le modèle choisit le tool et formule son retour
  4. Tools : ajouter des fonctions spécialisées typées et documentées
  5. Multi-provider : réutiliser la configuration active sans modifier le notebook
  6. Gestion de session : réutiliser session_id pour le contexte multi-tours

Sécurité

L’agent n’accède qu’aux tools explicitement déclarés dans build_agent. Pour une utilisation en production :

  • bornez les entrées et sorties de chaque tool ;
  • validez les noms de colonnes et les types avant tout calcul ;
  • appliquez des timeouts et des limites de ressources aux opérations coûteuses ;
  • n’exposez jamais de données sensibles dans les prompts ou les logs.

Prochaines étapes

  • Lab 10 : File Analyzer de DS-STAR
  • Lab 11 : boucle Planner-Coder-Verifier
  • Lab 12 : DS-STAR complet

Bonnes pratiques ADK

  1. Typage des tools : typer les paramètres et la valeur de retour pour rendre le contrat explicite.
  2. Documentation des tools : expliquer le but, la sémantique des paramètres et la structure du retour.
  3. Gestion des erreurs : utiliser des exceptions typées et des messages actionnables.
  4. Performance : prévoir des timeouts et des limites de ressources.
  5. Testabilité : tester les tools indépendamment du modèle.
  6. Idempotence : privilégier les opérations répétables sans effet de bord inattendu.
  7. Journalisation : tracer les appels sans exposer de secrets ni de données sensibles.

Ressources complémentaires

  • Documentation Google ADK : https://developers.google.com/adk
  • Exemples de tools : consultez le dépôt officiel pour des contrats d’outils complets
  • Communauté : partagez les retours d’expérience sur les agents ADK

Exercices supplémentaires

  1. Optimisation des tools : optimisez detect_outliers pour de grands datasets.
  2. Nouveaux tools : implémentez generate_report() pour produire un rapport HTML.
  3. Intégration : connectez un tool à une API externe de données.
  4. Benchmark : comparez l’agent ADK à une implémentation LangChain équivalente.

10. Exercice

  1. Posez 3 questions supplémentaires à l’agent
  2. Ajoutez un tool plot_histogram(column, bins=10)
  3. Testez avec un autre provider (changez ACTIVE_PROVIDER dans .env)
# Espace pour vos exercices

# Question 1:
# r_exercice = asyncio.run(
#     run_agent_turn(agent, "Votre question ici")
# )
# print(r_exercice.response_text)

# Question 2:

# Question 3:

print("Exercice a completer")
Exercice a completer

11. Exercice : Robustesse du Code Generation

Testez la robustesse de l’agent face a des questions ambigues ou mal formulees. L’objectif est d’identifier les limites du système de generation de code et de proposer des stratégies d’amelioration du prompt système.

Objectifs

  1. Poser 3 questions volontairement ambigues a l’agent
  2. Analyser les erreurs generees et les classer par type
  3. Proposer une amelioration du prompt système pour chaque type d’erreur

Indice : - Types d’ambiguite : noms de colonnes inexacts, questions vagues, demandes impossibles - Observez si le LLM demande des clarifications ou s’il devine et se trompe

# Exercice : tester la robustesse de l'agent
# TODO étudiant : complétez les trois questions et analysez les réponses.
questions_ambigues = [
    # "Quel est le total de la colonne ventes ?",  # Nom de colonne inexact
    # "Analyse les données.",                       # Demande trop vague
    # "Compare avec l'année précédente.",          # Donnée absente
]

# Étape 1 : exécutez chaque question avec la nouvelle API ADK.
# resultats_robustesse = [
#     asyncio.run(run_agent_turn(agent, question))
#     for question in questions_ambigues
# ]

# Étape 2 : classez chaque réponse et proposez une amélioration du prompt.
classifications = {
    "colonne_inexacte": None,
    "question_vague": None,
    "impossible_a_executer": None,
}  # TODO étudiant

print("Exercice a completer : robustesse de l'agent ADK")
Exercice a completer : robustesse de l'agent ADK

12. Références

  1. X. Wang et al., Executable Code Actions Elicit Better LLM Agents (CodeAct), arXiv:2402.01030, ICML 2024. Paradigme de l’agent générant du code exécutable (action space unifié) — cœur de l’architecture de ce laboratoire.
  2. Z. Xi et al., The Rise and Potential of Large Language Model Based Agents: A Survey, arXiv:2309.07864, 2023. Cadre conceptuel des agents LLM (perception-raisonnement-action, outils, mémoire) — suite du Lab 8.
  3. H. Chase, LangChain, octobre 2022, langchain.com. Framework de comparaison (create_pandas_dataframe_agent) — suite du Lab 8.
  4. OpenBMB Team, CodeAct / Data Interpreter, 2024. Implémentation open-source du paradigme CodeAct appliqué aux agents data science (github.com/OpenBMB/AgentVerse).
Retour au sommet