Anwendung entwickeln

Ein Beispiel für eine kleine Anwendung, die Sie mit LangChain in Vertex AI erstellen können, ist eine Anwendung, die den Wechselkurs zwischen zwei Währungen an einem bestimmten Datum zurückgibt.

Sie können Ihre eigene Python-Klasse definieren (siehe Anwendungsvorlage anpassen) oder die Klasse LangchainAgent im Vertex AI SDK for Python für Ihren Agent verwenden. In den folgenden Schritten wird gezeigt, wie Sie diese Anwendung mit der vordefinierten LangchainAgent-Vorlage erstellen:

  1. Modell definieren und konfigurieren
  2. Tool definieren und verwenden
  3. Optional: Chatverlauf im Geschäft speichern
  4. Optional: Vorlage für Prompts anpassen
  5. Optional: Orchestrierung anpassen

Hinweise

Bevor Sie mit dieser Anleitung beginnen, müssen Sie Ihre Umgebung einrichten. Folgen Sie dazu der Anleitung unter Umgebung einrichten.

Schritt 1: Modell definieren und konfigurieren

Führen Sie die folgenden Schritte aus, um das Modell zu definieren und zu konfigurieren:

  1. Sie müssen die Modellversion angeben, die verwendet werden soll.

    model = "gemini-1.5-flash-001"
    
  2. Optional: Sie können die Sicherheitseinstellungen des Modells konfigurieren. Weitere Informationen zu den Sicherheitseinstellungen in Gemini finden Sie unter Sicherheitsattribute konfigurieren.

    Im Folgenden finden Sie ein Beispiel für die Konfiguration der Sicherheitseinstellungen:

    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. Optional: Sie können Modellparameter auf folgende Weise angeben:

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

Sie können jetzt mithilfe der Modellkonfigurationen einen LangchainAgent erstellen und abfragen:

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

Die Antwort ist ein Python-Dictionary, das dem folgenden Beispiel ähnelt:

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

(Optional) Erweiterte Anpassungen

In der LangchainAgent-Vorlage wird standardmäßig ChatVertexAI verwendet, da es Zugriff auf alle in Google Cloud verfügbaren Basismodelle bietet. Wenn Sie ein Modell verwenden möchten, das nicht über ChatVertexAI verfügbar ist, können Sie das Argument model_builder= mit einer Python-Funktion der folgenden Signatur angeben:

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

Eine Liste der in LangChain unterstützten Chatmodelle und ihrer Funktionen finden Sie unter Chat-Modelle. Die unterstützten Werte für model= und model_kwargs= sind für jedes Chatmodell spezifisch. Weitere Informationen finden Sie in der entsprechenden Dokumentation.

ChatVertexAI

Standardmäßig installiert.

Wird in der LangchainAgent-Vorlage verwendet, wenn Sie das model_builder-Argument weglassen, z. B.

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

ChatAnthropic

Folgen Sie zuerst der Anleitung, um ein Konto einzurichten und das Paket zu installieren.

Als Nächstes definieren Sie einen model_builder, die ChatAnthropic zurückgibt:

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

Verwenden Sie ihn abschließend in der LangchainAgent-Vorlage mit dem folgenden Code:

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

Sie können ChatOpenAI in Verbindung mit der ChatCompletions API von Gemini verwenden.

Folgen Sie zuerst der Dokumentation, um das Paket zu installieren.

Als Nächstes definieren Sie eine model_builder, die ChatOpenAI zurückgibt:

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

Verwenden Sie ihn abschließend in der LangchainAgent-Vorlage mit dem folgenden Code:

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

Schritt 2: Tool definieren und verwenden

Nachdem Sie Ihr Modell definiert haben, definieren Sie im nächsten Schritt die Tools, die Ihr Modell für Logik verwendet. Ein Tool kann ein LangChain-Tool oder eine Python-Funktion sein. Sie können auch eine definierte Python-Funktion in ein LangChain-Tool konvertieren. Diese Anwendung verwendet eine Funktionsdefinition.

Wenn Sie eine Funktion definieren, ist es wichtig, Kommentare hinzuzufügen, die die Parameter der Funktion, ihre Funktionsweise und die Rückgabe vollständig und klar beschreiben. Anhand dieser Informationen wird im Modell festgelegt, welche Funktion verwendet werden soll. Sie müssen Ihre Funktion auch lokal testen, um sicherzustellen, dass sie funktioniert.

Verwenden Sie den folgenden Code, um eine Funktion zu definieren, die einen Wechselkurs zurückgibt:

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

