Desenvolva um agente LangGraph

Esta página mostra como desenvolver um agente usando o modelo LangGraph específico da framework (a classe LanggraphAgent no SDK Vertex AI para Python). O agente devolve a taxa de câmbio entre duas moedas numa data especificada. Siga estes passos:

  1. Defina e configure um modelo
  2. Defina e use uma ferramenta
  3. (Opcional) Armazenar pontos de controlo
  4. (Opcional) Personalize o modelo de comando
  5. (Opcional) Personalize a orquestração

Antes de começar

Certifique-se de que o seu ambiente está configurado seguindo os passos em Configure o seu ambiente.

Passo 1. Defina e configure um modelo

Defina a versão do modelo a usar.

model = "gemini-2.0-flash"

(Opcional) Configure as definições de segurança do modelo. Para saber mais acerca das opções disponíveis para as definições de segurança no Gemini, consulte o artigo Configure atributos de segurança. Segue-se um exemplo de como pode configurar as definições de segurança:

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 parâmetros do modelo da seguinte forma:

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,
}

Crie um LanggraphAgent com as configurações do modelo:

from vertexai import agent_engines

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

Se estiver a executar num ambiente interativo (por exemplo, um terminal ou um bloco de notas do Colab), pode executar uma consulta como um passo de teste intermédio:

response = agent.query(input={"messages": [
    ("user", "What is the exchange rate from US dollars to SEK today?"),
]})

print(response)

A resposta é um dicionário Python semelhante ao seguinte exemplo:

{
  'messages': [{
    'id': ['langchain', 'schema', 'messages', 'HumanMessage'],
    'kwargs': {
      'content': 'What is the exchange rate from US dollars to Swedish currency?',
      'id': '5473dd25-d796-42ad-a690-45bc49a64bec',
      'type': 'human',
    },
    'lc': 1,
    'type': 'constructor',
  }, {
    'id': ['langchain', 'schema', 'messages', 'AIMessage'],
    'kwargs': {
      'content': """
        I do not have access to real-time information, including currency exchange rates.

        To get the most up-to-date exchange rate from US dollars to Swedish currency (SEK),
        I recommend checking a reliable online currency converter like: ...

        These websites will provide you with the current exchange rate and allow you to
        convert specific amounts.""",
      'id': 'run-c42f9940-8ba8-42f1-a625-3aa0780c9e87-0',
      ...
      'usage_metadata': {
        'input_tokens': 12,
        'output_tokens': 145,
        'total_tokens': 157,
      },
    },
    'lc': 1,
    'type': 'constructor',
  }],
}

(Opcional) Personalização avançada

O modelo LanggraphAgent usa o ChatVertexAI por predefinição, porque oferece acesso a todos os modelos fundamentais disponíveis no Google Cloud. Para usar um modelo que não esteja disponível através de ChatVertexAI, pode especificar o argumento model_builder= com uma função Python da seguinte assinatura:

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 uma lista dos modelos de chat suportados no LangChain e as respetivas capacidades, consulte o artigo Modelos de chat. O conjunto de valores suportados para model= e model_kwargs= é específico de cada modelo de chat, pelo que tem de consultar a respetiva documentação para ver os detalhes.

ChatVertexAI

Instalada por predefinição.

É usado em LanggraphAgent quando omite o argumento model_builder, por exemplo

from vertexai import agent_engines

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

ChatAnthropic

Primeiro, siga a documentação para configurar uma conta e instalar o pacote.

Em seguida, defina um model_builder que devolva 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 fim, use-o em LanggraphAgent com o seguinte código:

from vertexai import agent_engines

agent = agent_engines.LanggraphAgent(
    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

Pode usar ChatOpenAI em conjunto com a API ChatCompletions do Gemini.

Primeiro, siga a documentação para instalar o pacote.

Em seguida, defina um model_builder que devolva 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 fim, use-o em LanggraphAgent com o seguinte código:

from vertexai import agent_engines

agent = agent_engines.LanggraphAgent(
    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.
    },
)

Passo 2. Defina e use uma ferramenta

Depois de definir o modelo, o passo seguinte é definir as ferramentas que o modelo usa para o raciocínio. Uma ferramenta pode ser uma ferramenta LangChain ou uma função Python. Também pode converter uma função Python definida numa ferramenta LangChain.

Quando define a sua função, é importante incluir comentários que descrevam de forma completa e clara os parâmetros da função, o que a função faz e o que a função devolve. Estas informações são usadas pelo modelo para determinar que função usar. Também tem de testar a função localmente para confirmar que funciona.

Use o seguinte código para definir uma função que devolve uma taxa de câmbio:

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 testar a função antes de a usar no seu agente, execute o seguinte:

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

A resposta deve ser semelhante à seguinte:

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

Para usar a ferramenta em LanggraphAgent, adicione-a à lista de ferramentas no argumento tools=:

from vertexai import agent_engines

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

Pode testar o agente localmente executando consultas de teste em relação ao mesmo. Execute o comando seguinte para testar o agente localmente com dólares americanos e coroas suecas:

