Desenvolver um aplicativo

Um exemplo de aplicativo pequeno que pode ser criado usando o LangChain na Vertex AI é aquele que retorna a taxa de câmbio entre duas moedas em uma data especificada.

É possível definir sua própria classe Python (consulte Personalizar um modelo de aplicativo) ou usar a classe LangchainAgent no SDK da Vertex AI para Python para seu agente. As etapas a seguir mostram como criar esse aplicativo usando o modelo pré-criado LangchainAgent:

  1. Definir e configurar um modelo
  2. Definir e usar uma ferramenta
  3. (Opcional) Armazenar o histórico de chat
  4. (Opcional) Personalizar o modelo de comando
  5. (Opcional) Personalizar a orquestração

Antes de começar

Antes de executar este tutorial, verifique se o ambiente está configurado seguindo as etapas em Configurar o ambiente.

Etapa 1. Definir e configurar um modelo

Execute as etapas a seguir para definir e configurar seu modelo:

  1. É necessário definir a versão do modelo a ser usada.

    model = "gemini-1.5-flash-001"
    
  2. (Opcional) Você pode definir as configurações de segurança do modelo. Para saber mais sobre as opções disponíveis para configurações de segurança no Gemini, consulte Configurar atributos de segurança.

    Confira a seguir um exemplo de como definir as configuraçõ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,
    }
    
  3. (Opcional) É possível especificar os parâmetros do modelo da seguinte maneira:

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

Agora é possível criar e consultar um LangchainAgent usando as configurações do 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?")

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

{"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) Personalização avançada

O modelo LangchainAgent usa ChatVertexAI por padrão, porque fornece isso acesso a todos os modelos básicos disponíveis no Google Cloud. Para usar um modelo não disponibilizado por ChatVertexAI, especifique 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 compatíveis com o LangChain e respectivos recursos, consulte Modelos de chat. O conjunto de valores aceitos para model= e model_kwargs= é específico para cada modelo de chat. Por isso, consulte a documentação correspondente para ver detalhes.

ChatVertexAI

Instalado por padrão.

Ele é usado no modelo LangchainAgent quando você omite o argumento model_builder, por exemplo

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

ChatAnthropic

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

Em seguida, defina um model_builder que retorne 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 no modelo LangchainAgent com o seguinte 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

É possível usar ChatOpenAI com a API ChatCompletions do Gemini.

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

Em seguida, defina um model_builder que retorne 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 no modelo LangchainAgent com o seguinte 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.
    },
)

Etapa 2. Definir e usar uma ferramenta

Depois de definir o modelo, a próxima etapa é definir as ferramentas que o modelo usa para raciocínio. Ela pode ser uma ferramenta LangChain ou uma função Python. Você também pode converter uma função definida do Python em uma ferramenta LangChain. Este aplicativo usa uma definição de função.

Ao definir a função, é importante incluir comentários que descrevam completa e claramente os parâmetros da função, o que ela faz e o que ela retorna. Essas informações são usadas pelo modelo para determinar qual função usar. Você também precisa testar a função localmente para confirmar se ela funciona.

Use o código a seguir para definir uma função que retorna 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 usá-la no aplicativo, execute o seguinte:

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

A resposta será semelhante a esta:

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

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

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

É possível testar o aplicativo executando consultas de teste nele. Execute o comando a seguir para testar o aplicativo usando dólares americanos e coroas suecas:

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

A resposta é um dicionário semelhante a este:

