Desarrollar una aplicación

Un ejemplo de una aplicación pequeña que puedes crear con LangChain en Vertex Generative AI es una que muestra el tipo de cambio entre dos monedas en una fecha específica.

Puedes definir tu propia clase de Python (consulta Personaliza una plantilla de aplicación) o puedes usar la clase LangchainAgent en el SDK de Vertex AI para Python para tu agente. En los siguientes pasos, se muestra cómo crear esta aplicación con la plantilla precompilada de LangchainAgent:

  1. Define y configura un modelo
  2. Define y usa una herramienta
  3. (Opcional) Almacenar el historial de chat
  4. (Opcional) Personaliza la plantilla de instrucciones
  5. (Opcional) Cómo personalizar la organización

Antes de comenzar

Antes de ejecutar este instructivo, asegúrate de que tu entorno esté configurado con los pasos que se indican en Configura tu entorno.

Paso 1: Define y configura un modelo

Ejecuta los siguientes pasos para definir y configurar tu modelo:

  1. Debes definir la versión del modelo que deseas usar.

    model = "gemini-1.5-flash-001"
    
  2. (Opcional) Puedes establecer la configuración de seguridad del modelo. Si quieres obtener más información sobre las opciones disponibles de parámetros de seguridad en Gemini, consulta Configura los atributos de seguridad.

    A continuación, se muestra un ejemplo de cómo puedes configurar los parámetros de configuración de seguridad:

    from langchain_google_vertexai import HarmBlockThreshold, HarmCategory
    
    safety_settings = {
        HarmCategory.HARM_CATEGORY_UNSPECIFIED: HarmBlockThreshold.BLOCK_NONE,
        HarmCategory.HARM_CATEGORY_DANGEROUS_CONTENT: HarmBlockThreshold.BLOCK_MEDIUM_AND_ABOVE,
        HarmCategory.HARM_CATEGORY_HATE_SPEECH: HarmBlockThreshold.BLOCK_ONLY_HIGH,
        HarmCategory.HARM_CATEGORY_HARASSMENT: HarmBlockThreshold.BLOCK_LOW_AND_ABOVE,
        HarmCategory.HARM_CATEGORY_SEXUALLY_EXPLICIT: HarmBlockThreshold.BLOCK_NONE,
    }
    
  3. De manera opcional, puedes especificar los parámetros del modelo de la siguiente manera:

    model_kwargs = {
        # temperature (float): The sampling temperature controls the degree of
        # randomness in token selection.
        "temperature": 0.28,
        # max_output_tokens (int): The token limit determines the maximum amount of
        # text output from one prompt.
        "max_output_tokens": 1000,
        # top_p (float): Tokens are selected from most probable to least until
        # the sum of their probabilities equals the top-p value.
        "top_p": 0.95,
        # top_k (int): The next token is selected from among the top-k most
        # probable tokens. This is not supported by all model versions. See
        # https://cloud.google.com/vertex-ai/generative-ai/docs/multimodal/image-understanding#valid_parameter_values
        # for details.
        "top_k": None,
        # safety_settings (Dict[HarmCategory, HarmBlockThreshold]): The safety
        # settings to use for generating content.
        # (you must create your safety settings using the previous step first).
        "safety_settings": safety_settings,
    }
    

Ahora puedes crear y consultar un LangchainAgent con las configuraciones del modelo:

agent = reasoning_engines.LangchainAgent(
    model=model,                # Required.
    model_kwargs=model_kwargs,  # Optional.
)

response = agent.query(input="What is the exchange rate from US dollars to Swedish currency?")

La respuesta es un diccionario de Python similar al siguiente ejemplo:

{"input": "What is the exchange rate from US dollars to Swedish currency?",
 "output": """I cannot provide the live exchange rate from US dollars to Swedish currency (Swedish krona, SEK).

**Here's why:**

* **Exchange rates constantly fluctuate.** Factors like global economics, interest rates, and political events cause
  these changes throughout the day.
* **Providing inaccurate information would be misleading.**

**How to find the current exchange rate:**

1. **Use a reliable online converter:** Many websites specialize in live exchange rates. Some popular options include:
   * Google Finance (google.com/finance)
   * XE.com
   * Bank websites (like Bank of America, Chase, etc.)
2. **Contact your bank or financial institution:** They can give you the exact exchange rate they are using.

Remember to factor in any fees or commissions when exchanging currency.
"""}

