Fermer

octobre 10, 2023

Un guide complet de LangChain en Python —

Un guide complet de LangChain en Python —


LangChaîne est un bibliothèque Python polyvalente qui permet aux développeurs et aux chercheurs de créer, d’expérimenter et d’analyser des modèles et des agents linguistiques. Il offre un riche ensemble de fonctionnalités pour les passionnés de traitement du langage naturel (NLP), de la création de modèles personnalisés à la manipulation efficace de données textuelles. Dans ce guide complet, nous approfondirons les composants essentiels de LangChain et démontrerons comment exploiter sa puissance en Python.

Table des matières

Mise en place

Pour suivre cet article, créez un nouveau dossier et installez LangChain et OpenAI à l’aide de pip :

pip3 install langchain openai

Agents

Dans LangChain, un Agent est une entité capable de comprendre et de générer du texte. Ces agents peuvent être configurés avec des comportements et des sources de données spécifiques et formés pour effectuer diverses tâches liées au langage, ce qui en fait des outils polyvalents pour un large éventail d’applications.

Créer un agent LangChain

Les agents peuvent être configurés pour utiliser des « outils » pour collecter les données dont ils ont besoin et formuler une bonne réponse. Jetez un œil à l’exemple ci-dessous. Il utilise API Serp (une API de recherche sur Internet) pour rechercher sur Internet des informations pertinentes pour la question ou la saisie, et les utilise pour répondre. Il utilise également le llm-math outil pour effectuer des opérations mathématiques — par exemple, pour convertir des unités ou trouver la variation en pourcentage entre deux valeurs :

from langchain.agents import load_tools
from langchain.agents import initialize_agent
from langchain.agents import AgentType
from langchain.llms import OpenAI
import os

os.environ["OPENAI_API_KEY"] = "YOUR_OPENAI_API_KEY"
os.environ["SERPAPI_API_KEY"] = "YOUR_SERP_API_KEY" 

OpenAI.api_key = "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"
llm = OpenAI(model="gpt-3.5-turbo", temperature=0)
tools = load_tools(["serpapi", "llm-math"], llm=llm)
agent = initialize_agent(tools, llm, agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, verbose=True)
agent.run("How much energy did wind turbines produce worldwide in 2022?")

Comme vous pouvez le voir, après avoir effectué toutes les opérations de base d’importation et d’initialisation de notre LLM (llm = OpenAI(model="gpt-3.5-turbo", temperature=0)), le code charge les outils nécessaires au fonctionnement de notre agent avec tools = load_tools(["serpapi", "llm-math"], llm=llm). Il crée ensuite l’agent en utilisant le initialize_agent fonction, en lui donnant les outils spécifiés, et il lui donne le ZERO_SHOT_REACT_DESCRIPTION description, ce qui signifie qu’il n’aura aucun souvenir des questions précédentes.

Exemple de test d’agent 1

Testons cet agent avec l’entrée suivante :

"How much energy did wind turbines produce worldwide in 2022?"

Agent de test

Comme vous pouvez le constater, il utilise la logique suivante :

  • recherchez « production d’énergie éolienne dans le monde 2022 » à l’aide de l’API de recherche Internet Serp
  • analyser le meilleur résultat
  • obtenez tous les numéros pertinents
  • convertir 906 gigawatts en joules en utilisant le llm-math outil, puisque nous avons demandé de l’énergie, pas de la puissance

Exemple de test d’agent 2

Les agents LangChain ne se limitent pas à rechercher sur Internet. Nous pouvons connecter pratiquement n’importe quelle source de données (y compris la nôtre) à un agent LangChain et lui poser des questions sur les données. Essayons de créer un agent formé sur un ensemble de données CSV.

Téléchargez ceci Ensemble de données sur les films et émissions de télévision Netflix de SHIVAM BANSAL sur Kaggle et déplacez-le dans votre répertoire. Ajoutez maintenant ce code dans un nouveau fichier Python :

from langchain.llms import OpenAI
from langchain.chat_models import ChatOpenAI
from langchain.agents.agent_types import AgentType
from langchain.agents import create_csv_agent
import os

os.environ["OPENAI_API_KEY"] = "YOUR_OPENAI_API_KEY"

agent = create_csv_agent(
    OpenAI(temperature=0),
    "netflix_titles.csv",
    verbose=True,
    agent_type=AgentType.ZERO_SHOT_REACT_DESCRIPTION,
)

agent.run("In how many movies was Christian Bale casted")