Wenn Sie die Funktion testen möchten, bevor Sie sie in Ihrer Anwendung verwenden, führen Sie Folgendes aus:

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

Die Antwort sollte in etwa so aussehen:

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

Wenn Sie das Tool in der LangchainAgent-Vorlage verwenden möchten, fügen Sie es der Liste der Tools unter dem tools=-Argument hinzu:

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

Sie können die Anwendung testen, indem Sie Testabfragen an sie durchführen. Führen Sie den folgenden Befehl aus, um die Anwendung mit US-Dollar und schwedischen Kronen zu testen:

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

Die Antwort ist ein Wörterbuch, das in etwa so aussieht:

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

(Optional) Mehrere Tools

Tools für LangchainAgent können auch auf andere Weise definiert und instanziiert werden.

Fundierungs-Tool

Importieren Sie zuerst das generate_models-Paket und erstellen Sie das Tool.

from vertexai.generative_models import grounding, Tool

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

Verwenden Sie als Nächstes das Tool in der LangchainAgent-Vorlage:

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

Die Antwort ist ein Wörterbuch, das in etwa so aussieht:

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

Weitere Informationen finden Sie unter Fundierung.

LangChain-Tool

Installieren Sie zuerst das Paket, das das Tool definiert.

pip install langchain-google-community

Als Nächstes importieren Sie das Paket und erstellen das Tool.

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

Verwenden Sie abschließend das Tool in der LangchainAgent-Vorlage:

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

Es sollte eine Antwort wie die folgende zurückgegeben werden:

