#
Bibliothèque d’Agents Factices

Ce cours est indépendant de tout framework car nous souhaitons nous concentrer sur les concepts des agents d’IA et éviter de nous enliser dans les spécificités d’un framework particulier.

De plus, nous voulons que les étudiants puissent utiliser les concepts qu’ils apprennent dans ce cours dans leurs propres projets, en utilisant le framework de leur choix.

Ainsi, pour cette Unité 1, nous utiliserons une bibliothèque d’agents factices et une API serverless simple pour accéder à notre moteur LLM.

Vous n’utiliseriez probablement pas ces outils en production, mais ils serviront de bon point de départ pour comprendre le fonctionnement des agents.

Après cette section, vous serez prêt à créer un agent simple en utilisant `smolagents`

Et dans les unités suivantes, nous utiliserons également d’autres bibliothèques d’agents d’IA telles que `LangGraph`, `LangChain` et `LlamaIndex`.

Pour simplifier, nous utiliserons une fonction Python simple comme Tool et Agent.

Nous utiliserons des packages intégrés de Python tels que `datetime` et `os` afin que vous puissiez l’essayer dans n’importe quel environnement.

Vous pouvez suivre le processus dans ce notebook et exécuter le code vous-même.

##
API serverless

Dans l’écosystème Hugging Face, il existe une fonctionnalité pratique appelée API serverless qui vous permet d’exécuter facilement des inférences sur de nombreux modèles. Aucune installation ou déploiement n’est requis.

    import os
    from huggingface_hub import InferenceClient

    ## Vous avez besoin d'un token depuis https://hf.co/settings/tokens. Si vous exécutez ceci sur Google Colab, vous pouvez le configurer dans l'onglet "settings" sous "secrets". Assurez-vous de l'appeler "HF_TOKEN"
    os.environ["HF_TOKEN"] = "hf_xxxxxxxxxxxxxx"

    client = InferenceClient("meta-llama/Llama-3.2-3B-Instruct")
    # si les sorties des cellules suivantes sont incorrectes, le modèle gratuit peut être surchargé. Vous pouvez également utiliser ce point d'accès public qui contient Llama-3.2-3B-Instruct
    # client = InferenceClient("https://jc26mwg228mkj8dw.us-east-1.aws.endpoints.huggingface.cloud")

    output = client.text_generation(
        "The capital of France is",
        max_new_tokens=100,
    )

    print(output)

output:

    Paris. La capitale de la France est Paris. La capitale de la France est Paris. La capitale de la France est Paris. La capitale de la France est Paris. La capitale de la France est Paris. La capitale de la France est Paris. La capitale de la France est Paris. La capitale de la France est Paris. La capitale de la France est Paris. La capitale de la France est Paris. La capitale de la France est Paris. La capitale de la France est Paris. La capitale de la France est Paris.

Comme nous l’avons vu dans la section LLM, si nous faisons simplement du décodage, le modèle s’arrêtera uniquement lorsqu’il prédit un token EOS, et cela ne se produit pas ici car il s’agit d’un modèle conversationnel (chat) et nous n’avons pas appliqué le template de chat attendu.

Si nous ajoutons maintenant les tokens spéciaux relatifs au modèle Llama-3.2-3B-Instruct que nous utilisons, le comportement change et il produit désormais le token EOS attendu.

    prompt = """<|begin_of_text|><|start_header_id|>user<|end_header_id|>
    The capital of France is<|eot_id|><|start_header_id|>assistant<|end_header_id|>"""
    output = client.text_generation(
        prompt,
        max_new_tokens=100,
    )

    print(output)

output:

    The capital of France is Paris.

Utiliser la méthode “chat” est une façon bien plus pratique et fiable d’appliquer les templates de chat :

    output = client.chat.completions.create(
        messages=[
            {"role": "user", "content": "La capitale de la France est"},
        ],
        stream=False,
        max_tokens=1024,
    )
    print(output.choices[0].message.content)

output:

    Paris.

La méthode de chat est la méthode RECOMMANDÉE à utiliser afin d’assurer une transition fluide entre les modèles, mais comme ce notebook est uniquement à des fins pédagogiques, nous continuerons à utiliser la méthode “text_generation” pour comprendre les détails.

##
Agent factice

Dans les sections précédentes, nous avons vu que le cœur d’une bibliothèque d’agents consiste à ajouter des informations dans le prompt système.