response = agent.query(input={"messages": [
    ("user", "What is the exchange rate from US dollars to Swedish currency?"),
]})

A resposta é um dicionário semelhante ao seguinte:

{"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) Várias ferramentas

As ferramentas para LanggraphAgent podem ser definidas e instanciadas de outras formas.

Ferramenta de fundamentação

Primeiro, importe o pacote generate_models e crie a ferramenta

from vertexai.generative_models import grounding, Tool

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

Em seguida, use a ferramenta em LanggraphAgent:

from vertexai import agent_engines

agent = agent_engines.LanggraphAgent(
    model=model,
    tools=[grounded_search_tool],
)
response = agent.query(input={"messages": [
    ("user", "When is the next total solar eclipse in US?"),
]})
print(response)

A resposta é um dicionário semelhante ao seguinte:

{"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 ver detalhes, consulte o artigo Fundamentação.

Ferramenta LangChain

Primeiro, instale o pacote que define a ferramenta.

pip install langchain-google-community

Em seguida, importe o pacote e crie a ferramenta.

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 fim, use a ferramenta em LanggraphAgent:

from vertexai import agent_engines

agent = agent_engines.LanggraphAgent(
    model=model,
    tools=[movie_search_tool],
)
response = agent.query(input={"messages": [
    ("user", "List some sci-fi movies from the 1990s"),
]})

print(response)

Deve devolver uma resposta como

{"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 o exemplo completo, aceda ao bloco de notas.

Para ver mais exemplos de ferramentas disponíveis no LangChain, visite Ferramentas Google.

Extensão do Vertex AI

Primeiro, importe o pacote de extensões e crie a ferramenta

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,
    )

Em seguida, use a ferramenta em LanggraphAgent:

from vertexai import agent_engines

agent = agent_engines.LanggraphAgent(
    model=model,
    tools=[generate_and_execute_code],
)
response = agent.query(input={"messages": [("user", """
    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},
    }
""")]})

print(response)

Deve devolver uma resposta como

{"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 o seu agente implementado aceda à extensão Code Interpreter, tem de adicionar a função de utilizador da Vertex AI (roles/aiplatform.user) à conta de serviço do agente de serviço do AI Platform Reasoning Engine. Para mais informações, consulte o artigo Gerir o acesso.

Para ver detalhes, visite Extensões do Vertex AI.

Pode usar todas (ou um subconjunto) das ferramentas que criou no LanggraphAgent:

from vertexai import agent_engines

agent = agent_engines.LanggraphAgent(
    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)
    ],
)

response = agent.query(input={"messages": [
    ("user", "List some sci-fi movies from the 1990s"),
]})

print(response)

(Opcional) Configuração da ferramenta

Com o Gemini, pode aplicar restrições à utilização de ferramentas. Por exemplo, em vez de permitir que o modelo gere respostas em linguagem natural, pode forçá-lo a gerar apenas chamadas de funções ("chamada de funções forçada").

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

agent = agent_engines.LanggraphAgent(
    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"],
            },
        },
    },
)

response = agent.query(input={"messages": [
    ("user", "Explain the Schrodinger equation in a few sentences"),
]})

print(response)

Para ver detalhes, aceda a Configuração de ferramentas.

Passo 3. Armazene pontos de restauro

Para acompanhar as mensagens de chat e anexá-las a uma base de dados, defina uma função checkpointer_builder e transmita-a quando criar o agente.

Configure uma base de dados

Primeiro, instale e use o pacote relevante para configurar uma base de dados à sua escolha (por exemplo, o AlloyDB for PostgreSQL ou o Cloud SQL for PostgreSQL):

Em seguida, defina uma função checkpointer_builder da seguinte forma:

Cloud SQL para PostgreSQL

checkpointer_kwargs = {
    "project_id": "PROJECT_ID",
    "region": "REGION",
    "instance": "INSTANCE",
    "database": "DATABASE",
}

def checkpointer_builder(**kwargs):
    from langchain_google_cloud_sql_pg import (
        PostgresEngine,
        PostgresSaver,
    )
    engine = PostgresEngine.from_instance(**kwargs)
    engine.init_checkpoint_table()

    return PostgresSaver.create_sync(engine)

AlloyDB para PostgreSQL

checkpointer_kwargs = {
    "project_id": "PROJECT_ID",
    "region": "REGION",
    "instance": "INSTANCE",
    "database": "DATABASE",
    "cluster": "CLUSTER",
}

def checkpointer_builder(**kwargs):
    from langchain_google_alloydb_pg import (
        AlloyDBEngine,
        AlloyDBSaver,
    )
    from google.cloud.alloydb.connector import IPTypes

    engine = AlloyDBEngine.from_instance(
        ip_type=IPTypes.PUBLIC,
        **kwargs,
    )
    engine.init_checkpoint_table()

    return AlloyDBSaver.create_sync(engine)

Por fim, crie o agente e transmita-o como checkpointer_builder:

from vertexai import agent_engines