{"input": "When is the next total solar eclipse in US?",
 "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.
    [...]
 """}

Das vollständige Beispiel finden Sie im Notebook.

Weitere Beispiele für Tools, die in LangChain verfügbar sind, finden Sie unter Google-Tools.

Vertex AI-Erweiterung

Importieren Sie zuerst das Erweiterungspaket und erstellen Sie das Tool.

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

Verwenden Sie als Nächstes das Tool in der LangchainAgent-Vorlage:

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

Es sollte eine Antwort wie die folgende zurückgegeben werden:

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

Weitere Informationen finden Sie unter Vertex AI-Erweiterungen.

Sie können alle oder einen Teil der Tools verwenden, die Sie in LangchainAgent erstellt haben:

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

(Optional) Toolkonfiguration

Mit Gemini können Sie Einschränkungen für die Toolnutzung festlegen. Anstatt dem Modell beispielsweise zu erlauben, Antworten in natürlicher Sprache zu generieren, können Sie erzwingen, dass nur Funktionsaufrufe generiert werden ("erzwungener Funktionsaufruf").

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

Weitere Informationen finden Sie unter Toolkonfiguration.

Schritt 3: Chatprotokoll speichern

Wenn Sie Chatnachrichten erfassen und einer Datenbank anhängen möchten, definieren Sie eine get_session_history-Funktion und übergeben Sie sie beim Erstellen des Bots. Diese Funktion sollte ein session_id-Objekt als Argument annehmen und ein BaseChatMessageHistory-Objekt zurückgeben.

  • session_id ist eine Kennung für die Sitzung, zu der diese Eingabenachrichten gehören. So können Sie mehrere Unterhaltungen gleichzeitig führen.
  • BaseChatMessageHistory ist die Schnittstelle für Klassen, die Nachrichtenobjekte laden und speichern können.

Datenbank einrichten

Eine Liste der ChatMessageHistory-Anbieter von Google, die in LangChain unterstützt werden, finden Sie unter Speicher.

Firestore (nativ)

Folgen Sie zuerst der LangChain-Dokumentation, um eine Datenbank einzurichten und das Paket zu installieren.

Definieren Sie als Nächstes eine get_session_history-Funktion so:

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

Erstelle den Agenten und gib ihn als chat_history ein:

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

Bigtable

Folgen Sie zuerst der LangChain-Dokumentation, um eine Datenbank einzurichten und das Paket zu installieren.

Definieren Sie als Nächstes eine get_session_history-Funktion so:

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

Erstelle den Agenten und gib ihn als chat_history ein:

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

Spanner

Folgen Sie zuerst der LangChain-Dokumentation, um eine Datenbank einzurichten und das Paket zu installieren.

Definieren Sie als Nächstes eine get_session_history-Funktion so:

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

Erstelle den Agenten und gib ihn als chat_history ein:

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

Wenn Sie den Agenten abfragen, geben Sie session_id an, damit der Agent frühere Fragen und Antworten „in Erinnerung“ behält:

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

Schritt 4: Vorlage für Prompts anpassen

Promptvorlagen helfen dabei, Nutzereingaben in Anweisungen für ein Modell umzuwandeln. Sie werden verwendet, um die Antwort eines Modells zu steuern, damit es den Kontext besser verstehen und relevante und kohärente sprachbasierte Ausgabe generieren kann. Weitere Informationen finden Sie unter ChatPromptTemplates.

Die Standardvorlage für Prompts ist in Abschnitte unterteilt.

Bereich Beschreibung
(Optional) Systemanweisung Eine Anleitung für den Kundenservicemitarbeiter, die auf alle Suchanfragen angewendet werden soll.
Optional: Chatprotokoll Nachrichten, die dem Chatverlauf aus einer früheren Sitzung entsprechen.
Nutzereingabe Die Anfrage des Nutzers, auf die der Kundenservicemitarbeiter antworten soll.
Agent-Scratchpad Nachrichten, die vom Bot erstellt werden (z.B. mit Funktionsaufrufen), wenn er seine Tools verwendet und eine Antwort für den Nutzer formuliert.

Die Standardvorlage für Prompts wird generiert, wenn Sie den Bot erstellen, ohne eine eigene Promptvorlage anzugeben. Sie sieht dann in vollem Umfang so aus:

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

Sie können die Standardvorlage für Prompts mit einer eigenen Vorlage überschreiben und beim Erstellen des Agents verwenden, z. B.:


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

Schritt 5: Orchestration anpassen

Alle LangChain-Komponenten implementieren die Runnable-Schnittstelle, die Eingabe- und Ausgabeschemata für die Orchestrierung bereitstellt. Für den LangchainAgent muss ein ausführbares Programm erstellt werden, damit er auf Abfragen reagieren kann. Standardmäßig erstellt LangchainAgent ein solches ausführbares Programm, indem es das Modell mit Tools bindet und einen AgentExecutor verwendet, der in einen RunnableWithMessageHistory eingewickelt ist, wenn der Chatverlauf aktiviert ist.

Sie können die Orchestrierung anpassen, wenn Sie (i) einen Agenten implementieren möchten, der eine deterministische Abfolge von Schritten ausführt (anstatt offene Überlegungen anzustellen) oder (ii) den Agenten in ReAct-ähnlicher Weise auffordern möchten, jeden Schritt mit Überlegungen dazu zu versehen, warum er diesen Schritt ausgeführt hat. Dazu müssen Sie beim Erstellen von LangchainAgent das ausführbare Standardprogramm überschreiben, indem Sie das runnable_builder=-Argument mit einer Python-Funktion der folgenden Signatur angeben:

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

Dabei gilt:

  • model entspricht dem Chatmodell, das von model_builder zurückgegeben wird (siehe Modell definieren und konfigurieren).
  • tools und model_tool_kwargs entsprechen den zu verwendenden Tools und Konfigurationen (siehe Tool definieren und verwenden).
  • chat_history entspricht der Datenbank zum Speichern von Chatnachrichten (siehe Chatprotokoll speichern),
  • system_instruction und prompt entsprechen der Prompt-Konfiguration (siehe Promptvorlage anpassen).
  • agent_executor_kwargs und runnable_kwargs sind die Schlüsselwortargumente, mit denen Sie das zu erstellende ausführbare Programm anpassen können.

So haben Sie verschiedene Möglichkeiten, die Orchestrierungslogik anzupassen.

ChatModel

Im einfachsten Fall kannst du einen Agenten ohne Orchestrierung erstellen, indem du runnable_builder durch LangchainAgent überschreibst, um model direkt zurückzugeben.

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

Wenn Sie das standardmäßige Tool-Aufrufverhalten durch einen eigenen ReAct-Agenten auf der Grundlage Ihres eigenen prompt überschreiben möchten (siehe Promptvorlage anpassen), müssen Sie die runnable_builder durch LangchainAgent überschreiben.

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

LCEL-Syntax

So erstellen Sie das folgende Diagramm mit der LangChain Expression Language (LCEL):

   Input
   /   \
 Pros  Cons
   \   /
  Summary

Sie müssen runnable_builder durch LangchainAgent überschreiben:

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

So erstellen Sie das folgende Diagramm mit LangGraph:

   Input
   /   \
 Pros  Cons
   \   /
  Summary

Sie müssen runnable_builder durch LangchainAgent überschreiben:

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

Nächste Schritte