Blocs de code

Lorsque vous définissez un playbook, vous pouvez éventuellement fournir des blocs de code, qui sont du code Python intégré permettant de mieux contrôler le comportement de l'agent. Ce code est composé de fonctions avec des décorateurs spéciaux et de toutes les fonctions utilitaires dont vous avez besoin.

Lorsque vous écrivez votre code, vous pouvez utiliser la bibliothèque système de blocs de code pour contrôler le comportement de l'agent.

Limites

Les limites suivantes s'appliquent :

  • Les blocs de code ne peuvent pas contenir d'objets qui conservent des données. Toutefois, vous pouvez utiliser des outils pour conserver des données et maintenir l'état.
  • Les blocs de code ne peuvent pas effectuer d'appels à distance directement. Par exemple, vous ne pouvez pas utiliser la bibliothèque de requêtes Python. Toutefois, vous pouvez utiliser des outils pour effectuer des appels à distance indirectement.
  • Les noms de ressources convertis en noms Python doivent être des noms Python valides.
  • Les blocs de code ne peuvent pas écrire de paramètres de session, sauf si une transition de flux a lieu.

Actions intégrées

Les actions intégrées se comportent de la même manière que les actions d'outil. Elles disposent d'un schéma d'entrée et de sortie défini, qui est déterminé par la signature de la fonction Python, y compris les annotations de type et la chaîne de documentation. Comme pour les appels d'outils, le LLM n'a pas connaissance du code qui implémente l'action.

Exemple :

@Action
def is_prime(n: int) -> bool:
  """Returns true if n is prime."""
  if not isinstance(n, int) or n < 2:
    return False

  for i in range(2, int(n ** 0.5) + 1):
    if n % i == 0:
      return False

  return True

Pour cette fonction, le LLM recevra des informations sur l'action, son entrée et sa sortie.

Pour référencer une action intégrée dans les instructions de votre playbook, il vous suffit de référencer le nom de l'action entre guillemets inversés et de décrire comment elle doit être utilisée.

Exemple d'action intégrée place_order :

Take the customer's order, then call the `place_order` action when the order is ready.

Pour créer des exemples qui utilisent des actions intégrées, utilisez le type d'outil inline-action dans la section Input &Output (Entrée et sortie).

Pour en savoir plus, consultez la documentation de référence sur @Action.

Déclencher des fonctions

Les fonctions de déclenchement permettent de définir des actions conditionnelles dans le code.

Les fonctions de déclenchement sont déclarées à l'aide de décorateurs. Vous pouvez utiliser les décorateurs de fonction de déclenchement suivants :

Décorateur Paramètres du décorateur Description
@EventTrigger event: str, condition: str, où la condition est facultative Déclenché par un événement
@BeforeModelTrigger condition: str, où la condition est facultative Déclenché chaque fois avant que le LLM ne prédise l'action suivante.
@BeforeActionTrigger condition: str, où la condition est facultative Déclenché chaque fois avant que le LLM n'exécute une action.
@BeforePlaybookTrigger condition: str, où la condition est facultative Déclenché la première fois qu'un playbook est démarré.

Par exemple, ces fonctions montrent comment utiliser ces décorateurs et leurs paramètres, ainsi que la fonction de la bibliothèque système de blocs de code de réponse .

# No decorator parameter
@PlaybookStartTrigger
def my_playbook_conditional_action():
  respond("How can I help?")

# With a condition decorator parameter
@BeforeActionTrigger('$next-action.name = "search"')
def my_before_action_conditional_action():
  respond("One moment please")

# Event
@EventTrigger(event="welcome")
def my_welcome_event():
  respond("hi")

# Event with a condition:
@EventTrigger(event="welcome",
              condition="$sys.func.NOW().hours < 10")
def my_good_morning_event():
  respond("Good morning ☕")

Référencer des flux, des playbooks et des outils

Dans votre bloc de code, vous pouvez référencer des flux, des playbooks et des outils spécifiques à l'aide des variables globales, flows, playbooks, et tools.

Chacun de ces objets comporte des membres qui correspondent aux noms des ressources correspondantes. Ces noms doivent être des noms Python valides.

