Développer un agent LangChain

Cette page explique comment développer un agent à l'aide du modèle LangChain spécifique au framework (classe LangchainAgent du SDK Vertex AI pour Python). L'agent renvoie le taux de change entre deux devises à une date spécifiée. Pour ce faire, procédez comme suit :

  1. Définir et configurer un modèle
  2. Définir et utiliser un outil
  3. (Facultatif) Stocker l'historique des discussions
  4. (Facultatif) Personnaliser le modèle d'invite
  5. (Facultatif) Personnaliser l'orchestration

Avant de commencer

Assurez-vous que votre environnement est configuré en suivant la procédure décrite dans la section Configurer votre environnement.

Étape 1. Définir et configurer un modèle

Définissez la version de modèle à utiliser.

model = "gemini-1.5-flash-001"

(Facultatif) Configurez les paramètres de sécurité du modèle. Pour en savoir plus sur les options disponibles pour configurer les paramètres de sécurité dans Gemini, consultez la section Configurer les attributs de sécurité. Voici un exemple de configuration des paramètres de sécurité :

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

(Facultatif) Spécifiez les paramètres de modèle de la manière suivante:

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

Créez un LangchainAgent à l'aide des configurations de modèle:

from vertexai.preview.reasoning_engines import LangchainAgent

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

Si vous exécutez le code dans un environnement interactif (par exemple, un terminal ou un notebook Colab), vous pouvez exécuter une requête comme étape de test intermédiaire:

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

print(response)

La réponse est un dictionnaire Python semblable à l'exemple suivant:

{"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.
"""}

(Facultatif) Personnalisation avancée

Le modèle LangchainAgent utilise ChatVertexAI par défaut, car il permet d'accéder à tous les modèles de base disponibles dans Google Cloud. Pour utiliser un modèle non disponible via ChatVertexAI, vous pouvez spécifier l'argument model_builder= avec une fonction Python de la signature suivante:

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.
):

Pour obtenir la liste des modèles de chat compatibles avec LangChain et de leurs fonctionnalités, consultez la page Modèles de chat. L'ensemble des valeurs acceptées pour model= et model_kwargs= est spécifique à chaque modèle de chat. Vous devez donc vous reporter à la documentation correspondante pour plus de détails.

ChatVertexAI

Installé par défaut.

Il est utilisé dans le modèle LangchainAgent lorsque vous omettez l'argument model_builder. Par exemple :

from vertexai.preview.reasoning_engines import LangchainAgent

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

ChatAnthropic

Commencez par suivre la documentation pour configurer un compte et installer le package.

Ensuite, définissez un model_builder qui renvoie ChatAnthropic :

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

Enfin, utilisez-le dans le modèle LangchainAgent avec le code suivant :

from vertexai.preview.reasoning_engines import LangchainAgent

agent = 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

Vous pouvez utiliser ChatOpenAI conjointement avec l'API ChatCompletions de Gemini.

Commencez par suivre la documentation pour installer le package.

Ensuite, définissez un model_builder qui renvoie 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,
    )

Enfin, utilisez-le dans le modèle LangchainAgent avec le code suivant :

from vertexai.preview.reasoning_engines import LangchainAgent

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

Étape 2 : Définir et utiliser un outil

Une fois votre modèle défini, l'étape suivante consiste à définir les outils qu'il utilise pour le raisonnement. Un outil peut être un outil LangChain ou une fonction Python. Vous pouvez également convertir une fonction Python définie en outil LangChain.

Lorsque vous définissez votre fonction, il est important d'inclure des commentaires qui décrivent pleinement et clairement les paramètres de la fonction, ce qu'elle fait et ce qu'elle renvoie. Le modèle utilise ces informations pour déterminer quelle fonction utiliser. Vous devez également tester votre fonction localement pour vérifier qu'elle fonctionne.

Utilisez le code suivant pour définir une fonction qui renvoie un taux de change :

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

Pour tester la fonction avant de l'utiliser dans votre agent, exécutez la commande suivante:

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

La sortie devrait ressembler à ce qui suit :

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

Pour utiliser l'outil dans le modèle LangchainAgent, vous devez l'ajouter à la liste des outils sous l'argument tools=:

from vertexai.preview.reasoning_engines import LangchainAgent

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

Vous pouvez tester l'agent localement en exécutant des requêtes de test. Exécutez la commande suivante pour tester l'agent en local en utilisant le dollar américain et la couronne suédoise:

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

La réponse est un dictionnaire semblable à celui-ci:

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

(Facultatif) Plusieurs outils

Les outils pour LangchainAgent peuvent être définis et instanciés de différentes manières.

Outil de mise à la terre

Commencez par importer le package generate_models et créer l'outil.

from vertexai.generative_models import grounding, Tool

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

Ensuite, utilisez l'outil dans le modèle LangchainAgent:

from vertexai.preview.reasoning_engines import LangchainAgent

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

La réponse est un dictionnaire semblable à celui-ci:

{"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."""}