Ce code appelle le create_csv_agent fonction et utilise le netflix_titles.csv base de données. L’image ci-dessous montre notre test.

Test de l'agent CSV

Comme indiqué ci-dessus, sa logique est de regarder dans le cast colonne pour toutes les occurrences de « Christian Bale ».

Nous pouvons également créer un agent Pandas Dataframe comme celui-ci :

from langchain.agents import create_pandas_dataframe_agent
from langchain.chat_models import ChatOpenAI
from langchain.agents.agent_types import AgentType
from langchain.llms import OpenAI
import pandas as pd
import os

os.environ["OPENAI_API_KEY"] = "YOUR_OPENAI_KEY"
df = pd.read_csv("netflix_titles.csv")

agent = create_pandas_dataframe_agent(OpenAI(temperature=0), df, verbose=True)

agent.run("In what year were the most comedy movies released?")

Si nous l’exécutons, nous verrons quelque chose comme les résultats présentés ci-dessous.

Test de la logique de l'agent Pandas Dataframe

Test de la réponse Pandas Dataframe

Ce ne sont que quelques exemples. Nous pouvons utiliser pratiquement n’importe quelle API ou ensemble de données avec LangChain.

Des modèles

Il existe trois types de modèles dans LangChain : les LLM, les modèles de discussion et les modèles d’intégration de texte. Explorons chaque type de modèle avec quelques exemples.

Modèle de langage

LangChain fournit un moyen d’utiliser des modèles de langage en Python pour produire une sortie de texte basée sur la saisie de texte. Ce n’est pas aussi complexe qu’un modèle de chat et il est mieux utilisé avec des tâches simples de langage d’entrée-sortie. Voici un exemple utilisant OpenAI :

from langchain.llms import OpenAI
import os
os.environ["OPENAI_API_KEY"] = "YOUR_OPENAI_API_KEY"

llm = OpenAI(model="gpt-3.5-turbo", temperature=0.9)
print(llm("Come up with a rap name for Matt Nikonorov"))

Comme vu ci-dessus, il utilise le gpt-3.5-turbo modèle pour générer une sortie pour l’entrée fournie (« Trouvez un nom de rap pour Matt Nikonorov »). Dans cet exemple, j’ai réglé la température sur 0.9 pour rendre le LLM vraiment créatif. Il a créé « MC MegaMatt ». Je donnerais à celui-là un solide 9/10.

Modèle de discussion

Faire en sorte que les modèles LLM proposent des noms de rap est amusant, mais si nous voulons des réponses et des conversations plus sophistiquées, nous devons intensifier notre jeu en utilisant un modèle de chat. En quoi les modèles de chat sont-ils techniquement différents des modèles de langage ? Eh bien, selon les mots du Documentation LangChain:

Les modèles de chat sont une variante des modèles de langage. Bien que les modèles de chat utilisent des modèles de langage sous le capot, l’interface qu’ils utilisent est un peu différente. Plutôt que d’utiliser une API « texte entrant, texte sortant », ils utilisent une interface où les « messages de discussion » sont les entrées et les sorties.

Voici un simple script de modèle de chat Python :

from langchain.llms import OpenAI
from langchain.chat_models import ChatOpenAI
from langchain.schema import (
    AIMessage,
    HumanMessage,
    SystemMessage
)
import os
os.environ["OPENAI_API_KEY"] = "YOUR_OPENAI_API_KEY"

chat = ChatOpenAI()
messages = [
    SystemMessage(content="You are a friendly, informal assistant"),
    HumanMessage(content="Convince me that Djokovic is better than Federer")
]
print(chat(messages))

Comme indiqué ci-dessus, le code envoie d’abord un SystemMessage et dit au chatbot d’être amical et informel, puis il envoie un HumanMessage dire au chatbot de nous convaincre que Djokovich est meilleur que Federer.

Si vous exécutez ce modèle de chatbot, vous verrez quelque chose comme le résultat ci-dessous.

Test du modèle de chatbot

Intégrations

Intégrations fournissent un moyen de transformer les mots et les nombres d’un bloc de texte en vecteurs qui peuvent ensuite être associés à d’autres mots ou nombres. Cela peut paraître abstrait, alors regardons un exemple :

from langchain.embeddings import OpenAIEmbeddings

embeddings_model = OpenAIEmbeddings()
embedded_query = embeddings_model.embed_query("Who created the world wide web?")
embedded_query[:5]

Cela renverra une liste de flottants : [0.022762885317206383, -0.01276398915797472, 0.004815981723368168, -0.009435392916202545, 0.010824492201209068]. Voici à quoi ressemble une intégration.

