יצירת סוכן LangChain

הסביבה Agent Runtime מאפשרת לפתח ולפרוס סוכנים באמצעות תבנית LangChain ספציפית למסגרת. באמצעות המחלקה LangchainAgent ב-Agent Platform SDK, אפשר ליצור סוכנים שמבצעים משימות מורכבות ומשתלבים עם כלים חיצוניים.

במאמר הזה נסביר איך לפתח סוכן LangChain, כולל הגדרת המודל, ציוד המודל בכלים לביצוע פעולות כמו אחזור של שערי חליפין וניהול היסטוריית הצ'אט.

מידע נוסף על ניהול הסוכנים שהופעלו זמין במאמר ניהול סוכנים שהופעלו.

לפני שמתחילים

פועלים לפי השלבים שמפורטים במאמר הגדרת הסביבה כדי לוודא שהסביבה מוגדרת.

הגדרה והגדרה של מודל

מציינים את המודל שרוצים להשתמש בו:

model = "gemini-3.5-flash"

אופציונלי: קובעים את הגדרות הבטיחות של המודל. מידע נוסף על האפשרויות שזמינות בהגדרות הבטיחות ב-Gemini זמין במאמר הגדרת מאפייני בטיחות. דוגמה להגדרת הגדרות הבטיחות:

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

אופציונלי: מציינים פרמטרים של מודל באופן הבא:

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

יוצרים LangchainAgent באמצעות הגדרות המודל:

from vertexai import agent_engines

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

אם אתם מריצים בסביבה אינטראקטיבית (כמו הטרמינל או נוטבוק של Colab), אתם יכולים להריץ שאילתה כשלב ביניים לבדיקה:

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

print(response)

התגובה היא מילון Python שדומה לדוגמה הבאה:

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

אופציונלי: התאמה אישית מתקדמת

בתבנית LangchainAgent נעשה שימוש ב-ChatVertexAI כברירת מחדל, כי היא מספקת גישה לכל המודלים הבסיסיים שזמינים ב- Google Cloud. כדי להשתמש במודל שלא זמין דרך ChatVertexAI, אפשר לציין את הארגומנט model_builder=, עם פונקציית Python בחתימה הבאה:

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

רשימה של מודלים של צ'אט שנתמכים ב-LangChain והיכולות שלהם מופיעה במאמר בנושא מודלים של צ'אט. קבוצת הערכים הנתמכים עבור model= ו-model_kwargs= ספציפית לכל מודל צ'אט, ולכן צריך לעיין במסמכים המתאימים כדי לקבל פרטים.

ChatVertexAI

מותקן כברירת מחדל.

היא משמשת ב-LangchainAgent כשמשמיטים את הארגומנט model_builder, לדוגמה

from vertexai import agent_engines

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

ChatAnthropic

קודם כל, צריך לעיין בתיעוד כדי להגדיר חשבון ולהתקין את החבילה.

לאחר מכן, מגדירים model_builder שמחזירה ChatAnthropic:

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

לבסוף, משתמשים בו ב-LangchainAgent עם הקוד הבא:

from vertexai import agent_engines

agent = agent_engines.LangchainAgent(
    model="claude-3-opus-20240229",                       # Required.
    model_builder=model_builder,                          # Required.
    model_kwargs={
        "api_key": "ANTHROPIC_API_KEY",  # Required.
        "temperature": 0.28,                              # Optional.
        "max_tokens": 1000,                               # Optional.
    },
)

ChatOpenAI

אפשר להשתמש ב-ChatOpenAI בשילוב עם ChatCompletions API של Gemini.

קודם צריך לפעול לפי ההוראות במאמרי העזרה כדי להתקין את החבילה.

לאחר מכן, מגדירים model_builder שמחזירה 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,
    )

לבסוף, משתמשים בו ב-LangchainAgent עם הקוד הבא:

from vertexai import agent_engines

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

הגדרה ושימוש בכלי

אחרי שמגדירים את המודל, השלב הבא הוא להגדיר את הכלים שהמודל משתמש בהם כדי להסיק מסקנות. כלי יכול להיות כלי LangChain או פונקציית Python. אפשר גם להמיר פונקציית Python מוגדרת לכלי LangChain.

כשמגדירים פונקציה, חשוב לכלול הערות שמתארות באופן מלא וברור את הפרמטרים של הפונקציה, את הפעולות שהיא מבצעת ואת הערך שהיא מחזירה. המודל משתמש במידע הזה כדי לקבוע באיזו פונקציה להשתמש. אתם צריכים גם לבדוק את הפונקציה באופן מקומי כדי לוודא שהיא פועלת.

משתמשים בקוד הבא כדי להגדיר פונקציה שמחזירה שער חליפין:

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