Ce prompt système est un peu plus complexe que celui que nous avons vu précédemment, mais il contient déjà :

1. Informations sur les outils
2. Instructions de cycle (Thought → Action → Observation)

    Répondez du mieux que vous pouvez aux questions suivantes. Vous avez accès aux outils suivants:

    get_weather: Obtenez la météo actuelle dans un lieu donné

    La manière d'utiliser les outils consiste à spécifier un blob JSON.
    Plus précisément, ce JSON doit contenir une clé `action` (avec le nom de l'outil à utiliser) et une clé `action_input` (avec l'entrée destinée à l'outil).

    Les seules valeurs qui devraient figurer dans le champ "action" sont:
    get_weather: Obtenez la météo actuelle dans un lieu donné, args: {"location": {"type": "string"}}
    exemple d'utilisation :

    {{
      "action": "get_weather",
      "action_input": {"location": "New York"}
    }}

    UTILISEZ TOUJOURS le format suivant:

    Question : la question à laquelle vous devez répondre
    Réflexion : vous devez toujours réfléchir à une action à entreprendre. Une seule action à la fois dans ce format:
    Action:

    $JSON_BLOB (dans une cellule markdown)

    Observation : le résultat de l'action. Cette Observation est unique, complète et constitue la source de vérité.
    ... (ce cycle Réflexion/Action/Observation peut se répéter plusieurs fois, vous devez effectuer plusieurs étapes si nécessaire. Le $JSON_BLOB doit être formaté en markdown et n'utiliser qu'une SEULE action à la fois.)

    Vous devez toujours terminer votre sortie avec le format suivant:

    Réflexion : Je connais désormais la réponse finale
    Final Answer: la réponse finale à la question d'entrée initiale

    Commencez maintenant! Rappel: utilisez TOUJOURS exactement les caractères `Final Answer:` lorsque vous fournissez une réponse définitive.

Puisque nous utilisons la méthode “text_generation”, nous devons appliquer le prompt manuellement:

    prompt = f"""<|begin_of_text|><|start_header_id|>system<|end_header_id|>
    {SYSTEM_PROMPT}
    <|eot_id|><|start_header_id|>user<|end_header_id|>
    Quel temps fait-il à Londres ?
    <|eot_id|><|start_header_id|>assistant<|end_header_id|>
    """

Nous pouvons également le faire ainsi, ce qui est ce qui se passe dans la méthode `chat` :

    messages = [
        {"role": "system", "content": SYSTEM_PROMPT},
        {"role": "user", "content": "Quel temps fait-il à Londres ?"},
    ]
    from transformers import AutoTokenizer
    tokenizer = AutoTokenizer.from_pretrained("meta-llama/Llama-3.2-3B-Instruct")

    tokenizer.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)