(Opcional) Personalización avanzada

La plantilla LangchainAgent usa ChatVertexAI de forma predeterminada, ya que proporciona acceso a todos los modelos fundamentales disponibles en Google Cloud. Para usar un modelo que no está disponible a través de ChatVertexAI, puedes especificar el argumento model_builder= con una función de Python de la siguiente firma:

from typing import Optional

def model_builder(
    *,
    model_name: str,                      # Required. The name of the model
    model_kwargs: Optional[dict] = None,  # Optional. The model keyword arguments.
    **kwargs,                             # Optional. The remaining keyword arguments to be ignored.
):

Para obtener una lista de los modelos de chat compatibles con LangChain y sus capacidades, consulta Modelos de chat. El conjunto de valores admitidos para model= y model_kwargs= es específico de cada modelo de chat, por lo que debes consultar la documentación correspondiente para obtener más detalles.

ChatVertexAI

Instalado de forma predeterminada.

Se usa en la plantilla LangchainAgent cuando omites el argumento model_builder, por ejemplo

agent = reasoning_engines.LangchainAgent(
    model=model,                # Required.
    model_kwargs=model_kwargs,  # Optional.
)

ChatAnthropic

Primero, sigue su documentación para configurar una cuenta e instalar el paquete.

A continuación, define un model_builder que muestre ChatAnthropic:

def model_builder(*, model_name: str, model_kwargs = None, **kwargs):
    from langchain_anthropic import ChatAnthropic
    return ChatAnthropic(model_name=model_name, **model_kwargs)

Por último, úsalo en la plantilla LangchainAgent con el siguiente código:

agent = reasoning_engines.LangchainAgent(
    model="claude-3-opus-20240229",                       # Required.
    model_builder=model_builder,                          # Required.
    model_kwargs={
        "api_key": "ANTHROPIC_API_KEY",  # Required.
        "temperature": 0.28,                              # Optional.
        "max_tokens": 1000,                               # Optional.
    },
)

ChatOpenAI

Puedes usar ChatOpenAI junto con la API de ChatCompletions de Gemini.

Primero, sigue su documentación para instalar el paquete.

A continuación, define un model_builder que muestre ChatOpenAI:

def model_builder(
    *,
    model_name: str,
    model_kwargs = None,
    project: str,   # Specified via vertexai.init
    location: str,  # Specified via vertexai.init
    **kwargs,
):
    import google.auth
    from langchain_openai import ChatOpenAI

    # Note: the credential lives for 1 hour by default.
    # After expiration, it must be refreshed.
    creds, _ = google.auth.default(scopes=["https://www.googleapis.com/auth/cloud-platform"])
    auth_req = google.auth.transport.requests.Request()
    creds.refresh(auth_req)

    if model_kwargs is None:
        model_kwargs = {}

    endpoint = f"https://{location}-aiplatform.googleapis.com"
    base_url = f'{endpoint}/v1beta1/projects/{project}/locations/{location}/endpoints/openapi'

    return ChatOpenAI(
        model=model_name,
        base_url=base_url,
        api_key=creds.token,
        **model_kwargs,
    )

Por último, úsalo en la plantilla LangchainAgent con el siguiente código:

agent = reasoning_engines.LangchainAgent(
    model="google/gemini-1.5-pro-001",  # Or "meta/llama3-405b-instruct-maas"
    model_builder=model_builder,        # Required.
    model_kwargs={
        "temperature": 0,               # Optional.
        "max_retries": 2,               # Optional.
    },
)

Paso 2. Define y usa una herramienta

Después de definir el modelo, el siguiente paso es definir las herramientas que usa el modelo para el razonamiento. Una herramienta puede ser una herramienta de LangChain o una función de Python. También puedes convertir una función de Python definida en una herramienta de LangChain. Esta aplicación usa una definición de función.

