Bloques de código

Los bloques de código le permiten añadir código personalizado Python directamente dentro de su flujo de trabajo agentic. El nodo de bloque de código recibe datos del nodo ascendente, los procesa utilizando la lógica que definas y pasa la salida transformada al nodo descendente. Puedes utilizar un bloque de código para procesar transformaciones de datos, implementar lógica personalizada o dar formato a los mensajes antes de que continúen al siguiente paso en el flujo de trabajo agencial.

Cuando el flujo de trabajo agéntico alcanza un nodo de bloque de código, ejecuta el código Python que ha definido y transforma los datos. El nodo actúa como un punto de decisión o transformación programable en su flujo de trabajo agentico, dándole mayor flexibilidad y control. Si desea utilizar un bloque de código Python más grande, considere la posibilidad de utilizar una herramienta.

Bibliotecas de Python

Dentro de un bloque de código, puede leer variables de diferentes partes del flujo de trabajo del agentic, aplicar lógica personalizada y definir variables de salida para su uso por nodos posteriores. El entorno Python incluye bibliotecas estándar de uso común, entre las que se incluyen los siguientes módulos:

  • array
  • calendar
  • collections
  • datetime
  • enum
  • json
  • math
  • random
  • re
  • string
  • time
  • yaml
  • zoneinfo

Soporte para las funciones Python

La siguiente lista describe las funciones que no son compatibles y las alternativas recomendadas.

  • La función eval() no es compatible. Utilice (my_str == "True") en lugar de eval(my_str), donde my_str es "Verdadero" o "Falso".
  • Para el módulo yaml sólo se admiten las funciones API safe_load(), safe_load_all(), safe dump() y safe_dump_all() .
  • Para el módulo string string.Formatter no es compatible. Utilice string.safe_format() en lugar de string.Formatter.format().
  • Para la función str str.format() no es compatible. No se admite ninguna función de la API xxx.format() o xxx.format_map() .
  • Algunas funciones integradas en Python no son compatibles, como import, class y type(). Para comprobar los tipos, utilice safe_type() en lugar de type().
Nota:
  • La lista de módulos disponibles en Python es fija y no puede modificarse ni ampliarse.
  • Es posible que algunas bibliotecas de los módulos Python no estén disponibles.
  • Las variables pueden referenciarse utilizando ["varname"] o.varname. El uso de ["varname"] permite utilizar espacios y comas.

Python objetos del diccionario

Agentic workflow builder utiliza prácticas de programación de Python, por lo que flow, self, y parent se tratan como diccionarios de Python. Si se produce una excepción al leer de o asignar a un auto-objeto, por ejemplo: self["input"]["customer"]["discount_rate"], es probable que se deba a que uno de los objetos que lo contiene (como "customer") aún no existe. En ese caso, primero hay que inicializar los objetos contenedores.

Cuando se ejecuta un bloque de código, utiliza objetos de diccionario Python para representar las entradas y salidas. Puede utilizar la sintaxis de expresión para referenciar o establecer estos valores según sea necesario. Para obtener más información sobre la sintaxis, consulte la sección Expresiones de flujo de IBM wastonsx Orchestrate ADK.

He aquí un ejemplo de diccionario de flujo de trabajo agéntico:

# flow represents the inputs and outputs of the outermost flow
flow = {
  "input": {
    "birthday": "1-10-2000",
    "first_name": "John",
    "last_name": "Doe",
    "address": {
      "street": "123 ABC Street",
      "city": "NY",
      "state": "NY",
      "country": "USA"
    },
    "customer_status": "Bronze"
  },
  "output": {
    "current_date": "<current date>",
    "current_datetime": "<current datetime>",
    "age": <number>,
    "address": <str>
  }
}

# self represents the inputs and outputs of the current node
self = {
  "input": {
    "customer_status": "Bronze",
    "price": 1000
  },
  "output": {
    "discount_rate": <number>
  }
}

Tipos de datos

La siguiente tabla enumera los tipos de datos que se admiten en los flujos de trabajo de agentic, junto con sus tipos equivalentes Python y JSON utilizados en expresiones y bloques de código.