agent = agent_engines.LanggraphAgent(
    model=model,
    checkpointer_kwargs=checkpointer_kwargs,    # <- new
    checkpointer_builder=checkpointer_builder,  # <- new
)

Quando consultar o agente, certifique-se de que especifica um thread_id para que o agente tenha "memória" de perguntas e respostas anteriores:

response = agent.query(
    input={"messages": [
        ("user", "What is the exchange rate from US dollars to Swedish currency?")
    ]},
    config={"configurable": {"thread_id": "THREAD_ID"}},
)

print(response)

Pode verificar se as consultas subsequentes mantêm a memória da sessão:

response = agent.query(
    input={"messages": [("user", "How much is 100 USD?")]},
    config={"configurable": {"thread_id": "THREAD_ID"}},
)

print(response)

Passo 4. Personalize o modelo de comando

Os modelos de comandos ajudam a traduzir a entrada do utilizador em instruções para um modelo e são usados para orientar a resposta de um modelo, ajudando-o a compreender o contexto e a gerar resultados relevantes e coerentes baseados em linguagem. Para ver detalhes, visite a página ChatPromptTemplates.

O modelo de comando predefinido está organizado sequencialmente em secções.

Secção Descrição
(Opcional) Instrução do sistema Instruções para o agente a serem aplicadas a todas as consultas.
(Opcional) Histórico do chat Mensagens correspondentes ao histórico do chat de uma sessão anterior.
Introdução do utilizador A consulta do utilizador à qual o agente deve responder.
Rascunhos do agente Mensagens criadas pelo agente (por exemplo, com a chamada de funções) à medida que realiza utiliza as suas ferramentas e realiza o raciocínio para formular uma resposta ao utilizador.

O modelo de comando predefinido é gerado se criar o agente sem especificar o seu próprio modelo de comando e tem o seguinte aspeto na íntegra:

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

Está a usar implicitamente o modelo de comando completo quando instancia o agente no seguinte exemplo:

from vertexai import agent_engines

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

agent = agent_engines.LanggraphAgent(
    model=model,
    system_instruction=system_instruction,
    checkpointer_kwargs=checkpointer_kwargs,
    checkpointer_builder=checkpointer_builder,
    tools=[get_exchange_rate],
)

Pode substituir o modelo de comando predefinido pelo seu próprio modelo de comando e usá-lo ao criar o agente, por exemplo:

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.LanggraphAgent(
    model=model,
    prompt=custom_prompt_template,
    checkpointer_kwargs=checkpointer_kwargs,
    checkpointer_builder=checkpointer_builder,
    tools=[get_exchange_rate],
)

response = agent.query(
    input={"messages": [
        ("user", "What is the exchange rate from US dollars to Swedish currency?"),
    ]}
    config={"configurable": {"thread_id": "THREAD_ID"}},
)

print(response)

Passo 5. Personalize a orquestração

Todos os componentes do LangChain implementam a interface Runnable, que fornece esquemas de entrada e saída para a orquestração. A classe LanggraphAgent requer a criação de um executável para responder a consultas. Por predefinição, o LanggraphAgent cria um executável deste tipo usando a implementação do agente React pré-criada do langgraph.

Pode querer personalizar a orquestração se pretender (i) implementar um agente que execute um conjunto determinístico de passos (em vez de executar um raciocínio aberto) ou (ii) pedir ao agente de forma semelhante ao ReAct que anote cada passo com reflexões sobre o motivo pelo qual executou esse passo. Para o fazer, tem de substituir o executável predefinido ao criar LanggraphAgent especificando o argumento runnable_builder= com uma função Python da seguinte assinatura:

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,
    checkpointer: Optional[Any] = None,
    runnable_kwargs: Optional[Mapping[str, Any]] = None,
    **kwargs,
):

onde

Isto oferece diferentes opções para personalizar a lógica de orquestração.

ChatModel

No caso mais simples, para criar um agente sem orquestração, pode substituir o runnable_builder para LanggraphAgent para devolver o model diretamente.

from vertexai import agent_engines
from langchain_core.language_models import BaseLanguageModel

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

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

ReAct

Para substituir o comportamento de chamada de ferramentas predefinido pelo seu próprio agente ReAct com base no seu próprio prompt (consulte Personalize o modelo de comando), tem de substituir o runnable_builder por LanggraphAgent.

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.LanggraphAgent(
    model=model,
    tools=[get_exchange_rate],
    prompt=hub.pull("hwchase17/react"),
    agent_executor_kwargs={"verbose": True}, # Optional. For illustration.
    runnable_builder=react_builder,
)

Sintaxe LCEL

Para construir o seguinte gráfico com o Idioma de expressão do LangChain (LCEL),

   Input
   /   \
 Pros  Cons
   \   /
  Summary

Tem de substituir o runnable_builder para LanggraphAgent:

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

LangGraph

Para construir o seguinte gráfico com o LangGraph:

   Input
   /   \
 Pros  Cons
   \   /
  Summary

Tem de substituir o runnable_builder para LanggraphAgent:

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

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

print(response)

O que se segue?