Cuando definas tu función, es importante incluir comentarios que describan de manera completa y clara los parámetros de la función, lo que hace y lo que muestra. El modelo usa esta información para determinar qué función usar. También debes probar la función de forma local para confirmar que funciona.

Usa el siguiente código para definir una función que muestre un tipo de cambio:

def get_exchange_rate(
    currency_from: str = "USD",
    currency_to: str = "EUR",
    currency_date: str = "latest",
):
    """Retrieves the exchange rate between two currencies on a specified date.

    Uses the Frankfurter API (https://api.frankfurter.app/) to obtain
    exchange rate data.

    Args:
        currency_from: The base currency (3-letter currency code).
            Defaults to "USD" (US Dollar).
        currency_to: The target currency (3-letter currency code).
            Defaults to "EUR" (Euro).
        currency_date: The date for which to retrieve the exchange rate.
            Defaults to "latest" for the most recent exchange rate data.
            Can be specified in YYYY-MM-DD format for historical rates.

    Returns:
        dict: A dictionary containing the exchange rate information.
            Example: {"amount": 1.0, "base": "USD", "date": "2023-11-24",
                "rates": {"EUR": 0.95534}}
    """
    import requests
    response = requests.get(
        f"https://api.frankfurter.app/{currency_date}",
        params={"from": currency_from, "to": currency_to},
    )
    return response.json()

Para probar la función antes de usarla en tu aplicación, ejecuta el siguiente comando:

get_exchange_rate(currency_from="USD", currency_to="SEK")

La respuesta podría ser similar a la siguiente:

{'amount': 1.0, 'base': 'USD', 'date': '2024-02-22', 'rates': {'SEK': 10.3043}}

Para usar la herramienta dentro de la plantilla LangchainAgent, la agregarás a la lista de herramientas en el argumento tools=:

agent = reasoning_engines.LangchainAgent(
    model=model,                # Required.
    tools=[get_exchange_rate],  # Optional.
    model_kwargs=model_kwargs,  # Optional.
)

Para probar la aplicación, realiza consultas de prueba en ella. Ejecuta el siguiente comando para probar la aplicación con dólares estadounidenses y corona sueca:

response = agent.query(
    input="What is the exchange rate from US dollars to Swedish currency?"
)

La respuesta es un diccionario similar al siguiente:

{"input": "What is the exchange rate from US dollars to Swedish currency?",
 "output": "For 1 US dollar you will get 10.7345 Swedish Krona."}

(Opcional) Varias herramientas

Las herramientas para LangchainAgent se pueden definir y crear instancias de otras maneras.

Herramienta de fundamentación

Primero, importa el paquete generate_models y crea la herramienta.

from vertexai.generative_models import grounding, Tool

grounded_search_tool = Tool.from_google_search_retrieval(
    grounding.GoogleSearchRetrieval()
)

A continuación, usa la herramienta dentro de la plantilla LangchainAgent:

agent = reasoning_engines.LangchainAgent(
    model=model,
    tools=[grounded_search_tool],
)
agent.query(input="When is the next total solar eclipse in US?")

La respuesta es un diccionario similar al siguiente:

{"input": "When is the next total solar eclipse in US?",
 "output": """The next total solar eclipse in the U.S. will be on August 23, 2044.
 This eclipse will be visible from three states: Montana, North Dakota, and
 South Dakota. The path of totality will begin in Greenland, travel through
 Canada, and end around sunset in the United States."""}

Para obtener más información, consulta Conexión a tierra.

Herramienta de LangChain

Primero, instala el paquete que define la herramienta.

pip install langchain-google-community

A continuación, importa el paquete y crea la herramienta.

from langchain_google_community import VertexAISearchRetriever
from langchain.tools.retriever import create_retriever_tool

retriever = VertexAISearchRetriever(
    project_id="PROJECT_ID",
    data_store_id="DATA_STORE_ID",
    location_id="DATA_STORE_LOCATION_ID",
    engine_data_type=1,
    max_documents=10,
)
movie_search_tool = create_retriever_tool(
    retriever=retriever,
    name="search_movies",
    description="Searches information about movies.",
)

Por último, usa la herramienta dentro de la plantilla LangchainAgent:

