Desarrollar un agente de LangChain

En esta página se explica cómo desarrollar un agente usando la plantilla de LangChain específica del framework (la clase LangchainAgent del SDK de Vertex AI para Python). El agente devuelve el tipo de cambio entre dos monedas en una fecha específica. A continuación, se indican los pasos que debes seguir:

  1. Definir y configurar un modelo
  2. Definir y usar una herramienta
  3. (Opcional) Almacenar historial de chat
  4. (Opcional) Personalizar la plantilla de petición
  5. (Opcional) Personaliza la orquestación.

Antes de empezar

Para configurar tu entorno, sigue los pasos que se indican en el artículo Configurar el entorno.

Paso 1. Definir y configurar un modelo

Define la versión del modelo que quieras usar.

model = "gemini-2.0-flash"

(Opcional) Configura los ajustes de seguridad del modelo. Para obtener más información sobre las opciones disponibles para los ajustes de seguridad en Gemini, consulta Configurar atributos de seguridad. A continuación, se muestra un ejemplo de cómo puedes configurar los ajustes 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,
}

(Opcional) Especifique 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,
}

Crea un LangchainAgent con las configuraciones del modelo:

from vertexai import agent_engines

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

Si estás en un entorno interactivo (por ejemplo, un terminal o un cuaderno de Colab), puedes ejecutar una consulta como paso de prueba intermedio:

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

print(response)

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 básicos 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 que tenga 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 ver una lista de los modelos de chat compatibles con LangChain y sus funciones, 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 debe consultar la documentación correspondiente para obtener más información.

ChatVertexAI

Instalado de forma predeterminada.

Se usa en la plantilla LangchainAgent cuando se omite el argumento model_builder, por ejemplo:

from vertexai import agent_engines

agent = agent_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 devuelva 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:

from vertexai import agent_engines

agent = agent_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 ChatCompletions de Gemini.

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

A continuación, define un model_builder que devuelva 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:

from vertexai import agent_engines

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

Paso 2: Definir y usar una herramienta

Una vez que hayas definido tu modelo, el siguiente paso es definir las herramientas que usará para razonar. 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.

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

Usa el siguiente código para definir una función que devuelva 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 agente, ejecuta lo siguiente:

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

La respuesta debería ser similar a la siguiente:

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

Para usar la herramienta en la plantilla LangchainAgent, añádela a la lista de herramientas del argumento tools=:

from vertexai import agent_engines

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

Puedes probar el agente de forma local haciendo consultas de prueba. Ejecuta el siguiente comando para probar el agente de forma local con dólares estadounidenses y coronas suecas:

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 de LangchainAgent se pueden definir e instanciar de otras formas.

Herramienta de grounding

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 de la plantilla LangchainAgent:

from vertexai import agent_engines

agent = agent_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 Fundamentación.

Herramienta 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 de la plantilla LangchainAgent:

from vertexai import agent_engines

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

Debería devolver 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 de la plantilla LangchainAgent:

from vertexai import agent_engines

agent = agent_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 devolver 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 que el agente implementado pueda acceder a la extensión Code Interpreter, debes añadir el rol Usuario de Vertex AI (roles/aiplatform.user) a la cuenta de servicio del agente de servicio del motor de razonamiento de AI Platform. Para obtener más información, consulta Gestionar el acceso.

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

Puedes usar todas las herramientas que hayas creado en LangchainAgent (o solo algunas):

from vertexai import agent_engines

agent = agent_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 en lenguaje natural, puedes obligarlo a que solo genere llamadas a funciones ("llamada a funciones obligatoria").

from vertexai import agent_engines
from vertexai.preview.generative_models import ToolConfig

