Cuando definas un playbook, puedes proporcionar bloques de código, que son código Python insertado que se puede usar para controlar mejor el comportamiento del agente. Este código se compone de funciones con decoradores especiales y las funciones de utilidad que necesites.
Cuando escribas tu código, puedes usar la biblioteca del sistema de bloques de código para controlar el comportamiento del agente.
Problemas conocidos
Se aplican los siguientes problemas conocidos:
- Los proyectos de los perímetros de VPC-SC que restrinjan el acceso a Artifact Registry también rechazarán las implementaciones de Code Block.
Limitaciones
Se aplican las siguientes limitaciones:
- Los bloques de código no pueden contener objetos que conserven datos. Sin embargo, puedes usar herramientas para conservar los datos y mantener el estado.
- Los bloques de código no pueden hacer llamadas remotas directamente. Por ejemplo, no puedes usar la biblioteca de solicitudes de Python. Sin embargo, puedes usar herramientas para hacer llamadas remotas de forma indirecta.
- Los nombres de recursos que se convierten en nombres de Python deben ser nombres de Python válidos.
- Los bloques de código no pueden escribir parámetros de sesión, a menos que se produzca una transición de flujo.
Acciones insertadas
Las acciones insertadas se comportan de forma similar a las acciones de herramientas. Tienen un esquema de entrada y salida definido, que se determina mediante la firma de la función de Python, incluidas las anotaciones de tipo y la cadena de documentación. Al igual que ocurre con las llamadas a herramientas, el LLM no conoce el código que implementa la acción.
Ejemplo:
@Action
def is_prime(n: int): bool
"""Returns true if n is prime."""
import math
return (all([False for i in range(2, math.sqrt(n)
if n % i == 0 ]) and not n < 2)
Para esta función, se proporcionará al LLM información sobre la acción, su entrada y su salida.
Para hacer referencia a una acción insertada en las instrucciones de tu manual de procedimientos, solo tienes que mencionar el nombre de la acción entre comillas inversas y describir cómo se debe usar.
Ejemplo de una acción insertada place_order
:
Take the customer's order, then call the `place_order` action when the order is ready.
Para crear ejemplos que usen acciones insertadas, usa el tipo de herramienta inline-action en la sección Entrada y salida.
Para obtener más información, consulta la documentación de referencia de @Action.
Funciones de activación
Las funciones de activación se usan para definir acciones condicionales en el código.
Las funciones de activación se declaran mediante decoradores. Puedes usar los siguientes decoradores de funciones de activación:
Decorador | Parámetros de decorador | Descripción |
---|---|---|
@EventTrigger | event: str, condition: str , donde la condición es opcional |
Se activa por un evento |
@BeforeModelTrigger | condition: str , donde la condición es opcional |
Se activa cada vez antes de que el LLM prediga la siguiente acción. |
@BeforeActionTrigger | condition: str , donde la condición es opcional |
Se activa cada vez antes de que el LLM ejecute una acción. |
@BeforePlaybookTrigger | condition: str , donde la condición es opcional |
Se activa la primera vez que se inicia un libro de jugadas. |
Por ejemplo, estas funciones muestran cómo usar estos decoradores y parámetros de decorador, así como la función de biblioteca del sistema de bloques de código respond.
# 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 ☕")
Hacer referencia a flujos, guías y herramientas
En tu bloque de código, puedes hacer referencia a flujos, guías y herramientas específicos mediante las variables globales flows, playbooks y tools.
Cada uno de estos objetos tiene miembros que coinciden con los nombres de los recursos correspondientes. Estos nombres deben ser nombres de Python válidos.
Ejemplo:
add_override(playbooks.troubleshooting, {})
add_override(flows.billing)
add_override(tools.weather_api.get_weather, {"location": "San Francisco"})
Cuando hagas referencia a flujos y manuales en un bloque de código, también debes hacer referencia a ellos en las instrucciones del manual con la siguiente sintaxis:
${RESOURCE_TYPE: my_resource_name}
Por ejemplo, si tu bloque de código contiene flows.myflow
y playbooks.myplaybook
, las instrucciones de tu guía deben incluir lo siguiente:
${FLOW: myflow}
${PLAYBOOK: myplaybook}
Reemplazos de acciones
Puedes usar bloques de código para crear una cola de acciones que se llevarán a cabo antes de cualquier otra acción determinada por el LLM y, potencialmente, anularlas. Para crear anulaciones de acciones, usa la función global add_override.
Todas las acciones de anulación en cola se ejecutarán secuencialmente y el LLM podrá acceder al resultado de la acción. Una vez que la cola esté vacía, la operación vuelve al LLM para que elija una acción y una entrada, a menos que una anulación finalice la conversación con respond u otra función que complete la conversación.
Argumentos de la función:
- action: la acción que se va a llevar a cabo.
Para una acción insertada, usa
my_function_name
. Para una acción de herramienta, usatools.my_tool_name.my_tool_action
. Para una acción de flujo, usaflows.my_flow_name
. - inputs: entradas opcionales de la acción.
Por ejemplo:
{"location": "Omaha"}
.
Ejemplos:
# 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)
Sustituciones de respuestas
Al igual que con las anulaciones de acciones, pero específicamente para las respuestas del agente, puedes usar la función global respond para obligar al agente a responder al usuario con contenido específico.
Ejemplo:
respond("Hello")
Herramientas de llamadas
En las funciones de bloque de código, puedes llamar a las herramientas definidas para tu agente. A diferencia de cuando anulas una acción de una herramienta, cuando llamas a una herramienta directamente, los resultados de la ejecución de la herramienta no están disponibles para el LLM.
Ejemplos:
# 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"]
Coincidencia de intención
Los bloques de código pueden coincidir de forma programática con una intención de un flujo determinado mediante la función Flow.match_intent.
Ejemplo:
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?")
Leer parámetros de sesión
Los bloques de código pueden leer los parámetros que estén disponibles en el momento de la ejecución.
Ejemplo:
state["$session.params.my-param"]
state["$request.session-id"]
Depuración
Puedes usar el simulador para depurar las funciones de bloque de código. Estas funciones se mostrarán como acciones en el simulador y nos proporcionarán los detalles que necesitemos.
Control adicional
En esta guía se describen algunos usos habituales de la biblioteca del sistema de bloques de código. Para ver otros tipos de control, consulta la documentación de la biblioteca.