agent = reasoning_engines.LangchainAgent(
    model=model,
    tools=[movie_search_tool],
)
response = agent.query(
    input="List some sci-fi movies from the 1990s",
)

Debería mostrar una respuesta como la siguiente:

{"input": "List some sci-fi movies from the 1990s",
 "output": """Here are some sci-fi movies from the 1990s:
    * The Matrix (1999): A computer hacker learns from mysterious rebels about the true nature of his reality and his role in the war against its controllers.
    * Star Wars: Episode I - The Phantom Menace (1999): Two Jedi Knights escape a hostile blockade to find a queen and her protector, and come across a young boy [...]
    * Men in Black (1997): A police officer joins a secret organization that monitors extraterrestrial interactions on Earth.
    [...]
 """}

Para ver el ejemplo completo, visita el notebook.

Para ver más ejemplos de herramientas disponibles en LangChain, visita Herramientas de Google.

Extensión de Vertex AI

Primero, importa el paquete de extensiones y crea la herramienta.

from typing import Optional

def generate_and_execute_code(
    query: str,
    files: Optional[list[str]] = None,
    file_gcs_uris: Optional[list[str]] = None,
) -> str:
    """Get the results of a natural language query by generating and executing
    a code snippet.

    Example queries: "Find the max in [1, 2, 5]" or "Plot average sales by
    year (from data.csv)". Only one of `file_gcs_uris` and `files` field
    should be provided.

    Args:
        query:
            The natural language query to generate and execute.
        file_gcs_uris:
            Optional. URIs of input files to use when executing the code
            snippet. For example, ["gs://input-bucket/data.csv"].
        files:
            Optional. Input files to use when executing the generated code.
            If specified, the file contents are expected be base64-encoded.
            For example: [{"name": "data.csv", "contents": "aXRlbTEsaXRlbTI="}].
    Returns:
        The results of the query.
    """
    operation_params = {"query": query}
    if files:
        operation_params["files"] = files
    if file_gcs_uris:
        operation_params["file_gcs_uris"] = file_gcs_uris

    from vertexai.preview import extensions

    # If you have an existing extension instance, you can get it here
    # i.e. code_interpreter = extensions.Extension(resource_name).
    code_interpreter = extensions.Extension.from_hub("code_interpreter")
    return extensions.Extension.from_hub("code_interpreter").execute(
        operation_id="generate_and_execute",
        operation_params=operation_params,
    )

A continuación, usa la herramienta dentro de la plantilla LangchainAgent:

agent = reasoning_engines.LangchainAgent(
    model=model,
    tools=[generate_and_execute_code],
)
agent.query(
    input="""Using the data below, construct a bar chart that includes only the height values with different colors for the bars:

    tree_heights_prices = {
      \"Pine\": {\"height\": 100, \"price\": 100},
      \"Oak\": {\"height\": 65, \"price\": 135},
      \"Birch\": {\"height\": 45, \"price\": 80},
      \"Redwood\": {\"height\": 200, \"price\": 200},
      \"Fir\": {\"height\": 180, \"price\": 162},
    }
    """
)

Debería mostrar una respuesta como la siguiente:

{"input": """Using the data below, construct a bar chart that includes only the height values with different colors for the bars:

 tree_heights_prices = {
    \"Pine\": {\"height\": 100, \"price\": 100},
    \"Oak\": {\"height\": 65, \"price\": 135},
    \"Birch\": {\"height\": 45, \"price\": 80},
    \"Redwood\": {\"height\": 200, \"price\": 200},
    \"Fir\": {\"height\": 180, \"price\": 162},
 }
 """,
 "output": """Here's the generated bar chart:
 ```python
 import matplotlib.pyplot as plt

 tree_heights_prices = {
    "Pine": {"height": 100, "price": 100},
    "Oak": {"height": 65, "price": 135},
    "Birch": {"height": 45, "price": 80},
    "Redwood": {"height": 200, "price": 200},
    "Fir": {"height": 180, "price": 162},
 }

 heights = [tree["height"] for tree in tree_heights_prices.values()]
 names = list(tree_heights_prices.keys())

 plt.bar(names, heights, color=['red', 'green', 'blue', 'purple', 'orange'])
 plt.xlabel('Tree Species')
 plt.ylabel('Height')
 plt.title('Tree Heights')
 plt.show()
 ```
 """}