agent = agent_engines.LangchainAgent(
    model="gemini-2.0-flash",
    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: Almacenar el historial de chat

Para monitorizar los mensajes de chat y añadirlos a una base de datos, define una función get_session_history y pásala cuando crees el agente. Esta función debe recibir un session_id y devolver un objeto BaseChatMessageHistory.

  • session_id es un identificador de la sesión a la que pertenecen estos mensajes de entrada. De esta forma, puedes mantener varias conversaciones al mismo tiempo.
  • BaseChatMessageHistory es la interfaz de las clases que pueden cargar y guardar objetos de mensaje.

Configurar una base de datos

Para ver una lista de los proveedores de ChatMessageHistory de Google compatibles con LangChain, consulta Memoria.

Primero, sigue la documentación de LangChain para instalar y usar el paquete pertinente para configurar una base de datos de tu elección (por ejemplo, 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:

from vertexai import agent_engines

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

Cuando consultes al agente, asegúrate de incluir 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"}},
)

Puedes comprobar que las consultas posteriores conservarán la memoria de la sesión:

response = agent.query(
    input="How much is 100 USD?",
    config={"configurable": {"session_id": "SESSION_ID"}},
)

print(response)

Paso 4: Personalizar la plantilla de petición

Las plantillas de peticiones ayudan a traducir las entradas de los usuarios en instrucciones para un modelo y se usan para guiar la respuesta de un modelo, lo que le permite entender el contexto y generar resultados relevantes y coherentes basados en el lenguaje. Para obtener más información, consulta ChatPromptTemplates.

La plantilla de petición predeterminada se organiza secuencialmente en secciones.

Sección Descripción
(Opcional) Instrucción del sistema Instrucciones para el agente que se aplicarán a todas las consultas.
(Opcional) Historial de chat Mensajes correspondientes al historial de chat de una sesión anterior.
Entrada del usuario La consulta del usuario a la que debe responder el agente.
Bloc de notas del agente Mensajes creados por el agente (por ejemplo, con llamadas a funciones) mientras usa sus herramientas y razona para formular una respuesta al usuario.

La plantilla de petición predeterminada se genera si creas el agente sin especificar tu propia plantilla de petición y tendrá el siguiente aspecto:

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}"),
])

En el siguiente ejemplo, se usa implícitamente la plantilla de petición completa al crear una instancia del agente:

from vertexai import agent_engines

system_instruction = "I help look up the rate between currencies"

agent = agent_engines.LangchainAgent(
    model=model,
    system_instruction=system_instruction,
    chat_history=get_session_history,
    tools=[get_exchange_rate],
)

Puedes sustituir la plantilla de petición predeterminada por la tuya propia y usarla al crear el agente. Por ejemplo:


from vertexai import agent_engines

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 = agent_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: Personalizar la orquestación

Todos los componentes de LangChain implementan la interfaz Runnable, que proporciona esquemas de entrada y salida para la orquestación. La LangchainAgent necesita que se cree un runnable para poder responder a las consultas. De forma predeterminada, LangchainAgent creará un elemento ejecutable de este tipo vinculando el modelo con las herramientas y usará un AgentExecutor que se envolverá en un RunnableWithMessageHistory si el historial de chat está habilitado.

Puede personalizar la orquestación si tiene previsto (i) implementar un agente que realice un conjunto de pasos determinista (en lugar de llevar a cabo un razonamiento abierto) o (ii) pedirle al agente que, de forma similar a ReAct, anote cada paso con las razones por las que lo ha llevado a cabo. Para ello, debes anular el ejecutable predeterminado al crear el LangchainAgent especificando el argumento runnable_builder= con una función de Python que tenga 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

De esta forma, se ofrecen diferentes opciones para personalizar la lógica de la orquestación.

ChatModel

En el caso más sencillo, para crear un agente sin orquestación, puedes anular el método runnable_builder de LangchainAgent para devolver model directamente.

from vertexai import agent_engines
from langchain_core.language_models import BaseLanguageModel

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

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

ReAct

Para anular el comportamiento predeterminado de llamada a herramientas con tu propio agente ReAct basado en tu propio prompt (consulta Personalizar la plantilla de petición), debes anular el runnable_builder de 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

from vertexai import agent_engines

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 = agent_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 crear el siguiente gráfico con el lenguaje de expresiones de LangChain (LCEL),

   Input
   /   \
 Pros  Cons
   \   /
  Summary

debes anular runnable_builder para LangchainAgent:

from vertexai import agent_engines

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 = agent_engines.LangchainAgent(
    model=model,
    runnable_builder=lcel_builder,
)

LangGraph

Para crear el siguiente gráfico con LangGraph,

   Input
   /   \
 Pros  Cons
   \   /
  Summary

debes anular runnable_builder para LangchainAgent:

from vertexai import agent_engines

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 = agent_engines.LangchainAgent(
    model=model,
    runnable_builder=langgraph_builder,
)

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

Siguientes pasos