17 octubre, 2026

OPTIMIZANDO EL CONSUMO DE TOKENS EN AI BUILDER: PROCESAMIENTO POR LOTES

Hola a todos;

En una publicación anterior vimos cómo utilizar $batch en Power Automate para agrupar varias operaciones de SharePoint en una única petición HTTP: OCULTAR O MOSTRAR VARIAS LISTAS DE SHAREPOINT A LA VEZ CON $BATCH EN POWER AUTOMATE

En esta ocasión vamos a utilizar una técnica diferente: el procesamiento por lotes (batching). Aunque ambos conceptos pueden parecer similares, existe una diferencia importante. Mientras que $batch permite agrupar varias operaciones independientes en una misma petición HTTP, el procesamiento por lotes que vamos a utilizar consiste en agrupar varios registros para que una única ejecución de la IA los procese y genere una respuesta individual para cada uno.

Para este ejemplo podríamos utilizar alguno de los modelos que tenemos desplegados en Azure AI Foundry, pero, de momento, vamos a trabajar con AI Builder, aprovechando su integración con Power Automate.

El objetivo es analizar los comentarios de 100 empleados y generar una propuesta de mejora para cada uno. En lugar de realizar 100 solicitudes independientes, utilizaremos la función chunk() para agrupar los comentarios en lotes de 10 y enviarlos juntos a la IA, conservando la identificación de cada empleado para recuperar posteriormente su análisis.

Lo interesante de esta técnica es que reducimos el número de llamadas al modelo y compartimos las instrucciones del prompt entre los registros de cada lote, evitando repetirlas individualmente para cada empleado. Esto nos permite optimizar el consumo de tokens, tanto por la reducción de instrucciones repetidas como por el menor número de ejecuciones.

Por supuesto, podríamos combinar ambas técnicas en un mismo flujo. Mientras que chunk() nos ayudaría a optimizar el procesamiento de los comentarios mediante IA, $batch podría utilizarse posteriormente para actualizar de forma masiva los resultados en SharePoint, algo especialmente interesante si trabajásemos con miles de empleados.

Sin embargo, en esta publicación no vamos a incorporar $batch, ya que queremos centrarnos exclusivamente en comprobar y medir el ahorro de tokens que conseguimos al procesar varios comentarios en una única solicitud a AI Builder. Dejaremos la combinación de ambas técnicas para una próxima publicación, en la que abordaremos también la optimización de los tiempos de ejecución.

Y, como veremos en los resultados de las pruebas, una modificación relativamente sencilla en la forma de enviar los datos a la IA puede suponer una reducción muy significativa del consumo de tokens.

Esta es la lista que vamos a utilizar:

La idea es procesar y analizar los comentarios del trabajador con AI Builder y extraer una solución al problema en el campo análisis. En cada proceso realizado el estado cambiará a Procesado.

La explicacion es necesario mostrar el flujo:

Este sería el código completo:

1. SHAREPOINT — OBTENER ELEMENTOS

   Filtro OData:
   Estado eq 'Pendiente'

   Ordenar por:
   ID asc

   Número máximo de elementos: 20
   Paginación: Activada
   Umbral de paginación: 200


2. VARIABLES — INICIALIZAR VARIABLE

   Nombre: TotalTokens
   Tipo: Entero
   Valor inicial: 0


3. OPERACIONES DE DATOS — SELECCIONAR

   Desde:
   outputs('Obtener_elementos')?['body/value']

   Mapa:

   ID:
   item()?['ID']

   Comentario:
   item()?['Comentario']


4. OPERACIONES DE DATOS — REDACTAR

   Entradas:
   chunk(outputs('Seleccionar')?['body'], 10)


