![](https://static.wixstatic.com/media/9456da_4858a92c360446fcaf07c6d05948f8e9~mv2.png/v1/fill/w_980,h_502,al_c,q_90,usm_0.66_1.00_0.01,enc_auto/9456da_4858a92c360446fcaf07c6d05948f8e9~mv2.png)
A estas alturas, no descubrimos nada nuevo si decimos que en Power Platform, una funcionalidad en concreto puede ser implementada de múltiples formas. En este caso ¿cómo podríamos ejecutar un modelo de AI Builder desde una aplicación basada en modelos? Está claro que podríamos hacerlo de muchísimas formas: Power Automate con un desencadenador "cuando se crea/actualiza un registro", un comando con Power Fx, e incluso para los mas oldies implementar un plugin que invoque al modelo vía API. Por que por si no lo sabías, si. Los modelos de AI Builder pueden ser invocados a través de API REST como puedes ver aquí.
Imagina que una organización dispone de diversos modelos de inteligencia artificial para extraer información de formularios o facturas. Imagina que esta organización quiere que los usuarios de una aplicación de gestión de facturación puedan seleccionar y lanzar bajo demanda los modelos de inteligencia artifical disponibles desde la propia aplicación. En este post vamos a ver cómo gracias al potencial de las Custom Pages, podríamos implementar este requisito.
Vamos a empezar por entrenar un modelo de inteligencia artifical para extraer campos específicos de una factura. Para esta prueba de concepto utilizaré los juegos de datos de ejemplo que Microsoft pone a nuestra disposición para jugar con la plataforma. En este post voy a utilizar el Reconocimiento de Formularios, y si aún no te has pegado con el, te aconsejo que le des una vuelta a la documentación oficial. 😉
He creado un modelo que se llama Procesamiento de Facturas con un par de colecciones de documentos y los campos mas comunes: número de factura, fecha de factura, cliente, subtotal, impuestos, total y una tabla con el detalle de las líneas de la factura. Ni nada nuevo, ni nada complejo.
![](https://static.wixstatic.com/media/9456da_c2f13ca5a311416e8ac29397a2ad1f98~mv2.png/v1/fill/w_980,h_450,al_c,q_90,usm_0.66_1.00_0.01,enc_auto/9456da_c2f13ca5a311416e8ac29397a2ad1f98~mv2.png)
Por si no lo sabías, todos los modelos, colecciones de documentos, datos a extraer, etc., son almacenados en tablas de Dataverse. Y esto significa que podemos explotar esta información para lo que necesitemos.
Como segundo paso voy a crear una nueva Custom Page que desde la aplicación basada en modelos de gestión de facturas, permita al usuario seleccionar los modelos de inteligencia artifical disponibles y procesar una determinada factura con el modelo seleccionado. Para ello, desde la solución en la que estés trabajando selecciona Nuevo, Aplicación, Página. Esto abrirá el editor de aplicaciones de lienzo sobre donde vamos a dar forma a nuestra Custom Page.
Para esta prueba de concepto algo muy sencillo: un selector de los modelos de inteligencia artificial disponibles, un bóton que permita ejecutar el modelo seleccionado y una etiqueta de texto donde se va a mostrar el JSON de salida con los datos de la factura extridos por el modelo.
![](https://static.wixstatic.com/media/9456da_309fee1d5a5544faa2b917d0e836b7b8~mv2.png/v1/fill/w_980,h_439,al_c,q_90,usm_0.66_1.00_0.01,enc_auto/9456da_309fee1d5a5544faa2b917d0e836b7b8~mv2.png)
![](https://static.wixstatic.com/media/9456da_12bf094fddf14418be368495cc5eea7d~mv2.png/v1/fill/w_559,h_710,al_c,q_90,enc_auto/9456da_12bf094fddf14418be368495cc5eea7d~mv2.png)
La tabla donde se almacenan los modelos de AI Builder disponibles se llama AI Builder Models. Podríamos incluirla como origen de datos del Dropdown pero cómo no aparece disponible lo que he hecho ha sido crear un flujo Power Automate que con un simple FetchXML filtra los modelos de inteligencia articial y los devuelve a la Custom Page. Antes de devolver la respuesta a la Custom Page, hago un tratamiento de los datos para simplificar la cantidad de información que se devuelve a la "canvas app". Algo parecido a lo que se puede ver a continuación.
[
{
"customAiModelName": "Procesamiento de Facturas",
"customAiModelId": "15a566b1-0c54-4f06-9bc0-123456ff25d9"
}
]
Al final, lo que queda en la propiedad OnStart de la Custom Page no es mas que un Collect de esta respuesta a una variable, que luego es utilizada en la propiedad Items del Dropdown:
ClearCollect(
CustomAIModels;
GetCustomAIModels.Run()
);
Una vez somos capaces de mostrar los modelos disponibles para ser ejecutados, utilizo otro flujo de Power Automate para lanzar el modelo seleccionado. Vamos a dejar para mas adelante el cómo pasamos la factura a procesar al modelo seleccionado.
Como puedes ver en la siguiente imagen, el flujo que ejecutará el modelo seleccionado, recibe dos parámetros: el identificador del modelo a ejecutar, y el identificador de la factura que vamos a procesar. Lo importante de este flujo es la request que hay que construir para invocar al modelo:
![](https://static.wixstatic.com/media/9456da_3ffa5bb5babc4077a7299f75616da5cc~mv2.png/v1/fill/w_546,h_768,al_c,q_90,enc_auto/9456da_3ffa5bb5babc4077a7299f75616da5cc~mv2.png)
Al final hago un breve tratamiento de la respuesta para no complicar demasiado la prueba de concepto, pero lo suyo sería devolver todo el response del modelo ejecutado a la Custom Page y si eres un Pro de las Canvas seguro que en un visor Pdf, puedes pintar rectángulos dinámicos utilizando galerías y las propiedades X e Y que AI Builder devuelve con las coordenadas de cada campo extraído.
Una vez el flujo de Power Automate que ejecuta el modelo seleccionado, está implementado y funcionando, lo único que queda es utilizar la propiedad OnSelect del botón con algo parecido a esto:
Set(
modelResponse;
JSON(
ExecuteAIModel.Run(
Dropdown1.Selected.customAiModelId;
InvoiceId
);
JSONFormat.IndentFour
)
)
Finalmente la variable modelResponse la utilizo en la propiedad Text de la Label que muestra la respuesta por pantalla.
Pero si te has fijado bien, ¿qué es InvoiceId?. Ni mas ni menos que el identificador de la factura que vamos a procesar. Identificador que vamos a pasar desde la aplicación basada en modelos, hasta nuestra Custom Page. ¿Cómo? Manos a la obra.
Desde la solución en la que estas trabajando, selecciona Nuevo, Más, Recurso Web. Sube un fichero que tenga el siguiente aspecto (no olvides actualizar los valores de name y entityName) y observa que el único parámetro de entrada a la función openCustomPane será el identificador de la factura que vamos a procesar.
Ahora crea, si no tienes creada aún una aplicación basada en modelos. Si ya dispones de una, puedes añadir esta aplicación a tu solución y trabajar con esa aplicación. Edita la aplicación con la edición en vista previa y añade la tabla con la que estes trabajando a la aplicación. En mi caso, la tabla Facturas. Una vez esté añadida, selecciona los tres puntos a la derecha y haz clic en la opción Editar barra de comandos. Yo he seleccionado Formulario Principal ya que este comando va a ser ejecutado desde el formulario de detalle de un registro de la tabla Facturas.
![](https://static.wixstatic.com/media/9456da_aa0f618b32464e09b019c5f18c63a1e8~mv2.png/v1/fill/w_980,h_451,al_c,q_90,usm_0.66_1.00_0.01,enc_auto/9456da_aa0f618b32464e09b019c5f18c63a1e8~mv2.png)
Selecciona Nuevo comando, indica un texto y un icono descriptivo, y en el desplegable Acción, selecciona Ejecutar Javascript. En el campo Biblioteca, selecciona el Web Resource que has subido en el paso anterior, en el campo Nombre de Función introduce openCustomPane y añade un parámetro nuevo que deberá estar establecido en FirstPrimaryItemId.
Pero.... ¿no has echado en falta algo? Nuestra Custom Page debe recibir el contexto desde la aplicación basada en modelos para saber que Factura debe procesar con el modelo de inteligencia artificial a ejecutar. Hasta ahora hemos creado un Comando que invoca a un Recurso Web y le pasa como parámetro el identificador del registro que estamos viendo desde el formulario de detalle. ¿Y la Custom Page cómo recibe ese contexto? ¡¡Este es justo el último paso que nos falta!!
Vuelve a editar la página custom y en la propiedad OnStart de la App, actualiza la fórmula que habíamos introducido para dejarla con el siguiente aspecto:
Concurrent(
ClearCollect(
CustomAIModels;
GetCustomAIModels.Run()
);
Set(
InvoiceId;
If(
IsBlank(Param("recordId"));
Blank();
GUID(
Substitute(
Substitute(
Param("recordId");
"{";
""
);
"}";
""
)
)
)
)
)
Si todo ha ido bien, cuando accedas a un registro (en mi caso) del tipo Factura, haciendo clic en el nuevo comando aparecerá un panel lateral con una "Canvas App" embebida, que habrá recibido el contexto del registro con el que estamos trabajando. Al seleccionar el modelo y presionar el botón, tendremos el output del modelo de inteligencia artificial ejecutado!!
![](https://static.wixstatic.com/media/9456da_61461fc1a1414665b37efd7b0a493299~mv2.gif)
Como siempre digo, esto es sólo el principio y a partir de aqui las posibilidades que aparecen son casi infinitas! Espero haber sido de ayuda o al menos haber contado algo interesante. Nos vemos en la siguiente!!
Comments