כדי לבדוק את הפונקציה לפני שמשתמשים בה בסוכן, מריצים את הפקודה הבאה:

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

התגובה אמורה להיות דומה לזו:

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

כדי להשתמש בכלי בתוך LangchainAgent, צריך להוסיף אותו לרשימת הכלים בארגומנט tools=:

from vertexai import agent_engines

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

אפשר לבדוק את הנציג באופן מקומי על ידי ביצוע שאילתות בדיקה. מריצים את הפקודה הבאה כדי לבדוק את הסוכן באופן מקומי באמצעות דולר אמריקאי וקרונה שוודית:

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

התגובה היא מילון שדומה לזה:

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

אופציונלי: כמה כלים

אפשר להגדיר וליצור מופעים של כלים ל-LangchainAgent בדרכים אחרות.

כלי העיגון

קודם מייבאים את חבילת generate_models ויוצרים את הכלי

from vertexai.generative_models import grounding, Tool

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

לאחר מכן, משתמשים בכלי בתוך LangchainAgent:

from vertexai import agent_engines

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

התגובה היא מילון שדומה לזה:

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

פרטים נוספים זמינים במאמר בנושא הארקה.

כלי LangChain

קודם כול, מתקינים את החבילה שמגדירה את הכלי.

pip install langchain-google-community

לאחר מכן מייבאים את החבילה ויוצרים את הכלי.

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

לבסוף, משתמשים בכלי בתוך LangchainAgent:

from vertexai import agent_engines

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

התגובה צריכה להיות כזו

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

כדי לראות את הדוגמה המלאה, אפשר לעיין במחברת.

דוגמאות נוספות לכלים שזמינים ב-LangChain אפשר למצוא בכלים של Google.

Agent Platform Extension

קודם מייבאים את חבילת התוספים ויוצרים את הכלי

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

לאחר מכן, משתמשים בכלי בתוך LangchainAgent:

from vertexai import agent_engines

agent = agent_engines.LangchainAgent(
    model=model,
    tools=[generate_and_execute_code],
)
agent.query(
    input="""Using the data below, construct a bar chart that includes only the height values with different colors for the bars:

    tree_heights_prices = {
      \"Pine\": {\"height\": 100, \"price\": 100},
      \"Oak\": {\"height\": 65, \"price\": 135},
      \"Birch\": {\"height\": 45, \"price\": 80},
      \"Redwood\": {\"height\": 200, \"price\": 200},
      \"Fir\": {\"height\": 180, \"price\": 162},
    }
    """
)

התשובה שמתקבלת צריכה להיות דומה לתשובה הבאה:

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

כדי שהסוכן הפרוס יוכל לגשת לתוסף Code Interpreter, צריך להוסיף את התפקיד Agent Platform User‏ (roles/aiplatform.user) לחשבון השירות של סוכן השירות של מנוע ההסקה של AI Platform. מידע נוסף זמין במאמר בנושא ניהול הגישה.

אתם יכולים להשתמש בכל הכלים שיצרתם ב-LangchainAgent (או בחלק מהם):

from vertexai import agent_engines

agent = agent_engines.LangchainAgent(
    model=model,
    tools=[
        get_exchange_rate,         # Optional (Python function)
        grounded_search_tool,      # Optional (Grounding Tool)
        movie_search_tool,         # Optional (Langchain Tool)
        generate_and_execute_code, # Optional (Vertex Extension)
    ],
)

agent.query(input="When is the next total solar eclipse in US?")

אופציונלי: הגדרת הכלי

עם Gemini, אתם יכולים להגביל את השימוש בכלים. לדוגמה, במקום לאפשר למודל ליצור תשובות בשפה טבעית, אפשר לחייב אותו ליצור רק קריאות לפונקציות ('קריאות לפונקציות בכפייה').

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

agent = agent_engines.LangchainAgent(
    model="gemini-3.5-flash",
    tools=[search_arxiv, get_exchange_rate],
    model_tool_kwargs={
        "tool_config": {  # Specify the tool configuration here.
            "function_calling_config": {
                "mode": ToolConfig.FunctionCallingConfig.Mode.ANY,
                "allowed_function_names": ["search_arxiv", "get_exchange_rate"],
            },
        },
    },
)

agent.query(
    input="Explain the Schrodinger equation in a few sentences",
)

פרטים נוספים זמינים במאמר בנושא הגדרת כלי.

שמירת היסטוריית הצ'אט

כדי לעקוב אחרי הודעות בצ'אט ולצרף אותן למסד נתונים, צריך להגדיר פונקציה get_session_history ולהעביר אותה כשיוצרים את הנציג. הפונקציה הזו צריכה לקבל session_id ולהחזיר אובייקט BaseChatMessageHistory.

  • session_id הוא מזהה של הסשן שהודעות הקלט האלה שייכות לו. כך תוכלו לנהל כמה שיחות בו-זמנית.
  • BaseChatMessageHistory הוא הממשק של מחלקות שיכולות לטעון ולשמור אובייקטים של הודעות.