5. CONTROL — APLICAR A CADA UNO

   Seleccionar una salida:
   outputs('Redactar')


   5.1. AI BUILDER — EJECUTAR UNA SOLICITUD

        Input Text:

        Actúa como especialista en Recursos Humanos
        y mejora de procesos empresariales.

        Recibirás una lista JSON de empleados con
        los campos ID y Comentario.

        Para cada empleado, genera una solución
        concreta, realista y aplicable, con un máximo
        de 250 caracteres, incluidos espacios.

        Devuelve exclusivamente un JSON válido
        con esta estructura:

        {"resultados":[{"ID":1,"Analisis":"Solución propuesta"}]}

        Incluye exactamente una respuesta por empleado.
        Conserva los ID originales, no omitas empleados
        ni mezcles comentarios.
        No añadas explicaciones ni bloques Markdown.

        Empleados:
        @{string(items('Aplicar_a_cada_uno'))}


   5.2. VARIABLES — INCREMENTAR VARIABLE

        Nombre: TotalTokens

        Incrementar en:
        add(
            int(outputs('Ejecutar_una_solicitud')?['body/responsev2/predictionOutput/promptTokens']),
            int(outputs('Ejecutar_una_solicitud')?['body/responsev2/predictionOutput/completionTokens'])
        )


   5.3. OPERACIONES DE DATOS — ANÁLISIS DEL ARCHIVO JSON

        Contenido:
        json(outputs('Ejecutar_una_solicitud')?['body/responsev2/predictionOutput/text'])

        Esquema JSON recomendado:

        {
          "type": "object",
          "properties": {
            "resultados": {
              "type": "array",
              "items": {
                "type": "object",
                "properties": {
                  "ID": {
                    "type": "integer"
                  },
                  "Analisis": {
                    "type": "string"
                  }
                },
                "required": [
                  "ID",
                  "Analisis"
                ]
              }
            }
          },
          "required": [
            "resultados"
          ]
        }


   5.4. CONTROL — APLICAR A CADA UNO 2

        Seleccionar una salida:
        items('Aplicar_a_cada_uno')


        5.4.1. OPERACIONES DE DATOS — FILTRAR MATRIZ

               Desde:
               body('Análisis_del_archivo_JSON')?['resultados']

               Izquierda:
               item()?['ID']

               Operador:
               es igual a

               Derecha:
               items('Aplicar_a_cada_uno_2')?['ID']


        5.4.2. CONTROL — CONDICIÓN

               Izquierda:
               length(body('Filtrar_matriz'))

               Operador:
               es igual a

               Derecha:
               1


        5.4.3. SI VERDADERO — SHAREPOINT — ACTUALIZAR ELEMENTO

               ID:
               items('Aplicar_a_cada_uno_2')?['ID']

               Análisis:
               take(first(body('Filtrar_matriz'))?['Analisis'], 250)

               Estado:
               Procesado


        5.4.4. SI FALSO

               No realizar ninguna actualización.


6. OPERACIONES DE DATOS — REDACTAR 2

   Entradas:
   variables('TotalTokens')

Importante que veáis el prompt usando en AI Builder:

   5.1. AI BUILDER — EJECUTAR UNA SOLICITUD

        Input Text:

        Actúa como especialista en Recursos Humanos
        y mejora de procesos empresariales.

        Recibirás una lista JSON de empleados con
        los campos ID y Comentario.

        Para cada empleado, genera una solución
        concreta, realista y aplicable, con un máximo
        de 250 caracteres, incluidos espacios.

        Devuelve exclusivamente un JSON válido
        con esta estructura:

        {"resultados":[{"ID":1,"Analisis":"Solución propuesta"}]}

        Incluye exactamente una respuesta por empleado.
        Conserva los ID originales, no omitas empleados
        ni mezcles comentarios.
        No añadas explicaciones ni bloques Markdown.

        Empleados:
        @{string(items('Aplicar_a_cada_uno'))}

Y ahora explicando fragmentos concretos:

outputs('Obtener_elementos')?['body/value']

Antes de agrupar los registros, utilizamos la acción Seleccionar de Power Automate para construir una matriz que contenga únicamente los campos necesarios: ID y Comentario.

De esta forma, eliminamos de la información que enviaremos a la IA todas las propiedades adicionales que devuelve SharePoint, reduciendo el tamaño de la entrada y evitando transmitir datos innecesarios.

La matriz resultante tendrá una estructura similar a esta:

[
  {
    "ID": 1,
    "Comentario": "Necesitamos mejorar la comunicación entre departamentos."
  },
  {
    "ID": 2,
    "Comentario": "Los procesos de aprobación son demasiado lentos."
  }
]
chunk(outputs('Seleccionar')?['body'], 10)

Esta es la función principal de nuestra optimización.

La función chunk() permite dividir una matriz o cadena en fragmentos de un tamaño determinado. En nuestro caso, recibe dos argumentos:

  • outputs(‘Seleccionar’)?[‘body’]: matriz de empleados preparada en el paso anterior.
  • 10: número máximo de empleados que contendrá cada lote.
    Así, una matriz de 100 empleados se transforma en 10 matrices de 10 empleados.

    La función no realiza ninguna llamada a la IA. Simplemente reorganiza los datos dentro de Power Automate para que posteriormente podamos procesar cada grupo en una única solicitud.

    Podríamos cambiar el tamaño de los lotes modificando el segundo argumento, por ejemplo, de 10 a 20. Esto reduciría el número de llamadas, aunque también aumentaría el tamaño de cada entrada y de la respuesta esperada.