Pour en savoir plus, consultez la section Ancrage.

Outil LangChain

Commencez par installer le package qui définit l'outil.

pip install langchain-google-community

Importez ensuite le package et créez l'outil.

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

Enfin, utilisez l'outil dans le modèle LangchainAgent:

from vertexai.preview.reasoning_engines import LangchainAgent

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

Vous devriez obtenir une réponse semblable à

{"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.
    [...]
 """}

Pour voir l'exemple complet, consultez le notebook.

Pour voir d'autres exemples d'outils disponibles dans LangChain, consultez Outils Google.

Extension Vertex AI

Commencez par importer le package d'extensions et créez l'outil.

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

Ensuite, utilisez l'outil dans le modèle LangchainAgent:

from vertexai.preview.reasoning_engines import LangchainAgent

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

Vous devriez obtenir une réponse semblable à

{"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()
 ```
 """}

Pour en savoir plus, consultez la page Extensions Vertex AI.

Vous pouvez utiliser tous (ou un sous-ensemble) des outils que vous avez créés dans LangchainAgent:

from vertexai.preview.reasoning_engines import LangchainAgent

agent = 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?")

(Facultatif) Configuration de l'outil

Avec Gemini, vous pouvez imposer des contraintes sur l'utilisation de l'outil. Par exemple, au lieu de permettre au modèle de générer des réponses en langage naturel, vous pouvez l'obliger à ne générer que des appels de fonction ("appel de fonction forcé").

from vertexai.preview.reasoning_engines import LangchainAgent
from vertexai.preview.generative_models import ToolConfig

agent = 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",
)

Pour en savoir plus, consultez Configuration de l'outil.

Étape 3 : Stocker l'historique des discussions

Pour suivre les messages de chat et les ajouter à une base de données, définissez une fonction get_session_history et transmettez-la lorsque vous créez l'agent. Cette fonction doit utiliser un session_id et renvoyer un objet BaseChatMessageHistory.

  • session_id est un identifiant de la session à laquelle appartiennent ces messages d'entrée. Vous pouvez ainsi mener plusieurs conversations en même temps.
  • BaseChatMessageHistory est l'interface des classes pouvant charger et enregistrer des objets de message.

Configurer une base de données

Pour obtenir la liste des fournisseurs ChatMessageHistory de Google compatibles avec LangChain, consultez la section Mémoire.

Commencez par suivre la documentation de LangChain pour installer et utiliser le package approprié afin de configurer la base de données de votre choix (par exemple, Firestore, Bigtable ou Spanner):

Ensuite, définissez une fonction get_session_history comme suit :

Firestore (mode natif)

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

Enfin, créez l'agent et transmettez-le en tant que chat_history:

from vertexai.preview.reasoning_engines import LangchainAgent

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

Lorsque vous interrogez l'agent, veillez à transmettre le session_id afin qu'il se souvienne des questions et réponses précédentes:

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

Vous pouvez vérifier que les requêtes suivantes conservent la mémoire de la session:

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

