NVIDIA ACE es un conjunto de tecnologías que permite la creación de agentes de inteligencia artificial para videojuegos. Esta suite ofrece modelos de IA listos para integrarse tanto en la nube como en dispositivos, abarcando aspectos desde el habla hasta la inteligencia y la animación de los personajes del juego.
Para ejecutar estos modelos de forma eficiente junto al motor del juego, el NVIDIA In-Game Inferencing (NVIGI) SDK proporciona una serie de bibliotecas optimizadas que los desarrolladores pueden integrar en aplicaciones y juegos en C++.
Nueva muestra de agente de código
La versión 1.5 del SDK de NVIDIA In-Game Inferencing presenta una nueva muestra de agente de código en la que un agente de IA colabora con el jugador para derrotar monstruos en una mazmorras 2D. Los agentes de IA impulsados por modelos de lenguaje pequeños (SLMs) pueden realizar llamadas excesivas a la GPU, lo que genera competencia con los gráficos. Este artículo analiza cómo minimizar el número de llamadas de inferencia y maximizar la eficacia de cada una, reduciendo la contención en la GPU entre gráficos y computación.
Andrej Karpathy, miembro fundador de OpenAI, compara trabajar con modelos de lenguaje grandes (LLMs) con invocar fantasmas, una metáfora adecuada para los agentes LLM, especialmente aquellos que generan código. Muchos agentes personalizados se limitan a la llamada de herramientas: se define una función, el LLM decide cuándo llamarla y se devuelve un resultado. Sin embargo, existe una posibilidad más ambiciosa. En lugar de solo llamar a una función, un agente de IA puede crear la función y el código que la respalda, lo que potencia la máquina con menos procesamiento.
Riesgos de ejecutar LLMs
No obstante, esto conlleva un compromiso. Un LLM sin restricciones con capacidades de ejecución de código representa un problema de seguridad. Puede agotar la memoria, colapsar el proceso del juego o, como descubrió un desafortunado usuario, eliminar un disco duro al intentar «limpiar la caché».
Sin embargo, también puede tener ventajas, como razonamiento complejo en múltiples pasos, adaptación dinámica y reducción del uso del SLM. A continuación, se explora cómo un potencial agente de codificación se convierte en un fantasma amistoso dispuesto a ayudar.
Uso de agentes de código
En el contexto de los agentes de IA, el caso de uso y enfoque más común es la llamada a herramientas. El modelo genera un JSON estructurado, el juego o la aplicación lo analiza y luego ejecuta la función correspondiente. Aunque la capacidad de llamar funciones es poderosa, esto solo ocurre después de que el modelo ha tenido la oportunidad de reflexionar un poco, y la inferencia es costosa, especialmente cuando compite por recursos en la GPU del usuario.
Una vez que el modelo envía el JSON, espera una respuesta, reflexiona de nuevo y devuelve una respuesta, potencialmente repitiendo el ciclo. Esto puede consumir fracciones valiosas de segundo que podrían usarse para renderizar el juego. Además, si se requiere lógica compleja alrededor de la llamada a la función, el sistema debe confiar en capacidades más débiles del modelo. El modelo no maneja inherentemente bucles; simplemente produce tokens. Puede tratar de rastrear variables de estado, pero no hay rigor. Si hay varios elementos que deben abordarse, el modelo debe recordar cada uno sin perder, duplicar o alucinar entradas. Y cada elemento procesado incurre en un costo de inferencia.
Desafíos de la llamada de herramientas
El análisis numérico presenta otro desafío. Con la llamada de herramientas, la precisión depende de la capacidad matemática del modelo o de escribir otra función para garantizar la corrección. Además, la llamada de herramientas puede tener dificultades para escalar. Cada llamada de función requiere otro golpe de inferencia que compite por recursos de GPU y debe mitigarse.
Los agentes de código funcionan utilizando algo en lo que las computadoras ya son buenas: ejecutar código. La programación es uno de los superpoderes emergentes de los modelos de lenguaje. En lugar de generar una llamada de función a la vez, una sola inferencia puede generar todas las llamadas de función a la vez. No hay penalización de rendimiento después de la generación inicial, solo código estándar que se ejecuta hasta que se completa la tarea.
Estos agentes también son flexibles. Mientras que los modelos de lenguaje no pueden hacer bucles fácilmente, los agentes de código pueden escribir código con bucles, contadores y filtros. A continuación, se presenta un ejemplo hipotético de cómo se podría utilizar la llamada de herramientas para atacar a un enemigo.
Ejemplo de agente de código en un dungeon
Siguiendo con el tema de los fantasmas, el IGI SDK incluye un dungeon crawler ASCII para demostrar el agente de código. El dungeon contiene todos los elementos de un gran juego, pero en una de las formas más simples del gaming. Los jugadores se mueven, recogen objetos y luchan contra monstruos. Pero también tienen un poderoso aliado en su aventura, un agente de IA que puede materializarse a voluntad para ayudarlos a luchar, realizar peligrosas misiones o proporcionar información sobre los peligros que les esperan.
Una vez que se da una instrucción, se escribe el código y el programa no vuelve a tocar el SLM hasta que se da una nueva instrucción. Una cadena de llamadas a herramientas puede producir los mismos resultados, pero a costa de llamadas de inferencia repetidas que consumen el tiempo de fotogramas asignado.
Modelo de amenaza de un agente de código
Usar un SLM para generar código que se ejecute en el host presenta riesgos de seguridad y seguridad evidentes, que incluyen:
- Acceso a funciones peligrosas. El SLM genera
os.execute("rm -rf /")orequire("socket"), y de repente el agente de código está eliminando archivos o abriendo conexiones de red. - Acceso no autorizado a archivos. El SLM localiza archivos críticos o claves de API para exfiltrarlos o eliminarlos.
- Agotamiento de recursos. El SLM escribe un bucle que asigna memoria indefinidamente.
- Desbordamiento de pila. El SLM escribe una función recursiva sin una terminación adecuada.
- Bucle infinito. El SLM escribe
while true do endy nunca retorna. - Escape de la sandbox. El SLM podría manipular estructuras internas para salir de su contención.
- Corrupción de estado. El SLM podría corromper el estado del juego o de la aplicación.
Elegir un lenguaje objetivo
Al elegir un lenguaje objetivo, se deben considerar: tiempo de ejecución, rendimiento general, complejidad de integración y depuración, y la calidad y seguridad del código producido.
Durante la ejecución de un juego, las llamadas de inferencia deben ocupar solo una fracción del tiempo total de fotograma. Las grandes penalizaciones que detienen el pipeline de renderizado son inaceptables. Si bien es posible generar algunos tokens a la vez en cada fotograma para suavizar la inferencia, la compilación no ofrece esa flexibilidad. Esto descarta lenguajes compilados como C++ o C#. En su lugar, se requiere un lenguaje interpretado.
Dos lenguajes destacan como ejemplos: Python y Lua.
Python es la opción obvia. Los SLM generan Python con fluidez. El ecosistema es masivo. Sin embargo, Python no fue diseñado para incrustarse o ejecutarse en un entorno restringido. El Global Interpreter Lock (GIL) complica los hosts multihilo. El aislamiento requiere subprocesos o subintérpretes, lo que añade complejidad. Además, no hay forma incorporada de limitar la memoria o el tiempo de ejecución. Python puede ejecutarse en una sandbox, pero es una lucha contra el lenguaje en sí.
Lua fue diseñado desde cero para incrustarse en entornos hostiles. Todo el runtime ocupa aproximadamente 200 kB y comienza en menos de un milisegundo. Además, cada amenaza identificada tiene una mitigación documentada, incluyendo:
- Funciones peligrosas: Carga selectiva de bibliotecas. No cargar
iooos, y no existen. - Agotamiento de memoria: Gancho de asignación personalizado. Rastrear cada asignación, imponer un límite.
- Desbordamiento de pila: Ganchos de depuración en llamadas de función. Contar la profundidad, error en caso de desbordamiento.
- Bucle infinito: Ganchos de depuración en el conteo de instrucciones. Error después de N instrucciones.
- Manipulación de metatabla: Eliminar
getmetatable/setmetatablede los globales. - Corrupción de estado: Métodos metamétodo personalizados
_ _newindexque rechazan escrituras en campos protegidos.
Por lo tanto, Lua cumple con todos los requisitos para esta muestra de IGI, pero aún requiere endurecimiento. Con Lua, las funciones peligrosas o no deseadas se establecen en nil (lua_pushnil(L); lua_setglobal(L,"funcname") patrón). El crecimiento de memoria se limita envolviendo el asignador predeterminado y rastreando asignaciones. El programador puede establecer ganchos (lua_sethook) para asegurarse de que los programas no desborden el stack de llamadas o se cuelguen indefinidamente. De manera similar, el acceso a la metatabla se puede restringir con metamétodos personalizados bloqueados para proteger el estado del juego.
Estos son solo algunos de los pasos tomados para asegurar esta muestra. Pueden ser necesarios más (dependiendo de cada juego o caso de uso particular), pero estos consejos deberían ayudar a guiar al lector mientras revisa el código.
Para mayor seguridad, Lua puede incrustarse en un runtime de WebAssembly. Vea los artículos del blog Sandboxing Agentic AI Workflows with WebAssembly y Practical Security Guidance for Sandboxing Agentic Workflows and Managing Execution Risk para más información sobre formas de asegurar el comportamiento agente.
La seguridad es una preocupación central, no un pensamiento posterior. La elección del lenguaje es una decisión de seguridad, no de conveniencia. Comience con esta premisa y comprenda los diferentes vectores de ataque a los que debe protegerse, y el fantasma permanecerá como amigo en la máquina.
Comience con el NVIDIA In-Game Inferencing SDK
Pruebe la muestra con el NVIDIA In-Game Inference SDK. Compílalo, experimenta y piensa en formas de emplearlo en juegos, aplicaciones y otros proyectos.
Únase a nosotros en GDC
Explore cómo NVIDIA RTX neural rendering e IA están dando forma a la próxima era del gaming. Obtenga un vistazo al futuro del desarrollo de juegos con John Spitzer, vicepresidente de Tecnología de Desarrollo y Rendimiento en NVIDIA, mientras presenta las últimas innovaciones en trazado de rayos y flujos de trabajo de IA generativa.
Acompañe a Bryan Catanzaro, vicepresidente de Investigación en Aprendizaje Profundo Aplicado en NVIDIA, en una sesión interactiva de “Pregúntame Cualquier Cosa” sobre las últimas tendencias en IA.