string(items('Aplicar_a_cada_uno'))

Una vez generados los lotes, utilizamos Aplicar a cada uno para recorrerlos.

La función items() recupera la matriz correspondiente al lote actual, mientras que string() la convierte en una representación textual que podemos incorporar al prompt de AI Builder.

En lugar de enviar diez solicitudes independientes, enviamos una única solicitud que contiene los diez comentarios.
El prompt indica al modelo que debe generar una solución individual para cada empleado y devolverla en formato JSON, conservando su identificador original.

Este procedimiento permite que las instrucciones generales se compartan entre varios comentarios, en lugar de repetirse en cada ejecución.

json(outputs('Ejecutar_una_solicitud')?['body/responsev2/predictionOutput/text'])

AI Builder devuelve el resultado del prompt como texto. Mediante la función json() interpretamos ese contenido como una estructura JSON para poder trabajar posteriormente con sus propiedades.

Esta es la estructura:

{
  "resultados": [
    {
      "ID": 1,
      "Analisis": "Establecer reuniones periódicas entre departamentos."
    },
    {
      "ID": 2,
      "Analisis": "Simplificar los circuitos de aprobación."
    }
  ]
}

La propiedad resultados contiene una matriz de objetos, cada uno con el identificador del empleado y el análisis generado.

Después, la acción Análisis del archivo JSON permite disponer de estos datos de forma estructurada.

Conviene definir un esquema que valide los tipos de datos esperados, especialmente el ID numérico y el texto del análisis.

body('Análisis_del_archivo_JSON')?['resultados']

Una vez recibida la respuesta, necesitamos asegurarnos de que cada análisis se guarda en el empleado correspondiente.

Para ello utilizamos la acción Filtrar matriz, comparando el identificador devuelto por AI Builder con el del empleado que estamos procesando.

Para garantizar que cada análisis se asigna al empleado correcto, utilizamos Filtrar matriz, comparando el ID devuelto por AI Builder con el ID original de SharePoint.

ID devuelto por AI Builder:

item()?['ID']

ID del empleado original:

items('Aplicar_a_cada_uno_2')?['ID']

De esta forma, no dependemos del orden de las respuestas generadas por la IA.

Antes de actualizar SharePoint, comprobamos que exista una única coincidencia mediante length():

length(body('Filtrar_matriz'))

Si el resultado es igual a 1, recuperamos el análisis y limitamos su longitud a 250 caracteres:

take(first(body('Filtrar_matriz'))?['Analisis'], 250)

Aquí, first() recupera el análisis correspondiente y take() garantiza que no se guarden más de 250 caracteres, aunque la IA supere el límite indicado en el prompt.

Para medir el consumo real de AI Builder, inicializamos una variable entera llamada TotalTokens con valor 0.

Después de cada solicitud, utilizamos Incrementar variable con la siguiente expresión:

add(
    int(outputs('Ejecutar_una_solicitud')?['body/responsev2/predictionOutput/promptTokens']),
    int(outputs('Ejecutar_una_solicitud')?['body/responsev2/predictionOutput/completionTokens'])
)

La expresión suma los tokens de entrada (promptTokens) y los tokens de salida (completionTokens) de cada ejecución. La función int() convierte los valores a enteros y add() calcula su suma.

Finalmente, fuera del bucle, recuperamos el total acumulado mediante:

variables('TotalTokens')

Este es el resumen de ejecutar la aplicación iterando por cada individuo y la realizada por lotes. El ahorro es evidente:

IndicadorIndividualPor lotes
Empleados100100
Solicitudes a AI Builder10010
Tokens consumidos145.72319.463
Media por empleado1.457,23194,63
Reducción de tokens—86,64 %

Y este es el resultado de aplicar la IA en cada comentario y la solución propuesta:

Espero os haya resultado de interés.

*** Ojo, es importante tener en cuenta que los resultados pueden variar en función del número de empleados procesados, la longitud y complejidad de sus comentarios y el tamaño de los lotes utilizados. Por tanto, el ahorro observado en esta prueba es orientativo y no tiene por qué reproducirse en las mismas proporciones en otros escenarios.

Comparte este post

Este sitio web utiliza cookies para que usted tenga la mejor experiencia de usuario. Si continúa navegando está dando su consentimiento para la aceptación de las mencionadas cookies y la aceptación de nuestra política de cookies, pinche el enlace para mayor información.plugin cookies

ACEPTAR
Aviso de cookies