LangChain Permettez aux LLMs d’interagir avec votre code

'LangChain Laissez les LLMs interagir avec votre code'

Photo de David Clode sur Unsplash

Apprenez à implémenter des fonctions personnalisées pour votre LLM en utilisant des outils

Introduction

Les modèles génératifs suscitent l’attention de tous. De nombreuses applications d’IA ne nécessitent plus l’expertise des spécialistes de l’apprentissage automatique dans le domaine, mais simplement la connaissance de la mise en œuvre des appels API.

Récemment, par exemple, j’ai participé à un hackathon et j’ai dû mettre en œuvre une reconnaissance d’entités nommées personnalisée, mais j’ai directement utilisé un LLM et exploité sa capacité d’apprentissage few-shot pour obtenir le résultat souhaité, ce qui était suffisant pour remporter le hackathon ! (Vous pouvez consulter le projet ici si vous le souhaitez). Ainsi, pour de nombreuses applications du monde réel, l’accent est de plus en plus mis sur la manière d’interagir et d’utiliser ces LLM plutôt que de créer des modèles. LangChain est une bibliothèque qui vous permet de faire exactement cela, et j’ai récemment écrit plusieurs articles à ce sujet.

Outils LangChain

Les outils sont des utilitaires qu’un LLM peut utiliser pour augmenter ses capacités. Les outils peuvent être instanciés au sein de chaînes ou d’agents. Par exemple, un LLM peut effectuer une recherche sur Wikipedia avant de répondre pour garantir une réponse à jour. Bien sûr, un agent peut utiliser plusieurs outils, et il est donc souvent nécessaire de définir une liste d’outils.

Examinons maintenant l’anatomie d’un outil. Un outil n’est rien de plus qu’une classe composée de plusieurs champs :

  • name (str) : définit un nom unique pour l’outil
  • description (str) : une description de l’utilité de l’outil en langage naturel. Le LLM pourra lire cette description et déterminer s’il a besoin ou non de l’outil pour répondre à la requête.
  • return_direct (bool) : un outil peut renvoyer la sortie d’une fonction personnalisée, par exemple. Voulons-nous que cette sortie soit présentée directement à l’utilisateur (True) ou qu’elle soit prétraitée par le LLM (False) ?
  • args_schema (Pydantic BaseModel) : Par exemple, l’outil peut utiliser une fonction personnalisée dont les paramètres d’entrée doivent être extraits de la requête de l’utilisateur. Nous pouvons fournir plus d’informations sur chaque paramètre afin que le LLM puisse effectuer cette étape plus facilement.

Comment définir un outil

Il existe plusieurs approches pour définir un outil que nous examinerons dans cet article. Tout d’abord, nous importons les bibliothèques nécessaires et instancions un modèle OpenAI. Pour cela, vous aurez besoin d’un jeton, vous pouvez voir dans mon article précédent comment l’obtenir.

!pip install langchain!pip install openaifrom langchain import LLMMathChain, SerpAPIWrapperfrom langchain.agents import AgentType, initialize_agentfrom langchain.chat_models import ChatOpenAIfrom langchain.tools import BaseTool, StructuredTool, Tool, toolimport osos.environ["OPENAI_API_KEY"] = ... # insérez votre API_TOKEN icillm = ChatOpenAI(temperature=0)

La première façon d’instancier un outil consiste à utiliser la classe Tool.

Supposons que nous voulons donner à l’outil la capacité de rechercher des informations sur le web, pour cela nous utiliserons une API de Google appelée SerpAPI, vous pouvez vous inscrire et obtenir l’API ici : https://serpapi.com/ Instancions une classe SerpAPIWrapper et définissons l’outil avec la méthode from_function.

Dans le champ func, nous devons mettre un pointeur vers la méthode que nous voulons lancer à l’aide de cet outil, qui est la méthode run de SerpAPI. Et comme nous l’avons vu, nous donnons un nom et une description à l’outil. C’est plus facile à faire qu’à expliquer.

search = SerpAPIWrapper()tools = [    Tool.from_function(        func=search.run,        name="Recherche",        description="utile lorsque vous avez besoin de répondre à des questions sur les événements actuels"    ),]

Maintenant, nous pouvons fournir à notre agent la liste des outils créés, dans ce cas un seul.

agent = initialize_agent(    tools, llm, agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, verbose=True)agent.run(    "Qui est la petite amie de Bob Dylan ?")

Outils personnalisés

La méthode la plus claire, selon moi, pour créer un outil personnalisé est d’hériter de la classe BaseTool.

class CustomTool(BaseTool):    name = "custom_tool"    description = "utile lorsque vous avez besoin de répondre à des questions sur les articles VoAGI"    def _run(        self, query: str, run_manager: Optional[CallbackManagerForToolRun] = None    ) -> str:        """Utiliser l'outil."""        return "Je ne suis pas un expert en VoAGI, mais je sais que Marcello est plutôt bon ! :I)"    async def _arun(        self, query: str, run_manager: Optional[AsyncCallbackManagerForToolRun] = None    ) -> str:        """Utiliser l'outil de manière asynchrone."""        raise NotImplementedError("custom_search ne prend pas en charge le mode asynchrone")

