Wykonywanie kodu w chmurze poniżej 90ms: Jak Daytona zastąpiła Docker w naszym stacku AI agentów
Spis treści
Każdy AI agent, który pisze kod, potrzebuje miejsca do jego uruchomienia. Agent generuje skrypt Pythona, komendę shell, pipeline przetwarzania danych — i coś musi ten kod bezpiecznie wykonać, w izolacji od środowiska produkcyjnego.
Przez ostatni rok używaliśmy Dockera. Uruchom kontener, wykonaj kod, zamknij go. Działa. Ale “działa” ma swoją cenę: 2-5 sekund opóźnienia cold startu na każdy sandbox. Kiedy Twój agent wykonuje 10-20 wywołań narzędzi na zadanie, to 30-100 sekund samego czekania na start kontenerów.
Wtedy wypróbowaliśmy Daytonę. Start poniżej 90ms. Bez Docker daemon. Efemeryczne sandboxy w chmurze, które uruchamiają się szybciej niż agent zdąży wymyślić następny krok.
Problem: Cold starty Dockera rujnują UX agenta
Nasze AI agenty używają pydantic-ai-backend — biblioteki Pythona, która dostarcza backendy do przechowywania plików i wykonywania kodu dla agentów Pydantic AI. Przed Daytoną mieliśmy trzy backendy:
| Backend | Storage | Execution | Zastosowanie |
|---|---|---|---|
StateBackend | In-memory | Nie | Testy, sesje efemeryczne |
LocalBackend | System plików | Tak | Rozwój lokalny |
DockerSandbox | Kontener | Tak | Wielu użytkowników, niezaufany kod |
Docker był naszym wyborem na produkcję. Izolowane wykonywanie, kontrolowane środowisko, brak ryzyka, że agenty zniszczą hosta. Ale narzut startowy był realny:
- Pobranie obrazu (jeśli nie jest w cache) — sekundy
- Utworzenie kontenera — setki ms
- Uruchomienie kontenera — setki ms
- Oczekiwanie na health check — zmienne
- Wykonanie właściwej komendy — jedyna część, która się liczy
Wchodzi Daytona: Efemeryczne sandboxy w chmurze
Daytona dostarcza efemeryczne sandboxy w chmurze — izolowane maszyny wirtualne, które wstępnie alokują zasoby i eliminują narzut cold startu. Poniżej 90ms od utworzenia do wykonania pierwszej komendy.
Dodaliśmy DaytonaSandbox jako czwarty backend w pydantic-ai-backend v0.1.12:
from pydantic_ai_backends import DaytonaSandbox, create_console_toolsetfrom pydantic_ai import Agentfrom dataclasses import dataclass
@dataclassclass 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()Ten sam agent, ten sam toolset, to samo API — inny backend. Agent nie wie (i nie musi wiedzieć), czy działa w Dockerze, czy w Daytonie.
Architektura: Abstrakcja BaseSandbox
Aby obsłużyć Daytonę obok Dockera w czysty sposób, wyodrębniliśmy abstrakcyjną klasę bazową 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 ...Zarówno DockerSandbox, jak i DaytonaSandbox dziedziczą po BaseSandbox. Toolset nie interesuje się, który z nich dostaje.
| Metoda | Docker | Daytona |
|---|---|---|
execute() | docker.exec_run() | sandbox.process.exec() |
_read_bytes() | Shell cat przez Docker exec | Natywne API pobierania plików |
write() | Shell cat > przez Docker exec | Natywne API wysyłania plików |
stop() | Usunięcie kontenera | Usunięcie sandboxa w chmurze |
Natywne API plikowe Daytony są szczególnie interesujące — zamiast przepuszczać dane przez shell (co robi Docker), Daytona wysyła/pobiera pliki bezpośrednio przez swoje SDK.
Docker vs Daytona: Kiedy używać którego
| Cecha | DaytonaSandbox | DockerSandbox |
|---|---|---|
| Czas startu | Poniżej 90ms | 2-5 sekund |
| Infrastruktura | Chmura (platforma Daytona) | Lokalny Docker daemon |
| Wymagana konfiguracja | Tylko klucz API | Docker zainstalowany + uruchomiony |
| Izolacja | VM w chmurze | Kontener |
| Koszt | Cennik Daytony | Darmowy (lokalne zasoby) |
| Najlepszy do | CI/CD, serverless, chmura | Lokalne dev, self-hosted |
Używaj Daytony gdy: wdrożenia w chmurze, opóźnienie startu ma znaczenie, skalowanie horyzontalne, pipeline CI/CD, gdzie Docker-in-Docker jest problematyczny.
Używaj Dockera gdy: uruchamiasz lokalnie, potrzebujesz niestandardowych runtime’ów, chcesz hostować wszystko samodzielnie, zależy Ci na kosztach.
Konfiguracja: 3 linie do zmiany
# Before: Dockerfrom pydantic_ai_backends import DockerSandboxsandbox = DockerSandbox(image="python:3.12-slim")
# After: Daytonafrom pydantic_ai_backends import DaytonaSandboxsandbox = DaytonaSandbox(api_key="dtna_...")Instalacja z dodatkową zależnością Daytona:
pip install pydantic-ai-backend[daytona]Dlaczego poniżej 90ms ma znaczenie
Sama liczba robi wrażenie, ale prawdziwy wpływ widać w workflow agentów:
Sekwencyjne wywołania narzędzi się kumulują. Agent rozwiązujący zadanie programistyczne może: odczytać 5 plików, zaplanować, napisać 3 pliki, uruchomić testy, naprawić 2 pliki, uruchomić testy ponownie. To ~15 wywołań narzędzi. Przy 2-sekundowym narzucie Dockera na operację sandboxa: 30 sekund czekania. Z Daytoną: ~1.3 sekundy łącznego narzutu.
Interaktywne agenty potrzebują responsywności. Kiedy użytkownik obserwuje pracę agenta w terminalu, każda sekunda opóźnienia odczuwana jest jako lag. Poniżej 100ms sprawia, że wykonanie wydaje się natychmiastowe.
Pipeline CI/CD zyskują najbardziej. W CI zazwyczaj nie da się łatwo uruchomić Docker-in-Docker. Daytona potrzebuje tylko klucza API — bez daemona, bez uprzywilejowanych kontenerów, bez montowania socketów.
Wzorzec Composite: Najlepsze z obu światów
Dla złożonych konfiguracji CompositeBackend kieruje różne operacje do różnych backendów:
from pydantic_ai_backends import CompositeBackend, LocalBackend, DaytonaSandbox
backend = CompositeBackend( backends={ "local": LocalBackend("/workspace"), "sandbox": DaytonaSandbox(api_key="dtna_..."), }, routing={"src/": "local", "tmp/": "sandbox"},)Odczytuj pliki źródłowe lokalnie (szybko, bez narzutu), wykonuj niezaufany kod w Daytonie (izolacja, efemeryczność). Agent tego nie wie — composite kieruje każde wywołanie.
Kluczowe wnioski
- Abstrakcja backendów się opłaca —
BaseSandboxpozwolił nam dodać Daytonę bez zmiany ani jednej linii kodu agenta czy logiki toolsetu - Poniżej 90ms to realność — wstępnie alokowane VM Daytony całkowicie eliminują cold start Dockera
- Docker nie umarł — nadal jest właściwym wyborem do lokalnego developmentu i konfiguracji self-hosted
- UX agenta jest kumulatywny — 15 wywołań narzędzi x 2 sekundy narzutu = 30 sekund bólu. Małe usprawnienia opóźnień kumulują się
Wypróbuj: pydantic-ai-backend na GitHubie — pip install pydantic-ai-backend[daytona]
Powiązane artykuły
Od create-react-app do create-ai-app: Nowy standard dla aplikacji AI
W 2016 roku create-react-app ustandaryzował budowanie frontendów. W 2026 roku aplikacje AI potrzebują tego samego moment...
AGENTS.md: Jak przygotować repozytorium dla agentów AI (Copilot, Cursor, Codex, Claude Code)
Każde narzędzie AI do kodowania czyta Twoje repozytorium inaczej. Sprawdź, jak AGENTS.md — wschodzący standard — daje im...
Od zera do produkcyjnego agenta AI w 30 minut — szablon full-stack z 5 frameworkami AI
Krok po kroku: konfigurator webowy, wybierz preset, wybierz framework AI, skonfiguruj 75+ opcji, docker-compose up — dzi...