Para obtener más información, consulta Extensiones de Vertex AI.

Puedes usar todas (o un subconjunto) de las herramientas que creaste en LangchainAgent:

agent = reasoning_engines.LangchainAgent(
    model=model,
    tools=[
        get_exchange_rate,         # Optional (Python function)
        grounded_search_tool,      # Optional (Grounding Tool)
        movie_search_tool,         # Optional (Langchain Tool)
        generate_and_execute_code, # Optional (Vertex Extension)
    ],
)

agent.query(input="When is the next total solar eclipse in US?")

(Opcional) Configuración de la herramienta

Con Gemini, puedes establecer restricciones en el uso de las herramientas. Por ejemplo, en lugar de permitir que el modelo genere respuestas de lenguaje natural, puedes forzarlo para que solo genere llamadas a función (“llamadas a función forzadas”).

from vertexai.preview.generative_models import ToolConfig

agent = reasoning_engines.LangchainAgent(
    model="gemini-1.5-pro",
    tools=[search_arxiv, get_exchange_rate],
    model_tool_kwargs={
        "tool_config": {  # Specify the tool configuration here.
            "function_calling_config": {
                "mode": ToolConfig.FunctionCallingConfig.Mode.ANY,
                "allowed_function_names": ["search_arxiv", "get_exchange_rate"],
            },
        },
    },
)

agent.query(
    input="Explain the Schrodinger equation in a few sentences",
)

Para obtener más información, consulta Configuración de herramientas.

Paso 3: Almacena el historial de chat

Para hacer un seguimiento de los mensajes de chat y agregarlos a una base de datos, define una función get_session_history y pásala cuando crees el agente. Esta función debe tomar un session_id y mostrar un objeto BaseChatMessageHistory.

  • session_id es un identificador de la sesión a la que pertenecen estos mensajes de entrada. Esto te permite mantener varias conversaciones al mismo tiempo.
  • BaseChatMessageHistory es la interfaz para las clases que pueden cargar y guardar objetos de mensajes.

Configura una base de datos

Para obtener una lista de los proveedores de ChatMessageHistory de Google que son compatibles con LangChain, consulta Memoria.

Primero, sigue la documentación de LangChain para instalar y usar el paquete relevante y configurar la base de datos que elijas (p.ej., Firestore, Bigtable o Spanner):

A continuación, define una función get_session_history de la siguiente manera:

Firestore (modo nativo)

def get_session_history(session_id: str):
    from langchain_google_firestore import FirestoreChatMessageHistory
    from google.cloud import firestore

    client = firestore.Client(project="PROJECT_ID")
    return FirestoreChatMessageHistory(
        client=client,
        session_id=session_id,
        collection="TABLE_NAME",
        encode_message=False,
    )

Bigtable

def get_session_history(session_id: str):
    from langchain_google_bigtable import BigtableChatMessageHistory

    return BigtableChatMessageHistory(
        instance_id="INSTANCE_ID",
        table_id="TABLE_NAME",
        session_id=session_id,
    )

Spanner

def get_session_history(session_id: str):
    from langchain_google_spanner import SpannerChatMessageHistory

    return SpannerChatMessageHistory(
        instance_id="INSTANCE_ID",
        database_id="DATABASE_ID",
        table_name="TABLE_NAME",
        session_id=session_id,
    )

Por último, crea el agente y pásalo como chat_history:

agent = reasoning_engines.LangchainAgent(
    model=model,
    chat_history=get_session_history,  # <- new
)

Cuando consultes al agente, asegúrate de pasar el session_id para que el agente tenga “memoria” de las preguntas y respuestas anteriores:

agent.query(
    input="What is the exchange rate from US dollars to Swedish currency?",
    config={"configurable": {"session_id": "SESSION_ID"}},
)

Paso 4: Personaliza la plantilla de instrucciones

Las plantillas de instrucciones ayudan a traducir la entrada del usuario en instrucciones para un modelo y se usan para guiar la respuesta de un modelo, lo que lo ayuda a comprender el contexto y generar resultados relevantes y coherentes basados en el lenguaje. Para obtener más información, consulta ChatPromptTemplates.