Tipos de datos de flujo Python tipos de datos Tipos de datos de JSON
Serie Str Serie
Entero Int Entero
Número Flotante Número
Booleano Booleano Booleano
Fecha Str Serie
Objecto Dict Objecto
Archivo WxoFile Serie

Nota:

  • Para definir un tipo de datos de objeto en los flujos de trabajo de agentic, debe adherirse al estándar del esquema JSON. Para más información, consulte la documentación sobre el esquema JSON.

  • En Python, las fechas son cadenas que utilizan el formato de fecha ISO 8601. Las fechas JSON son cadenas con formato "date", que utiliza el formato de fecha ISO 8601, por ejemplo:

"startDate": {
 "type": "string",
 "description": "Employee's start date",
 "format": "date"
}

Conversión del tipo de datos

Las conversiones de tipos de datos permiten transformar un valor de un formato a otro. Los siguientes bloques de código proporcionan ejemplos de expresiones Python de diferentes tipos de conversión de datos.

Ejemplos

Conversión de cadenas


Un bloque de código que convierte una cadena en un número entero.



Un bloque de código que convierte una cadena en un número.



Un bloque de código que convierte una cadena en un booleano.
my_str = str("False")
my_bool = (my_str == "True")
test_results += "my_str: " + my_str + " converted to my_bool: " + str(my_bool) + "\n"
my_str = str("True")
my_bool = (my_str == "True")
test_results += "my_str: " + my_str + " converted to my_bool: " + str(my_bool) + "\n"


Un bloque de código que convierte una cadena en una fecha.

Nota: Python las fechas son cadenas que se ajustan al formato de fecha ISO 8601: "%Y-%m-%d"



Un bloque de código que convierte una cadena en una fecha utilizando el paquete datetime.



Conversión de números enteros


Un bloque de código que convierte un entero en una cadena.
my_int = int(10)
my_str = str(my_int)
test_results += "my_int: " + str(my_int) + " converted to my_str: " + my_str + "\n"


Un bloque de código que convierte un entero en un número.
my_int = int(10)
my_num = float(my_int)
test_results += "my_int: " + str(my_int) + " converted to my_num: " + str(my_num) + "\n"


Un bloque de código que convierte un entero en un booleano.
my_int = int(0)
my_bool = bool(my_int)
test_results += "my_int: " + str(my_int) + " converted to my_bool: " + str(my_bool) + "\n"
my_int = int(1)
my_bool = bool(my_int)
test_results += "my_int: " + str(my_int) + " converted to my_bool: " + str(my_bool) + "\n"

Nota: En este ejemplo de bloque de código, 0 se convierte en Falso, y 1 se convierte en Verdadero.



Un bloque de código que convierte un número entero en una fecha.
my_int = int(739470)
my_date_date = datetime.date.fromordinal(my_int)
my_date_str_isoformat = my_date_date.isoformat()
test_results += "my_int: " + str(my_int) + " converted to my_date_date: " + my_date_str_isoformat + "\n"


Conversión de números


Un bloque de código que convierte un número en una cadena.
my_num = float(1.5)
my_str = str(my_num)
test_results += "my_num: " + str(my_num) + " converted to my_str: " + my_str + "\n"


Un bloque de código que convierte un número en un entero.
my_num = float(1.5)
my_int = int(my_num)
test_results += "my_num: " + str(my_num) + " converted to my_int: " + str(my_int) + "\n"
my_int = math.ceil(my_num)
test_results += "my_num: " + str(my_num) + " converted to my_int using math.ceil(): " + str(my_int) + "\n"
my_int = math.floor(my_num)
test_results += "my_num: " + str(my_num) + " converted to my_int using math.floor(): " + str(my_int) + "\n"

Nota: Utilice math.ceil() para redondear hacia arriba y math.floor() para redondear hacia abajo.



Un bloque de código que convierte un número en un booleano.
my_num = float(0)
my_bool = bool(my_num)
test_results += "my_num: " + str(my_num) + " converted to my_bool: " + str(my_bool) + "\n"
my_num = float(1)
my_bool = bool(my_num)
test_results += "my_num: " + str(my_num) + " converted to my_bool: " + str(my_bool) + "\n"

