Vous pouvez fournir du code Python intégré comme outil pour votre agent, ce qui vous permet d'étendre ses capacités de manière flexible. Ce code peut accepter les entrées fournies par l'agent et renvoyer un résultat utilisé par l'agent dans la conversation. Vous pouvez implémenter n'importe quelle logique personnalisée, vous connecter à des API ou bases de données propriétaires, et garantir des résultats déterministes pour les tâches qui nécessitent de la précision.
Nom et description
Lors de la création de l'outil, le nom de l'outil et celui de la fonction principale à appeler doivent être identiques et en snake case.
Les docstrings sont un élément essentiel de la définition d'un outil Python. La docstring de la fonction est utilisée comme description de l'outil, qui est fournie aux agents qui l'utilisent. Considérez les docstrings comme une extension de l'incitation. Une docstring claire, descriptive et bien structurée a une incidence directe sur la capacité du modèle à comprendre ce que fait votre outil, quand l'utiliser et quels arguments fournir. C'est la clé pour sélectionner des outils fiables et précis.
Environnement
Dans le code de votre outil Python, vous avez accès à certaines classes et fonctions qui vous aident à écrire le code. Pour en savoir plus, consultez la documentation de référence sur l'environnement d'exécution Python.
Par exemple, l'objet context est une variable disponible globalement qui fournit un instantané de l'état actuel de la conversation.
Vous n'avez pas besoin de l'importer ni de le définir comme paramètre. Vous pouvez y accéder directement.
Il contient des informations utiles pour exécuter une logique complexe.
Voici le détail des clés disponibles dans l'objet de contexte :
function_call_id: ID unique de l'appel d'outil spécifique en cours d'exécution.user_content: dictionnaire contenant le message le plus récent de l'utilisateur, y compris le texte et le rôle. Il s'agit de l'un des attributs les plus couramment utilisés.state: dictionnaire représentant l'état de la session. Vous pouvez l'utiliser pour stocker et récupérer des variables qui doivent persister sur plusieurs tours de conversation (profil utilisateur, contenu du panier, etc.).events: liste de tous les événements de l'historique des conversations jusqu'à présent, ce qui vous permet de créer des outils avec une conscience contextuelle plus complexe.session_id: identifiant unique de l'ensemble de la session de conversation.invocation_id: identifiant unique du tour de conversation en cours.agent_name: nom de l'agent qui exécute l'outil.
Outils Python appelant d'autres outils
Lorsque vous définissez des outils de code Python, vous pouvez appeler explicitement d'autres outils définis dans l'application d'agent.
Par exemple, si vous disposez d'un outil OpenAPI appelé crm_service_get_cart_information, vous pouvez l'appeler avec le code suivant :
# 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({})
Exemples de code
Les sections suivantes fournissent des exemples.
Obtenir la dernière entrée utilisateur
Cet exemple illustre une fonctionnalité fondamentale : accéder au message le plus récent de l'utilisateur.
L'outil inspecte l'objet context.user_content et extrait le texte du dernier tour de l'utilisateur.
Ce modèle est essentiel pour tout outil qui doit effectuer une action directement basée sur ce que l'utilisateur vient de dire.
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
Obtenir et mettre à jour des variables
Les modèles de langage ne peuvent pas modifier directement l'état de la session. C'est intentionnel, car cela garantit que les changements d'état sont gérés de manière contrôlée et prévisible. L'état ne peut être modifié que par deux mécanismes : les outils Python ou les rappels.
Cet exemple montre comment un outil Python peut gérer l'état.
L'outil lit d'abord le customer_profile actuel à partir de context.state.
Il exécute ensuite sa logique métier (ajout de points) et réécrit le profil mis à jour dans context.state.
Ce nouvel état sera ensuite disponible pour l'agent et les autres outils pendant le reste de la session.
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"]
Demandes de réseau externe
Les outils Python peuvent effectuer des requêtes réseau externes, ce qui est utile pour récupérer des données en temps réel ou s'intégrer à des services tiers qui ne disposent pas de spécification OpenAPI. Cela constitue une alternative flexible à l'utilisation d'outils basés sur OpenAPI. L'exemple utilise la bibliothèque de requêtes standard (disponible dans l'environnement) pour appeler une API publique et récupérer une information aléatoire.
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