3

LangChain Agents and Tools

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.

1.0 Que son los Agents

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:

  • El agente en sí, que decide qué acción tomar después utilizando el LLM. LangChain proporciona varios tipos de agentes como punto de partida.
  • Las herramientas, que son las funciones que el agente puede llamar. Se deben describir bien para que el agente sepa cómo usarlas. LangChain proporciona muchas herramientas integradas.
  • El executor del agente es el entorno de ejecución que llama al agente y ejecuta las acciones. Maneja casos de error y logging.

Ejemplo: Agente que nos ayuda a realizar búsquedas

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)

1.1 Agent Types

Dentro de los agentes encontramos AgentType este condiciona la forma en la que usara las herramientas.

  • ZeroShotAgent

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.

  • FewShotAgent

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.

  • ReactDescriptionAgent

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.

  • ReactDescriptionAgent

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:

  • Utiliza el framework ReAct para representar hechos y el historial de conversación, permitiendo mantener el contexto.
  • Invoca herramientas (como funciones de OpenAI) basándose únicamente en sus descripciones, sin necesidad de ejemplos, gracias a las capacidades de razonamiento de ReAct.

Estos son algunos ejemplos de AgentType. Aquí dejo un recurso donde pueden consultar mas tipos.

2.0 Herramientas (Tools)

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.

Ejemplo uso de multiples herramientas

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)

2.1 Custom tools

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”

.

TipoCosto 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:

  1. Calcular area de construcción
  2. Buscar en tabla de precios
  3. Calcular precio final

.


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

3.0 Conclusiones

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.

4.0 Recursos

  1. Agentes

  2. Tools

  3. Recursos adicionales LangChain

  4. Implementación de Agente de ventas

Escribe tu comentario
+ 2