Le prompt est maintenant :

    <|begin_of_text|><|start_header_id|>system<|end_header_id|>
    Répondez du mieux que vous pouvez aux questions suivantes. Vous avez accès aux outils suivants:

    get_weather: Obtenez la météo actuelle dans un lieu donné

    La manière d'utiliser les outils consiste à spécifier un blob JSON.
    Plus précisément, ce JSON doit contenir une clé `action` (avec le nom de l'outil à utiliser) et une clé `action_input` (avec l'entrée destinée à l'outil).

    Les seules valeurs qui devraient figurer dans le champ "action" sont:
    get_weather: Obtenez la météo actuelle dans un lieu donné, args: {"location": {"type": "string"}}
    exemple d'utilisation :

    {{
      "action": "get_weather",
      "action_input": {"location": "New York"}
    }}

    UTILISEZ TOUJOURS le format suivant:

    Question : la question à laquelle vous devez répondre
    Réflexion : vous devez toujours réfléchir à une action à entreprendre. Une seule action à la fois dans ce format:
    Action:

    $JSON_BLOB (dans une cellule markdown)

    Observation : le résultat de l'action. Cette Observation est unique, complète et constitue la source de vérité.
    ... (ce cycle Réflexion/Action/Observation peut se répéter plusieurs fois, vous devez effectuer plusieurs étapes si nécessaire. Le $JSON_BLOB doit être formaté en markdown et n'utiliser qu'une SEULE action à la fois.)

    Vous devez toujours terminer votre sortie avec le format suivant:

    Réflexion : Je connais désormais la réponse finale
    Final Answer: la réponse finale à la question d'entrée initiale

    Commencez maintenant! Rappel: utilisez TOUJOURS exactement les caractères `Final Answer:` lorsque vous fournissez une réponse définitive.
    <|eot_id|><|start_header_id|>user<|end_header_id|>
    Quel temps fait-il à Londres ?
    <|eot_id|><|start_header_id|>assistant<|end_header_id|>

Décodons !

    output = client.text_generation(
        prompt,
        max_new_tokens=200,
    )

    print(output)

output:

    Action:

{ “action”: “get_weather”, “action_input”: {“location”: “London”} }

    Réflexion : Je vais vérifier la météo à Londres.
    Observation : La météo actuelle à Londres est principalement nuageuse avec un maximum de 12°C et un minimum de 8°C.

Voyez-vous le problème ?

> La réponse a été hallucinée par le modèle. Nous devons arrêter avant d’exécuter réellement la fonction ! Arrêtons-nous maintenant sur “Observation” afin de ne pas halluciner la véritable réponse de la fonction.

    output = client.text_generation(
        prompt,
        max_new_tokens=200,
        stop=["Observation:"]
    )

    print(output)

output:

    Action:

{ “action”: “get_weather”, “action_input”: {“location”: “London”} }

    Réflexion : Je vais vérifier la météo à Londres.
    Observation:

Beaucoup mieux !

Créons maintenant une fonction factice pour obtenir la météo. Dans une situation réelle, vous appelleriez probablement une API.

    # Fonction factice
    def get_weather(location):
        return f"la météo à {location} est ensoleillée avec des températures basses. \n"

    get_weather('London')

output:

    'la météo à London est ensoleillée avec des températures basses. \n'

Concaténons le prompt de base, la complétion jusqu’à l’exécution de la fonction et le résultat de la fonction en tant qu’Observation, puis reprenons la génération.

    new_prompt = prompt + output + get_weather('London')
    final_output = client.text_generation(
        new_prompt,
        max_new_tokens=200,
    )

    print(final_output)

Voici le nouveau prompt:

    <|begin_of_text|><|start_header_id|>system<|end_header_id|>
    Répondez du mieux que vous pouvez aux questions suivantes. Vous avez accès aux outils suivants:

    get_weather: Obtenez la météo actuelle dans un lieu donné

    La manière d'utiliser les outils consiste à spécifier un blob JSON.
    Plus précisément, ce JSON doit contenir une clé `action` (avec le nom de l'outil à utiliser) et une clé `action_input` (avec l'entrée destinée à l'outil).

    Les seules valeurs qui devraient figurer dans le champ "action" sont:
    get_weather: Obtenez la météo actuelle dans un lieu donné, args: {"location": {"type": "string"}}
    exemple d'utilisation :

    {{
      "action": "get_weather",
      "action_input": {"location": "New York"}
    }}

    UTILISEZ TOUJOURS le format suivant:

    Question : la question à laquelle vous devez répondre
    Réflexion : vous devez toujours réfléchir à une action à entreprendre. Une seule action à la fois dans ce format:
    Action:

    $JSON_BLOB (dans une cellule markdown)

    Observation : le résultat de l'action. Cette Observation est unique, complète et constitue la source de vérité.
    ... (ce cycle Réflexion/Action/Observation peut se répéter plusieurs fois, vous devez effectuer plusieurs étapes si nécessaire. Le $JSON_BLOB doit être formaté en markdown et n'utiliser qu'une SEULE action à la fois.)

    Vous devez toujours terminer votre sortie avec le format suivant:

    Réflexion : Je connais désormais la réponse finale
    Final Answer: la réponse finale à la question d'entrée initiale

    Commencez maintenant! Rappel: utilisez TOUJOURS exactement les caractères `Final Answer:` lorsque vous fournissez une réponse définitive.
    <|eot_id|><|start_header_id|>user<|end_header_id|>
    Quel temps fait-il à Londres ?
    <|eot_id|><|start_header_id|>assistant<|end_header_id|>

Output:

    Final Answer: La météo à Londres est ensoleillée avec des températures basses.

Nous avons appris comment créer des Agents à partir de zéro en utilisant du code Python, et nous avons constaté à quel point ce processus peut être fastidieux. Heureusement, de nombreuses bibliothèques d’agents simplifient ce travail en prenant en charge la majeure partie de la charge de travail pour vous.

Maintenant, nous sommes prêts à créer notre premier vrai Agent en utilisant la bibliothèque `smolagents`.

< > Update on GitHub