La plantilla de instrucciones predeterminada se organiza de forma secuencial en secciones.

Sección Descripción
(Opcional) Instrucción del sistema Son instrucciones para que el agente se aplique en todas las consultas.
(Opcional) Historial de chat Mensajes correspondientes al historial de chat de una sesión anterior.
Entrada del usuario Es la consulta del usuario que el agente debe responder.
Bloc de notas del agente Son los mensajes que crea el agente (p. ej., con llamadas a funciones) a medida que usa sus herramientas y realiza razonamientos para formular una respuesta al usuario.

La plantilla de instrucciones predeterminada se genera si creas el agente sin especificar tu propia plantilla de instrucciones y se verá de la siguiente manera:

from langchain_core.prompts import ChatPromptTemplate
from langchain.agents.format_scratchpad.tools import format_to_tool_messages

prompt_template = {
    "user_input": lambda x: x["input"],
    "history": lambda x: x["history"],
    "agent_scratchpad": lambda x: format_to_tool_messages(x["intermediate_steps"]),
} | ChatPromptTemplate.from_messages([
    ("system", "{system_instruction}"),
    ("placeholder", "{history}"),
    ("user", "{user_input}"),
    ("placeholder", "{agent_scratchpad}"),
])

Puedes anular la plantilla de instrucciones predeterminada con tu propia plantilla de instrucciones y usarla cuando construyas el agente, por ejemplo:


custom_prompt_template = {
    "user_input": lambda x: x["input"],
    "history": lambda x: x["history"],
    "agent_scratchpad": lambda x: format_to_tool_messages(x["intermediate_steps"]),
} | ChatPromptTemplate.from_messages([
    ("placeholder", "{history}"),
    ("user", "{user_input}"),
    ("placeholder", "{agent_scratchpad}"),
])

agent = reasoning_engines.LangchainAgent(
    model=model,
    prompt=custom_prompt_template,
    chat_history=get_session_history,
    tools=[get_exchange_rate],
)

agent.query(
    input="What is the exchange rate from US dollars to Swedish currency?",
    config={"configurable": {"session_id": "SESSION_ID"}},
)

Paso 5: Personaliza la organización

Todos los componentes de LangChain implementan la interfaz Runnable, que proporciona esquemas de entrada y salida para la organización. LangchainAgent requiere que se compile un elemento ejecutable para que responda a las consultas. De forma predeterminada, LangchainAgent compilará un elemento ejecutable de este tipo vinculando el modelo con herramientas y usará un AgentExecutor que se une a un RunnableWithMessageHistory si el historial de chat está habilitado.

Te recomendamos que personalices la organización si deseas (i) implementar un agente que realice un conjunto determinístico de pasos (en lugar de realizar un razonamiento abierto) o (ii) solicitarle al agente de forma similar a ReAct que annote cada paso con pensamientos sobre por qué lo realizó. Para ello, debes anular el ejecutable predeterminado cuando crees el LangchainAgent especificando el argumento runnable_builder= con una función de Python de la siguiente firma:

from typing import Optional
from langchain_core.language_models import BaseLanguageModel

def runnable_builder(
    model: BaseLanguageModel,
    *,
    system_instruction: Optional[str] = None,
    prompt: Optional["RunnableSerializable"] = None,
    tools: Optional[Sequence["_ToolLike"]] = None,
    chat_history: Optional["GetSessionHistoryCallable"] = None,
    model_tool_kwargs: Optional[Mapping[str, Any]] = None,
    agent_executor_kwargs: Optional[Mapping[str, Any]] = None,
    runnable_kwargs: Optional[Mapping[str, Any]] = None,
    **kwargs,
):

donde

Esto proporciona diferentes opciones para personalizar la lógica de organización.

ChatModel

En el caso más simple, para crear un agente sin organización, puedes reemplazar runnable_builder por LangchainAgent para que devuelva model directamente.

from langchain_core.language_models import BaseLanguageModel

def llm_builder(model: BaseLanguageModel, **kwargs):
    return model

