Skip to content
Volver al blog
Open Source

Ejecución de Código en la Nube en Menos de 90ms: Cómo Daytona Reemplazó a Docker en Nuestro Stack de Agentes IA

Vstorm · · 6 min de lectura
Disponible en: Deutsch · English · Polski
Tabla de contenidos

Todo agente de IA que escribe código necesita un lugar donde ejecutarlo. El agente genera un script de Python, un comando de shell, un pipeline de datos — y algo tiene que ejecutar ese código de forma segura, aislado de tu entorno de producción.

Durante el último año, usamos Docker. Levantar un contenedor, ejecutar el código, destruirlo. Funciona. Pero “funciona” tiene un costo: 2-5 segundos de latencia de arranque en frío por sandbox. Cuando tu agente hace 10-20 llamadas a herramientas por tarea, eso son 30-100 segundos solo esperando que los contenedores arranquen.

Entonces probamos Daytona. Arranque en menos de 90ms. Sin Docker daemon. Sandboxes efímeros en la nube que se levantan más rápido de lo que tu agente puede pensar en el siguiente paso.

El Problema: Los Arranques en Frío de Docker Arruinan la Experiencia del Agente

Nuestros agentes de IA usan pydantic-ai-backend — una biblioteca de Python que proporciona backends de almacenamiento de archivos y ejecución de código para agentes de Pydantic AI. Antes de Daytona, teníamos tres backends:

BackendAlmacenamientoEjecuciónCaso de Uso
StateBackendEn memoriaNoPruebas, sesiones efímeras
LocalBackendSistema de archivosDesarrollo local
DockerSandboxContenedorMulti-usuario, código no confiable

Docker era nuestra elección para producción. Ejecución aislada, entorno controlado, sin riesgo de que los agentes destruyan el host. Pero la sobrecarga de arranque era real:

  1. Descargar imagen (si no está en caché) — segundos
  2. Crear contenedor — cientos de ms
  3. Iniciar contenedor — cientos de ms
  4. Esperar health check — variable
  5. Ejecutar el comando real — la única parte que importa

Llega Daytona: Sandboxes Efímeros en la Nube

Daytona proporciona sandboxes efímeros en la nube — VMs aisladas que pre-aprovisionan recursos y eliminan la sobrecarga de arranque en frío. Menos de 90ms desde la creación hasta la ejecución del primer comando.

Añadimos DaytonaSandbox como cuarto backend en pydantic-ai-backend v0.1.12:

from pydantic_ai_backends import DaytonaSandbox, create_console_toolset
from pydantic_ai import Agent
from dataclasses import dataclass
@dataclass
class Deps:
backend: DaytonaSandbox
sandbox = DaytonaSandbox(api_key="dtna_...")
try:
toolset = create_console_toolset()
agent = Agent("openai:gpt-4.1", deps_type=Deps)
agent = agent.with_toolset(toolset)
result = agent.run_sync(
"Write a script that calculates fibonacci and run it",
deps=Deps(backend=sandbox),
)
print(result.output)
finally:
sandbox.stop()

El mismo agente, el mismo toolset, la misma API — diferente backend. El agente no sabe (ni le importa) si está ejecutándose en Docker o en Daytona.

La Arquitectura: Abstracción BaseSandbox

Para soportar Daytona junto a Docker de forma limpia, extrajimos una clase base abstracta BaseSandbox:

class BaseSandbox(ABC):
"""Abstract sandbox backend for isolated code execution."""
@abstractmethod
def execute(self, command: str, timeout: int = 1800) -> ExecuteResult: ...
@abstractmethod
def _read_bytes(self, path: str) -> bytes: ...
@abstractmethod
def write(self, path: str, content: str | bytes) -> WriteResult: ...
def edit(self, path: str, old: str, new: str, replace_all: bool = False) -> EditResult:
# Default: read → Python string replace → write
...

Tanto DockerSandbox como DaytonaSandbox heredan de BaseSandbox. Al toolset no le importa cuál recibe.

MétodoDockerDaytona
execute()docker.exec_run()sandbox.process.exec()
_read_bytes()Shell cat vía Docker execAPI nativa de descarga de archivos
write()Shell cat > vía Docker execAPI nativa de carga de archivos
stop()Eliminar contenedorEliminar sandbox en la nube

