Bloques de código

Cuando defines un playbook, puedes proporcionar bloques de código de forma opcional, que son código de Python intercalado 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 en perímetros de VPC-SC que restringen el acceso a Artifact Registry también rechazarán las implementaciones de Code Block.

Limitaciones

Se aplica la siguiente limitación:

  • 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 realizar llamadas remotas directamente. Por ejemplo, no puedes usar la biblioteca de solicitudes de Python. Sin embargo, puedes usar herramientas para realizar llamadas de forma remota indirectamente.
  • 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 leer ni escribir parámetros de sesión, a menos que se produzca una transición de flujo.

Acciones directas

Las acciones intercaladas se comportan de manera similar a las acciones de herramientas. Tienen un esquema de entrada y salida definido, que se determina según la firma de la función de Python, incluidas las anotaciones de tipo y la docstring. Al igual que con las llamadas a herramientas, el LLM no conoce el código que implementa la acción.

Muestra:

@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 le proporcionará al LLM información sobre la acción, su entrada y su salida.

Para hacer referencia a una acción intercalada en las instrucciones de tu manual, solo debes mencionar el nombre de la acción entre comillas inversas y describir cómo se debe usar.

Ejemplo de una acción intercalada place_order:

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

Para crear ejemplos que usen acciones intercaladas, usa el tipo de herramienta inline-action en la sección Input & Output.

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 con decoradores. Puedes usar los siguientes decoradores de funciones de activación:

Decorator Parámetros del 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 una guía.

Por ejemplo, estas funciones muestran cómo usar estos parámetros y decoradores, y también cómo usar la función de biblioteca del sistema del bloque 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 ☕")

Cómo 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 con 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 legales de Python.

Muestra:

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

Cuando hagas referencia a flujos y guías en un bloque de código, también debes hacer referencia a ellos en las instrucciones de la guía 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}

Anulaciones de acciones

Puedes usar bloques de código para crear una fila de acciones que se llevarán a cabo antes de cualquier otra acción determinada por el LLM y, posiblemente, anularlas. Para crear reemplazos de acciones, usa la función global add_override.

Todas las acciones de anulación en cola se ejecutarán de forma secuencial, y el LLM tendrá disponible el resultado de la acción. Una vez que la cola esté vacía, la operación volverá al LLM para la selección de acciones y entradas, a menos que una anulación finalice el turno con respond o con otra función que complete el turno.

Argumentos de la función:

  • action: Es la acción que se llevará a cabo. Para una acción intercalada, usa my_function_name. Para una acción de herramienta, usa tools.my_tool_name.my_tool_action. Para una acción de flujo, usa flows.my_flow_name.
  • inputs: Son las entradas opcionales para la acción. Por ejemplo: {"location": "Omaha"}.

Muestras:

# 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)

Anulaciones de respuesta

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 responderle al usuario con contenido específico.

Muestra:

respond("Hello")

Herramientas de llamadas

En las funciones de los bloques de código, puedes llamar a las herramientas definidas para tu agente. A diferencia de cuando anulas una acción de herramienta, cuando llamas a una herramienta directamente, los resultados de la ejecución de la herramienta no están disponibles para el LLM.

Muestras:

# 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"]

Intención de coincidencia

Los bloques de código pueden hacer coincidir de forma programática una intención para un flujo determinado con la función Flow.match_intent.

Muestra:

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?")

Depuración

Puedes usar el simulador para depurar las funciones de los bloques de código. Estas funciones se mostrarán como acciones en el simulador y proporcionarán nuestros detalles según sea necesario.

Control adicional

En esta guía, se explican algunos usos comunes de la biblioteca del sistema de bloques de código. Para conocer otros tipos de controles, consulta la documentación de la biblioteca.