{"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 LangchainAgent podem ser definidas e instanciadas de outras maneiras.

Ferramenta de embasamento

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 no modelo LangchainAgent:

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

A resposta é um dicionário semelhante a este:

{"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, acesse Embasamento.

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 no modelo LangchainAgent:

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

Ele deve retornar 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 conferir o exemplo completo, acesse o notebook.

Para mais exemplos de ferramentas disponíveis no LangChain, acesse Ferramentas do Google.

Extensão da 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 no modelo 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},
    }
    """
)

Ele deve retornar 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 ver detalhes, acesse Extensões da Vertex AI.

É possível usar todas (ou um subconjunto) das ferramentas criadas em 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) Configuração da ferramenta

Com o Gemini, é possível aplicar restrições ao uso da ferramenta. Por exemplo, em vez de permitir que o modelo gere respostas de linguagem natural, é possível forçar a geração apenas de chamadas de função ("chamadas de função forçadas").

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 ver detalhes, acesse Configuração da ferramenta.

Etapa 3. Armazenar o histórico de chat

Para acompanhar as mensagens de chat e adicioná-las a um banco de dados, defina uma função get_session_history e transmita-a ao criar o agente. Essa função precisa receber um session_id e retornar um objeto BaseChatMessageHistory.

  • session_id é um identificador da sessão a que essas mensagens de entrada pertencem. Isso permite manter várias conversas ao mesmo tempo.
  • BaseChatMessageHistory é a interface para classes que podem carregar e salvar objetos de mensagem.

Configurar um banco de dados

Para ver uma lista dos provedores ChatMessageHistory do Google compatíveis com o LangChain, consulte Memória.

Firestore (nativo)

Primeiro, siga a documentação do LangChain para configurar um banco de dados e instalar o pacote.

Em seguida, defina uma função get_session_history conforme a seguir:

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

Crie o agente e transmita-o como chat_history:

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

Bigtable

Primeiro, siga a documentação do LangChain para configurar um banco de dados e instalar o pacote.

Em seguida, defina uma função get_session_history conforme a seguir:

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

Crie o agente e transmita-o como chat_history:

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

Spanner

Primeiro, siga a documentação do LangChain para configurar um banco de dados e instalar o pacote.

Em seguida, defina uma função get_session_history conforme a seguir:

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

Crie o agente e transmita-o como chat_history:

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

Ao consultar o agente, transmita o session_id para que ele "memorize" as perguntas e respostas anteriores:

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

Etapa 4. Personalizar o modelo de comando

Os modelos de comando ajudam a traduzir a entrada do usuário em instruções para um modelo e são usados para orientar a resposta de um modelo, ajudando-o a entender o contexto e gerar uma saída relevante e coerente baseada em linguagem. Para ver detalhes, acesse ChatPromptTemplates.

O modelo de comando padrão é organizado sequencialmente em seções.

Seção Descrição
(Opcional) Instrução do sistema Instruções para o agente ser aplicado em todas as consultas.
(Opcional) Histórico de chat Mensagens correspondentes ao histórico de chat de uma sessão anterior.
Entrada do usuário A consulta do usuário que o agente precisa responder.
Bloco de rascunho do agente Mensagens criadas pelo agente (por exemplo, com chamadas de função) à medida que ele usa as ferramentas e realiza o raciocínio para formular uma resposta ao usuário.

O modelo de comando padrão será gerado se você criar o agente sem especificar seu próprio modelo de comando e terá o seguinte aspecto por completo:

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

É possível substituir o modelo de comando padrão pelo seu próprio modelo e usá-lo ao criar o agente, por exemplo:


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

Etapa 5. Personalizar a orquestração

Todos os componentes do LangChain implementam a interface executável, fornecendo esquemas de entrada e saída para orquestração. O LangchainAgent precisa que um executável seja criado para responder a consultas. Por padrão, o LangchainAgent cria um executável vinculando o modelo a ferramentas e usa um AgentExecutor que é agrupado em um RunnableWithMessageHistory quando o histórico de chat está ativado.

Convém personalizar a orquestração se você pretende (i) implementar um agente que executa um conjunto determinista de etapas (em vez de realizar raciocínio aberto) ou (ii) solicitar de forma semelhante ao ReAct que o agente anote cada etapa com comentários sobre por que ela foi realizada. Para fazer isso, substitua o executável padrão ao criar o LangchainAgent 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,
    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,
):

em que

  • model corresponde ao modelo de chat retornado pelo model_builder (consulte Definir e configurar um modelo).
  • tools e model_tool_kwargs correspondem às ferramentas e configurações a serem usadas (consulte Definir e usar uma ferramenta).
  • chat_history corresponde ao banco de dados para armazenar mensagens de chat (consulte Armazenar o histórico de chat).
  • system_instruction e prompt correspondem à configuração do comando (consulte Personalizar o modelo de comando).
  • agent_executor_kwargs e runnable_kwargs são os argumentos de palavra-chave que podem ser usados para personalizar o executável a ser criado.

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

ChatModel

No caso mais simples, para criar um agente sem orquestração, é possível substituir o runnable_builder por LangchainAgent para retornar o model diretamente.

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 substituir o comportamento padrão de chamada de ferramenta com seu próprio agente ReAct com base no seu prompt (consulte Personalizar o modelo de comando), substitua o runnable_builder por 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,
)

Sintaxe de LCEL

Para criar o gráfico a seguir usando a LangChain Expression Language (LCEL),

   Input
   /   \
 Pros  Cons
   \   /
  Summary

é necessário substituir o runnable_builder por 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 criar o gráfico a seguir usando o LangGraph,

   Input
   /   \
 Pros  Cons
   \   /
  Summary

é necessário substituir o runnable_builder por 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"})

A seguir