Ubuntu TechHive
getting-started-with-ai-agents.md
Getting Started With AI Agents
article.détail

Getting Started With AI Agents

reading.progression 8 min de lecture

Description de la prise en main des agents d'IA

Introduction

Qu'est-ce qu'un Agent, bon sang ?

Concepts liés aux Agents et aux LLM

ReAct (Raisonner + Agir) : [Synergiser le raisonnement et l'action dans les modèles de langage](https: //arxiv.org/pdf/2210.03629)( Github)

Réfléchissez à l'invite et agissez en conséquence (ou non ?).

Auto-raffinement : [Raffinement itératif avec auto-retour d'information](https: //arxiv.org/pdf/2303.17651)( Github)

Après avoir reçu une invite, effectuer itérativement une action, inspecter ses résultats et prendre d'autres actions si nécessaire pour améliorer les résultats jusqu'à ce qu'aucune autre amélioration ne soit nécessaire ou qu'une autre contrainte soit remplie pour forcer un arrêt, puis renvoyer le résultat final.

Ingénierie des flux : [Génération de code avec AlphaCodium : De l'ingénierie des invites à l'ingénierie des flux](https: //arxiv.org/pdf/2401.08500)( Github)

Un flux itératif basé sur des tests, multi-étapes et orienté code, qui améliore les performances des LLM sur les problèmes de code.

Cadres d'agents

CrewAI: [Agents IA pour des cas d'utilisation réels](https: //www.crewai.com/)

La plupart des cadres d'agents IA sont difficiles à utiliser. Nous offrons de la puissance avec simplicité. Automatisez rapidement vos flux de travail les plus importants.

LangChain: [Agents](https: //www.langchain.com/agents)

Construisez la bonne architecture cognitive pour votre application. Identifiez et mettez en œuvre les meilleures stratégies et architectures de prompt afin que vos LLM fonctionnent comme prévu.

Construisons un agent

Qu'est-ce qui est nécessaire pour construire un agent alimenté par un LLM ?

  • Contexte : Informations pour l'agent (Rôle, Objectif, Données initiales, etc.)

  • Prompt : Message en langage naturel pour s'adresser à l'agent (Texte, Audio, etc.)

  • Python : Codez la magie en utilisant Instructor

  • Lire : Lisez davantage pour en apprendre plus sur les Agents et codez.

Récupération d'informations vs Génération de données vs Appel de fonctions avec la bibliothèque Python Instructor

Jusqu'à présent, nous avons utilisé Instructor pour la récupération d'informations et la génération de données en tant que données structurées. Nous allons maintenant approfondir les capacités d'appel de fonctions plus avancées de la bibliothèque Python Instructor. Pour le bloc-notes, nous utiliserons les Marimo Notebooks.

Alors, où est le A ?

Un agent est tout ce qui peut être considéré comme percevant son environnement par le biais de capteurs et agissant sur cet environnement par le biais d'actionneurs -- Stuart Russel et Peter Norvig.

Emprunté à Artificial Intelligence: A Modern Approach Fourth Edition

Percepts

class SystemMessage(BaseModel):
    role: Literal ["system"] = "system"
    content: str

class UserMessage(BaseModel):
    role: Literal ["user"] = "user"
    content: str

class AssistantMessage(BaseModel):
    role: Literal ["assistant"] = "assistant"
    content: str

percept_seq: List [Union [SystemMessage, UserMessage, AssistantMessage]] = []

Table des actions

class DefaultFunc(OpenAISchema):
    response: str
    def run(self):
        msg = f"DefaultFunc-\u003erun: {self.response}"
        return msg

class UserFunc(OpenAISchema):
    name: str
    age: int

def run(self):
        msg = f"UserFunc-\u003erun: User's name is {self.name} and age is {self.age}"
        return msg

toolbox = [DefaultFunc, UserFunc]

Actions et actionneur

def actuate(self, tool_call: ChatCompletionMessageToolCall):
        Func = next(iter([func for func in toolbox if func.__name__ == tool_call.function.name]))

if not Func:
            available_function_names = [func.__name__ for func in toolbox]
            err_msg = f"Error: Function {tool_call.function.name} not found. Available functions: {available_function_names}"
            console.error(err_msg)
            return err_msg

try:
            console.log(f"Tool Call -> {tool_call.function.name} ->with {tool_call.function.arguments} of type {type(tool_call.function.arguments)}", style="bold blue")
            args = from_json(tool_call.function.arguments)
            console.log(f"Args -> {args} of type {type(args)}", style="bold blue")
            func = Func.model_validate(args)
            console.log(f"Func -> {repr(func)}", style="bold blue")
            output = func.run()
            return output
        except Exception as e:
            return f"Error: {e}"

Une tentative de conception d'agent

Ce diagramme aide à visualiser le flux d'actions et de pensées à travers les agents, assurant une approche structurée et itérative pour atteindre le résultat final.

graph TD
A [Début : Réfléchir à l'invite] --> B [Dériver les entrées]
B --> T1{Boîte à outils}
T1 -->|Outil 1| T2 [Réfléchir aux résultats de l'Outil 1]
T1 -->|Outil 2| T3 [Réfléchir aux résultats de l'Outil 2]
T1 -->|Outil 3| T4 [Réfléchir aux résultats de l'Outil 3]
T1 -->|Outil 4| T5 [Réfléchir aux résultats de l'Outil 4]
T1 -->|Outil 5| T6 [Réfléchir aux résultats de l'Outil 5]

T2 --> T7{Boîte à outils}
T3 --> T7
T4 --> T7
T5 --> T7
T6 --> T7

T7 -->|Outil 1| T8 [Réfléchir aux résultats de l'Outil 1]
T7 -->|Outil 2| T9 [Réfléchir aux résultats de l'Outil 2]
T7 -->|Outil 3| T10 [Réfléchir aux résultats de l'Outil 3]
T7 -->|Outil 4| T11 [Réfléchir aux résultats de l'Outil 4]
T7 -->|Outil 5| T12 [Réfléchir aux résultats de l'Outil 5]

T8 --> T13{Boîte à outils}
T9 --> T13
T10 --> T13
T11 --> T13
T12 --> T13

T13 -->|Outil 1| T14 [Résultat final de l'Outil 1]
T13 -->|Outil 2| T15 [Résultat final de l'Outil 2]
T13 -->|Outil 3| T16 [Résultat final de l'Outil 3]
T13 -->|Outil 4| T17 [Résultat final de l'Outil 4]
T13 -->|Outil 5| T18 [Résultat final de l'Outil 5]

T14 --> F [Résultat Final]
T15 --> F
T16 --> F
T17 --> F
T18 --> F

style A fill:#f9f,stroke:#333,stroke-width:2px;
style B fill:#bbf,stroke:#333,stroke-width:2px;
style T1 fill:#bfb,stroke:#333,stroke-width:2px;
style T2 fill:#ff9,stroke:#333,stroke-width:2px;
style T3 fill:#ff9,stroke:#333,stroke-width:2px;
style T4 fill:#ff9,stroke:#333,stroke-width:2px;
style T5 fill:#ff9,stroke:#333,stroke-width:2px;
style T6 fill:#ff9,stroke:#333,stroke-width:2px;
style T7 fill:#bfb,stroke:#333,stroke-width:2px;
style T8 fill:#ff9,stroke:#333,stroke-width:2px;
style T9 fill:#ff9,stroke:#333,stroke-width:2px;
style T10 fill:#ff9,stroke:#333,stroke-width:2px;
style T11 fill:#ff9,stroke:#333,stroke-width:2px;
style T12 fill:#ff9,stroke:#333,stroke-width:2px;
style T13 fill:#bfb,stroke:#333,stroke-width:2px;
style T14 fill:#f99,stroke:#333,stroke-width:2px;
style T15 fill:#f99,stroke:#333,stroke-width:2px;

style T16 fill:#f99,stroke:#333,stroke-width:2px;
style T17 fill:#f99,stroke:#333,stroke-width:2px;
style T18 fill:#f99,stroke:#333,stroke-width:2px;
style F fill:#9f9,stroke:#333,stroke-width:2px;

Explication- Début : Réfléchir à l'invite : Le processus commence par l'agent qui examine l'invite donnée.

  • Dériver les entrées : L'agent dérive les entrées nécessaires pour décider quel(s) outil(s) utiliser de la boîte à outils.

  • Boîte à outils : L'agent a accès à une boîte à outils contenant 5 outils différents. En fonction des entrées dérivées, l'agent sélectionne un outil.

  • Réfléchir aux résultats de l'outil : Après avoir utilisé le premier outil, l'agent réfléchit aux résultats qu'il a obtenus.

  • Invocation séquentielle d'outils : L'agent peut décider d'invoquer un deuxième et même un troisième outil en fonction des résultats intermédiaires.

  • Résultat final : Finalement, l'agent produit le résultat final après avoir traité les outils nécessaires et les étapes de réflexion intermédiaires.

#+begin_src python

from instructor import OpenAISchema

from getting_started_with_ai_agents.agents.club_bouncer import (
ClubBouncer,
Person,
Guest,
)
from getting_started_with_ai_agents.llm import gen_client, SystemMessage, UserMessage

client = gen_client()

class ClubSecurity(OpenAISchema):
""" Agent de sécurité pour le Club UbuntuTechHive. Aide le videur à gérer la file d'attente et à vérifier la liste des invités selon les règles du club. si la personne a au moins 21 ans et au moins 20 $ en espèces, elle peut entrer dans le club. si la personne est sur la liste des invités, elle peut entrer dans le club. si la personne est un VIP, elle doit avoir au moins 1000 $ en espèces pour bénéficier du service de table. """

name: str # nom de la personne
age: int # âge de la personne
cash: float # montant d'argent liquide que la personne possède
is_on_guest_list: bool # si la personne est sur la liste des invités

def run(self): person = Person(
name=self.name,
age=self.age,
cash=self.cash,
is_on_guest_list=self.is_on_guest_list,
) return person

class ClubHost(OpenAISchema): """ Hôtesse pour le Club UbuntuTechHive. Collecte le droit d'entrée et attribue les billets aux invités. Vérifie la liste des invités et assigne les invités à la file VIP. Gère les VIP et le service de table. Accepte les VIP avec au moins 1000 $ en espèces et les demandes de service de table. Accepte le paiement pour le service de table et attribue les tables aux VIP. Si la personne a de l'argent pour un billet, laissez-la acheter le billet et marquez-la comme ayant un billet à l'aide d'un bracelet. Si l'invité est sur la liste des invités, marquez-le comme présent sur la copie de la liste des invités du club et laissez-le entrer. Si l'invité a 1000 $ en espèces, il est un VIP, marquez-le comme VIP, puis conduisez-le à une table libre. """

name: str # nom de la personne
age: int # âge de la personne
cash: float # montant d'argent liquide que la personne possède
has_ticket: bool = False # si la personne a un billet
is_on_guest_list: bool = False # si la personne est sur la liste des invités
is_vip: bool = False # si la personne est un VIP

def run(self):
guest = Guest(
name=self.name,
age=self.age,
cash=self.cash,
has_ticket=self.has_ticket,
is_on_guest_list=self.is_on_guest_list,
is_vip=self.is_vip,
)
return guest

bouncer = ClubBouncer(
context= [
SystemMessage(
content=""" Bienvenue au Club UbuntuTechHive ! Je suis le videur du club. Je vais gérer la file d'attente ce soir pour le club. Je déciderai qui peut entrer dans le club. Mes décisions sont basées sur les critères suivants :

  • La personne doit avoir au moins 21 ans.

  • La personne doit avoir au moins 20 $ en espèces.

  • La personne doit avoir un billet ou être sur la liste des invités.""",
    format="markdown"
    )
    ]
    )

  • Il y aura un droit d'entrée de 20 $ pour ceux qui n'ont pas de billet ou qui ne sont pas sur la liste des invités.

  • Les VIP doivent avoir au moins 1000 $ en espèces pour bénéficier du service de table.

  • Le service de table est disponible pour les VIP uniquement s'il y a un nombre limité de tables disponibles.

  • Lorsque aucune table n'est disponible, les VIP doivent attendre dans la file d'attente VIP qu'une table se libère. """ ) ], capacity=100, table_count=10, client=client, toolbox= [ClubSecurity, ClubHost],

)

ifname == "main": bouncer.manage_line( UserMessage( content=""" The person is John Doe and is 25 years old with $50 in cash. They on the guest list. """ ) )

bouncer.manage_line( UserMessage( content=""" Lambert is 21 years old with $20 in cash. They want to purchase a ticket. """ ) )

#+end_src

Conclusion

Ce domaine évolue rapidement et il y a peu d'experts. N'ayez pas peur de lire, d'apprendre et de coder pour acquérir de la compréhension. Décidez ensuite vous-même si vous souhaitez adopter une bibliothèque qui répond à vos besoins ou créer la vôtre !

Références