הגדרת מסד נתונים

רשימה של ChatMessageHistory ספקים מ-Google שנתמכים ב-LangChain זמינה במאמר בנושא זיכרון.

קודם כל, פועלים לפי ההוראות במסמכי LangChain כדי להתקין את החבילה הרלוונטית ולהשתמש בה כדי להגדיר מסד נתונים לפי בחירתכם (למשל Firestore,‏ Bigtable או Spanner):

לאחר מכן, מגדירים פונקציה get_session_history באופן הבא:

‫Firestore (מצב Native)

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

לבסוף, יוצרים את הסוכן ומעבירים אותו כ-chat_history:

from vertexai import agent_engines

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

כששולחים שאילתה לסוכן, חשוב להעביר את session_id כדי שלסוכן יהיה "זיכרון" של שאלות ותשובות קודמות:

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

כדי לוודא שהזיכרון של הסשן יישמר בשאילתות הבאות:

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

print(response)

התאמה אישית של תבנית ההנחיה

תבניות של הנחיות עוזרות לתרגם את קלט של משתמשים להוראות עבור מודל, והן משמשות להכוונת התגובה של המודל, כדי לעזור לו להבין את ההקשר וליצור פלט רלוונטי ועקבי שמבוסס על שפה. פרטים נוספים זמינים במאמר בנושא ChatPromptTemplates.

תבנית ברירת המחדל של ההנחיה מאורגנת ברצף לקטעים.

קטע תיאור
אופציונלי: הוראות למערכת הוראות לסוכן שחלות על כל השאילתות.
אופציונלי: היסטוריית הצ'אט הודעות שמתאימות להיסטוריית הצ'אט מפעילות קודמת.
קלט של משתמשים השאילתה שהמשתמש שולח לסוכן כדי לקבל ממנו תשובה.
פנקס של סוכן הודעות שנוצרו על ידי הסוכן (למשל, באמצעות קריאה להפעלת פונקציות) כשהוא משתמש בכלים שלו ומבצע חשיבה רציונלית כדי לגבש תשובה למשתמש.

תבנית ברירת המחדל של ההנחיה נוצרת אם יוצרים את הסוכן בלי לציין תבנית הנחיה משלכם, והיא תיראה כך במלואה:

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

בדוגמה הבאה, אתם משתמשים בתבנית לפרומפט המלאה באופן מרומז כשאתם יוצרים מופע של הסוכן:

from vertexai import agent_engines

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

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

אתם יכולים להחליף את תבנית ברירת המחדל של ההנחיה בתבנית הנחיה משלכם, ולהשתמש בה כשאתם יוצרים את הסוכן, למשל:


from vertexai import agent_engines

custom_prompt_template = {
    "user_input": lambda x: x["input"],
    "history": lambda x: x["history"],
    "agent_scratchpad": lambda x: format_to_tool_messages(x["intermediate_steps"]),
} | ChatPromptTemplate.from_messages([
    ("placeholder", "{history}"),
    ("user", "{user_input}"),
    ("placeholder", "{agent_scratchpad}"),
])

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

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

התאמה אישית של התזמור

כל הרכיבים של LangChain מטמיעים את ממשק ה-Runnable, שמספק סכימות של קלט ופלט לתיאום. כדי שמחלקה מסוג LangchainAgent תגיב לשאילתות, צריך ליצור עבורה קובץ הפעלה. כברירת מחדל, LangchainAgent יוצרת קובץ הפעלה כזה על ידי קישור המודל לכלים ושימוש ב-AgentExecutor שעטוף ב-RunnableWithMessageHistory אם היסטוריית הצ'אט מופעלת.

אולי תרצו להתאים אישית את התזמור אם אתם מתכוונים (i) להטמיע סוכן שמבצע קבוצה דטרמיניסטית של שלבים (במקום לבצע נימוק פתוח), או (ii) להנחות את הסוכן באופן שדומה ל-ReAct כדי להוסיף הערות לכל שלב עם הסברים למה הוא ביצע את השלב הזה. כדי לעשות את זה, צריך לשנות את ברירת המחדל של ההפעלה כשיוצרים LangchainAgent על ידי ציון הארגומנט runnable_builder= עם פונקציית Python עם החתימה הבאה:

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

איפה

כך אפשר להתאים אישית את לוגיקת התזמור.

ChatModel

במקרה הפשוט ביותר, כדי ליצור סוכן בלי תזמור, אפשר לשנות את runnable_builder של LangchainAgent כדי להחזיר את model ישירות.

