Hola llevo un par de meses experimentando con Langchain y encontré que los agentes (agents) son una función muy interesante, que nos ayudan potenciar nuestros chatbots. Ya que el curso no abarca esta parte les comparto un poco de lo que he aprendido.
Los agentes son una forma de usar un modelo de lenguaje (LLM) que toman una secuencia de acciones para lograr un objetivo. Permiten que un LLM controle la ejecución de herramientas y funciones.
Son útiles para una variedad de tareas como interactuar con bases de datos, APIs, y más. Permiten automatizar flujos de trabajo complejos.
Los componentes clave de los agentes son:
Importamos las librarías necesarias SerpAPIWrapper es la herramienta encargada de realizar búsquedas en internet.
from langchain.agents import Tool
from langchain.agents import AgentType
from langchain.memory import ConversationBufferMemory
from langchain import OpenAI
from langchain.utilities import SerpAPIWrapper
from langchain.agents import initialize_agent
Listamos las herramienta que usara el agente
search = SerpAPIWrapper()
tools = [
Tool(
name = "Current Search",
func=search.run,description="useful for when you need to answer questions about current events or the current state of the world"
),
]
Definimos el agente junto con las herramientas que usara.
memory = ConversationBufferMemory(memory_key="chat_history")llm=OpenAI(temperature=0)agent_chain = initialize_agent(
tools,
llm,
agent=AgentType.CONVERSATIONAL_REACT_DESCRIPTION,verbose=True,memory=memory
)
query = “Peticion relacionada con una busqueda en internet”
agente_chain.run(query)
Dentro de los agentes encontramos AgentType este condiciona la forma en la que usara las herramientas.
Este agente invoca herramientas basándose únicamente en sus descripciones, sin necesidad de ejemplos. Utiliza el modelo de lenguaje subyacente para determinar qué herramienta es la más adecuada para una tarea dada solo con la descripción de la herramienta.
Este agente invoca herramientas basándose en unos pocos ejemplos de uso de cada herramienta. Requiere unos pocos ejemplos de cómo se utiliza cada herramienta para poder determinar cuál es la más adecuada para una tarea dada.
Este agente utiliza el framework ReAct para invocar herramientas basándose en sus descripciones. Hace uso de las capacidades de ReAct para representar y razonar sobre descripciones de herramientas.
Este agente utiliza el framework ReAct para invocar herramientas basándose en sus descripciones. Hace uso de las capacidades de ReAct para representar y razonar sobre descripciones de herramientas.
StructuredChatZeroShotReactDescriptionAgent
en LangChain es un agente conversacional diseñado para tener conversaciones naturales manteniendo el contexto y la memoria a través de múltiples preguntas.
Este agente combina características de los agentes ZeroShotAgent
y ReactAgent
:
Estos son algunos ejemplos de AgentType. Aquí dejo un recurso donde pueden consultar mas tipos.
Ahora exploremos las herramientas estas son funciones que el agente puede llamar como acciones para ayudar a responder preguntas. Se definen como objetos Tool
que contienen el nombre, descripción, y la función a ejecutar. Permiten integrar funciones externas en los prompts del agente.
Podemos encadenar multiples tools para que se ejecuten en cadena, en este ejemplo el agente es capaz de buscar en internet gracias a SerpAPIWrapper
, realizar cálculos matemáticos con LLMMathChain
y realizar consultas SQL con SQLDatabaseChain
.
# Importamos las librerías necesarias
from langchain import LLMMathChain, OpenAI, SerpAPIWrapper, SQLDatabase, SQLDatabaseChain
from langchain.agents import initialize_agent, Tool
from langchain.agents import AgentType
from langchain.chat_models import ChatOpenAI
llm = ChatOpenAI(temperature=0,model="gpt-3.5-turbo-0613")search = SerpAPIWrapper()
llm_math_chain = LLMMathChain.from_llm(llm=llm,verbose=True)db = SQLDatabase.from_uri("sqlite:///../../../../../notebooks/Chinook.db")
db_chain = SQLDatabaseChain.from_llm(llm, db, verbose=True)tools = [
Tool(
name = "Search",
func=search.run,description="useful for when you need to answer questions about current events. You should ask targeted questions"
),
Tool(
name="Calculator",
func=llm_math_chain.run,
description="useful for when you need to answer questions about math"
),
Tool(
name="FooBar-DB",
func=db_chain.run,
description="useful for when you need to answer questions about FooBar. Input should be in the form of a question containing full context"
)
]
Ahora procedemos a inicialiar el agente y a correrlo:
agent = initialize_agent(
tools,
llm,
agent=AgentType.OPENAI_FUNCTIONS,verbose=True
)
query = "Busca el año de la independencia de Mexico y elévalo a la 0.58 potencia"
agent.run(query)
Una de las grandes ventajas de las tools es customizar tus propios recursos para tareas específicas, por ejemplo ahora estoy desarrollando un chatbot que sirva como asistente para hacer cálculos y dado el resultado busque en una tabla csv.
Para crear una herramienta tool
necesitamos:
from langchain.tools import BaseTool
from typing import Union, Optional
Creamos las herramientas necesarias, en este ejemplo calcularemos los costos de construcción dado el tipo de construcción y la superficie hara una cotización dados los precios en la tabla “materiales.csv”
columnas = Tipo: str, Costo por Metro Cuadrado: float
supongamos que los tipos son: “bodega”, “vivienda austera”, “vivienda media”, “vivienda lujo”, “deportivo”
.
Tipo | Costo por Metro Cuadrado |
---|---|
Bodega | $1592.613115 |
Vivienda Austera | $929.298321 |
Vivienda Media | $1309.880846 |
Vivienda Lujo | $1632.274331 |
Deportivo | $3402.611113 |
.
Ahora creamos las herramientas necesarias para ejecutar esta tarea especifica, en esta caso partí las tareas en tres:
.
classAreaCalculatorTool(BaseTool):
name = "Calculadora de area de construccion"
description = (
"Usa esta herramienta para calcular el area de construccion""Necesitas los datos de largo y ancho del terreno""Para usar esta herramienta necesitas la siguiente informacion""['largo_terreno', 'ancho_terreno'].")
def_run(self, largo_terreno: Optional[Union[int, float]]=None, ancho_terreno: Optional[Union[int, float]]=None):
return largo_terreno * ancho_terreno
def_arun(self, query: str):
raise NotImplementedError("This tool does not support async")
classSearchPriceTool(BaseTool):
name = "Cotizador de construccion"
description = (
"Usa esta herramienta para buscar el costo por metro cuadrado de construccion""Busca en la tabla el precio asociado al tipo de construccion""El tipo de construccion puede ser: 'bodega', 'vivienda austera', 'vivienda media', 'vivienda lujo', 'deportivo'""Para usar esta herramienta necesitas los siguientes parametros:""['tipo']"
)
def_run(self, tipo: Optional[str]=None, superficie: Optional[Union[int, float]]=None):
csv_file = 'materiales.csv'
agent = create_csv_agent(
llm,
csv_file,
verbose=True
)
return agent
def_arun(self, query: str):
raise NotImplementedError("This tool does not support async")
classTotalPriceCalculator(BaseTool):
name = "Calculadora de precio final"
description = (
"Usa esta herramienta para cotizar el precio final de construccion""Para usar la herramienta necesitas los datos de superficie en metros cuadrados y el tipo de vivienda a construir""El tipo de construccion puede ser: 'bodega', 'vivienda austera', 'vivienda media', 'vivienda lujo', 'deportivo'""Para usar esta herramienta necesitas los siguientes parametros:""['costo_por_metro_cuadrado', 'superficie']"
)
def_run(self, costo_por_metro_cuadrado: Optional[Union[int, float]]=None, superficie: Optional[Union[int, float]]=None):
return costo_por_metro_cuadrado * superficie
def_arun(self, query: str):
raise NotImplementedError("This tool does not support async")
Definimos las herramientas e inicializamos el agente
from langchain import OpenAI
from langchain.agents import initialize_agent, Tool
llm = OpenAI(temperature=0)tools = [
AreaCalculatorTool(),
SearchPriceTool(),
TotalPriceCalculator()]
agent_building = initialize_agent(
tools,
llm,
agent='structured-chat-zero-shot-react-description',verbose=True,
)
Ejecutamos el agente
query = "Cotiza la construccion de una vivienda media de con un ancho de 10 y largo de 5"
agent_building.run(query)
Output:
> Entering new AgentExecutor chain...
Action:
{
“action”: “Calculadora de area de construccion”,
“action_input”: {“largo_terreno”: 10, “ancho_terreno”: 5}
}
Observation:50Thought: Necesito el costo por metro cuadrado
Action:
{
“action”: “Cotizador de construccion”,
“action_input”: {“tipo”: “vivienda media”}
}
Observation: memory=Nonecallbacks=Nonecallback_manager=Noneverbose=Truetags=Nonemetadata=Noneagent=ZeroShotAgent(llm_chain=LLMChain(memory=None,callbacks=None,callback_manager=None,verbose=False,tags=None,metadata=None,prompt=PromptTemplate(input_variables=['agent_scratchpad', 'input'], output_parser=None,partial_variables={'df_head': '| | Unnamed: 0 | Tipo | Costo por Metro Cuadrado |\n|---:|-------------:|:-----------------|---------------------------:|\n| 0 | 0 | Bodega | 1592.61 |\n| 1 | 1 | Vivienda Austera | 929.298 |\n| 2 | 2 | Vivienda Media | 1309.88 |\n| 3 | 3 | Vivienda Lujo | 1632.27 |\n| 4 | 4 | Deportivo | 3402.61 |'}, template='\nYou are working with a pandas dataframe in Python. The name of the dataframe is `df`.\nYou should use the tools below to answer the question posed of you:\n\npython_repl_ast: A Python shell. Use this to execute python commands. Input should be a valid python command. When using this tool, sometimes output is abbreviated - make sure it does not look abbreviated before using it in your answer.\n\nUse the following format:\n\nQuestion: the input question you must answer\nThought: you should always think about what to do\nAction: the action to take, should be one of [python_repl_ast]\nAction Input: the input to the action\nObservation: the result of the action\n... (this Thought/Action/Action Input/Observation can repeat N times)\nThought: I now know the final answer\nFinal Answer: the final answer to the original input question\n\n\nThis is the result of `print(df.head())`:\n{df_head}\n\nBegin!\nQuestion: {input}\n{agent_scratchpad}', template_format='f-string',validate_template=True),llm=OpenAI(cache=None,verbose=False,callbacks=None,callback_manager=None,tags=None,metadata=None,client= 'openai.api_resources.completion.Completion'>, model_name='text-davinci-003',temperature=0.0,max_tokens=256,top_p=1,frequency_penalty=0,presence_penalty=0,n=1,best_of=1,model_kwargs={},openai_api_key='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',openai_api_base='',openai_organization='',openai_proxy='',batch_size=20,request_timeout=None,logit_bias={},max_retries=6,streaming=False,allowed_special=set(),disallowed_special='all',tiktoken_model_name=None),output_key='text',output_parser=StrOutputParser(),return_final_only=True,llm_kwargs={}),output_parser=MRKLOutputParser(),allowed_tools=['python_repl_ast'])tools=[PythonAstREPLTool(name='python_repl_ast',description='A Python shell. Use this to execute python commands. Input should be a valid python command. When using this tool, sometimes output is abbreviated - make sure it does not look abbreviated before using it in your answer.', args_schema=None,return_direct=False,verbose=False,callbacks=None,callback_manager=None,tags=None,metadata=None,handle_tool_error=False,globals={},locals={'df': Unnamed: 0 Tipo Costo por Metro Cuadrado
00 Bodega 1592.61311511 Vivienda Austera 929.29832122 Vivienda Media 1309.88084633 Vivienda Lujo 1632.27433144 Deportivo 3402.611113}, sanitize_input=True)]return_intermediate_steps=Falsemax_iterations=15max_execution_time=Noneearly_stopping_method='force'handle_parsing_errors=Falsetrim_intermediate_steps=-1
Thought: Ya tengo el costo por metro cuadrado
Action:
{
“action”: “Calculadora de precio final”,
“action_input”: {“costo_por_metro_cuadrado”: 1309.880846, “superficie”: 50}
}
Observation: 65494.0423
Ya tengo el precio finalAction:
{
“action”: “Final Answer”,
“action_input”: “El precio final para construir una vivienda media de 10 x 5 metros es de 65494.0423”
}
> Finished chain.
El precio final para construir una vivienda media de 10 x 5 metros es de 65494.0423
No cabe duda de que LangChain nos ofrece una gran cantidad de recursos para darle “esteroides” a nuestros chatbots, en mi caso particular encontre en los Agentes y herramientas caracteristicas para crear soluciones a los problemas que he encontrado.
Les invito a seguir profundizando en la documentación ya que hay módulos que no se tocan en el curso y puede que ahi encuentren los recursos que necesitan.
Agentes
Tools
Recursos adicionales LangChain
Implementación de Agente de ventas