CodeWorlds
Powrót do kolekcji
Przewodnik16 min czytaniaZespół CodeWorlds

E2B, piaskownice dla kodu generowanego przez model

E2B uruchamia kod od modelu w izolowanej mikromaszynie w chmurze. Jak działa, ile kosztuje sekunda pracy piaskownicy i kiedy nie warto po nią sięgać.

E2B, piaskownice dla kodu generowanego przez model

E2B uruchamia obcy kod w izolowanej maszynie wirtualnej w chmurze, którą tworzysz jednym wywołaniem i za którą płacisz sekundami jej działania. Repozytorium e2b-dev/E2B ma około trzynastu i pół tysiąca gwiazdek, kod infrastruktury jest publiczny, a bieżąca wersja pakietów SDK to 2.44.0 dla JavaScriptu i dla Pythona.

Po co osobna piaskownica, skoro kod można uruchomić u siebie

To pytanie trzeba postawić na początku, bo od odpowiedzi zależy, czy reszta tekstu jest Ci do czegokolwiek potrzebna.

Kiedy model zwraca fragment kodu, masz trzy drogi. Pierwsza to uruchomienie go w swoim procesie, przez eval albo exec. To jest droga najprostsza i najgorsza: kod dostaje dostęp do zmiennych środowiskowych procesu, czyli do Twoich kluczy API, do systemu plików serwera i do sieci wewnętrznej, w której ten serwer stoi. Żadna ilość filtrowania wygenerowanego tekstu tego nie naprawi, bo filtrujesz coś, czego przestrzeń możliwych postaci jest nieskończona.

Druga droga to kontener na własnej maszynie. Izolacja jest już realna, ale kontenery dzielą jądro z hostem, więc powierzchnia ataku obejmuje cały interfejs wywołań systemowych. Dochodzi do tego praca operacyjna, o której łatwo zapomnieć przy pierwszym prototypie: limity procesora i pamięci, sprzątanie po kontenerach, które się zawiesiły, reguły sieciowe, obraz z zainstalowanymi bibliotekami i kolejka, kiedy dziesięciu użytkowników poprosi o wykonanie kodu w tej samej sekundzie.

Trzecia droga to usługa, która to wszystko ma zrobione, i tym właśnie jest E2B. Dostajesz maszynę wirtualną z własnym jądrem, tworzoną na żądanie i niszczoną po ustalonym czasie, plus bibliotekę, która pozwala w niej uruchamiać polecenia, zapisywać pliki i wystawiać porty na zewnątrz. Ma to sens wtedy, gdy kod naprawdę pochodzi od modelu albo od użytkownika, a nie od Ciebie, i gdy nie chcesz utrzymywać własnej floty maszyn.

Równie ważne jest, kiedy po E2B sięgać nie warto. Jeśli kod, który uruchamiasz, napisałeś sam i jest deterministyczny, izolacja nie kupuje Ci nic poza rachunkiem i dodatkowym przeskokiem sieciowym. Jeśli dane, na których operuje kod, nie mogą opuścić Twojej infrastruktury, zostaje samodzielne wdrożenie albo inne rozwiązanie. Jeśli budżet opóźnienia w Twojej pętli agenta jest liczony w dziesiątkach milisekund, każde wywołanie do zewnętrznej usługi będzie widoczne. I jeśli zadanie da się wyrazić jako czysta funkcja bez uruchamiania kodu, to zwykle lepiej ją wywołać niż generować skrypt.

Narzędzie jest niezależne od modelu, więc pracuje tak samo z OpenAI, Claude i modelami uruchamianymi lokalnie. Do frameworków agentowych, takich jak LangChain, CrewAI, Pydantic AI czy OpenAI Agents SDK, wpina się jako zwykłe narzędzie, którego ciałem jest wywołanie SDK.

Co siedzi pod spodem

