AWS Builder Center
Agent-Native ya ejecuta software en AWS Lambda: de Semantic IR a WebAssembly sin escribir en un lenguaje de programación tradicional

Agent-Native ya ejecuta software en AWS Lambda: de Semantic IR a WebAssembly sin escribir en un lenguaje de programación tradicional

¿Qué pasaría si un agente de IA pudiera construir software sin tener que escribirlo directamente en JavaScript, Python, Rust o cualquier otro lenguaje de programación tradicional? Esa es una de las preguntas que estamos explorando con Agent-Native, un proyecto open source que busca cambiar la manera en que los agentes construyen y entregan software ejecutable. La idea es introducir una representación intermedia que permita expresar el comportamiento del software, validarlo y convertirlo en un artefacto.

Series: Knowledge Driven Development - KDD (10 articles)

  1. …
  2. 10
    Agent-Native ya ejecuta software en AWS Lambda: de Semantic IR a WebAssembly sin escribir en un lenguaje de programación tradicional This article
Cloud Solutions Architect Lead | Content Creator TryCatch.tv
¿Qué pasaría si un agente de IA pudiera construir software sin tener que escribirlo directamente en JavaScript, Python, Rust o cualquier otro lenguaje de programación tradicional? Esa es una de las preguntas que estamos explorando con Agent-Native, un proyecto open source que busca cambiar la manera en que los agentes construyen y entregan software ejecutable. La idea es introducir una representación intermedia que permita expresar el comportamiento del software, validarlo y convertirlo en un artefacto independiente del agente que participó en su construcción sin depender de un lenguaje de programación.
 
 
Durante las últimas iteraciones alcanzamos un avance que considero especialmente importante, Agent-Native ya logró ejecutar un componente WebAssembly en AWS Lambda. No se trató de simular la ejecución dentro del entorno de desarrollo ni de pedirle a un modelo de lenguaje que respondiera una operación. Construimos un artefacto ejecutable a partir de Semantic IR, lo incorporamos a una función Lambda y lo ejecutamos utilizando un runtime independiente desarrollado en Rust. Posteriormente lo comparamos contra una implementación equivalente en Rust nativo para entender el costo técnico de esta arquitectura.
 
 

El problema no es que los agentes escriban código, sino lo que hacemos después

Actualmente utilizamos agentes de IA para generar funciones, crear APIs, implementar pruebas e incluso desarrollar aplicaciones completas. Sin embargo, la mayoría de esos flujos continúa siguiendo una estructura conocida, describimos un requerimiento, el agente genera código en algún lenguaje y posteriormente utilizamos sus herramientas de compilación, dependencias y despliegue. Es una aproximación útil, pero nos hace depender de que el agente produzca código correctamente estructurado y de que todo el ecosistema necesario para ejecutarlo esté disponible. También deja abierta una pregunta sobre cómo representar, verificar y evolucionar el comportamiento que realmente queríamos construir.
 
Con Agent-Native estamos explorando una separación diferente entre la intención funcional y el artefacto ejecutable. En lugar de considerar el código fuente tradicional como la única salida posible de un agente, proponemos que pueda producir una representación semántica intermedia llamada Semantic IR. Esta representación describe funciones, tipos, operaciones y contratos de manera estructurada, de forma que un verificador pueda revisar su consistencia antes de entregarla a un compilador determinista. El resultado es un componente WebAssembly que puede ejecutarse sin volver a consultar al agente, sin depender de un proveedor de modelos de lenguaje y sin necesitar el compilador durante su operación.
 

Una representación semántica que termina convertida en software ejecutable

