LangChain Permettez aux LLMs d’interagir avec votre code
'LangChain Laissez les LLMs interagir avec votre code'
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 :
- Implémenter les mathématiques des articles sur l’apprentissage profond en code PyTorch efficace Perte contrastive SimCLR
- T5 Transformateurs de texte à texte (Partie Deux)
- Agents orientés document Un voyage avec les bases de données vectorielles, les LLMs, Langchain, FastAPI et Docker
- 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!
Was this article helpful?
93 out of 132 found this helpful
Related articles
- Booster votre Python Asyncio avec Aiomultiprocess Un guide complet
- Comment j’ai converti une base de données relationnelle classique en une base de données vectorielle pour stocker des embeddings
- Un chercheur de l’UCLA développe une bibliothèque Python appelée ClimateLearn pour accéder aux données climatiques de pointe et aux modèles d’apprentissage automatique de manière standardisée et simple.
- Ce modèle de langage protéique basé sur l’intelligence artificielle débloque la modélisation de séquences à usage général.
- Meilleurs outils de confidentialité DNS en 2023
- Rencontrez DiffComplete Une méthode AI intéressante qui peut compléter des objets 3D à partir de formes incomplètes.
- Des chercheurs de l’Université de Pékin présentent ChatLaw un modèle de langage juridique à grande échelle en open-source avec des bases de connaissances externes intégrées.