Każda piaskownica to mikromaszyna wirtualna oparta o Firecracker, czyli ten sam monitor maszyn wirtualnych, którego Amazon używa pod funkcjami bezserwerowymi. Różnica wobec kontenera jest zasadnicza: maszyna ma własne jądro, a granica izolacji leży na poziomie wirtualizacji, nie na poziomie przestrzeni nazw jądra hosta.

Wewnątrz maszyny działa agent sterujący, z którym SDK rozmawia po sieci. To on wykonuje polecenia, obsługuje operacje na plikach i strumieniuje wyjście. Dlatego każda metoda z biblioteki jest asynchroniczna i ma własny limit czasu żądania, domyślnie sześćdziesiąt sekund.

Czas startu jest głównym argumentem sprzedażowym tej usługi i tu należy się ostrzeżenie. Strona główna E2B podaje w jednym miejscu, że piaskownica w tym samym regionie co klient startuje w czasie poniżej 200 milisekund, a kilka sekcji niżej, że startuje w 80 milisekundach. Obie liczby stoją na tej samej stronie, więc traktuj je jako rząd wielkości, a nie jako gwarancję. Sam rząd wielkości jest jednak wiarygodny i to on odróżnia mikromaszynę od obrazu kontenera pobieranego z rejestru przy każdym uruchomieniu.

Piaskownica dostaje identyfikator oraz własną domenę. Jeśli uruchomisz w niej serwer HTTP, metoda getHost zwróci adres, pod którym port jest widoczny z zewnątrz, co jest wygodne przy podglądzie aplikacji wygenerowanej przez model.

Pierwsze uruchomienie

Instalacja sprowadza się do jednego pakietu i jednej zmiennej środowiskowej.

Code
Bash
# podstawowe SDK, sterowanie piaskownicą
npm install e2b            # JavaScript, Node 20.18.1 lub nowszy z linii 20, albo 22 i wyżej
pip install e2b            # Python 3.10 lub nowszy

# nakładka do wykonywania kodu z zachowaniem stanu
npm install @e2b/code-interpreter
pip install e2b-code-interpreter

# narzędzie wiersza poleceń, oddzielny pakiet
npm install -g @e2b/cli

export E2B_API_KEY=e2b_twoj_klucz

Nazwa zmiennej E2B_API_KEY jest wartością domyślną dla opcji apiKey, więc w typowym projekcie nie przekazujesz klucza w kodzie w ogóle. Biblioteka sprawdza po swojej stronie, czy klucz zaczyna się od e2b_, i można to wyłączyć opcją validateApiKey, co ma znaczenie wyłącznie przy samodzielnym wdrożeniu wydającym klucze w innym formacie.

Najkrótszy sensowny przykład wygląda tak.

Code
TypeScript
import { Sandbox } from 'e2b'

const sandbox = await Sandbox.create({
  template: 'base',
  timeoutMs: 120_000,
  metadata: { uzytkownik: 'u-8891', zadanie: 'analiza-csv' },
  envs: { TZ: 'Europe/Warsaw' },
  allowInternetAccess: false
})

try {
  await sandbox.files.write('/home/user/dane.csv', 'a,b\n1,2\n3,4\n')

  const wynik = await sandbox.commands.run('python -c "import csv; print(sum(1 for _ in open(\'/home/user/dane.csv\')))"', {
    cwd: '/home/user',
    timeoutMs: 30_000,
    onStdout: (linia) => console.log('OUT', linia)
  })

  console.log(wynik.exitCode, wynik.stdout, wynik.stderr)
} finally {
  await sandbox.kill()
}

Cztery rzeczy z tego przykładu wracają potem w każdym projekcie. timeoutMs to czas życia całej piaskownicy, domyślnie 300 000 milisekund, czyli pięć minut. metadata to dowolne pary tekstowe, po których można później filtrować listę piaskownic, i to jest jedyny sensowny sposób na powiązanie maszyny z użytkownikiem w Twoim systemie. allowInternetAccess ustawione na false odcina ruch wychodzący i działa tak samo jak wpisanie 0.0.0.0/0 do network.denyOut. Blok finally z wywołaniem kill jest tym, co odróżnia rachunek przewidywalny od zaskakującego.