Para entender qué estamos construyendo, podemos tomar una operación sencilla, recibir un número y devolver su doble. Normalmente escribiríamos esa lógica como una función en JavaScript, Python o Rust, pero en Agent-Native el comportamiento puede describirse mediante una estructura que identifica una multiplicación, un parámetro de entrada y una constante. No necesitamos expresar la operación utilizando la sintaxis de un lenguaje de propósito general, porque esa responsabilidad queda en el compilador. La Semantic IR es un contrato técnico verificable, no una instrucción ambigua que deba volver a interpretar un LLM cada vez que se ejecuta.
En la prueba utilizamos Semantic IR v0.5 y un contrato WIT que define las operaciones disponibles en el componente. El ejemplo contiene dos funciones: double-value, que multiplica un entero por dos, y make-point-sum, que suma dos valores y devuelve un registro con la suma y su doble. Son operaciones deliberadamente simples porque el objetivo inicial no era resolver un problema de negocio complejo, sino comprobar que el artefacto podía atravesar todo el proceso de compilación, empaquetado y ejecución en un servicio cloud. La lógica de esas operaciones vive en el componente WebAssembly, no en el adaptador Rust de AWS Lambda.
1
{ "op": "mul", "left": { "op": "param", "name": "x" }, "right": { "op": "const", "type": "i32", "value": 2 }}
Este fragmento corresponde al cuerpo de una operación de la Semantic IR utilizada en el experimento. Aunque la representación se serializa en JSON, no estamos utilizando JSON como un lenguaje de programación general; estamos describiendo una operación mediante estructuras conocidas y reglas que el compilador comprende. El modelo completo también incorpora tipos, parámetros, funciones y referencias al contrato WIT, que permiten comprobar cómo debe comportarse el componente y cómo será invocado desde el exterior. Esa separación resulta particularmente interesante para el desarrollo asistido por agentes, porque permite validar una representación intermedia antes de producir el software ejecutable.
 
https://github.com/Kaddo-kdd/agent-native/blob/main/crates/compiler/tests/fixtures/ir/program-005.ir.json
 
https://github.com/Kaddo-kdd/agent-native/blob/main/crates/compiler/tests/fixtures/wit/program-005.wit
 

De Semantic IR a AWS Lambda

Para ejecutar este componente en AWS utilizamos las capacidades que Agent-Native ya tenía al completar su tercer hito de desarrollo, M3. El compilador transforma la Semantic IR en un componente WebAssembly compatible con Component Model y su contrato WIT, mientras que el runtime utiliza Wasmtime para cargarlo e invocar sus operaciones. Creamos un adaptador AWS Lambda en Rust que recibe eventos JSON, los convierte a los tipos correspondientes y entrega las respuestas generadas por el componente. La característica central es que el runtime no depende del compilador ni de un LLM para funcionar, por lo que la construcción del software y su ejecución ocurren en momentos distintos.
 
La función Lambda se desplegó utilizando provided.al2023 y un ejecutable nativo llamado bootstrap, que contiene el runtime y el componente WASM generado previamente. Durante el inicio de un entorno Lambda se construye el motor de Wasmtime y se carga el componente, de manera que ambos puedan reutilizarse en invocaciones posteriores. Sin embargo, cada solicitud se ejecuta creando un nuevo wasmtime::Store, siguiendo la estrategia de aislamiento definida para Agent-Native. Así podemos aprovechar la reutilización del motor y del componente sin convertir una instancia WASM persistente en un estado compartido entre solicitudes.
 
 
Lo interesante de esta integración es que AWS Lambda no necesita conocer cómo se construyó la lógica del componente. Su responsabilidad consiste en ejecutar el adaptador Rust, mientras que Agent-Native se encarga de cargar e invocar el artefacto WebAssembly. El componente tampoco conoce detalles de AWS, como IAM, CloudWatch o la API de invocación de Lambda, porque en este experimento no utiliza imports funcionales del host. Esta separación nos permitió probar una de las propiedades arquitectónicas que buscamos: que el software compilado pueda ejecutarse en un entorno diferente al utilizado para construirlo.

La primera ejecución real

La primera prueba consistió en desplegar una función denominada agent-native-wasm-poc en AWS Lambda, dentro de la región us-west-2, con arquitectura x86_64 y 256 MB de memoria configurada. Enviamos un evento JSON solicitando la operación double-value con un valor de entrada de 21, y la función respondió correctamente con {"result":42}. También invocamos make-point-sum con los valores 3 y 4, obteniendo un registro con sum: 7 y doubled: 14. Finalmente, probamos una operación desconocida para comprobar que el adaptador devolviera un error explícito en lugar de inventar una respuesta o utilizar un valor por defecto.
 