Nota: En este ejemplo de bloque de código, 0 se convierte en Falso, y 1 se convierte en Verdadero.



Un bloque de código que convierte un número en una fecha.
my_num = float(739470)
my_date_date = datetime.date.fromordinal(int(my_num))
my_date_str_isoformat = my_date_date.isoformat()
test_results += "my_num: " + str(my_num) + " converted to my_date_date: " + my_date_str_isoformat + "\n"


Conversión booleana


Un bloque de código que convierte un booleano en una cadena.
my_bool = bool(True)
my_str = str(my_bool)
test_results += "my_bool: " + str(my_bool) + " converted to my_str: " + my_str + "\n"
my_bool = bool(False)
my_str = str(my_bool)
test_results += "my_bool: " + str(my_bool) + " converted to my_str: " + my_str + "\n"


Un bloque de código que convierte un booleano en un entero.
my_bool = bool(True)
my_int = int(my_bool)
test_results += "my_bool: " + str(my_bool) + " converted to my_int: " + str(my_int) + "\n"
my_bool = bool(False)
my_int = int(my_bool)
test_results += "my_bool: " + str(my_bool) + " converted to my_int: " + str(my_int) + "\n"


Un bloque de código que convierte un booleano en un número.
my_bool = bool(True)
my_num = float(my_bool)
test_results += "my_bool: " + str(my_bool) + " converted to my_num: " + str(my_num) + "\n"
my_bool = bool(False)
my_num = float(my_bool)
test_results += "my_bool: " + str(my_bool) + " converted to my_num: " + str(my_num) + "\n"


Conversión de fechas


Un bloque de código que convierte una fecha en una cadena.
my_date_date = datetime.date.today()
my_date_str_isoformat = my_date_date.isoformat()
my_date_str = my_date_date.strftime("%a %d %B %Y")
test_results += "my_date_date: " + my_date_str_isoformat + " converted to my_date_str: " + my_date_str + "\n"

Nota: Para obtener más información sobre los códigos de formato de fecha, consulte Python strftime y strptime códigos de formato.



Un bloque de código que convierte una fecha en un número entero.
my_date_date = datetime.date.today()
my_date_str_isoformat = my_date_date.isoformat()
my_int = int(my_date_date.toordinal())
test_results += "my_date_date: " + my_date_str_isoformat + " converted to my_int: " + str(my_int) + "\n"


Un bloque de código que convierte una fecha en un número.
my_date_date = datetime.date.today()
my_date_str_isoformat = my_date_date.isoformat()
my_num = float(my_date_date.toordinal())
test_results += "my_date_date: " + my_date_str_isoformat + " converted to my_num: " + str(my_num) + "\n"
self.output.test_results = test_results


Casos prácticos y ejemplos

Puede utilizar el nodo de bloque de código para personalizar la forma en que su flujo de trabajo agentic maneja los datos. Es útil cuando los nodos estándar no satisfacen sus necesidades específicas. A continuación, se muestran algunos casos de uso común.

Formato de los mensajes

Puede dar formato o reestructurar los mensajes según sea necesario, al tiempo que traslada la información al siguiente nodo. El siguiente ejemplo de bloque de código muestra una aplicación práctica del formateo de mensajes.

Ejemplos


Un bloque de código que formatea la entrada de direcciones y la muestra como una única cadena separada por comas.
# Format address
addr = flow["input"]["address"]
formatted_address = f"{addr['street']}, {addr['city']}, {addr['state']}, {addr['country']}"
self["output"]["address"] = formatted_address


Integración flexible

Puede colocar el nodo de bloque de código en cualquier lugar del flujo de trabajo agentic para integrarlo con otros nodos y herramientas. El siguiente ejemplo de bloque de código muestra una aplicación práctica de la integración flexible.

Ejemplos


Un bloque de código que define una variable que se llama todays_date como un tipo de datos Date e inicializa todays_date y establece el valor en la fecha actual.