Wykonywanie kodu z zachowanym stanem

Metoda commands.run uruchamia proces i po jego zakończeniu nie zostaje nic poza plikami. Jeśli agent ma prowadzić analizę w kilku krokach, gdzie drugi krok korzysta ze zmiennych wczytanych w pierwszym, potrzebujesz czegoś innego. Do tego służy osobny pakiet z nakładką na jądro Jupytera.

Code
Python
import base64
from e2b_code_interpreter import Sandbox

with Sandbox.create(timeout=300) as sandbox:
    sandbox.run_code("import pandas as pd")
    sandbox.run_code("df = pd.DataFrame({'x': [1, 2, 3], 'y': [2, 4, 8]})")

    wykonanie = sandbox.run_code(
        "df['z'] = df.x * df.y\ndf.z.sum()",
        on_stdout=lambda wiadomosc: print("OUT", wiadomosc.line),
        timeout=60,
    )

    if wykonanie.error:
        print(wykonanie.error.name, wykonanie.error.value)
        print(wykonanie.error.traceback)
    else:
        print(wykonanie.text)            # tekstowa postać ostatniego wyrażenia
        print(wykonanie.logs.stdout)     # lista linii wypisanych na standardowe wyjście

    for wynik in wykonanie.results:
        if wynik.png:
            # pole png to obraz zakodowany w base64, nie surowe bajty
            with open("wykres.png", "wb") as plik:
                plik.write(base64.b64decode(wynik.png))

Obiekt Execution ma cztery pola, które trzeba znać. results to lista wyników, gdzie każdy element może mieć równolegle postać tekstową, HTML, Markdown, SVG oraz PNG, bo dokładnie tak zachowuje się jądro Jupytera przy rysowaniu wykresów. logs rozdziela standardowe wyjście od strumienia błędów, oba jako listy linii. error jest ustawiony tylko wtedy, gdy kod rzucił wyjątek, i zawiera nazwę, treść oraz surowy ślad stosu. Czwarte pole to numer komórki, w Pythonie execution_count, w JavaScripcie executionCount.

Domyślnym językiem jest Python, ale run_code przyjmuje parametr language. Kontekstami zarządza się jawnie przez create_code_context, list_code_contexts, remove_code_context i restart_code_context, co pozwala trzymać osobne przestrzenie nazw dla różnych wątków rozmowy w jednej maszynie.

Ważna różnica dla rachunku: kod rzucający wyjątek nie kończy piaskownicy. Wyjątek wraca jako pole error, maszyna dalej działa i dalej jest liczona, a agent może na tej podstawie poprawić kod i spróbować ponownie. To jest przewaga tego podejścia nad uruchamianiem procesu, ale trzeba o niej pamiętać przy planowaniu kosztu.

Rozliczenie, czyli za co dokładnie płacisz

Model rozliczenia jest tutaj prostszy niż u większości dostawców i to jest jego zaleta, bo daje się policzyć przed wdrożeniem.

Płacisz za sekundę działania piaskownicy, według wzoru podanego w dokumentacji: koszt to suma liczby rdzeni pomnożonej przez stawkę za rdzeń oraz pamięci w gibibajtach pomnożonej przez stawkę za pamięć, całość razy liczba sekund. Stawki wynoszą 0,000014 dolara za sekundę za jeden wirtualny rdzeń oraz 0,0000045 dolara za sekundę za gibibajt pamięci. Domyślna konfiguracja to dwa rdzenie i 512 mebibajtów pamięci, co daje około 0,109 dolara za godzinę pracy i około 0,009 dolara za pięciominutowe uruchomienie.

Do tego dochodzi warstwa planów, która nie zawiera puli zużycia, tylko limity techniczne.