Un cas d’utilisation de l’intégration de modèles

Si nous voulons former un chatbot ou un LLM pour répondre à des questions liées à nos données ou à un échantillon de texte spécifique, nous devons utiliser des intégrations. Créons un simple fichier CSV (embs.csv) qui comporte une colonne « texte » contenant trois informations :

text
"Robert Wadlow was the tallest human ever"
"The Burj Khalifa is the tallest skyscraper"
"Roses are red"

Voici maintenant un script qui répondra à la question « Qui était l’humain le plus grand de tous les temps ? » et trouvez la bonne réponse dans le fichier CSV en utilisant les intégrations :

from langchain.embeddings import OpenAIEmbeddings
from openai.embeddings_utils import cosine_similarity
import os
import pandas

os.environ["OPENAI_API_KEY"] = "YOUR_OPENAI_KEY"
embeddings_model = OpenAIEmbeddings()

df = pandas.read_csv("embs.csv")


emb1 = embeddings_model.embed_query(df["text"][0])
emb2 = embeddings_model.embed_query(df["text"][1])
emb3 = embeddings_model.embed_query(df["text"][2])
emb_list = [emb1, emb2, emb3]
df["embedding"] = emb_list

embedded_question = embeddings_model.embed_query("Who was the tallest human ever?") 
df["similarity"] = df.embedding.apply(lambda x: cosine_similarity(x, embedded_question)) 
df.to_csv("embs.csv")
df2 = df.sort_values("similarity", ascending=False) 
print(df2["text"][0])

Si nous exécutons ce code, nous verrons qu’il affichera « Robert Wadlow était l’humain le plus grand de tous les temps ». Le code trouve la bonne réponse en obtenant l’intégration de chaque élément d’information et en trouvant celle la plus liée à l’intégration de la question « Qui était l’humain le plus grand de tous les temps ? Le pouvoir des intégrations !

Morceaux

Les modèles LangChain ne peuvent pas gérer des textes volumineux en même temps et les utiliser pour formuler des réponses. C’est là qu’interviennent les morceaux et le fractionnement du texte. Examinons deux façons simples de diviser nos données texte en morceaux avant de les introduire dans LangChain.

Diviser les morceaux par caractère

Pour éviter les coupures brusques en morceaux, nous pouvons diviser nos textes par paragraphes en les divisant à chaque occurrence d’une nouvelle ligne ou d’une double nouvelle ligne :

from langchain.text_splitter import RecursiveCharacterTextSplitter
text_splitter = RecursiveCharacterTextSplitter(separators=["\n\n", "\n"], chunk_size=2000, chunk_overlap=250)
texts = text_splitter.split_text(your_text)

Diviser des morceaux de manière récursive

Si nous voulons diviser strictement notre texte selon une certaine longueur de caractères, nous pouvons le faire en utilisant RecursiveCharacterTextSplitter:

from langchain.text_splitter import RecursiveCharacterTextSplitter
text_splitter = RecursiveCharacterTextSplitter(
    chunk_size=2000,
    chunk_overlap=250,
    length_function=len,
    add_start_index=True,
)
texts = text_splitter.create_documents([your_text])

Taille des morceaux et chevauchement

En regardant les exemples ci-dessus, vous vous êtes peut-être demandé ce que signifient exactement les paramètres de taille de bloc et de chevauchement, et quelles implications ils ont sur les performances. Cela peut s’expliquer par deux points :

  • La taille du morceau détermine le nombre de caractères qui seront dans chaque morceau. Plus la taille du bloc est grande, plus le bloc contient de données et plus il faudra de temps à LangChain pour les traiter et produire une sortie, et vice versa.
  • Le chevauchement des morceaux est ce qui partage les informations entre les morceaux afin qu’ils partagent un certain contexte. Plus le chevauchement des fragments est élevé, plus nos fragments seront redondants, plus le chevauchement des fragments est faible et moins le contexte sera partagé entre les fragments. Généralement, un bon chevauchement de fragments se situe entre 10 % et 20 % de la taille du fragment, bien que le chevauchement idéal varie selon les types de texte et les cas d’utilisation.

Chaînes

Les chaînes sont essentiellement de multiples fonctionnalités LLM liées entre elles pour effectuer des tâches plus complexes qui ne pourraient pas être effectuées autrement avec un simple LLM. input --> output mode. Regardons un exemple sympa :

from langchain.llms import OpenAI
from langchain.prompts import PromptTemplate
from langchain.chains import LLMChain
import os
os.environ["OPENAI_API_KEY"] = "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"