Las APIs nativas de archivos de Daytona son particularmente interesantes — en lugar de pasar por un shell (como hace Docker), Daytona sube/descarga archivos directamente a través de su SDK.

Docker vs Daytona: Cuándo Usar Cada Uno

CaracterísticaDaytonaSandboxDockerSandbox
Tiempo de arranqueMenos de 90ms2-5 segundos
InfraestructuraNube (plataforma Daytona)Docker daemon local
Configuración necesariaSolo API keyDocker instalado + ejecutándose
AislamientoVM en la nubeContenedor
CostoPrecios de DaytonaGratis (recursos locales)
Ideal paraCI/CD, serverless, nubeDesarrollo local, auto-hospedado

Usa Daytona cuando: despliegues en la nube, la latencia de arranque importa, escalado horizontal, pipelines CI/CD donde Docker-in-Docker es problemático.

Usa Docker cuando: ejecutas localmente, necesitas runtimes personalizados, quieres auto-hospedar todo, eres sensible al costo.

Configuración: 3 Líneas para Cambiar

# Before: Docker
from pydantic_ai_backends import DockerSandbox
sandbox = DockerSandbox(image="python:3.12-slim")
# After: Daytona
from pydantic_ai_backends import DaytonaSandbox
sandbox = DaytonaSandbox(api_key="dtna_...")

Instala con el extra de Daytona:

Terminal window
pip install pydantic-ai-backend[daytona]

Por Qué Importan los Menos de 90ms

El número en bruto es impresionante, pero el impacto real está en los flujos de trabajo del agente:

Las llamadas secuenciales a herramientas se acumulan. Un agente resolviendo una tarea de programación podría: leer 5 archivos, planificar, escribir 3 archivos, ejecutar tests, corregir 2 archivos, ejecutar tests de nuevo. Son ~15 llamadas a herramientas. Con la sobrecarga de 2 segundos de Docker por operación de sandbox: 30 segundos de espera. Con Daytona: ~1.3 segundos de sobrecarga total.

Los agentes interactivos necesitan capacidad de respuesta. Cuando un usuario observa al agente trabajar en una terminal, cada segundo de latencia se siente como retraso. Menos de 100ms hace que la ejecución se sienta instantánea.

Los pipelines CI/CD son los más beneficiados. En CI, normalmente no puedes ejecutar Docker-in-Docker fácilmente. Daytona solo necesita una API key — sin daemon, sin contenedores privilegiados, sin montar sockets.

El Patrón Composite: Lo Mejor de Ambos

Para configuraciones complejas, CompositeBackend enruta diferentes operaciones a diferentes backends:

from pydantic_ai_backends import CompositeBackend, LocalBackend, DaytonaSandbox
backend = CompositeBackend(
backends={
"local": LocalBackend("/workspace"),
"sandbox": DaytonaSandbox(api_key="dtna_..."),
},
routing={"src/": "local", "tmp/": "sandbox"},
)

Lee archivos fuente localmente (rápido, sin sobrecarga), ejecuta código no confiable en Daytona (aislado, efímero). El agente no lo sabe — el composite enruta cada llamada.

Conclusiones Clave

  • La abstracción de backends vale la penaBaseSandbox nos permitió añadir Daytona sin tocar una sola línea de código del agente o lógica del toolset
  • Los menos de 90ms son reales — las VMs pre-aprovisionadas de Daytona eliminan por completo el arranque en frío de Docker
  • Docker no está muerto — sigue siendo la elección correcta para desarrollo local y configuraciones auto-hospedadas
  • La UX del agente es acumulativa — 15 llamadas a herramientas x 2 segundos de sobrecarga = 30 segundos de dolor. Las pequeñas mejoras de latencia se acumulan

Pruébalo: pydantic-ai-backend en GitHubpip install pydantic-ai-backend[daytona]

Compartir artículo

Artículos relacionados

¿Listo para desplegar tu app de IA?

Elige tus frameworks, genera un proyecto listo para producción y despliega. 75+ opciones, un comando, cero deuda de configuración.

¿Necesitas ayuda construyendo agentes de IA?