PlanKoszt stałyDługość sesjiPiaskownice równolegleDysk w cenie
Hobby0 dolarów, jednorazowo 100 dolarów w kredytachdo 1 godzinydo 2010 GiB
Pro150 dolarów miesięczniedo 24 godzindo 100, z dokupieniem do 110020 GiB
Ultimatewycena indywidualnaustalana indywidualnieustalana indywidualnieustalana indywidualnie

Konsekwencja tej konstrukcji jest taka, że sto pięćdziesiąt dolarów miesięcznie na planie Pro kupuje limity, a nie zużycie. Zużycie dolicza się osobno. Przy stu równoległych maszynach w domyślnej konfiguracji działających bez przerwy rachunek za samo zużycie idzie w tysiące dolarów miesięcznie, więc kalkulację trzeba zrobić na własnych liczbach, a nie na przykładzie z jedną maszyną.

Naliczanie zatrzymuje się w chwili, w której piaskownica zostaje wstrzymana, zabita albo przekroczy swój limit czasu. Nie ma opłaty za samo istnienie wstrzymanej maszyny ani za jej zrzut. Ta jedna właściwość jest powodem, dla którego opisany niżej mechanizm pauzy jest ważniejszy, niż na pierwszy rzut oka wygląda.

Pauza, wznowienie i cykl życia piaskownicy

Piaskownica ma limit czasu ustawiany przy tworzeniu i można go przedłużać w trakcie przez setTimeout. Po jego przekroczeniu dzieje się to, co ustawisz w polu lifecycle, a domyślnie maszyna zostaje zabita.

Code
TypeScript
import { Sandbox } from 'e2b'

const sandbox = await Sandbox.create({
  timeoutMs: 600_000,
  lifecycle: { onTimeout: 'pause', autoResume: true }
})

const id = sandbox.sandboxId

// zapis stanu na żądanie, razem z pamięcią procesów
await sandbox.pause()

// powrót do tej samej maszyny, z tymi samymi zmiennymi i otwartymi plikami
const wznowiona = await Sandbox.connect(id, { timeoutMs: 600_000 })

const info = await wznowiona.getInfo()
console.log(info.state)

// pełna kopia maszyny, na przykład pod dwa równoległe warianty rozwiązania
const [wariantA, wariantB] = await Sandbox.fork(id, { count: 2 })

await wznowiona.kill()

Wstrzymana piaskownica trzyma zarówno system plików, jak i stan pamięci, więc po wznowieniu wracają zmienne, wczytane biblioteki i uruchomione procesy. Dokumentacja podaje, że wstrzymanie zajmuje mniej więcej cztery sekundy na gigabajt pamięci, a wznowienie około sekundy. Opcja keepMemory ustawiona na false daje zrzut tylko systemu plików, tańszy w czasie, ale maszyna po wznowieniu startuje od zera, tracąc procesy i otwarte połączenia.

Dwie rzeczy z tego mechanizmu mają bezpośredni wpływ na koszt i na projekt systemu. Po pierwsze, wstrzymane piaskownice nie liczą się do limitu równoległych maszyn, więc można ich trzymać dużo, nie blokując sobie możliwości uruchamiania nowych. Po drugie, wstrzymana piaskownica jest trzymana bezterminowo i nie znika sama. Jeśli nie wywołasz kill, zostanie tam na zawsze, a listę takich sierot zobaczysz dopiero, gdy wywołasz Sandbox.list z filtrem stanu.

Własne szablony i praca z wiersza poleceń

Domyślny szablon base zawiera podstawowe środowisko, ale instalowanie zależności przy każdym starcie piaskownicy jest marnowaniem tych samych sekund, za które płacisz. Rozwiązaniem jest własny szablon budowany raz.

Code
TypeScript
import { Template, waitForPort, defaultBuildLogger } from 'e2b'