from vertexai import agent_engines
from langchain_core.language_models import BaseLanguageModel

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

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

ReAct

כדי לשנות את התנהגות ברירת המחדל של הפעלת כלים עם סוכן ReAct משלכם שמבוסס על prompt משלכם (ראו התאמה אישית של תבנית ההנחיה), צריך לשנות את runnable_builder בשביל LangchainAgent.

from typing import Sequence
from langchain_core.language_models import BaseLanguageModel
from langchain_core.prompts import BasePromptTemplate
from langchain_core.tools import BaseTool
from langchain import hub

from vertexai import agent_engines

def react_builder(
    model: BaseLanguageModel,
    *,
    tools: Sequence[BaseTool],
    prompt: BasePromptTemplate,
    agent_executor_kwargs = None,
    **kwargs,
):
    from langchain.agents.react.agent import create_react_agent
    from langchain.agents import AgentExecutor

    agent = create_react_agent(model, tools, prompt)
    return AgentExecutor(agent=agent, tools=tools, **agent_executor_kwargs)

agent = agent_engines.LangchainAgent(
    model=model,
    tools=[get_exchange_rate],
    prompt=hub.pull("hwchase17/react"),
    agent_executor_kwargs={"verbose": True}, # Optional. For illustration.
    runnable_builder=react_builder,
)

תחביר LCEL

כדי לבנות את הגרף הבא באמצעות LangChain Expression Language ‏ (LCEL),

   Input
   /   \
 Pros  Cons
   \   /
  Summary

צריך לבטל את ההגדרה של runnable_builder עבור LangchainAgent:

from vertexai import agent_engines

def lcel_builder(*, model, **kwargs):
    from operator import itemgetter
    from langchain_core.prompts import ChatPromptTemplate
    from langchain_core.runnables import RunnablePassthrough
    from langchain_core.output_parsers import StrOutputParser

    output_parser = StrOutputParser()

    planner = ChatPromptTemplate.from_template(
        "Generate an argument about: {input}"
    ) | model | output_parser | {"argument": RunnablePassthrough()}

    pros = ChatPromptTemplate.from_template(
        "List the positive aspects of {argument}"
    ) | model | output_parser

    cons = ChatPromptTemplate.from_template(
        "List the negative aspects of {argument}"
    ) | model | output_parser

    final_responder = ChatPromptTemplate.from_template(
        "Argument:{argument}\nPros:\n{pros}\n\nCons:\n{cons}\n"
        "Generate a final response given the critique",
    ) | model | output_parser

    return planner | {
        "pros": pros,
        "cons": cons,
        "argument": itemgetter("argument"),
    } | final_responder

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

LangGraph

כדי ליצור את הגרף הבא באמצעות LangGraph:

   Input
   /   \
 Pros  Cons
   \   /
  Summary

צריך לשנות את runnable_builder עבור LangchainAgent:

from vertexai import agent_engines

def langgraph_builder(*, model, **kwargs):
    from langchain_core.prompts import ChatPromptTemplate
    from langchain_core.output_parsers import StrOutputParser
    from langgraph.graph import END, MessageGraph

    output_parser = StrOutputParser()

    planner = ChatPromptTemplate.from_template(
        "Generate an argument about: {input}"
    ) | model | output_parser

    pros = ChatPromptTemplate.from_template(
        "List the positive aspects of {input}"
    ) | model | output_parser

    cons = ChatPromptTemplate.from_template(
        "List the negative aspects of {input}"
    ) | model | output_parser

    summary = ChatPromptTemplate.from_template(
        "Input:{input}\nGenerate a final response given the critique",
    ) | model | output_parser

    builder = MessageGraph()
    builder.add_node("planner", planner)
    builder.add_node("pros", pros)
    builder.add_node("cons", cons)
    builder.add_node("summary", summary)

    builder.add_edge("planner", "pros")
    builder.add_edge("planner", "cons")
    builder.add_edge("pros", "summary")
    builder.add_edge("cons", "summary")
    builder.add_edge("summary", END)
    builder.set_entry_point("planner")
    return builder.compile()

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

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

המאמרים הבאים

מדריך

במאמר הזה מוסבר על חמש דרכים לפריסת סוכן ב-Agent Platform Runtime, בהתאם לצרכי הפיתוח שלכם.

מדריך

שימוש בסוכן LangChain עם Agent Platform Runtime.

מדריך

יצירה ופריסה של סוכן בסיסי ושימוש בשירות ההערכה של AI גנרטיבי כדי להעריך את הסוכן

פתרון בעיות

איך פותרים שגיאות נפוצות כשיוצרים סוכנים מותאמים אישית

Resource

מקורות מידע ותמיכה ב-Google Agent Platform