Transferir las cargas de trabajo de Apps Script a un entorno aislado gestionado por Gemini en Linux.
Google Apps Script que impulsa un entorno aislado Linux para agentes gestionados por Gemini: transfiere archivos a Drive mediante ggsrun, evita el límite de 50 MB y ejecuta Playwright, FFmpeg y esbuild.
Fuentes: Taking Advantage of Gemini Managed Agents with Google Apps Script
¿Por qué combinar Apps Script con un entorno aislado de Linux?
Google Apps Script es una herramienta útil para automatizar Google Workspace, pero se trata de un entorno sin servidor ligero y restringido que no permite acceso a nivel de sistema operativo. Esto descarta una larga lista de tareas más complejas. El control de red y protocolos a nivel bajo es limitado. No existe un navegador sin interfaz para renderizar páginas dinámicas, no hay forma de ejecutar binarios nativos para la transcodificación de medios o el procesamiento de señales, faltan compiladores modernos o cadenas de herramientas de compilación, y existen cuotas estrictas en cuanto al tiempo de ejecución y al tamaño de la carga.
Gemini Managed Agents ofrecen una solución a este problema. Como parte de la API Gemini v1beta Interactions and Environments, permiten a los desarrolladores configurar entornos aislados de Linux remotos que pueden ejecutar código por sí mismos, lanzar comandos de shell y gestionar paquetes. Su combinación con la CLI de Google Workspace ya ha generado interés en la comunidad.
La arquitectura descrita aquí conecta ambos elementos. Apps Script gestiona un contenedor Linux persistente con 4 vCPUs y 16 GB de RAM, además de Python 3.12, Node.js 22 y los gestores de paquetes habituales (apt, npm, pip); el contenedor transmite los archivos generados directamente a Google Drive mediante la herramienta de línea de comandos ggsrun. Dado que los archivos nunca viajan de vuelta a través de la respuesta de la API, este diseño evita los límites de carga y la sobrecarga de tokens, permitiendo así una automatización en la nube de alto rendimiento.
El problema de devolver archivos binarios en formato Base64
Supongamos que la caja de pruebas genera algo de gran tamaño, como capturas de pantalla de alta resolución, formas de onda de audio o un archivo JavaScript empaquetado, y que debe guardarse en Drive. La ruta obvia es devolver los bytes en bruto como una cadena Base64 en la respuesta de la API de Gemini y decodificarlos en Apps Script. Sin embargo, ese enfoque se topa con varios problemas al mismo tiempo.
UrlFetchAppen Apps Script impone un límite de 50 MB en los volúmenes de respuesta.- El entorno de ejecución de código de la API de Interacciones limita el búfer de salida estándar, por lo que una cadena Base64 de varios megabytes puede quedar incompleta a mitad del proceso.
- Los Agentes gestionados tienen una cuota de 200,000 tokens por minuto. El formato Base64 aumenta el tamaño binario en aproximadamente un tercio, y en sesiones de múltiples interacciones las cadenas Base64 anteriores se acumulan en el historial de conversaciones hasta que se agotan las cuotas de entrada y aparecen de inmediato los errores
429 Quota Exceeded.
El siguiente diagrama contrasta ese método con la transmisión directa.
El enfoque más eficaz consiste en ejecutar la herramienta ggsrun, basada en Go, dentro de la propia sandbox, utilizando un token de acceso OAuth inyectado en tiempo de ejecución a través de ScriptApp.getOAuthToken(). A continuación, la sandbox envía los archivos binarios a Drive a través de la infraestructura interna de Google Cloud a velocidades superiores a 2 MB/s, evitando así los límites de memoria de Apps Script, los límites de tamaño de respuesta y el agotamiento de cuotas de tokens de una sola vez.
La transmisión en flujo funciona en ambas direcciones
La transferencia directa de nube a nube también es útil para las descargas. Cuando grandes conjuntos de datos externos, como imágenes de alta resolución, audio, video, archivos CSV o JSON de varios gigabytes o modelos de aprendizaje automático, deben llegar al entorno aislado, incrustarlos en una instrucción como texto Base64 o serializado agota casi de inmediato la cuota de tokens de entrada, lo que provoca un error 429. Con ggsrun, el entorno aislado obtiene el archivo directamente del Drive, y la instrucción solo necesita una indicación breve del tipo “descargar el conjunto de datos objetivo del Drive y analizarlo”. El uso de tokens de entrada disminuye prácticamente a cero, lo que evita el agotamiento de los límites de velocidad.
Compartir una sandbox persistente reduce aún más los costos. Un único paso de aprovisionamiento genera un environmentId que pueden utilizar tanto los proyectos de Apps Script como las estaciones de trabajo locales de Node.js, los scripts en Python y las pipelines de CI/CD. Los conjuntos de datos maestros, corpus, bibliotecas o modelos preentrenados almacenados en /workspace/ quedan así a disposición de cada cliente, por lo que nadie tiene que volver a subir datos ni repetir la configuración en cada ocasión. Esto disminuye la latencia, el ancho de banda de red y la carga acumulada de las API, además de permitir que las tareas reutilicen archivos de trabajo compartidos y paquetes preinstalados.
El siguiente diagrama muestra la arquitectura completa, donde Apps Script y las estaciones de trabajo locales de Node.js orquestan la misma sandbox persistente a través de un environmentId compartido, utilizando transmisión bidireccional y conjuntos de datos compartidos para una generación rápida de contenido.
Se divide en cuatro partes:
- Varios clientes manejan un único contenedor. Apps Script basado en la nube utiliza un disparador síncrono y un token OAuth dinámico, mientras que las estaciones de trabajo locales de Node.js emplean transmisión en tiempo real mediante SSE y autenticación con
gcloud. - La zona de pruebas almacena conjuntos de datos compartidos y herramientas de compilación como Playwright, FFmpeg y esbuild, de modo que el contenido puede generarse sin tener que volver a subir los datos.
ggsrun downloadtransmite grandes conjuntos de datos desde Drive a la zona de pruebas, lo que evita la inserción inmediata de datos y mantiene segura la cuota de 200k TPM.ggsrun uploadenvía los binarios terminados a Drive a una velocidad de 2 MB/s o superior, superando así el límite de 50 MB de carga y la truncación de stdout.
El código fuente completo (las clases de Apps Script, los clientes de transmisión de Node.js, los conjuntos de pruebas y los registros brutos de ejecución) se encuentra en el repositorio público de GitHub del proyecto.
Configuración
Primero, genere una clave API en Google AI Studio. Esta sirve para autenticar las solicitudes a las APIs Gemini v1beta Interactions and Environments. Luego, cree un proyecto Apps Script de dos maneras: un proyecto independiente desde script.google.com mediante “Nuevo proyecto”, o uno vinculado a un contenedor abriendo una Hoja de cálculo, un Documento o un Formulario y seleccionando “Extensiones” y luego “Apps Script”.
Copie dos archivos del repositorio al editor:
ManagedAgentSandboxClient.jses la clase de cliente principal. Gestiona el ciclo de vida del entorno de pruebas y las variables de entorno dinámicas, almacena los datos de la sesión enPropertiesServicey aplica un retraso razonable cuando se recibe un error 429.tests.jses el conjunto principal de pruebas. Cubre la configuración del entorno de pruebas, las verificaciones de herramientas, el procesamiento de medios, el scraping web y las pruebas de rendimiento.
Siguiente paso: abra Ajustes del proyecto, luego Propiedades de la script, y agregue una propiedad llamada GEMINI_API_KEY que contenga la clave. Finalmente, asegúrese de que el manifiesto (appsscript.json) incluya los alcances OAuth adecuados. El alcance https://www.googleapis.com/auth/script.external_request es necesario para las llamadas a UrlFetchApp, mientras que https://www.googleapis.com/auth/drive permite crear carpetas de destino y subir archivos. El código que utiliza carpetas existentes sin DriveApp.createFolder() puede funcionar con https://www.googleapis.com/auth/drive.file. Los registros de ejecución de cada prueba se encuentran en gas-src/execution-logs.md del repositorio.
Provisión de la sandbox compartida
Al ejecutar provisionSharedSandbox() se inicia un nuevo contenedor remoto de Linux, se instalan las herramientas de línea de comandos y las dependencias, se configuran las rutas del Drive de destino y se guarda el environmentId resultante en PropertiesService.
La infografía muestra cuatro pasos. Primero, Drive crea una carpeta de destino llamada ManagedAgent_Artifacts_YYYYMMDD. Luego, el contenedor con 4 vCPU y 16 GB inicia ggsrun, ffmpeg, sox, jq, typescript, esbuild y Playwright con Chromium, a través de una solicitud de inicialización. A continuación, el entorno aislado verifica los binarios instalados y muestra READY. Finalmente, el environmentId único se almacena bajo SHARED_SANDBOX_SESSION para que pruebas posteriores y otros clientes puedan reutilizarlo. Al llamar a testListSandboxes() después, se consulta la API de Entornos para confirmar que el entorno aislado está activo y se devuelven sus metadatos.
Prueba 1: encabezados personalizados que Apps Script sobrescribe
La primera prueba muestra algo que UrlFetchApp no puede hacer. Apps Script reemplaza automáticamente un encabezado User-Agent personalizado por la cadena de identidad del proxy de Google, mientras que el entorno aislado mantiene cualquier encabezado que usted establezca, ya que envía solicitudes a través de sockets POSIX en bruto y curl nativo.
El diagrama muestra una solicitud que contiene User-Agent: sample user agent dirigida a httpbin.org/anything. En el lado de Apps Script, la política de proxy de la plataforma cambia ese encabezado. En el entorno de sandbox, curl mantiene la cadena exacta. A continuación, un script Python integrado compara los payloads JSON reflejados y muestra una matriz de verificación. En concreto, Apps Script envía una solicitud GET con el encabezado personalizado, el sandbox envía la misma solicitud curl, y la comparación confirma que Apps Script sustituyó Mozilla/5.0 (compatible; Google-Apps-Script; beanserver; ...) mientras que el sandbox conservó sample user agent tal como estaba.
Prueba 2: autenticación en Drive desde el interior del sandbox
Esta prueba verifica la autenticación de Drive y el acceso directo a través de ggsrun al inyectar un token OAuth nuevo obtenido mediante ScriptApp.getOAuthToken() en la ejecución de esa fase.
En el primer paso, Apps Script extrae el token y lo inserta como la variable de entorno GGSRUN_AT, lo que elimina el riesgo de que el token expire en una hora. En el segundo paso, el entorno de pruebas genera un archivo de verificación, 00_ggsrun_verification.txt, en la carpeta /workspace/test2/ y lo sube con ggsrun upload en modo de sobrescritura no bloqueante (--nc --cm OverwriteIfNewer -j). En el tercer paso, ggsrun searchfiles consulta la carpeta de destino y devuelve metadatos estructurados que confirman la existencia de los nueve archivos. Todo el ciclo de creación, subida y verificación tardó 12.1 segundos, y ningún token sensible permaneció entre sesiones.
Prueba 3: extracción sin interfaz con Playwright
A continuación, una sesión automatizada sin interfaz de Chromium en el entorno aislado extrae contenido dinámico renderizado por JavaScript y toma capturas de pantalla en varios tamaños de vista.
Un script de Node.js Playwright abre un sitio de citas renderizado en JavaScript (quotes.toscrape.com/js/), toma capturas de pantalla de toda la página en tamaño de escritorio (1280x800) y en emulación de iPhone (375x812), luego hace clic en el control de paginación, captura una imagen del escritorio de la página dos y extrae las citas en 02_Page2_Quotes.json. Los tamaños fueron de aproximadamente 92.5 KB para la captura del escritorio, 51.6 KB para el móvil y 171.9 KB para la página dos, más 4.1 KB de JSON, lo que suma unos 320 KB en total para los cuatro archivos. Una sola orden ggsrun upload envió las tres imágenes PNG y el conjunto de datos JSON a Drive sin ninguna conversión a Base64, y toda la operación tardó 20.4 segundos. Eso corresponde a la renderización del lado del cliente que Apps Script no puede analizar de forma nativa.
Prueba 4: síntesis de audio con FFmpeg y SoX
La cuarta prueba ejecuta el procesamiento de señales digitales nativo en el entorno aislado, creando un acorde de varios tonos con FFmpeg y SoX.
Tres generadores de ondas senoidales a 440 Hz (A4), 554.37 Hz (C#5) y 659.25 Hz (E5) se mezclan mediante el filtro amix de ffmpeg para formar un MP3 de acorde mayor de tres segundos con un tamaño de 73.4 KB. Luego, ffprobe extrae los metadatos del flujo en 03_Audio_Analysis.json, cuyo tamaño resultó ser de 1.8 KB. ggsrun upload envió directamente 03_Chord_Major.mp3 y el archivo JSON a Drive. La síntesis, la extracción de metadatos y la subida tomaron 9.1 segundos.
Prueba 5: Análisis de TypeScript y empaquetado con esbuild
Esta prueba muestra cómo funcionan las herramientas modernas de compilación de JavaScript y TypeScript dentro del entorno aislado.
Dos cadenas de herramientas trabajan en un módulo de TypeScript, matrix.ts, que define clases e interfaces genéricas y se encuentra en /workspace/test5/. En la primera rama, un script de Node.js utiliza la API oficial del Compilador de TypeScript para analizar el árbol de sintaxis abstracta y exportar los esquemas de interfaces y métodos a 04_TypeScript_AST.json, con solo 152 bytes. En la segunda, esbuild empaca y minifica el módulo en un archivo IIFE independiente, 04_Matrix_Bundle.iife.js, de 1,2 KB, con un tiempo de compilación de tan solo 13 milisegundos. Luego, ggsrun upload envió ambos resultados a Drive, y la ejecución completa tomó 10,0 segundos.
Prueba 6: carga directa mediante Base64 a través de Apps Script
La prueba de rendimiento traslada un archivo binario de 10,000 bytes desde la zona de pruebas a Drive mediante dos métodos diferentes.
En el Enfoque A, el entorno aislado crea un archivo binario de 10 KB a partir de /dev/urandom y lo transmite a Drive mediante ggsrun en una sola interacción (freshInteraction: true). En el Enfoque B, el entorno aislado codifica los mismos bytes en formato Base64 y los devuelve en el texto de respuesta de la API; Apps Script luego decodifica esa cadena y guarda el archivo en Drive. El Enfoque A finalizó en 16.20 segundos a una velocidad de 0.60 KB/s y no utilizó recursos de CPU de Apps Script. El Enfoque B necesitó 32.13 segundos a una velocidad de 0.30 KB/s, además de 1.23 segundos de uso de CPU de Apps Script; por lo tanto, el Enfoque A fue 1.98 veces más rápido. También evita la inflación aproximada del 33 por ciento que ocurre al usar Base64 y el agotamiento de tokens que sufren las sesiones con múltiples interacciones. El informe generado se ve así.
================================================================================
PERFORMANCE BENCHMARK REPORT: 10,000 BYTES FILE TRANSFER TO GOOGLE DRIVE
================================================================================
| Metric | Approach A: Direct ggsrun Upload | Approach B: Base64 via Gemini API -> GAS |
| :--------------------------- | :------------------------------- | :--------------------------------------- |
| Transfer Method | Direct Sandbox-to-Drive (Go CLI) | Base64 Stream -> GAS -> Drive |
| Drive File Name | benchmark_10kb_ggsrun.bin | benchmark_10kb_gas.bin |
| Verified File Size | 10,000 bytes (9.77 KB) | 10,000 bytes (9.77 KB) |
| API Turns Required | 1 Turn (Direct Offload) | 1 Turn (Base64 Retrieval) |
| Local GAS Processing Time | 0.00 s (Zero CPU overhead) | 1.23 s (Base64 Decode & Blob Creation) |
| Total End-to-End Duration | 16.20 s | 32.13 s |
| Effective Throughput | 0.60 KB/s | 0.30 KB/s |
| Performance Multiplier | 1.98x FASTER | Baseline (Higher Latency & Token Usage) |
================================================================================
La transmisión mediante ggsrun fue 1,98 veces más rápida, eliminó todos los costos de CPU y memoria de Apps Script relacionados con la decodificación, y no consumió ninguna cuota de tokens de conversación. Para cargas de varios megabytes, esta ruta directa es la que evita los errores 429 Quota Exceeded.
Controlar la misma sandbox desde una estación de trabajo local
Para demostrar que se puede controlar la misma sandbox persistente de Linux desde Apps Script y desde una computadora portátil, se creó un cliente de Node.js con transmisión de Server-Sent Events basado en el SDK @google/genai. Apps Script se ejecuta de forma síncrona y bloqueante, recopilando los eventos del agente al final de la solicitud HTTP; por lo tanto, el ejecutor local brinda a los desarrolladores varias ventajas que Apps Script no puede ofrecer.
- Visibilidad en tiempo real del proceso de ejecución. Los pasos de razonamiento (
thought), comandos de shell (code_execution_call), salida estándar y de error del entorno aislado (code_execution_result) y el texto del modelo (model_output) se envían al terminal a medida que ocurren, con colores ANSI. - Un flujo de trabajo híbrido para el desarrollo. Se pueden prototipar, depurar y ajustar prompts y cadenas de herramientas localmente con retroalimentación en tiempo real, para luego pasarlos a desencadenadores automatizados de Apps Script que se ejecutan sin intervención humana.
- Compartir entornos aislados de forma sencilla. Al introducir el identificador generado durante la configuración de Apps Script en
ENVIRONMENT_IDde un archivo local.env, el cliente se conecta al contenedor existente, con todos sus paquetes instalados, binarios compilados y archivos de trabajo, sin necesidad de reinstalarlo.
gcloud auth print-access-token e los inserta en GGSRUN_AT, de modo que las subidas directas a Drive funcionen como en Apps Script sin necesidad de copiar las credenciales manualmente.Ejecutar las pruebas locales implica cuatro pasos.
- Clona el repositorio y ejecuta
npm installdentro delocal-node.js-src. - Duplica
.env.examplecomo.envy rellena tres valores: tu clave de API comoGEMINI_API_KEY, el identificador de entorno de larga duración comoENVIRONMENT_ID, y la carpeta de Drive a la que escribir comoTARGET_FOLDER_ID. - Ejecuta
npm test, o una prueba específica connpm run test:1hastatest:6, y observa cómo funciona el agente en tiempo real. - Una vez terminado, ejecute
npm run test:teardownpara eliminar la sandbox remota y liberar los recursos en la nube.
Las transcripciones en bruto completas, junto con los resultados de la transmisión en vivo, se guardan en local-node.js-src/execution-logs.md del repositorio, y muestran los mismos resultados funcionales que las ejecuciones de Apps Script.
Patrones de API para Agentes Gestionados
Los patrones a continuación resumen las formas comunes de trabajar con la API de Interacciones y Entornos de Gemini v1beta. Cada uno de ellos envía una solicitud POST al mismo endpoint base.
POST https://generativelanguage.googleapis.com/v1beta/interactions?key=${API_KEY}
Content-Type: application/json
El escenario 1 comparte una única sandbox persistente entre muchos clientes. Crea el entorno remoto una vez, con environment.type establecido en "remote", guarda el environment_id que se obtiene y envíalo como una cadena simple en las solicitudes posteriores desde Apps Script, Node.js, Python o un trabajo de CI/CD.
{
"agent": "antigravity-preview-05-2026",
"input": "Run task in shared container...",
"environment": "environments/env-12345"
}
El escenario 2 es un entorno aislado para cada ejecución. Cuando una tarea necesita un entorno Linux completamente nuevo, establezca environment.type en "remote" en cada llamada.
{
"agent": "antigravity-preview-05-2026",
"input": "Execute client-specific isolated task...",
"environment": {
"type": "remote"
}
}
El escenario 3 mantiene el contexto de la conversación a lo largo de las interacciones. Incluir previous_interaction_id cada vez que el agente deba recordar razonamientos anteriores, variables o resultados de comandos.
{
"agent": "antigravity-preview-05-2026",
"input": "Based on the previous output, proceed to step 2...",
"environment": "environments/env-12345",
"previous_interaction_id": "interaction-prev-67890"
}
El escenario 4 reutiliza un entorno aislado con un contexto nuevo, mediante la opción freshInteraction. Se debe proporcionar el environment_id existente y omitir previous_interaction_id. Todos los archivos y herramientas instaladas en el contenedor permanecen, mientras que el historial de conversaciones se reinicia a cero tokens, lo que evita agotar el límite de velocidad del TPM.
{
"agent": "antigravity-preview-05-2026",
"input": "Execute a completely new task in the existing sandbox...",
"environment": "environments/env-12345"
}
Comparación a primera vista
La matriz de resumen coloca los enfoques uno al lado del otro.
Qué implica esto
Combinar Apps Script con Gemini Managed Agents supera los límites habituales de un entorno sin servidor. Un entorno aislado remoto persistente, además de la transmisión directa en ambos sentidos entre el almacenamiento en la nube y dicho entorno aislado, permite ejecutar cargas de trabajo que Apps Script por sí solo no puede manejar, y evita los límites de carga de las API y las cuotas de tokens de conversación.
- Se superan los límites de Apps Script. Las tareas que requieren un entorno Linux nativo, como el scraping con navegadores sin interfaz mediante Playwright, la síntesis de audio con FFmpeg y la compilación de TypeScript con
esbuild, ahora pueden iniciarse desde Apps Script. - El razonamiento de la IA se combina con la ejecución en Linux. En lugar de ejecutar comandos externos fijos, el razonamiento de Gemini funciona junto con una shell real, lo que permite componer comandos en tiempo real, ejecutar código durante la ejecución y que el agente se corrija a sí mismo en flujos de trabajo complejos.
- La transmisión en ambas direcciones ahorra tokens y datos. Subir archivos y también extraer grandes conjuntos de datos de entrada desde Drive a la zona de pruebas evita cargar datos en los prompts y la conversión a Base64, lo que mantiene bajos los tokens de entrada y salida, evitando el límite de 50 MB y la cuota de 200,000 TPM.
- Las zonas de pruebas compartidas reducen los costos. Al almacenar conjuntos de datos y herramientas comunes en un sistema de archivos de contenedor compartido, se eliminan las subidas y configuraciones repetidas para cada tarea, lo que disminuye la latencia y el ancho de banda.
- Las pruebas de rendimiento lo confirman. La transmisión directa de datos de nube a nube mediante la CLI fue 1,98 veces más rápida que obtener datos en formato Base64 a través de la API, sin costos de decodificación en la CPU ni uso de memoria local en Apps Script.