const szablon = Template()
  .fromPythonImage('3.12')
  .aptInstall(['git', 'curl'])
  .pipInstall(['pandas', 'matplotlib', 'scikit-learn'])
  .setWorkdir('/home/user')
  .setEnvs({ MPLBACKEND: 'Agg' })
  .setStartCmd('python -m http.server 8000', waitForPort(8000))

await Template.build(szablon, 'analiza-danych:v1', {
  onBuildLogs: defaultBuildLogger({ minLevel: 'info' })
})

Metoda setStartCmd przyjmuje polecenie startowe oraz sprawdzenie gotowości, a pomocnicze funkcje waitForPort, waitForURL, waitForFile i waitForProcess generują typowe warianty tego sprawdzenia. Bez poprawnego sprawdzenia gotowości pierwsze żądanie do piaskownicy trafi w usługę, która jeszcze nie wstała.

Wiersz poleceń przydaje się głównie do sprzątania i diagnostyki.

Code
Bash
e2b auth login

# szablony
e2b template init            # nowy szablon w formacie SDK
e2b template create moj-obraz
e2b template list
e2b template migrate         # przejście z e2b.Dockerfile i e2b.toml na Template SDK

# piaskownice
e2b sandbox list             # domyślnie tylko działające
e2b sandbox info <id>
e2b sandbox metrics <id>
e2b sandbox exec <id> -- python --version
e2b sandbox pause <id>
e2b sandbox kill <id>

Polecenie template migrate jest wskazówką, że sposób budowania szablonów się zmienił. Starsze materiały opisują plik e2b.Dockerfile razem z e2b.toml, a bieżące podejście to budowanie z kodu przez opisany wyżej mechanizm. Stary format nadal działa, ale przykłady z sieci sprzed tej zmiany będą wyglądały inaczej niż to, co zobaczysz w dokumentacji.

Licencja i to, co faktycznie jest otwarte

Projekt jest opisywany jako otwarty i to jest prawda, ale odpowiedź na pytanie o licencję zależy od tego, gdzie zajrzysz, więc przy audycie zależności trzeba to rozstrzygnąć raz.

Plik LICENSE w katalogu głównym repozytorium e2b-dev/E2B zawiera tekst Apache License 2.0 i taką licencję pokazuje też interfejs GitHuba oraz jego API. Natomiast pole license pakietu e2b w rejestrze npm mówi MIT, to samo mówi pakiet w PyPI, a plik LICENSE w środku opublikowanej paczki, po jej pobraniu i rozpakowaniu, zawiera pełny tekst licencji MIT z notą copyright FOUNDRYLABS, Inc. Ta sama sytuacja dotyczy pakietów @e2b/code-interpreter i @e2b/cli. Źródłem tej rozbieżności jest podkatalog packages/js-sdk w repozytorium, który ma własny plik licencji na MIT, nadpisujący licencję głównego katalogu dla tego, co trafia do rejestru.

Praktycznie oznacza to, że repozytorium jako całość jest na Apache 2.0, a paczki, które faktycznie instalujesz, na MIT. Obie licencje są permisywne i żadna nie ogranicza użycia komercyjnego, więc różnica boli wyłącznie tam, gdzie ktoś zestawia listę licencji zależności i oczekuje jednej odpowiedzi na pytanie o E2B.

Otwarta jest też infrastruktura, w osobnym repozytorium e2b-dev/infra, również na Apache 2.0, z około tysiącem trzystoma gwiazdkami. Wdrożenie idzie przez Terraform. Warto znać zakres wsparcia, zanim potraktujesz samodzielne wdrożenie jako plan awaryjny: obsługiwane jest Google Cloud, wsparcie dla Amazon Web Services jest oznaczone jako wersja zapowiadana, a Azure i zwykła maszyna z Linuksem figurują na liście jako niezrealizowane. Postawienie własnej floty mikromaszyn to zadanie dla zespołu utrzymującego infrastrukturę, nie projekt na weekend, więc realnie ta możliwość zabezpiecza przed zamknięciem usługi, a nie stanowi codziennej alternatywy.