Exemple :

  add_override(playbooks.troubleshooting, {})
  add_override(flows.billing)
  add_override(tools.weather_api.get_weather, {"location": "San Francisco"})

Lorsque vous référencez des flux et des playbooks dans un bloc de code, vous devez également les référencer dans les instructions du playbook avec la syntaxe suivante :

${RESOURCE_TYPE: my_resource_name}

Par exemple, si votre bloc de code contient flows.myflow et playbooks.myplaybook, les instructions de votre playbook doivent inclure :

${FLOW: myflow}
${PLAYBOOK: myplaybook}

Remplacements d'actions

Vous pouvez utiliser des blocs de code pour créer une file d'attente d'actions qui auront lieu avant toute autre action déterminée par le LLM, et potentiellement les remplacer. Pour remplacer des actions, utilisez la add_override fonction globale.

Toutes les actions de remplacement mises en file d'attente s'exécutent de manière séquentielle, et la sortie de l'action est disponible pour le LLM. Une fois la file d'attente vide, l'opération revient au LLM pour la sélection de l'action et de l'entrée, sauf si un remplacement termine le tour avec une réponse ou une autre fonction qui termine le tour.

Arguments de fonction :

  • action : action à effectuer. Pour une action intégrée, utilisez my_function_name. Pour une action d'outil, utilisez tools.my_tool_name.my_tool_action. Pour une action de flux, utilisez flows.my_flow_name.
  • inputs : entrées facultatives pour l'action. Exemple : {"location": "Omaha"}.

Exemples :

# Assuming remote tool named "dmv" with operationId "search_offices"
# remote tool with only requestBody
add_override(tools.dmv.search_offices,{"address": "95030"})

# remote tool with only parameters
add_override(tools.pets.get_pet, {"id": "123"})

# remote tool with requestBody + parameters:
add_override(tools.pets.create_pet, {"requestBody": {"arg1":"foo"}, "param1": "bar"})

# datastore. Assumes existing datastore tool named "Menu".
add_override(tools.menu.Menu, {"query": "what is the menu"})

# code block action. Assumes another code block @Action my_action.
add_override(my_action)

Remplacements de réponses

Comme pour les remplacements d'actions, mais spécifiquement pour les réponses de l'agent, vous pouvez utiliser la fonction globale respond pour forcer l'agent à répondre à l'utilisateur avec un contenu spécifique.

Exemple :

respond("Hello")

Appeler des outils

Dans les fonctions de votre bloc de code, vous pouvez appeler les outils définis pour votre agent. Contrairement au remplacement d'une action d'outil, lorsque vous appelez un outil directement, les résultats de l'exécution de l'outil ne sont pas disponibles pour le LLM.

Exemples :

# Assumes existing tool named "DMV" with operationId "search_offices"
# remote tool with only request body.
offices = tools.dmv.search_offices({"address": "95030"})

# remote tool with parameters and request body
offices = tools.dmv.search_offices({"requestBody": {"address":"95030"}, "param1":"foo"})

# datastore actions. Assumes existing datastore tool named "Menu".
data = tools.menu.Menu({"query": "get the menu"})["snippets"]

Faire correspondre l'intention

Les blocs de code peuvent faire correspondre une intention de manière programmatique pour un flux donné à l'aide de la Flow.match_intent.

Exemple :

matches = flows.flow1.match_intent(history.last_user_utterance).matches
if matches and matches[0].intent == "some_intent":
  to_country = matches[0].parameters.get("to_country")
  if to_country:
    respond(f"To confirm, you're going to {to_country}, right?")

Lire les paramètres de session

Les blocs de code peuvent lire les paramètres disponibles au moment de l'exécution.

Exemple :

state["$session.params.my-param"]
state["$request.session-id"]

Débogage

Vous pouvez utiliser le simulateur pour déboguer les fonctions de votre bloc de code. Ces fonctions s'affichent sous forme d'actions dans le simulateur et fournissent les détails nécessaires.

Contrôle supplémentaire

Ce guide couvre certaines utilisations courantes de la bibliothèque système de blocs de code. Pour d'autres types de contrôle, consultez la documentation de la bibliothèque.