Sie können Inline-Python-Code als Tool für Ihren Agenten bereitstellen, um die Funktionen Ihres Agenten flexibel zu erweitern. Dieser Code kann Eingaben vom Agenten akzeptieren und ein Ergebnis zurückgeben, das vom Agenten in der Unterhaltung verwendet wird. Sie können benutzerdefinierte Logik implementieren, eine Verbindung zu proprietären APIs oder Datenbanken herstellen und deterministische Ergebnisse für Aufgaben erzielen, die Präzision erfordern.
Name und Beschreibung
Beim Erstellen des Tools sollten der Name des Tools und der Name der aufzurufenden Hauptfunktion identisch sein und im Snake-Case-Format geschrieben werden.
Docstrings sind ein wichtiger Bestandteil der Definition eines Python-Tools. Der Docstring der Funktion wird als Toolbeschreibung verwendet, die Agenten zur Verfügung gestellt wird, die das Tool nutzen. Sie sollten Docstrings als Erweiterung von Prompts betrachten. Ein klarer, beschreibender und gut strukturierter Docstring hat direkten Einfluss darauf, wie gut das Modell versteht, was Ihr Tool tut, wann es verwendet werden sollte und welche Argumente angegeben werden müssen. Das ist der Schlüssel zu einer zuverlässigen und genauen Toolauswahl.
Umgebung
In Ihrem Python-Toolcode haben Sie Zugriff auf bestimmte Klassen und Funktionen, die Ihnen beim Schreiben des Codes helfen. Weitere Informationen finden Sie in der Referenz zur Python-Laufzeit.
Das Objekt context vom Typ ToolContext ist beispielsweise eine global verfügbare Variable
, die eine Momentaufnahme des aktuellen Unterhaltungsstatus enthält.
Sie müssen es nicht importieren oder als Parameter definieren, sondern können direkt darauf zugreifen.
Es enthält wertvolle Informationen für die Ausführung komplexer Logik.
Hier eine Aufschlüsselung der verfügbaren Schlüssel im Kontextobjekt:
function_call_id: Eine eindeutige ID für den spezifischen Toolaufruf, der ausgeführt wird.user_content: Ein Wörterbuch mit der letzten Nachricht des Nutzers, einschließlich Text und Rolle. Dies ist eines der am häufigsten verwendeten Attribute.state: Ein Wörterbuch, das den Sitzungsstatus darstellt. Sie können damit Variablen speichern und abrufen, die über mehrere Unterhaltungsrunden hinweg bestehen bleiben müssen (Nutzerprofil, Inhalt des Einkaufswagens usw.).events: Eine Liste aller Ereignisse im Unterhaltungsverlauf bis zu diesem Zeitpunkt. So können Sie Tools mit komplexerer Kontextsensitivität erstellen.session_id: Die eindeutige ID für die gesamte Unterhaltungssitzung.invocation_id: Eine eindeutige ID für die aktuelle Unterhaltungsrunde.agent_name: Der Name des Agenten, der das Tool ausführt.
Python-Tools, die andere Tools aufrufen
Beim Definieren von Python-Code-Tools können Sie explizit andere Tools aufrufen, die in der Agentenanwendung definiert sind.
Wenn Sie beispielsweise ein OpenAPI-Tool namens crm_service_get_cart_information haben, können Sie es mit dem folgenden Code aufrufen:
# Deterministically call another tool from this tool.
# This syntax for OpenAPI spec tool is:
# tools.<tool_name>_<endpoint_name>({tool_args})
res = tools.crm_service_get_cart_information({})
Codebeispiele
In den folgenden Abschnitten finden Sie Beispiele.
Letzte Nutzereingabe abrufen
Dieses Beispiel veranschaulicht eine grundlegende Funktion: den Zugriff auf die letzte Nachricht des Nutzers.
Das Tool prüft das Objekt context.user_content und extrahiert den Text aus der letzten Unterhaltungsrunde des Nutzers.
Dieses Muster ist für jedes Tool unerlässlich, das eine Aktion direkt auf Grundlage dessen ausführen muss, was der Nutzer gerade gesagt hat.
from typing import Optional
# Docstrings in tools are important because they are directly
# sent to the model as the description for the tool. You should
# think of docstrings as an extension of prompting. Clear and
# descriptive docstrings will yield higher quality tool
# selection from the model.
def get_last_user_utterance() -> Optional[str]:
"""
Retrieves the most recent message sent by the user from the conversation history.
Returns:
The text of the last user message, or None if no user messages are found.
"""
# The 'context.user_content' contains the last input data
# provided by the user.
# We can filter it to find only the text input from the user.
user_messages = [
part.text for part in context.user_content.parts
if context.user_content.role == "user"
]
if user_messages:
# The most recent message is the first one in the list.
return user_messages[0]
return None
Variablen abrufen und aktualisieren
Sprachmodelle können den Sitzungsstatus nicht direkt ändern. Das ist beabsichtigt, da so sichergestellt wird, dass Statusänderungen kontrolliert und vorhersehbar erfolgen. Der Status kann nur über zwei Mechanismen geändert werden: Python-Tools oder Callbacks.
Dieses Beispiel zeigt, wie ein Python-Tool den Status verwalten kann.
Das Tool liest zuerst das aktuelle customer_profile aus context.state.
Anschließend wird die Geschäftslogik ausgeführt (Punkte hinzufügen) und das aktualisierte Profil wird zurück in „context.state“ geschrieben.
Dieser neue Status ist dann für den Rest der Sitzung für den Agenten und andere Tools verfügbar.
from pydantic import BaseModel, Field
from typing import Optional, Dict, Any
# Using Pydantic defines the expected structure of your state variables. This makes your code more reliable and easier to
# debug.
class CustomerProfile(BaseModel):
email: Optional[str] = None
loyalty_points: int = Field(default=0, ge=0) # Must be >= 0
plan: str = "Standard"
# Docstrings in tools are important because they are directly
# sent to the model as the description for the tool. You should
# think of docstrings as an extension of prompting. Clear and
# descriptive docstrings will yield higher quality tool
# selection from the model.
def update_customer_loyalty_points(points_to_add: int) -> Dict[str, Any]:
"""
Adds loyalty points to the customer's profile and returns the updated profile.
Args:
points_to_add: The number of loyalty points to add to the existing total.
Returns:
A dictionary containing the customer's updated profile information.
"""
# 1. Get the current profile data from the session state.
# The .get() method safely returns an empty dict if
# 'customer_profile' doesn't exist.
current_profile_data = context.state.get("customer_profile", {})
# 2. Load the data into a Pydantic model for validation and easy access.
profile = CustomerProfile(**current_profile_data)
# 3. Perform the business logic.
# Print statements can be used for debugging and will show
# up in the tracing details.
profile.loyalty_points += points_to_add
print(f"Updated loyalty points to: {profile.loyalty_points}")
# 4. Save the updated data back into the session state.
# .model_dump() converts the Pydantic model back to a
# dictionary.
context.state["customer_profile"] = profile.model_dump()
return context.state["customer_profile"]
Anfragen an externe Netzwerke
Python-Tools können Anfragen an externe Netzwerke senden. Das ist nützlich, um Echtzeitdaten abzurufen oder in Drittanbieterdienste zu integrieren, für die keine OpenAPI-Spezifikation vorhanden ist. So haben Sie eine flexible Alternative zu OpenAPI-basierten Tools. Im Beispiel wird die Standardbibliothek „requests“ (in der Umgebung verfügbar) verwendet, um eine öffentliche API aufzurufen und eine zufällige Information abzurufen.
from typing import Optional
# Docstrings in tools are important because they are directly sent to the model as the
# description for the tool. You should think of docstrings as an extension of prompting.
# Clear and descriptive docstrings will yield higher quality tool selection from the model.
def get_random_fact() -> Optional[str]:
"""
Fetches a random fact from a public API.
Returns:
A string containing the fact on success, or None if an error occurs.
"""
# The 'ces_requests' library is inspired by 'requests', a standard and powerful way in Python
# to make HTTP network calls to any external API, just like you would with `curl` or a web browser.
url = "https://uselessfacts.jsph.pl/api/v2/facts/random"
try:
# This example calls a public API that is completely open and requires no authentication
# (like an API key). Many other APIs for services like weather or e-commerce require you
# to send credentials, often as an API key in the request headers or parameters.
res = ces_requests.get(url=url, json=request_body, headers=headers)
# Example POST request
#res = ces_requests.post(url=url, json=request_body, headers=headers)
# This is a standard practice with 'ces_requests' to check if the call was successful. It will
# raise an error for statuses like 404 or 500.
res.raise_for_status()
fact_data = res.json()
return fact_data.get("text")
except:
return None