E2B a alternatywy

Rynek piaskownic dla agentów zrobił się gęsty w ciągu ostatnich dwóch lat i wybór rzadko rozstrzyga się na czasie startu.

RozwiązanieIzolacjaKod infrastrukturyPakiet SDKLicencja pakietu
E2Bmikromaszyna Firecrackerotwarty, e2b-dev/infrae2b 2.44.0MIT
Vercel Sandboxmikromaszyna Firecrackerzamknięty@vercel/sandbox 3.0.1Apache 2.0
Modalkontener po stronie dostawcyzamkniętymodal 1.5.4Apache 2.0
Cloudflare Sandboxkontener sterowany z Workerszamknięty@cloudflare/sandbox 0.12.7Apache 2.0
Daytonainfrastruktura dostawcyotwarty, daytonaio/daytona@daytonaio/sdk 0.205.1Apache 2.0
Docker na własnej maszyniekontener, jądro wspólne z hostemTwójbrak, warstwa własnazależnie od narzędzi

Wybór rozstrzyga się zwykle na trzech pytaniach. Czy jesteś już w ekosystemie jednego dostawcy, bo wtedy piaskownica wpięta w rozliczenie, które i tak masz, oszczędza Ci osobnej umowy. Czy potrzebujesz izolacji na poziomie maszyny wirtualnej, bo jeśli kod pochodzi od nieznanych użytkowników, kontener dzielący jądro z hostem jest słabszą granicą. Czy zależy Ci na możliwości uruchomienia całości u siebie, bo tu E2B i Daytona mają publiczny kod infrastruktury, a pozostali nie.

Osobno stoi porównanie z uruchamianiem kontenerów u siebie. Ta droga jest tańsza w rachunku od dostawcy i droższa we wszystkim innym, więc opłaca się wtedy, gdy obciążenie jest duże, przewidywalne i stałe. Przy ruchu skokowym, typowym dla agentów, płacenie za sekundy jest zwykle tańsze niż utrzymywanie maszyn, które przez większość doby stoją bezczynnie.

Typowe błędy

Pierwszy dotyczy jednostek czasu i wraca w każdym projekcie łączącym oba języki. SDK dla JavaScriptu przyjmuje timeoutMs w milisekundach, a SDK dla Pythona przyjmuje timeout w sekundach. Przepisanie wartości 300_000 z jednego przykładu do drugiego daje piaskownicę żyjącą ponad trzy miesiące zamiast pięciu minut, z rachunkiem odpowiadającym tej różnicy.

Drugi to brak wywołania kill. Piaskownica nie kończy się razem z Twoim procesem ani z żądaniem HTTP, tylko żyje do swojego limitu czasu i przez cały ten czas jest naliczana. Wywołanie kill w bloku finally albo konstrukcja with w Pythonie kosztują jedną linię i zamykają całą klasę problemów.

Trzeci to traktowanie piaskownicy jak trwałego dysku. Domyślnie po przekroczeniu limitu czasu maszyna jest zabijana razem z zawartością. Jeśli chcesz zachować stan, ustaw lifecycle.onTimeout na pause albo wywołaj pause samodzielnie, a wyniki, które mają przetrwać, pobierz przez files.read lub downloadUrl.

Czwarty to mieszanie dwóch sposobów uruchamiania kodu. commands.run startuje proces, który po zakończeniu nie zostawia stanu w pamięci, a runCode wykonuje kod w kontekście jądra Jupytera, gdzie zmienne z poprzednich wywołań są dostępne. Zdziwienie, że zmienna zdefiniowana w jednym kroku zniknęła w następnym, prawie zawsze oznacza, że użyto pierwszej metody zamiast drugiej.