Vous voyez, c’est l’implémentation d’un outil personnalisé, qui sera utilisé chaque fois que l’utilisateur pose une question concernant VoAGI. Cependant, la chaîne de caractères retournée ne sera pas exactement celle que j’ai configurée car elle sera traitée ultérieurement par le modèle de langage volumineux.

Si nous voulons renvoyer quelque chose directement, il suffit d’ajouter un champ “return_direct” de la manière suivante.

class CustomTool(BaseTool):    name = "custom_tool"    description = "utile lorsque vous avez besoin de répondre à des questions sur les articles VoAGI"    return_direct=True    def _run(        self, query: str, run_manager: Optional[CallbackManagerForToolRun] = None    ) -> str:        """Utiliser l'outil."""        return "Je ne suis pas un expert en VoAGI, mais je sais que Marcello est plutôt bon ! :I)"    async def _arun(        self, query: str, run_manager: Optional[AsyncCallbackManagerForToolRun] = None    ) -> str:        """Utiliser l'outil de manière asynchrone."""        raise NotImplementedError("custom_search ne prend pas en charge le mode asynchrone")

Même si nous n’utilisons pas la méthode _arun (qui est utile pour les appels asynchrones), nous devons quand même l’implémenter car BaseTool est une classe abstraite, et si nous n’implémentons pas toutes les méthodes abstraites, nous obtiendrons une erreur.

Exemple réel

Un jour, un ami à moi a dit : “Hé Marcello, puisque tu fais de l’IA et ce genre de trucs, pourquoi ne me ferais-tu pas un chatbot qui, lorsque cela est nécessaire, renvoie les heures de travail des médecins et prend des rendez-vous ?” La première chose à laquelle j’ai pensé pour résoudre ce problème est d’utiliser LangChain et de laisser le LLM interagir avec l’utilisateur, puis dès que le modèle comprend que l’utilisateur a demandé à voir les heures de travail, il renverra simplement un fichier CSV (ou un dataframe si vous préférez).

Donc, la même chose peut être utilisée pour ce cas d’utilisation également. Supposons que nous ayons un fichier CSV appelé “work_time.csv”

import pandas as pdclass WorkingHours(BaseTool):    name = "working_hours"    description = "utile lorsque vous avez besoin de répondre à des questions sur les heures de travail du personnel médical"    return_direct=True+    def _run(        self, query: str, run_manager: Optional[CallbackManagerForToolRun] = None    ) -> str:        """Utiliser l'outil."""        df = pd.read_csv("working_hours.csv") #peut-être que vous devez récupérer des données en temps réel à partir d'une base de données        return df    async def _arun(        self, query: str, run_manager: Optional[AsyncCallbackManagerForToolRun] = None    ) -> str:        """Utiliser l'outil de manière asynchrone."""        raise NotImplementedError("custom_search ne prend pas en charge le mode asynchrone")

Et voilà, un prototype de l’application que mon ami voulait est prêt en quelques lignes de code seulement ! Bien sûr, travaillez avec un bon développeur front-end pour lui donner meilleure allure !

Réflexion finale

LangChain est une bibliothèque récente qui nous permet d’utiliser la puissance des LLM dans différents contextes. Je trouve très utile de pouvoir utiliser un LLM pour comprendre le contexte, pour comprendre ce que l’utilisateur demande, puis exécuter ma propre fonction personnalisée pour résoudre réellement la tâche. Cela vous permettra d’écrire un code polyvalent. Pour ajouter une fonctionnalité à votre application, il vous suffit de écrire une fonction et indiquer au modèle d’utiliser cette fonction lorsqu’il estime que c’est nécessaire, et le tour est joué ! Si vous étiez intéressé par cet article, suivez-moi sur VoAGI !

💼 Linkedin ️| 🐦 Twitter | 💻 Site web

We will continue to update IPGirl; if you have any questions or suggestions, please contact us!

Share:

Was this article helpful?

93 out of 132 found this helpful

Discover more

Science des données

Réentraînez les modèles de ML et automatisez les prédictions par lots dans Amazon SageMaker Canvas en utilisant des ensembles de données mis à jour.

Vous pouvez maintenant ré-entraîner des modèles d'apprentissage automatique (ML) et automatiser des flux de travail d...

AI

Des chercheurs de l'Université de Tokyo présentent une nouvelle technique pour protéger les applications sensibles basées sur l'intelligence artificielle (IA) des attaquants.

Ces dernières années, les progrès rapides de l’intelligence artificielle (IA) ont conduit à son application gén...

AI

Dernières avancées dans le domaine de l'IA multimodale (ChatGPT + DALLE 3) + (Google BARD + Extensions) et bien d'autres encore...

L’IA multimodale est un domaine de l’intelligence artificielle (IA) qui combine différents types de donné...

AI

Donner aux utilisateurs plus qu'ils ne peuvent gérer

Est-ce que les fichiers d'intelligence artificielle de Microsoft créent des problèmes de sécurité pour les clients?

AI

Analyse de la complexité des séries temporelles à l'aide de l'entropie

Tout data scientist le sait la première étape pour résoudre un problème d'apprentissage automatique est l'exploratio...