print(response)

Étape 4. Personnaliser le modèle d'invite

Les modèles de requêtes permettent de traduire les entrées utilisateur en instructions pour un modèle. Ils sont utilisés pour guider la réponse d'un modèle, l'aider à comprendre le contexte et à générer une sortie basée sur le langage pertinente et cohérente. Pour en savoir plus, consultez ChatPromptTemplates.

Le modèle de requête par défaut est organisé de manière séquentielle en sections.

Section Description
(Facultatif) Instruction système Instructions à appliquer à l'agent pour toutes les requêtes.
(Facultatif) Historique des discussions Messages correspondant à l'historique des discussions d'une session passée.
Entrée utilisateur Requête de l'utilisateur à laquelle l'agent doit répondre.
Bloc-notes de l'agent Messages créés par l'agent (par exemple, avec un appel de fonction) lorsqu'il utilise ses outils et effectue un raisonnement pour formuler une réponse à l'utilisateur.

Le modèle de requête par défaut est généré si vous créez l'agent sans spécifier votre propre modèle de requête. Il se présente comme suit :

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

Vous utilisez implicitement le modèle de requête complet lorsque vous instanciez l'agent dans l'exemple suivant:

from vertexai.preview.reasoning_engines import LangchainAgent

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

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

Vous pouvez remplacer le modèle de requête par défaut par votre propre modèle de requête et l'utiliser lors de la création de l'agent, par exemple :


from vertexai.preview.reasoning_engines import LangchainAgent

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

Étape 5 : Personnaliser l'orchestration

Tous les composants LangChain implémentent l'interface Runnable, qui fournit des schémas d'entrée et de sortie pour l'orchestration. Le LangchainAgent nécessite la création d'un exécutable pour qu'il puisse répondre aux requêtes. Par défaut, LangchainAgent crée un tel exécutable en liant le modèle à des outils et en utilisant un AgentExecutor encapsulé dans un RunnableWithMessageHistory si l'historique des discussions est activé.

Vous pouvez personnaliser l'orchestration si vous souhaitez (i) implémenter un agent qui exécute un ensemble déterministe d'étapes (plutôt que d'effectuer un raisonnement ouvert) ou (ii) inviter l'agent à annoter chaque étape avec des réflexions sur la raison pour laquelle il a effectué cette étape, comme dans ReAct. Pour ce faire, vous devez remplacer l'exécutable par défaut lors de la création de LangchainAgent en spécifiant l'argument runnable_builder= avec une fonction Python de la signature suivante:

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

Où :

Vous disposez ainsi de différentes options pour personnaliser la logique d'orchestration.

ChatModel

Dans le cas le plus simple, pour créer un agent sans orchestration, vous pouvez remplacer runnable_builder par LangchainAgent pour renvoyer directement model.

from vertexai.preview.reasoning_engines import LangchainAgent
from langchain_core.language_models import BaseLanguageModel

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

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

ReAct

Pour remplacer le comportement d'appel d'outil par défaut par votre propre agent ReAct basé sur votre propre prompt (voir Personnaliser le modèle de requête), vous devez remplacer runnable_builder par 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.preview.reasoning_engines import LangchainAgent

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

Syntaxe LCEL

Pour créer le graphique suivant à l'aide du langage LCEL (LangChain Expression Language),

   Input
   /   \
 Pros  Cons
   \   /
  Summary

vous devez remplacer runnable_builder pour LangchainAgent:

from vertexai.preview.reasoning_engines import 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 = LangchainAgent(
    model=model,
    runnable_builder=lcel_builder,
)

LangGraph

Pour créer le graphique suivant à l'aide de LangGraph,

   Input
   /   \
 Pros  Cons
   \   /
  Summary

vous devez remplacer runnable_builder pour LangchainAgent:

from vertexai.preview.reasoning_engines import 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 = LangchainAgent(
    model=model,
    runnable_builder=langgraph_builder,
)

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

Étape suivante