Piąty dotyczy sekretów. Wartości przekazane w envs trafiają do środowiska, w którym uruchamia się wygenerowany kod, więc kod może je odczytać. Jeśli piaskownica ma odpytać zewnętrzne API w Twoim imieniu, właściwym mechanizmem są reguły w network.rules, które dokładają nagłówek autoryzacyjny po stronie serwera proxy ruchu wychodzącego, w połączeniu z network.allowOut ograniczającym listę adresów.

Szósty to przenoszenie limitów z planu płatnego na darmowy. Maksymalny czas życia piaskownicy wynosi dwadzieścia cztery godziny na planie Pro, ale tylko godzinę na planie Hobby. Kod ustawiający timeoutMs na wartość ponad godzinę zadziała na koncie deweloperskim inaczej niż na koncie testowym i będzie to wyglądało jak błąd losowy.

FAQ

Czy wstrzymana piaskownica kosztuje i czy zajmuje limit?

Nie i nie. Naliczanie zatrzymuje się w chwili wstrzymania, zabicia albo przekroczenia limitu czasu, a do limitu równoległych piaskownic liczą się wyłącznie te działające. Wstrzymane maszyny są przechowywane bezterminowo i trzeba je usunąć samodzielnie przez kill.

Ile realnie kosztuje godzina pracy piaskownicy?

Dla domyślnej konfiguracji z dwoma rdzeniami i 512 mebibajtami pamięci wychodzi około 0,109 dolara za godzinę, licząc ze wzoru podanego w dokumentacji. Zmiana konfiguracji na cztery rdzenie i cztery gibibajty pamięci podnosi tę kwotę mniej więcej trzykrotnie, więc dobranie rozmiaru maszyny do zadania jest tu najprostszą dźwignią oszczędności.

Czy mogę uruchomić E2B na własnej infrastrukturze?

Możesz, kod infrastruktury jest publiczny na licencji Apache 2.0, a wdrożenie idzie przez Terraform. Obsługiwane jest Google Cloud, wsparcie dla Amazon Web Services jest oznaczone jako wersja zapowiadana, a Azure nie jest wspierany. Skala pracy operacyjnej odpowiada utrzymywaniu floty maszyn wirtualnych, więc dla większości zespołów jest to zabezpieczenie na wypadek zniknięcia usługi, a nie codzienny tryb pracy.

Czym różni się pakiet e2b od @e2b/code-interpreter?

Pakiet e2b steruje piaskownicą: tworzy ją, uruchamia polecenia, obsługuje pliki i sieć. Pakiet @e2b/code-interpreter jest nakładką, która dokłada metodę runCode wykonującą kod w kontekście jądra Jupytera, z zachowaniem zmiennych między wywołaniami i ze zwracaniem wykresów jako obrazów. Ten drugi zależy od pierwszego, więc instalujesz go zamiast, a nie obok.

Co się dzieje, gdy piaskownica przekroczy limit czasu?

Domyślnie zostaje zabita razem z zawartością. Można to zmienić polem lifecycle przy tworzeniu: onTimeout ustawione na pause powoduje zapisanie stanu zamiast zniszczenia maszyny, a dodatkowa flaga autoResume pozwala wznowić ją automatycznie przy kolejnym odwołaniu. Flaga autoResume działa tylko razem z pauzą zachowującą pamięć.

Czy E2B jest związane z konkretnym dostawcą modeli?

Nie jest. Piaskownica dostaje tekst kodu i go uruchamia, więc źródło tego kodu nie ma znaczenia. Integracje z frameworkami agentowymi sprowadzają się do zadeklarowania narzędzia, którego implementacja wywołuje SDK, i wyglądają tak samo niezależnie od tego, który model generuje kod.

Dokumentację znajdziesz na stronie dokumentacji, stawki na stronie cennika, a kod źródłowy w repozytorium SDK oraz w repozytorium infrastruktury.

Czytaj dalej

Używamy cookies, żeby zwiększyć Twoje doświadczenia na stronie