curso
Construir agentes LangChain para automatizar tareas en Python
Las 90.000 estrellas GitHub de LangChain son toda la credibilidad que necesita: ahora mismo, es el marco más popular para crear aplicaciones basadas en LLM. Su completo conjunto de herramientas y componentes te permite construir soluciones de IA de principio a fin utilizando casi cualquier LLM.
Quizá el núcleo de las capacidades de LangChain sean los agentes LangChain. Son herramientas autónomas o semiautónomas que pueden realizar tareas, tomar decisiones e interactuar con otras herramientas y API. Representan un importante salto adelante en la automatización de flujos de trabajo complejos con los LLM.
En este artículo, aprenderás a construir tus propios agentes LangChain que puedan realizar tareas que no son estrictamente posibles con las aplicaciones de chat actuales, como ChatGPT.
Configurar
Antes de entrar en materia, vamos a configurar nuestro entorno para el tutorial.
En primer lugar, crear un nuevo entorno Conda:
$ conda create -n langchain python=3.9 -y
$ conda activate langchain
Instalar los paquetes de LangChain y algunas otras bibliotecas necesarias:
$ pip install langchain langchain_openai langchain_community langgraph ipykernel python-dotenv
Añadir el entorno Conda recién creado a Jupyter como núcleo:
$ ipython kernel install --user --name=langchain
Creación de un archivo .env para almacenar secretos como las claves API:
$ touch .env
$ vim .env # Paste your OPENAI key
OPENAI_API_KEY='YOUR_KEY_HERE'
Recuperar tu clave de API de OpenAI del archivo .env :
import os
from dotenv import load_dotenv
load_dotenv()
api_key = os.getenv('OPENAI_API_KEY')
Prueba que todo funciona correctamente consultando GPT-3.5 (el modelo de lenguaje por defecto) de OpenAI:
from langchain_openai import OpenAI
llm = OpenAI(openai_api_key=api_key)
question = "Is Messi the best footballer of all time?"
output = llm.invoke(question)
print(output[:75])
There is no definitive answer to this question, as it is subjective and de
Ahora estamos listos para empezar.
¿Qué son los Agentes LangChain?
Dediquemos algún tiempo a pensar en el marco del agente. Concretamente, consideraremos en qué se diferencia del paradigma tradicional de la cadena y cuáles son los componentes de un agente. Comprender por qué tenemos que elegir una nueva forma de crear aplicaciones nos preparará para escribir el código.
Cadenas vs. Agentes
El rasgo que define a los agentes es su capacidad para elegir el mejor orden de acciones para resolver un problema dado un conjunto de herramientas.
Por ejemplo, supongamos que tenemos lo siguiente:
- Una API meteorológica
- Modelo ML para recomendaciones de ropa
- API de Strava para rutas en bicicleta
- Base de datos de preferencias del usuario
- Modelo de reconocimiento de imágenes
- Modelo lingüístico (generación de texto)
La resolución de problemas tradicional implicaría utilizar una cadena de herramientas seleccionadas de la lista:
Cadena 1: Recomendador de ropa basado en el tiempo
- Llama a la API meteorológica
- Introducir datos meteorológicos en el modelo de ropa ML
- Generar recomendaciones de ropa
- Presentar los resultados al usuario
Cadena 2: Sugeridor de rutas ciclistas basado en el tiempo
- Llama a la API meteorológica
- Llama a la API de Strava para rutas populares
- Filtrar rutas en función de las condiciones meteorológicas
- Presentar rutas adecuadas al usuario
Cadena 3: Analizador fotográfico de conjuntos
- Recibir la foto del atuendo del usuario
- Utilizar un modelo de reconocimiento de imágenes para identificar prendas de vestir
- Comparar con la base de datos de preferencias del usuario
- Generar respuestas utilizando el modelo de generación de texto
- Presentar el análisis al usuario
Cada cadena resuelve un problema concreto utilizando una secuencia predeterminada de pasos y un subconjunto de las herramientas disponibles. No pueden adaptarse más allá de su ámbito definido. Además, requieren tres ramas distintas de desarrollo, lo que es ineficaz en términos de tiempo y recursos.
Ahora, imagina un sistema agentico con acceso a todas estas herramientas. Sería capaz de hacerlo:
- Comprender la consulta o el problema del usuario (a través del lenguaje natural con un modelo lingüístico)
- Evalúa qué herramientas son relevantes para el problema (razonamiento)
- Crea dinámicamente un flujo de trabajo utilizando las herramientas más adecuadas
- Ejecuta el flujo de trabajo, haciendo ajustes en tiempo real si es necesario (actuando)
- Evalúa el resultado y aprende de las interacciones anteriores
Por ejemplo, si un usuario pregunta: "¿Qué ropa me pongo hoy para ir en bici?", el agente podría comprobar la API meteorológica, analizar las rutas ciclistas adecuadas a través de Strava, recomendar la ropa adecuada, teniendo en cuenta las preferencias anteriores del usuario, y generar una respuesta personalizada.
El agente puede:
- Manejar una amplia variedad de problemas utilizando el mismo conjunto de herramientas
- Crea flujos de trabajo personalizados para cada situación única
- Adaptar su enfoque en función del contexto específico y de las necesidades de los usuarios
- Aprende de las interacciones para mejorar el rendimiento futuro
La capacidad de LangChain para transformar los modelos lingüísticos -que, por sí mismos, sólo producen texto- en motores de razonamiento capaces de utilizar los recursos de que disponen para emprender las acciones adecuadas es una de sus principales aplicaciones. En resumen, LangChain permite el desarrollo de agentes autónomos fuertes que interactúan con el mundo exterior.
Componentes clave
Un agente LangChain está formado por varios componentes, como modelos de chat, plantillas de avisos, herramientas externas y otros constructos relacionados. Para construir agentes de éxito, tenemos que revisar cada componente y comprender su uso.
Lenguaje y modelos de chat
Hay muchas partes móviles implicadas en la creación de un agente LangChain. La primera y más obvia es un modelo lingüístico.
from langchain_openai import OpenAI
llm = OpenAI(api_key=api_key, model="gpt-3.5-turbo-instruct")
question = "What is special about the number 73?"
output = llm.invoke(question)
print(output[:100])
1. Prime Number: 73 is a prime number, which means it is only divisible by 1 and itself. This make
Los modelos lingüísticos, como el GPT-3.5 Turbo de OpenAI, toman y generan cadenas. Suelen ser más antiguos y funcionan mejor para responder a las consultas individuales de los usuarios.
Los modelos más nuevos y potentes suelen ser los modelos de chat, que pueden tomar una secuencia de mensajes como entrada y devolver mensajes de chat como salida (en lugar de utilizar texto plano):
from langchain_openai import ChatOpenAI
from langchain_core.messages import HumanMessage, AIMessageChunk, SystemMessage
# Initialize the model
chat_model = ChatOpenAI(api_key=api_key, model='gpt-4o-mini')
# Write the messages
messages = [SystemMessage(content='You are a grumpy pirate.'),
HumanMessage(content="What's up?")]
output = chat_model.invoke(messages)
Dicho de otro modo, los modelos de chat nos permiten mantener conversaciones en lenguaje natural. En el ejemplo anterior, estamos inicializando la GPT-4o-mini con un mensaje del sistema seguido de una consulta del usuario. Observa el uso de las clases SystemMessage
y HumanMessage
.
El output
es un objeto mensaje, que es el comportamiento esperado de los modelos de chat:
type(output)
langchain_core.messages.ai.AIMessage
print(output.content)
Arrr, not much but the sound of waves and the creakin' of me ship. What do ye want? Make it quick, I've got treasure to hunt and rum to drink!
Además, devuelven otros metadatos útiles accesibles con la anotación por puntos:
output.dict()
{'content': "Arrr, not much but the sound of waves and the creakin' of me ship. What do ye want? Make it quick, I've got treasure to hunt and rum to drink!",
'additional_kwargs': {},
'response_metadata': {'token_usage': {'completion_tokens': 38,
'prompt_tokens': 21,
'total_tokens': 59},
'model_name': 'gpt-4o-mini-2024-07-18',
'system_fingerprint': 'fp_48196bc67a',
'finish_reason': 'stop',
'logprobs': None},
'type': 'ai',
'name': None,
'id': 'run-fde829bf-8f5f-4926-a1ed-ab53609ce03a-0',
'example': False,
'tool_calls': [],
'invalid_tool_calls': [],
'usage_metadata': {'input_tokens': 21,
'output_tokens': 38,
'total_tokens': 59}}
La mayoría de los agentes utilizan modelos de chat por su base de conocimientos actualizada y sus capacidades conversacionales. Sin embargo, para los agentes sencillos sin requisitos de memoria, bastará con modelos lingüísticos como el GPT-3.5.
Plantillas de instrucciones
La forma más eficaz de consultar modelos de lenguaje o chat es utilizar plantillas de consulta. Te permiten estructurar tus consultas de forma coherente e insertar variables dinámicamente, haciendo que tus interacciones con el modelo sean más flexibles y reutilizables.
En LangChain, hay muchos tipos de plantillas de avisos, siendo la más básica la clasePromptTemplate
. Puede utilizarse con modelos de lenguaje (texto sin formato):
from langchain_core.prompts import PromptTemplate
query_template = "Tell me about {book_name} by {author}."
prompt = PromptTemplate(input_variables=["book_name", "author"], template=query_template)
prompt.invoke({"book_name": "Song of Ice and Fire", "author": "GRRM"})
StringPromptValue(text='Tell me about Song of Ice and Fire by GRRM.')
La clase requiere que crees una cadena con marcadores de posición para las variables que quieras sustituir utilizando la notación de corchetes. A continuación, tienes que pasar esta cadena de plantilla a la clase PromptTemplate
junto con los nombres de las variables, construyendo así tu prompt
.
Si llamas a .invoke()
con valores para las variables mostrará cómo se pasará tu consulta a un modelo.
Para pasar esta plantilla de instrucciones a un modelo de lenguaje, debemos encadenarla mediante el operador de tubería:
from langchain_openai import OpenAI
llm = OpenAI(api_key=api_key)
# Create a chain
chain = prompt | llm
# Invoke the chain
output = chain.invoke({"book_name": "Deathly Hallows", "author": "J.K. Rowling"})
print(output[:100])
Deathly Hallows is the seventh and final book in the popular Harry Potter series, written by J.K. R
El operador tubería (|
) forma parte del Lenguaje de Expresión LangChain (LCEL)diseñado para encadenar múltiples componentes y herramientas LangChain.
type(chain)
langchain_core.runnables.base.RunnableSequence
Cuando utilizas el operador de tubería en objetos LangChain, creas una instancia de la claseRunnableSequence
. Una secuencia ejecutable representa una cadena de objetos que admiten el método .invoke()
, como plantillas de avisos y modelos de lenguaje/chat.
Veamos ahora otra clase de plantilla para modelos de chat:
from langchain_core.prompts import ChatPromptTemplate
Hemos mencionado que los modelos de chat requieren una secuencia de mensajes como entrada. La entrada inicial suele ser un aviso del sistema que indica al modelo de chat cómo debe comportarse. Así, utilizando la clase ChatPromptTemplate
, podemos crear fácilmente modelos de chat con diferentes personalidades:
chat_model = ChatOpenAI(api_key=api_key, model="gpt-4o-mini")
template = ChatPromptTemplate([
('system', 'You are a helpful AI bot. Your specialty is {specialty}.'),
('human', 'Explain the concept of {concept} based on your expertise.')
])
La clase requiere como entrada una lista de mensajes basados en roles. Cada miembro de la lista debe ser una tupla (rol, mensaje) con los marcadores de posición variables definidos cuando sea necesario.
Cuando lo tengamos listo, podemos utilizar el mismo operador de tuberías para crear modelos de chat con diferentes comportamientos:
specialties = ["psychology", "economics", "politics"]
concept = "time"
# Call the model with different personalities
for s in specialties:
chain = template | chat_model
output = chain.invoke({"specialty": s, "concept": concept})
print(output.content[:100], end="\n" + "-" * 25 + '\n')
Time is a complex and multifaceted concept that has been explored from various perspectives, includi
-------------------------
In economics, the concept of time is multifaceted and plays a crucial role in various theories and m
-------------------------
While my primary focus is on politics, I can provide a brief overview of the concept of time as it m
-------------------------
Herramientas
En una sección anterior, mencionamos que los agentes pueden elegir una combinación de herramientas a su disposición para resolver un problema concreto, con los LLM como motores de razonamiento bajo el capó.
LangChain ofrece integraciones con docenas de API y servicios populares para que los agentes puedan interactuar con el resto del mundo. La mayoría de ellos están disponibles en el paquete langchain_community
, mientras que algunos están dentro de langchain_core
.
Por ejemplo, así es como puedes utilizar la herramienta ArXiv para recuperar resúmenes de artículos sobre diversos temas:
!pip install -Uq arxiv # Install arXiv Python SDK
from langchain_community.tools import ArxivQueryRun
tool = ArxivQueryRun()
print(tool.invoke('Photosynthesis')[:250])
Published: 2019-08-28
Title: Photosynthesis on Exoplanets and Exomoons from Reflected Light
Authors: Manasvi Lingam, Abraham Loeb
Summary: Photosynthesis offers a convenient means of sustaining biospheres. We
quantify the constraints for photosynthes
Hay una forma alternativa de cargar herramientas en lugar de importarlas por su nombre de clase:
from langchain_community.agent_toolkits.load_tools import load_tools
tools = load_tools(["arxiv", "dalle-image-generator"])
Arriba, estamos cargando las herramientas generadoras de imágenes arXiv y Dall-E al mismo tiempo utilizando la funciónload_tools()
. Las herramientas cargadas con esta función tienen la misma sintaxis de uso:
# Call arXiv
print(tools[0].invoke("Kaggle")[:150])
Published: 2020-06-06
Title: StackOverflow vs Kaggle: A Study of Developer Discussions About Data Science
Authors: David Hin
Summary: Software develop
# Generate an image with DallE
output_image_url = tools[1].invoke("A magnificent chain in a cartoon.")
output_image_url
'https://oaidalleapiprodscus.blob.core.windows.net/...'
La función load_tools
requiere que conozcas los nombres de cadena de las clases de herramientas, como el ejemplo de ArxivQueryRun
frente a 'arxiv
'. Puedes comprobar rápidamente el nombre en cadena de cualquier herramienta ejecutando la función get_all_tool_names
:
from langchain_community.agent_toolkits.load_tools import get_all_tool_names
get_all_tool_names()[:10]
['sleep',
'wolfram-alpha',
'google-search',
'google-search-results-json',
'searx-search-results-json',
'bing-search',
'metaphor-search',
'ddg-search',
'google-lens',
'google-serper']
Ten en cuenta que load_tools()
es sólo una función abreviada. Al construir agentes, se recomienda cargar las herramientas utilizando su constructor de clase, que te permite configurarlas en función de su comportamiento específico.
Flujo de trabajo paso a paso de cómo construir agentes LangChain
Por último, en esta sección veremos cómo crear agentes LangChain paso a paso utilizando los conocimientos que hemos adquirido en las secciones anteriores.
En los próximos ejemplos, construiremos un agente capaz de explicar cualquier tema a través de tres medios: texto, imagen o vídeo. Más concretamente, en función de la pregunta formulada, el agente decidirá si explica el tema y en qué formato.
Empecemos. Recuerda consultar cómo configurar el entorno, que se explica al principio del artículo.
1. Definir herramientas
El primer paso después de configurar nuestro entorno es definir las herramientas que daremos a nuestro agente. Vamos a importarlos:
from langchain_community.tools import WikipediaQueryRun # pip install wikipedia
from langchain_community.utilities import WikipediaAPIWrapper
from langchain_community.tools import YouTubeSearchTool # pip install youtube_search
from langchain_community.tools.openai_dalle_image_generation import (
OpenAIDALLEImageGenerationTool
)
from langchain_community.utilities.dalle_image_generator import DallEAPIWrapper
Importamos cinco clases:
WikipediaAPIWrapper
: para configurar cómo acceder a la API de WikipediaWikipediaQueryRun
: para generar resúmenes de páginas de WikipediaYouTubeSearchTool
: para buscar vídeos de YouTube sobre temasDallEAPIWrapper
: para configurar cómo acceder al punto final DallE de OpenAIOpenAIDALLEImageGenerationTool
: para generar imágenes mediante avisos
Cuando un usuario consulta a nuestro agente, éste decidirá si explica el tema utilizando un artículo de Wikipedia en formato de texto, o creando una imagen utilizando Dall-E para la comprensión visual, o sugiriendo vídeos de YouTube para una comprensión más profunda.
Vamos a inicializarlas, empezando por la herramienta Wikipedia:
wiki_api_wrapper = WikipediaAPIWrapper(top_k_results=1, doc_content_chars_max=250)
wikipedia = WikipediaQueryRun(description="A tool to explain things in text format. Use this tool if you think the user’s asked concept is best explained through text.", api_wrapper=wiki_api_wrapper)
print(wikipedia.invoke("Mobius strip"))
Page: Möbius strip
Summary: In mathematics, a Möbius strip, Möbius band, or Möbius loop is a surface that can be formed by attaching the ends of a strip of paper together with a half-twist. As a mathematical object, it was discovered by Johann Benedi
Generador de imágenes DallE:
dalle_api_wrapper = DallEAPIWrapper(model="dall-e-3", size="1792x1024")
dalle = OpenAIDALLEImageGenerationTool(
api_wrapper=dalle_api_wrapper, description="A tool to generate images. Use this tool if you think the user’s asked concept is best explained through an image."
)
output = dalle.invoke("A mountain bike illustration.")
print(output)
Herramienta de búsqueda de YouTube:
youtube = YouTubeSearchTool(
description="A tool to search YouTube videos. Use this tool if you think the user’s asked concept can be best explained by watching a video."
)
youtube.run("Oiling a bike's chain")
"['https://www.youtube.com/watch?v=X1Vze17bhgk&pp=ygUVT2lsaW5nIGEgYmlrZSdzIGNoYWlu', 'https://www.youtube.com/watch?v=T6xyn1FGHiU&pp=ygUVT2lsaW5nIGEgYmlrZSdzIGNoYWlu']"
Ten especial cuidado con las descripciones de las herramientas. El agente decidirá qué herramienta utilizar en función de la descripción que le proporciones.
Ahora, pondremos las herramientas en una lista:
tools = [wikipedia, dalle, youtube]
Ya podemos vincular este conjunto de herramientas a un modelo de chat sin crear un agente:
chat_model = ChatOpenAI(api_key=api_key)
model_with_tools = chat_model.bind_tools(tools)
Probemos a llamar al modelo con un mensaje sencillo:
response = model_with_tools.invoke([HumanMessage("What's up?!")])
print(f"Text response: {response.content}")
print(f"Tools used in the response: {response.tool_calls}")
Text response: Hello! How can I assist you today?
Tools used in the response: []
La salida muestra que no se utilizó ninguna de las herramientas de vinculación al generar una respuesta. Ahora, hagamos una pregunta concreta que obligue al modelo a mirar más allá de sus datos de entrenamiento:
response = model_with_tools.invoke([
HumanMessage("Can you generate an image of a mountain bike?")
])
print(f"Text response: {response.content}")
print(f"Tools used in the response: {response.tool_calls}")
Text response:
Tools used in the response: [{'name': 'openai_dalle', 'args': {'query': 'mountain bike'}, 'id': 'call_92GBfmsYtPi9TpGuIOFB1pG8', 'type': 'tool_call'}]
Podemos ver que no hay salida de texto, pero se menciona el DallE de OpenAI. La herramienta aún no se ha llamado; el modelo simplemente sugiere que la utilicemos. Para llamarlo realmente, para pasar a la acción, tenemos que crear un agente.
2. Crear un agente simple
Tras definir el modelo y las herramientas, creamos el agente. LangChain ofrece una interfaz de funciones de alto nivel create_react_agent()
desde su paquetelanggraph
para crear rápidamente agentes ReAct (razonar y actuar):
from langgraph.prebuilt import create_react_agent
system_prompt = SystemMessage("You are a helpful bot named Chandler.")
agent = create_react_agent(chat_model, tools, state_modifier=system_prompt)
Al inicializar el agente con un modelo de chat y una lista de herramientas, le pasamos una indicación del sistema para decirle al modelo cómo comportarse en general. Ahora está listo para aceptar consultas:
from pprint import pprint
response = agent.invoke({"messages": HumanMessage("What's up?")})
pprint(response["messages"])
[HumanMessage(content="What's up?", id='133b9380-cfe1-495a-98f7-b835c874bd57'),
AIMessage(content='Hello! How can I assist you today?', response_metadata={'token_usage': {'completion_tokens': 10, 'prompt_tokens': 112, 'total_tokens': 122}, 'model_name': 'gpt-3.5-turbo-0125', 'system_fingerprint': None, 'finish_reason': 'stop', 'logprobs': None}, id='run-0a920c15-39b4-4857-ab51-6ea905575dba-0', usage_metadata={'input_tokens': 112, 'output_tokens': 10, 'total_tokens': 122})]
Hemos recibido una respuesta probable, que es una simple respuesta de texto sin llamadas de herramienta. Ahora, vamos a preguntar algo más al grano:
response = agent.invoke({"messages": [
HumanMessage('Explain how photosynthesis works.')
]})
print(len(response['messages']))
4
Esta vez, hay cuatro mensajes. Veamos los nombres de las clases de mensajes y su contenido:
for message in response['messages']:
print(
f"{message.__class__.__name__}: {message.content}"
) # Print message class name and its content
print("-" * 20, end="\n")
HumanMessage: Explain how photosynthesis works.
--------------------
AIMessage:
--------------------
ToolMessage: Page: Photosynthesis
Summary: Photosynthesis ( FOH-tə-SINTH-ə-sis) is a system of biological processes by which photosynthetic organisms, such as most plants, algae, and cyanobacteria, convert light energy, typically from sunlight, into the chemical
--------------------
AIMessage: Photosynthesis is a biological process where photosynthetic organisms like plants, algae, and cyanobacteria convert light energy, usually from sunlight, into chemical energy. This process involves capturing light energy through pigments like chlorophyll in plant cells and using it to convert carbon dioxide and water into glucose and oxygen. Glucose serves as a source of energy for the plant, while oxygen is released into the atmosphere as a byproduct. Photosynthesis is crucial for the survival of plants and the balance of oxygen and carbon dioxide in the atmosphere.
--------------------
¡Allá vamos! El tercer mensaje es de una llamada a una herramienta, que es un resumen de una página de Wikipedia sobre la fotosíntesis. El último mensaje es del modelo de chat, que utiliza el contenido de la llamada a la herramienta al construir su respuesta.
Vamos a crear rápidamente una función para modular los últimos pasos que hemos dado:
def execute(agent, query):
response = agent.invoke({'messages': [HumanMessage(query)]})
for message in response['messages']:
print(
f"{message.__class__.__name__}: {message.content}"
) # Print message class name and its content
print("-" * 20, end="\n")
return response
3. Perfeccionar el aviso del sistema
Ahora, vamos a actualizar el aviso de nuestro sistema con instrucciones detalladas sobre cómo debe comportarse el agente:
system_prompt = SystemMessage(
"""
You are a helpful bot named Chandler. Your task is to explain topics
asked by the user via three mediums: text, image or video.
If the asked topic is best explained in text format, use the Wikipedia tool.
If the topic is best explained by showing a picture of it, generate an image
of the topic using Dall-E image generator and print the image URL.
Finally, if video is the best medium to explain the topic, conduct a YouTube search on it
and return found video links.
"""
)
Volvamos a crear nuestro agente con el nuevo indicador del sistema:
agent = create_react_agent(chat_model, tools, state_modifier=system_prompt)
response = execute(agent, query='Explain the Fourier Series visually.')
HumanMessage: Explain the Fourier Series visually.
--------------------
AIMessage:
--------------------
ToolMessage: https://oaidalleapiprodscus.blob.core.windows.net/private/org-qRwX4bsgcnaYHHwbxFBdZxUy/user-LOXQPflMtXxamV72hac9oS2O/img-iY3gXXBzWapRWKdmkd9cXEIN.png?st=2024-08-09T18%3A36%3A46Z&se=2024-08-09T20%3A36%3A46Z&sp=r&sv=2024-08-04&sr=b&rscd=inline&rsct=image/png&skoid=d505667d-d6c1-4a0a-bac7-5c84a87759f8&sktid=a48cca56-e6da-484e-a814-9c849652bcb3&skt=2024-08-09T17%3A56%3A46Z&ske=2024-08-10T17%3A56%3A46Z&sks=b&skv=2024-08-04&sig=Ly8F4jvakFeEtpZ/6jMliLq%2BG3Xs%2Bz1AmX1sL06%2BQ3U%3D
--------------------
AIMessage: Here is a visual representation of the Fourier Series:
![Fourier Series](https://oaidalleapiprodscus.blob.core.windows.net/private/org-qRwX4bsgcnaYHHwbxFBdZxUy/user-LOXQPflMtXxamV72hac9oS2O/img-iY3gXXBzWapRWKdmkd9cXEIN.png)
The Fourier Series is a way to represent a function as the sum of simple sine waves. It is used in many areas of mathematics and physics to analyze and understand periodic phenomena.
--------------------
Impresionante, basándose en nuestro mensaje (que era muy instructivo :), el agente eligió la herramienta correcta para el trabajo. Aquí tienes la imagen generada:
4. Añadir memoria a los agentes
Ahora mismo, nuestro agente es apátrida, lo que significa que no recuerda interacciones anteriores:
response = execute(agent, query="What did I ask you in the previous query?")
HumanMessage: What did I ask you in the previous query?
--------------------
AIMessage: I'm sorry, I cannot remember the previous query as I don't have access to the conversation history. How can I assist you today?
--------------------
La forma más sencilla de añadir el historial de mensajes de chat a los agentes es utilizando langgraph
's SqliteSaver
clase:
from langgraph.checkpoint.sqlite import SqliteSaver
memory = SqliteSaver.from_conn_string(':agent_history:')
agent = create_react_agent(chat_model, tools, checkpointer=memory, state_modifier=system_prompt)
Inicializamos la memoria utilizando el método .from_conn_string()
de la claseSqliteSaver
, que crea un archivo de base de datos. A continuación, pasamos lamemoria al parámetro checkpointer
de la funcióncreate_react_agent()
.
Ahora tenemos que crear un diccionario de configuración:
config = {'configurable': {'thread_id': 'a1b2c3'}}
El diccionario define un ID de hilo para distinguir una conversación de otra y se pasa al método.invoke()
de nuestro agente. Así pues, actualicemos nuestra función execute()
para incluir este comportamiento:
def execute(agent, query, thread_id="a1b2c3"):
config = {"configurable": {"thread_id": thread_id}}
response = agent.invoke({'messages': [HumanMessage(query)]}, config=config)
for message in response["messages"]:
print(
f"{message.__class__.__name__}: {message.content}"
) # Print message class name and its content
print("-" * 20, end="\n")
return response
Let’s test it again:
response = execute(
agent, query="Explain how to oil a bike's chain using a YouTube video", thread_id="123"
)
HumanMessage: Explain how to oil a bike's chain using a YouTube video
--------------------
AIMessage:
--------------------
ToolMessage: ['https://www.youtube.com/watch?v=X1Vze17bhgk&pp=ygUXaG93IHRvIG9pbCBhIGJpa2UgY2hhaW4%3D', 'https://www.youtube.com/watch?v=ubKCHtZ20-0&pp=ygUXaG93IHRvIG9pbCBhIGJpa2UgY2hhaW4%3D']
--------------------
AIMessage: I found a couple of YouTube videos that explain how to oil a bike chain:
1. [Video 1: How to oil a bike chain](https://www.youtube.com/watch?v=X1Vze17bhgk&pp=ygUXaG93IHRvIG9pbCBhIGJpa2UgY2hhaW4%3D)
2. [Video 2: Step-by-step guide on oiling a bike chain](https://www.youtube.com/watch?v=ubKCHtZ20-0&pp=ygUXaG93IHRvIG9pbCBhIGJpa2UgY2hhaW4%3D)
You can watch these videos to learn how to oil your bike's chain effectively.
--------------------
Ahora, preguntemos al agente sobre consultas anteriores:
response = execute(agent, query='What have I asked you so far?', thread_id='123')
print(response)
{'messages': [HumanMessage(content="Explain how to oil a bike's chain using a YouTube video", id='8254142b-fb77-4958-8ad9-0a0283c6611a'), ...
]
Como era de esperar, ¡el agente devuelve los mensajes anteriores! Ahora, sólo necesitamos una interfaz de chat como la de ChatGPT y ya tenemos un chatbot personalizado.
Tendencias y desarrollos futuros
A lo largo del artículo, hemos vislumbrado hacia dónde se dirige LangChain en términos de agentes. Hasta hace muy poco, LangChain había utilizado principalmente el AgenteEjecutor clase pero poco a poco está siendo sustituida por los agentes delanggraph
.
Los agentes LangChain puros están bien para empezar, pero requieren más líneas de código para construir el mismo agente que en LangGraph. Además, a partir de cierto punto, el marco AgentExecutor
no proporcionará la flexibilidad que tiene LangGraph para construir complejos agentes multiherramienta.
Por eso ahora es un buen momento para subirse a la ola y empezar directamente con LangGraph.
Recomendamos encarecidamente empezar utilizar también LangSmith que se ha convertido en una parte esencial del ecosistema LangChain para crear aplicaciones LLM de nivel de producción. He aquí algunas de sus principales ventajas:
- Depurando: LangSmith proporciona trazas detalladas de la ejecución de tu agente, lo que facilita la identificación y solución de problemas.
- Optimización del rendimiento: Con LangSmith, puedes analizar el uso de tokens, la latencia y otras métricas de rendimiento para optimizar la eficacia de tu agente.
- Pruebas y evaluación: LangSmith facilita la creación y gestión de conjuntos de datos de prueba, lo que te permite evaluar rigurosamente el rendimiento de tu agente en una serie de escenarios.
- Monitorización: En entornos de producción, LangSmith ofrece funciones de supervisión en tiempo real, que te permiten seguir el rendimiento de tu agente y detectar anomalías rápidamente.
A continuación te explicamos cómo puedes empezar con LangSmith:
- Regístrate para obtener una cuenta gratuita aquí.
- Establece variables de entorno.
export LANGCHAIN_TRACING_V2="true"
export LANGCHAIN_API_KEY="..."
y ¡listo! Cuando empiezas a consultar modelos de lengua/chat, LangSmith empieza a registrar diversas métricas sobre cada ejecución:
Conclusión
En este artículo, exploramos lo que hace que los agentes LangChain sean distintos de las cadenas y los importantes bloques de construcción que se utilizan para construirlas. Primero presentamos qué son los agentes y en qué se diferencian de los constructos más tradicionales de la cadena en cuanto a flexibilidad y capacidad para tomar decisiones.
Luego vimos los componentes clave que debes conocer para construir un agente: modelos de chat, herramientas y plantillas de avisos. Por último, repasamos dos ejemplos que demuestran cómo construir agentes sencillos y avanzados. El procesamiento del lenguaje natural está en continuo desarrollo, y los agentes LangChain están a la vanguardia de esta progresión, allanando el camino para una familia de IA aún más inteligente y versátil.
Aquí tienes algunos recursos relacionados para aumentar tu LangChain:
- Curso de Desarrollo de Aplicaciones LLM con LangChain
- Introducción a la ingeniería de instrucciones con LangChain
- Tutorial sobre cómo crear aplicaciones LLM con LangChain
- Construir un modelo GPT con capacidades de navegación utilizando herramientas LangChain
- LangChain vs LlamaIndex: Una comparación detallada
¡Gracias por leer!
Top Cursos DataCamp LLM
programa
Developing AI Applications
programa
Associate AI Engineer for Data Scientists
tutorial
Tutorial sobre cómo crear aplicaciones LLM con LangChain
tutorial
Construir un transformador con PyTorch
tutorial
Guía de torchchat de PyTorch: Configuración local con Python
François Aubry
tutorial
Cómo formar a un LLM con PyTorch
tutorial
Tutorial de la API de OpenAI Assistants
tutorial