Bloque de código que inicializa un conjunto de variables de salida utilizando tipos de datos primitivos: cadena, entero, número y booleano.

Las variables de salida son:

  • name : Cadena
  • age : Entero
  • salary : Número
  • isActive : Booleano

En el bloque de código, cada variable se inicializa con un valor de muestra.

self.output.name = "John Doe"
self.output.age = 37
self.output.salary = 12345.67
self.output.isActive = True


Transformación de datos personalizada

Puede escribir código Python para transformar, filtrar, inicializar variables o mejorar los datos existentes a medida que pasan por el flujo de trabajo agentic. Los siguientes ejemplos de bloques de código muestran una aplicación práctica de la transformación de datos personalizada.

Ejemplos


Un bloque de código que analiza una cadena JSON que contiene campos de dirección en un diccionario Python.



Un bloque de código que asigna el valor de estado del diccionario de direcciones a la dirección de entrada en el flujo de trabajo agentico.
Este bloque de código solo se ejecuta si flow["input"]["address"] existe. Si no existe, debe crearla primero.
flow["input"]["address"]["state"] = address["state"]


Un bloque de código establece e inicializa una variable de salida llamada empleado como un tipo de datos de objeto.
El tipo de variable se define utilizando una estructura JSON Schema.



Aplicación de la lógica empresarial

Puede aplicar lógica condicional, realizar cálculos y tomar decisiones, o ejecutar operaciones personalizadas según sea necesario en el flujo de trabajo del agente. Los siguientes ejemplos de bloques de código muestran una aplicación práctica de la implementación de la lógica empresarial.

Ejemplos


Un bloque de código que calcula y muestra la edad del usuario basándose en la fecha de nacimiento introducida.
# Get today's date
today = datetime.date.today()

# Get the user's birthday from the output of the previous user activity
birthday_str = flow["User activity 1"]["Ask for date of birth"].output.value

# Convert the user's birthday into a date object
birthday = datetime.datetime.strptime(birthday_str, "%Y-%m-%d").date()

# Calculate the user's age
age = today.year - birthday.year - ((today.month, today.day) < (birthday.month, birthday.day))

# Return the user's age
self.output.age = age



Bloque de código que comprueba el tipo de producto y la antigüedad para determinar si se acepta el pago.



Un bloque de código que muestra una tasa de descuento basada en las variables de entrada precio y estado_cliente.



Un bloque de código que formatea la dirección de entrada en una cadena utilizando la lógica if-then.



Un bloque de código que calcula la fecha tres días antes de la fecha actual, y la almacena en la variable thee_days_ago.


Procesamiento de archivos

Puede utilizar el nodo de bloque de código para gestionar operaciones con archivos, como gestionar cargas de uno o varios archivos, extraer o transformar contenidos de archivos y generar archivos para su descarga. El siguiente ejemplo muestra un caso práctico de procesamiento de archivos.

Funciones disponibles para el procesamiento de archivos

Las operaciones con archivos se pueden realizar utilizando funciones de archivo del sistema o métodos WxoFile de instancia.

Funciones de los archivos del sistema

A continuación se describen los system.file métodos para trabajar con archivos:

  • system.file.get_name(file) – Devuelve el nombre del archivo
  • system.file.get_type(file) – Devuelve el tipo de archivo
  • system.file.get_size(file) – Devuelve el tamaño del archivo
  • system.file.get_content(file) – Devuelve el contenido del archivo en bytes

WxoFile Métodos de instancia

A continuación se muestran los métodos de instancia disponibles en un WxoFile objeto :

  • file.get_name() – Devuelve el nombre del archivo
  • file.get_type() – Devuelve el tipo de archivo
  • file.get_size() – Devuelve el tamaño del archivo
  • file.get_content() – Devuelve el contenido del archivo en bytes

A continuación se muestran ejemplos prácticos que muestran cómo acceder a archivos desde entradas de flujo, formularios de actividad de usuario y carga de archivos de actividad de usuario, y recuperar URL su nombre, tipo y tamaño utilizando tanto system.file funciones como métodos WxoFile de instancia.