Esta prueba también nos permitió observar el comportamiento de ejecuciones frías y calientes. En la primera invocación, AWS Lambda reportó un tiempo de inicialización de 92.21 milisegundos, mientras que las siguientes solicitudes registraron duraciones de ejecución entre 1.12 y 2.34 milisegundos. El consumo máximo de memoria reportado estuvo entre 25 y 26 MB, incluyendo el adaptador Rust, Wasmtime y el componente WebAssembly. Los resultados fueron alentadores, aunque esa primera batería de seis invocaciones era demasiado pequeña para sacar conclusiones generales sobre rendimiento o estabilidad.
 

¿Cuánto cuesta utilizar Agent-Native frente a Rust nativo?

Después de comprobar que el componente podía ejecutarse en Lambda, quisimos resolver otra pregunta: ¿cuál es el costo técnico de introducir WebAssembly en comparación con implementar directamente la misma lógica en Rust? Para responderla creamos dos funciones con el mismo contrato JSON, la misma configuración de AWS y las mismas operaciones. La primera ejecutaba la lógica en Rust nativo, mientras que la segunda utilizaba el componente generado por Agent-Native y cargado mediante Wasmtime. El experimento incluyó diez inicializaciones frías verificadas por implementación y cincuenta invocaciones calientes por operación, para un total de doscientas invocaciones calientes entre ambas funciones.
 
 
MétricaRust nativoAgent-Native WASMDiferencia
Inicialización fría (media)36.27 ms85.22 ms+48.95 ms
double-value caliente (p50)0.99 ms1.06 ms+0.07 ms
make-point-sum caliente (p50)0.91 ms0.99 ms+0.08 ms
Memoria observada en caliente20 MB~25 MB~+5 MB
Ejecutable descomprimido1.92 MiB7.81 MiB+5.89 MiB
Paquete comprimido0.85 MiB3.12 MiB+2.26 MiB
 
Los resultados muestran un comportamiento que vale la pena analizar. Como era de esperar, Agent-Native necesita más tiempo para inicializarse porque incorpora Wasmtime y debe cargar el componente WebAssembly, además de ejecutar el adaptador Rust. En cambio, durante las invocaciones calientes, la diferencia de latencia observada fue pequeña: entre 0.07 y 0.08 milisegundos en la mediana de las dos operaciones. El tamaño del artefacto también aumentó, aunque el paquete final de aproximadamente 3.12 MiB sigue siendo relativamente compacto para una función que incorpora un motor de ejecución WebAssembly.
 
Es importante interpretar estos resultados dentro de sus límites. Los 48.95 milisegundos adicionales corresponden a la diferencia de inicialización entre ambas funciones completas; no medimos por separado cuántos milisegundos consumió exclusivamente Wasmtime. Lo mismo ocurre con la diferencia de 0.08 milisegundos, corresponde a la duración total reportada por Lambda, no a una medición aislada de la llamada al componente WebAssembly. Tampoco podemos concluir que no existen fugas de memoria porque las cifras se mantuvieron estables en unas pocas decenas de invocaciones; para eso necesitaremos pruebas más prolongadas, instrumentación específica y escenarios con mayor complejidad.

La verdadera novedad no está en los milisegundos

 
Los resultados de rendimiento son útiles, pero no fueron la motivación principal de este experimento. Lo que queríamos comprobar era si una lógica expresada como Semantic IR podía transformarse en software ejecutable y funcionar en un servicio cloud administrado sin requerir el agente que participó en su desarrollo. La respuesta fue afirmativa: el componente se compiló antes del despliegue y, una vez en AWS Lambda, se ejecutó de manera independiente. Esto abre la posibilidad de construir flujos donde los agentes trabajen sobre representaciones funcionales verificables, mientras que la infraestructura de ejecución permanezca desacoplada de los modelos de inteligencia artificial.
 
Aquí hay una distinción importante entre lo que ya demostramos y la visión completa del proyecto. En esta POC reutilizamos un archivo Semantic IR existente y versionado; no ejecutamos todavía el proceso integral en el que un LLM interpreta automáticamente una narrativa de negocio y produce esa representación como parte del pipeline de construcción. Esa integración forma parte de las siguientes etapas de Agent-Native. Lo que sí quedó validado es la parte que permite convertir la representación semántica en WebAssembly y llevar ese resultado hasta una Lambda real, utilizando una implementación desarrollada y verificada con asistencia de agentes durante el ciclo del proyecto.
 
