Blog

Crash zbog nedostatka memorije skriven u oznaci napretka

Jedne večeri krajem septembra, AI agent u radnom prostoru jednog korisnika srušio se zbog greške nedostatka memorije usred zadatka. Očigledni osumnjičeni — previše podagenata koji rade u isto vreme ili kontekst koji je previše narastao — bili su pogrešni. Pravi uzrok bila je oznaka statusa: dok je model strimovao veliku shell komandu po nekoliko karaktera, mi smo na svaki deo ponovo slali celu komandu do tog trenutka kao oznaku napretka. Jedna komanda od 124 KB pretvorila se u oko 41.000 događaja i otprilike 690 MB stringova u redu čekanja.

Kako agent strimuje rad

Kada gradite na Mythexu, agent radi unutar privatnog cloud sandbox-a vašeg projekta. Dok model piše, njegov izlaz se strimuje nazad u vaš pregledač: tekst se pojavljuje reč po reč, a kada pokrene alat — recimo shell komandu koja piše fajl — vidite oznaku za to koja se uživo ažurira, pa znate šta radi.

Model strimuje u malim delovima. Sa modelom koji smo koristili, ti delovi su često bili dugi samo tri karaktera.

Prve hipoteze bile su pogrešne

Pad je izgledao kao problem skaliranja, pa smo tu počeli.

  • Paralelni podagenti? Zadatak je koristio samo dvojicu, svaki sa oko 1,5 MB stanja. Nedovoljno.
  • Zadržani tragovi? Naše praćenje držalo je stablo pokretanja u memoriji, ali ono nije bilo ni blizu veličine heap-a u trenutku pada.

Obe priče bile su verovatne, i obe su bilo lako poverovati. Nijedna nije reprodukovala pad. Lekcija koju stalno ponovo učimo: hipoteza nije uzrok dok ne reprodukuje grešku.

Reprodukovanje zaista

Napravili smo privremeni sandbox sa istim ograničenjima memorije kao produkcija i lažni model koji je strimovao veliki fajl u realističnim delovima od tri karaktera. Takođe smo usporili čitača na drugom kraju soketa, kao pravu mrežu.

To je uspelo. Heap je rastao i proces je pao sa istom greškom.

Mehanizam je bio jednostavan kada smo ga mogli posmatrati. Dok je model pisao veliku komandu — u ovom slučaju heredoc koji je upisao fajl od 124 KB — naš kod za strimovanje ažurirao je oznaku alata na svakom delu. Oznaka nije bila nova tri karaktera; bila je cela komanda do tog trenutka. Zato su se događaji gomilali: 3 karaktera, zatim 6, zatim 9, … do 124 KB, oko 41.000 puta. Soket nije mogao da šalje brzo koliko su nastajali, pa su se gomilali u njegovom baferu za upis kao stringovi — oko 690 MB.

Ispravka

  • Ograničiti oznaku. Oznaka statusa treba samo da kaže šta se dešava. Sada je ograničena na 200 karaktera, a ponovno skeniranje delimične komande je usporeno.
  • Zaustaviti kvadratno nadovezivanje. Spajanje strimovanih delova ponovljenim nadovezivanjem stringova je O(n²) za velike izlaze. Prešli smo na pristup zasnovan na delovima koji dodaje u linearnom vremenu.

Zatim smo potražili bilo šta drugo što može da raste bez ograničenja pri poplavi izlaza, i ograničili smo to:

  • Uživo prikazan izlaz komandi u čatu se grupiše i čuva poslednjih 8.000 karaktera.
  • Pojedinačne linije događaja ograničene su na 4 MB.
  • Bafer za ponovno puštanje koji pregledač koristi da se sustigne posle ponovnog povezivanja ograničen je na 8 MB po projektu.
  • Stari checkpoint-i se proreduju dok turn napreduje, zadržavajući najnovije stanje i sidra koja su ranijim turn-ovima potrebna.

Iskreno testiranje poplava

Dve stvari su ovo učinile težim za testiranje nego što je trebalo:

  1. Pravi modeli ne sarađuju. Zamolite model da ispiše ogroman fajl i obično će odbiti, sažeti ga ili napisati nešto pametnije. Da biste testirali poplave, potreban vam je skriptovani model koji radi tačno ono što mu kažete, kroz pravi kod agenta.
  2. Skripte moraju da se ponašaju kao modeli. Naš prvi skriptovani model koristio je isti ID odgovora pri svakom odgovoru, pa je radni framework agenta tretirao svaki odgovor kao zamenu za prethodni i prekidao turn-ove prerano. Izgledalo je kao bag osvežavanja interfejsa. Nije bio — test okruženje nas je lagalo. Takođe smo morali da u skripti primenimo stvarni limit konteksta modela, inače brojke memorije nisu bile realne.

Šta smo iz ovoga izvukli

  • Strimovani UI-jevi množe male greške. Sve što šaljete „po delu” pošalje se desetine hiljada puta. Šaljite delte ili ograničite korisni teret.
  • Ograničite svaki bafer koji prelazi spor spoj. Soketi, logovi za ponovno puštanje i checkpoint-i svi trebaju plafon.
  • Reprodukujte pre popravke. Naša prva dva objašnjenja zvučala su tačno, a bila su pogrešna.

Ako ste nedavno videli veoma dug fajl kako se pojavljuje u Mythex čatu bez da agent zastane, ovo je deo razloga.

Mythex · Pricing · Pravite bilo šta uz AI · Šabloni za sajtove i aplikacije · Mythex u poređenju · Rečnik pojmova za pravljenje aplikacija uz AI · Besplatni alati za pravljenje aplikacija uz AI · English

English አማርኛ العربية Български বাংলা Bosanski Català Čeština Dansk Deutsch Ελληνικά Español Español (España) Eesti فارسی Suomi Français Français (Canada) ગુજરાતી हिन्दी Hrvatski Magyar Հայերեն Bahasa Indonesia Íslenska Italiano 日本語 ქართული Қазақ тілі ಕನ್ನಡ 한국어 Lietuvių Latviešu Македонски മലയാളം Монгол मराठी Bahasa Melayu မြန်မာ Norsk bokmål Nederlands ਪੰਜਾਬੀ Polski Português (Brasil) Português (Portugal) Română Русский Slovenčina Slovenščina Soomaali Shqip Svenska Kiswahili தமிழ் తెలుగు ไทย Tagalog Türkçe Українська اردو Tiếng Việt 简体中文 繁體中文(香港) 繁體中文(台灣)