llm = OpenAI(temperature=0.9)
prompt = PromptTemplate(
    input_variables=["media", "topic"],
    template="What is a good title for a {media} about {topic}",
)
chain = LLMChain(llm=llm, prompt=prompt)
print(chain.run({
    'media': "horror movie",
    'topic': "math"
}))

Ce code prend deux variables dans son invite et formule une réponse créative (temperature=0.9). Dans cet exemple, nous lui avons demandé de trouver un bon titre pour un film d’horreur sur les mathématiques. Le résultat après l’exécution de ce code était « The Calculating Curse », mais cela ne montre pas vraiment toute la puissance des chaînes.

Jetons un coup d’œil à un exemple plus pratique :

from langchain.chat_models import ChatOpenAI
from langchain.prompts import PromptTemplate
from typing import Optional

from langchain.chains.openai_functions import (
    create_openai_fn_chain,
    create_structured_output_chain,
)
import os

os.environ["OPENAI_API_KEY"] = "YOUR_KEY"

llm = ChatOpenAI(model="gpt-3.5-turbo", temperature=0.1)
template = """Use the given format to extract information from the following input: {input}. Make sure to answer in the correct format"""

prompt = PromptTemplate(template=template, input_variables=["input"])

json_schema = {
    "type": "object",
    "properties": {
        "name": {"title": "Name", "description": "The artist's name", "type": "string"},
        "genre": {"title": "Genre", "description": "The artist's music genre", "type": "string"},
        "debut": {"title": "Debut", "description": "The artist's debut album", "type": "string"},
        "debut_year": {"title": "Debut_year", "description": "Year of artist's debut album", "type": "integer"}
    },
    "required": ["name", "genre", "debut", "debut_year"],
}

chain = create_structured_output_chain(json_schema, llm, prompt, verbose=False)
f = open("Nas.txt", "r")
artist_info = str(f.read())
print(chain.run(artist_info))

Ce code peut sembler déroutant, alors parcourons-le.

Ce code se lit une courte biographie de Nas (artiste hip-hop) et extrait les valeurs suivantes du texte et les formate dans un objet JSON :

  • le nom de l’artiste
  • le genre musical de l’artiste
  • le premier album de l’artiste
  • l’année du premier album de l’artiste

Dans l’invite, nous spécifions également « Assurez-vous de répondre dans le bon format », afin que nous obtenions toujours la sortie au format JSON. Voici le résultat de ce code :

{'name': 'Nas', 'genre': 'Hip Hop', 'debut': 'Illmatic', 'debut_year': 1994}

En fournissant un schéma JSON au create_structured_output_chain fonction, nous avons fait en sorte que la chaîne mette sa sortie au format JSON.

Aller au-delà d’OpenAI

Même si je continue d’utiliser les modèles OpenAI comme exemples des différentes fonctionnalités de LangChain, cela ne se limite pas aux modèles OpenAI. Nous pouvons utiliser LangChain avec une multitude d’autres LLM et services d’IA. (Voici un liste complète des LLM intégrables LangChain.)

Par exemple, nous pouvons utiliser Adhérer avec LangChain. Voici la documentation pour l’intégration LangChain Coheremais juste pour donner un exemple pratique, après avoir installé Cohere en utilisant pip3 install cohere nous pouvons faire un simple question --> answer codez en utilisant LangChain et Cohere comme ceci :

from langchain.llms import Cohere
from langchain.prompts import PromptTemplate
from langchain.chains import LLMChain

template = """Question: {question}

Answer: Let's think step by step."""

prompt = PromptTemplate(template=template, input_variables=["question"])
llm = Cohere(cohere_api_key="YOUR_COHERE_KEY")
llm_chain = LLMChain(prompt=prompt, llm=llm)

question = "When was Novak Djokovic born?"

print(llm_chain.run(question))

Le code ci-dessus produit le résultat suivant :

The answer is Novak Djokovic was born on May 22, 1987.

Novak Djokovic is a Serbian tennis player.

Conclusion

Dans ce guide, vous avez vu les différents aspects et fonctionnalités de LangChain. Fort de ces connaissances, vous êtes désormais équipé pour tirer parti des capacités de LangChain pour vos projets de PNL, que vous soyez chercheur, développeur ou amateur.

Vous pouvez trouver un dépôt avec toutes les images et le Nas.txt fichier de cet article sur GitHub.

Bon codage et expérimentation avec LangChain en Python !






Source link

octobre 10, 2023