Les rappels sont une fonctionnalité avancée qui fournit un mécanisme puissant pour s'intégrer au processus d'exécution d'un agent spécifique à l'aide de code Python. Ils vous permettent d'observer, de personnaliser et même de contrôler le comportement de l'agent à des points spécifiques prédéfinis.
Vous pouvez utiliser différents types de rappels, chacun étant exécuté à un moment précis du tour de conversation. Ces types sont décrits dans les sections ci-dessous.
Environnement d'exécution et classes Python
Dans votre code de rappel 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.
Types de rappel
En fonction du type de rappel, votre fonction de rappel principale doit porter un nom spécifique. Cela vous permet de définir des fonctions d'assistance de n'importe quel nom dans votre code de rappel.
Chaque type de rappel est exécuté à un moment précis du tour de conversation :

Si vous définissez plusieurs rappels d'un type spécifique, ils seront exécutés dans l'ordre dans lequel vous les définissez.
Les sections ci-dessous décrivent chaque type de rappel, en fournissant les informations suivantes pour chacun d'eux :
| X | X |
|---|---|
| Nom | Nom de la fonction de rappel requise |
| Exécution | Point d'exécution dans le tour de conversation. |
| Objectif | Scénarios utiles pour utiliser le rappel. |
| Arguments | Arguments d'entrée pour la fonction. |
| Renvoyer | Valeur de retour de la fonction. |
| Rappel ADK | Lien vers la documentation du rappel ADK correspondant. |
Avant le début de l'agent (before_agent_callback)
| X | X |
|---|---|
| Nom | before_agent_callback |
| Exécution | Appelé avant l'invocation de l'agent. |
| Objectif | Utile pour configurer les ressources ou l'état nécessaires à l'agent, effectuer des contrôles de validation sur l'état de la session ou éviter l'appel de l'agent. |
| Arguments | CallbackContext |
| Renvoyer | Content(facultatif) : si cette option est définie, l'agent n'est pas appelé et la réponse fournie est utilisée. |
| Rappel ADK | before_agent_callback |
Exemple de code :
import random
def before_agent_callback(
callback_context: CallbackContext
) -> Optional[Content]:
username = callback_context.variables.get("username", None)
if not username:
# default user
final_name = "Default Name"
else:
# add a random integer to the username
final_name = f"{username} {random.randint(1,10)}"
# update the username variable
callback_context.variables["username"] = final_name
Une fois l'agent terminé (after_agent_callback)
| X | X |
|---|---|
| Nom | after_agent_callback |
| Exécution | Appelé une fois l'agent terminé. |
| Objectif | Utile pour les tâches de nettoyage, la validation post-exécution, la modification de l'état final ou la mise à jour de la réponse de l'agent. |
| Arguments | CallbackContext |
| Renvoyer | Contenu(facultatif) : si cette option est définie, remplacez la sortie de l'agent par la sortie fournie. |
| Rappel ADK | after agent callback |
Exemple de code :
def after_agent_callback(
callback_context: CallbackContext
) -> Optional[Content]:
if callback_context.agent_name == "Routing Agent":
counter = callback_context.variables.get("counter", 0)
counter += 1
# increment the invoked counter for this agent
callback_context.variables["counter"] = int(counter)
Avant l'appel LLM (before_model_callback)
| X | X |
|---|---|
| Nom | before_model_callback |
| Exécution | Appelé avant la requête de modèle. |
| Objectif | Utile pour inspecter/modifier la requête du modèle ou pour éviter l'utilisation du modèle. |
| Arguments | CallbackContext, LlmRequest |
| Renvoyer | LlmResponse : si cette valeur est définie, l'appel de modèle est ignoré et la réponse est utilisée comme si elle provenait du modèle. |
| Rappel ADK | before_model_callback |
Exemple de code :
def before_model_callback(
callback_context: CallbackContext,
llm_request: LlmRequest
) -> Optional[LlmResponse]:
"""
This callback executes *before* a request is sent to the LLM.
By returning an `LlmResponse` object, we are intercepting the call to the
LLM. The LLM will *not* be called, and the framework will instead use the
`LlmResponse` we provide as if it came from the model.
This is the core mechanism for implementing input guardrails, prompt
validation, or serving responses from a cache. Here, we force the agent to
call a function instead of thinking with the LLM.
"""
# Modify the shared session state.
callback_context.variables['foo'] = 'baz'
# Skip the LLM call and return a custom response telling the agent to
# execute a specific function.
return LlmResponse(
content=Content(parts=[Part(
function_call=FunctionCall(
name="function_name", args={"arg_name": "arg_value"}))],
role="model"))
Après l'appel LLM (after_model_callback)
| X | X |
|---|---|
| Nom | after_model_callback |
| Exécution | Appelé après la réception d'une réponse du modèle. |
| Objectif | Utile pour reformater les réponses du modèle, censurer les informations sensibles générées par le modèle, analyser les données structurées du modèle pour les utiliser dans des variables et gestion des exceptions du modèle. |
| Arguments | CallbackContext, LlmResponse |
| Renvoyer | LlmResponse : si cette valeur est définie, remplacez la réponse du modèle par la réponse fournie. |
| Rappel ADK | après le rappel du modèle |
Exemple de code :
def after_model_callback(
callback_context: CallbackContext,
llm_response: LlmResponse
) -> Optional[LlmResponse]:
"""
This callback executes *after* a response has been received from the LLM,
but before the agent processes it.
The `llm_response` parameter contains the actual data from the LLM.
By returning `None`, we are approving this response and allowing the agent
to use it as-is.
If we returned a new `LlmResponse` object, it would *replace* the original,
which is useful for redacting sensitive information, enforcing output
formatting, or adding disclaimers.
"""
# Returning None allows the LLM's actual response to be used.
return None
Avant l'appel d'outil (before_tool_callback)
| X | X |
|---|---|
| Nom | before_tool_callback |
| Exécution | Appelé avant les appels d'outil. |
| Objectif | Utile pour inspecter et modifier les arguments des outils, vérifier les autorisations avant l'exécution des outils ou implémenter une mise en cache au niveau de l'outil. |
| Arguments | Tool, Dict[str,Any]: tool inputs, CallbackContext |
| Renvoyer | Dict[str,Any] : si cette valeur est définie, l'exécution de l'outil est ignorée et cette sortie est fournie au modèle. |
| Rappel ADK | before tool callback |
Exemple de code :
def before_tool_callback(
tool: Tool,
input: dict[str, Any],
callback_context: CallbackContext
) -> Optional[dict[str, Any]]:
"""
This callback executes *before* a specific tool is called by the agent.
Here, we modify the input arguments intended for the tool and then return
a dictionary. By returning a dictionary instead of `None`, we are
overriding the default behavior. The actual tool function will *not* be
executed. Instead, the dictionary we return will be treated as the
llm.tool's result and passed back to the LLM for the next step.
This is ideal for validating tool inputs, applying policies, or returning
mocked/cached data for testing.
"""
# Modify the shared session state.
callback_context.variables['foo'] = 'baz'
# Modify the arguments for the tool call in-place.
input['input_arg'] = 'updated_val1'
input['additional_arg'] = 'updated_val2'
# Override the tool call and return a mocked result.
return {"result": "ok"}
Après l'appel d'outil (after_tool_callback)
| X | X |
|---|---|
| Nom | after_tool_callback |
| Exécution | Appelé après l'exécution de l'outil. |
| Objectif | Utile pour inspecter et modifier la réponse de l'outil avant de la renvoyer au modèle, post-traiter les résultats de l'outil ou enregistrer des parties spécifiques d'une réponse d'outil dans des variables. |
| Arguments | Tool, Dict[str,Any]: tool inputs, CallbackContext, Dict[str,Any]: tool response |
| Renvoyer | Dict[str,Any]: si cette valeur est définie, elle remplace la réponse de l'outil fournie au modèle. |
| Rappel ADK | after tool callback |
Exemple de code :
# Previous tool was named `get_user_info`
# Previous tool returned the payload:
# {"username": "Patrick", "fave_food": ["pizza"]}
def after_tool_callback(
tool: Tool,
input: dict[str, Any],
callback_context: CallbackContext,
tool_response: dict
) -> Optional[dict]:
if tool.name == "get_user_info":
tool_response["username"] = "Gary"
tool_response["pet"] = "dog"
# Override tool response
return tool_response
Créer un rappel
Pour créer un rappel :
- Ouvrez les paramètres de l'agent.
- Cliquez sur Ajouter un code.
- Sélectionnez un type de rappel.
- Fournis du code Python.
- Cliquez sur Enregistrer.
Charges utiles personnalisées (custom_payloads)
Les charges utiles personnalisées permettent d'inclure des données structurées supplémentaires et non textuelles (généralement au format JSON) dans la réponse d'un agent. Cette charge utile est essentielle pour orienter ou augmenter l'interaction de l'agent avec des systèmes externes ou des applications clientes.
La valeur de la charge utile n'est pas visible par le grand modèle de langage (LLM). Elle n'est utilisée que pour générer la réponse finale.
Les charges utiles personnalisées sont générées et définies à l'aide de rappels, en particulier before_model_callback ou after_model_callback.
La charge utile personnalisée peut être utilisée à plusieurs fins, généralement axées sur l'activation d'interactions riches et structurées :
- Escalade/Transfert d'agent : cette fonctionnalité est fréquemment utilisée pour transférer une interaction à un agent humain en fournissant des instructions de routage (par exemple, la file d'attente spécifique vers laquelle transférer l'interaction).
- Contenu enrichi et actions côté client : il permet d'intégrer des widgets et d'autres contenus enrichis directement dans les expériences de chat, ce qui est particulièrement utile pour les intégrations de chat personnalisées.
- Par exemple, vous pouvez afficher des URL d'images ou des options et des chips de réponse rapide pour un client qui utilise une interface comme Call Companion.
- Composition de la réponse :
Les charges utiles personnalisées peuvent être configurées pour être renvoyées de différentes manières :
- Renvoie uniquement la charge utile explicite de manière déterministe.
- Renvoyez la charge utile avec une réponse textuelle générée par le LLM.
- Renvoyer la charge utile avec une réponse texte statique
Configurer l'agent
Les charges utiles personnalisées ne peuvent être générées et définies qu'à l'aide de rappels.
La charge utile est définie en tant que Blob avec un mime_type de application/json.
Part.from_json(data=payload_string)
Exemple d'after_model_callback
Il s'agit d'un exemple de after_model_callback qui renvoie la réponse du modèle ainsi qu'une réponse de charge utile personnalisée supplémentaire.
import json
def after_model_callback(callback_context: CallbackContext, llm_response: LlmResponse) -> Optional[LlmResponse]:
"""
Adds a custom payload to every model response which is a text
"""
if (llm_response.content.parts[0].text is not None):
# construct payload
payload_dict = { "custom_payload_key": "custom_payload_value"}
payload_json_string = json.dumps(payload_dict)
new_parts = []
# Keep the origial agent response part, as model only sees text in the historical context.
new_parts.append(Part(text=llm_response.content.parts[0].text))
# Append custom payload
new_parts.append(Part.from_json(data=payload_string))
return LlmResponse(content=Content(parts=new_parts))
Exemple de before_model_callback
Il s'agit d'un exemple de before_model_callback qui renvoie une charge utile personnalisée supplémentaire après le déclenchement d'un certain outil.
import json
def has_escalate(llm_request: LlmRequest) -> bool:
for content in llm_request.contents:
for part in content.parts:
if part.function_call and part.function_call.name == 'escalate':
return True
return False
def before_model_callback(callback_context: CallbackContext, llm_request: LlmRequest) -> Optional[LlmResponse]:
# checks if `escalate` tool is being called
if not has_escalate(llm_request):
return None
payload_dict = { "escalate": "user ask for escalation"}
payload_json_string = json.dumps(payload_dict)
return LlmResponse(content=Content(parts=[Part(text="ESCALATE!!!"), Part.from_json(data=payload_json_string)]))
Valider la charge utile dans la réponse au moment de l'exécution
La charge utile est renseignée sous forme de structure dans le champ payload pour RunSession et BidiRunSession.
La valeur de la charge utile n'est pas visible par le LLM.