agent = reasoning_engines.LangchainAgent(
    model=model,
    runnable_builder=llm_builder,
)

ReAct

Para anular el comportamiento de llamada de herramientas predeterminado con tu propio agente de ReAct basado en tu propio prompt (consulta Cómo personalizar la plantilla de instrucciones), debes anular el runnable_builder para LangchainAgent.

from typing import Sequence
from langchain_core.language_models import BaseLanguageModel
from langchain_core.prompts import BasePromptTemplate
from langchain_core.tools import BaseTool
from langchain import hub

def react_builder(
    model: BaseLanguageModel,
    *,
    tools: Sequence[BaseTool],
    prompt: BasePromptTemplate,
    agent_executor_kwargs = None,
    **kwargs,
):
    from langchain.agents.react.agent import create_react_agent
    from langchain.agents import AgentExecutor

    agent = create_react_agent(model, tools, prompt)
    return AgentExecutor(agent=agent, tools=tools, **agent_executor_kwargs)

agent = reasoning_engines.LangchainAgent(
    model=model,
    tools=[get_exchange_rate],
    prompt=hub.pull("hwchase17/react"),
    agent_executor_kwargs={"verbose": True}, # Optional. For illustration.
    runnable_builder=react_builder,
)

Sintaxis de LCEL

Para construir el siguiente gráfico con LangChain Expression Language (LCEL),

   Input
   /   \
 Pros  Cons
   \   /
  Summary

debes anular runnable_builder para LangchainAgent.

def lcel_builder(*, model, **kwargs):
    from operator import itemgetter
    from langchain_core.prompts import ChatPromptTemplate
    from langchain_core.runnables import RunnablePassthrough
    from langchain_core.output_parsers import StrOutputParser

    output_parser = StrOutputParser()

    planner = ChatPromptTemplate.from_template(
        "Generate an argument about: {input}"
    ) | model | output_parser | {"argument": RunnablePassthrough()}

    pros = ChatPromptTemplate.from_template(
        "List the positive aspects of {argument}"
    ) | model | output_parser

    cons = ChatPromptTemplate.from_template(
        "List the negative aspects of {argument}"
    ) | model | output_parser

    final_responder = ChatPromptTemplate.from_template(
        "Argument:{argument}\nPros:\n{pros}\n\nCons:\n{cons}\n"
        "Generate a final response given the critique",
    ) | model | output_parser

    return planner | {
        "pros": pros,
        "cons": cons,
        "argument": itemgetter("argument"),
    } | final_responder

agent = reasoning_engines.LangchainAgent(
    model=model,
    runnable_builder=lcel_builder,
)

LangGraph

Para construir el siguiente gráfico con LangGraph,

   Input
   /   \
 Pros  Cons
   \   /
  Summary

debes anular runnable_builder para LangchainAgent.

def langgraph_builder(*, model, **kwargs):
    from langchain_core.prompts import ChatPromptTemplate
    from langchain_core.output_parsers import StrOutputParser
    from langgraph.graph import END, MessageGraph

    output_parser = StrOutputParser()

    planner = ChatPromptTemplate.from_template(
        "Generate an argument about: {input}"
    ) | model | output_parser

    pros = ChatPromptTemplate.from_template(
        "List the positive aspects of {input}"
    ) | model | output_parser

    cons = ChatPromptTemplate.from_template(
        "List the negative aspects of {input}"
    ) | model | output_parser

    summary = ChatPromptTemplate.from_template(
        "Input:{input}\nGenerate a final response given the critique",
    ) | model | output_parser

    builder = MessageGraph()
    builder.add_node("planner", planner)
    builder.add_node("pros", pros)
    builder.add_node("cons", cons)
    builder.add_node("summary", summary)

    builder.add_edge("planner", "pros")
    builder.add_edge("planner", "cons")
    builder.add_edge("pros", "summary")
    builder.add_edge("cons", "summary")
    builder.add_edge("summary", END)
    builder.set_entry_point("planner")
    return builder.compile()

agent = reasoning_engines.LangchainAgent(
    model=model,
    runnable_builder=langgraph_builder,
)

# Example query
agent.query(input={"role": "user", "content": "scrum methodology"})

¿Qué sigue?