También me parece relevante lo que esta arquitectura plantea sobre la responsabilidad de los agentes. Si toda la lógica depende de volver a preguntar a un modelo qué hacer, entonces la ejecución hereda su latencia, sus costos y su comportamiento probabilístico. En cambio, cuando el resultado del proceso de construcción es un componente compilado, las decisiones de ejecución pasan a estar gobernadas por un contrato y por instrucciones concretas. El agente puede participar en la construcción y evolución del software, pero no necesita estar presente para resolver cada invocación. Esa es una de las separaciones fundamentales que buscamos con Agent-Native.
 
 

¿Qué sigue para Agent-Native?

Todavía estamos trabajando con una superficie funcional limitada, especialmente en Semantic IR v0.5, y sería prematuro presentar estos resultados como evidencia de que Agent-Native puede reemplazar cualquier implementación tradicional. La siguiente etapa es integrar de forma más completa la interpretación de especificaciones, los agentes de construcción y el pipeline que transforma requerimientos en artefactos verificables. También necesitaremos ampliar las capacidades del runtime, explorar operaciones más representativas de aplicaciones reales y medir el comportamiento con volúmenes de trabajo mayores. Los experimentos con Lambda nos proporcionan una referencia inicial para tomar esas decisiones basándonos en datos y no únicamente en suposiciones.
 
Aun así, considero que este avance marca un punto importante en el desarrollo del proyecto. Pasamos de discutir cómo podría funcionar una arquitectura orientada a agentes a disponer de un componente generado desde Semantic IR, ejecutándose realmente en AWS y acompañado de un benchmark frente a Rust nativo. La novedad no es haber inventado una nueva manera de desplegar una Lambda, sino demostrar una ruta alternativa para producir la lógica que termina ejecutándose allí. Agent-Native busca que un agente pueda construir software sin estar obligado a escribir directamente un lenguaje de programación tradicional, y ahora sabemos que el artefacto resultante puede llegar hasta un entorno cloud real.
 
El proyecto es open source y tanto el ejemplo como los datos del experimento están disponibles para que cualquiera pueda revisarlos, reproducirlos o cuestionar nuestras conclusiones. De hecho, ese último punto es especialmente valioso, estamos construyendo Agent-Native de manera incremental, procurando que cada avance tenga evidencia verificable y que las limitaciones queden documentadas. Todavía quedan varios problemas técnicos por resolver, pero ya contamos con una base concreta para seguir experimentando. Y si algo nos ha enseñado este proceso, es que una arquitectura comienza a ponerse realmente a prueba cuando deja de vivir solamente en los diagramas.
 
Por último estoy evaluando cambiar el nombre de Agent Native, espero lograr definirlo pronto.

Código, resultados y referencias

  • Repositorio Agent-Native: https://github.com/Kaddo-kdd/agent-native
  • Ejemplo AWS Lambda — AN-021: https://github.com/Kaddo-kdd/agent-native/tree/main/examples/aws-lambda
  • Benchmark Rust Native vs Agent-Native — AN-022: https://github.com/Kaddo-kdd/agent-native/tree/main/examples/aws-lambda-benchmark
  • Reporte técnico: https://github.com/Kaddo-kdd/agent-native/blob/main/examples/aws-lambda-benchmark/BENCHMARK_REPORT.md
  • Datasets CSV/JSON: https://github.com/Kaddo-kdd/agent-native/tree/main/examples/aws-lambda-benchmark/results
  • Release técnica M3: https://github.com/Kaddo-kdd/agent-native/releases/tag/v0.0.4-m3

Series: Knowledge Driven Development - KDD (10 articles)

  1. …
  2. 10
    Agent-Native ya ejecuta software en AWS Lambda: de Semantic IR a WebAssembly sin escribir en un lenguaje de programación tradicional This article
Any opinions in this article are those of the individual author and may not reflect the opinions of AWS.
Enjoyed reading this content? Let the author know!

Your likes, comments, shares, and saves help creators reach more builders.

Loading recommendations

Loading article