Bloque de código que accede a un archivo desde la entrada de flujo y recupera su nombre URL y tamaño utilizando system.file el método.

input_file = flow.input.externalFile
self.output.file_name = system.file.get_name(input_file)
self.output.file_type = system.file.get_type(input_file)
self.output.file_size = system.file.get_size(input_file)
self.output.file_content = system.file.get_content(input_file)


Bloque de código que accede a un archivo desde la entrada de flujo y recupera su nombre URL y tamaño utilizando el método WxoFile de instancia.

input_file = flow.input.externalFile
self.output.file_name = input_file.get_name()
self.output.file_type = input_file.get_type()
self.output.file_size = input_file.get_size()
self.output.file_content = input_file.get_content()


Bloque de código que accede a un único archivo desde un formulario de actividad del usuario (con la opción «Permitir varios archivos» desactivada) y recupera su nombre URL y tamaño utilizando el system.file método.

form_single_file = flow["User activity 1"]["Form 1"].output["single file upload"]
self.output.file_name = system.file.get_name(form_single_file)
self.output.file_type = system.file.get_type(form_single_file)
self.output.file_size = system.file.get_size(form_single_file)
self.output.file_content = system.file.get_content(form_single_file)


Bloque de código que accede a un único archivo desde un formulario de actividad del usuario (con la opción «Permitir varios archivos» desactivada) y recupera su nombre URL y tamaño utilizando el método WxoFile de instancia.

form_single_file = flow["User activity 1"]["Form 1"].output["single file upload"]
self.output.file_name = form_single_file.get_name()
self.output.file_type = form_single_file.get_type()
self.output.file_size = form_single_file.get_size()
self.output.file_content = form_single_file.get_content()


Bloque de código que accede a un archivo múltiple desde un formulario de actividad del usuario (con la opción «Permitir archivos múltiples» habilitada) y recupera su nombre URL y tamaño utilizando el system.file método.

form_multi_file = flow["User activity 1"]["Form 1"].output["Multi file upload"]
self.output.file_count = len(form_multi_file)
self.output.first_file_name = system.file.get_name(form_multi_file[0])
self.output.first_file_type = system.file.get_type(form_multi_file[0])
self.output.first_file_size = system.file.get_size(form_multi_file[0])
self.output.first_file_content = system.file.get_content(form_multi_file[0])


Bloque de código que accede a varios archivos desde un formulario de actividad del usuario (con la opción «Permitir varios archivos» habilitada) y recupera su nombre URL y tamaño utilizando el método WxoFile de instancia.

form_multi_file = flow["User activity 1"]["Form 1"].output["Multi file upload"]
self.output.file_count = len(form_multi_file)
self.output.first_file_name = form_multi_file[0].get_name()
self.output.first_file_type = form_multi_file[0].get_type()
self.output.first_file_size = form_multi_file[0].get_size()
self.output.first_file_content = form_multi_file[0].get_content()


Un bloque de código que accede a un único archivo que no es un formulario desde la actividad del usuario y recupera su nombre URL y tamaño utilizando el system.file método.

normal_single_file = flow["User activity 1"]["File upload 1"].output.value
self.output.file_name = system.file.get_name(normal_single_file)
self.output.file_type = system.file.get_type(normal_single_file)
self.output.file_size = system.file.get_size(normal_single_file)
self.output.file_content = system.file.get_content(normal_single_file)


Bloque de código que accede a un único archivo que no es un formulario desde una actividad de usuario y recupera su nombre URL y tamaño utilizando el método WxoFile de instancia.

normal_single_file = flow["User activity 1"]["File upload 1"].output.value
self.output.file_name = normal_single_file.get_name()
self.output.file_type = normal_single_file.get_type()
self.output.file_size = normal_single_file.get_size()
self.output.file_content = normal_single_file.get_content()

Nota:
  • Las cargas de archivos individuales deben accederse directamente sin utilizar un índice.
  • Las cargas de múltiples archivos requieren indexación (ejemplo: [0], [1]) para hacer referencia a cada archivo individualmente.