Blog

Képekkel teli ügynöki körök a memórián belül

Egy éles ügynöki kör 952 MB-nál kifutott a memóriából, miközben hat katalógusszkennelésből vágott ki termékeket, és visszanézte a kivágásokat. Nem egyetlen szivárgás volt, hanem három. A modellhívások mindegyike a kör képeit teljes méretben küldte újra; a modellhívó könyvtár a kör végéig életben tartotta minden kérést; az ügynökkeretrendszer nyomkövetése pedig a kör egész ideje alatt megtartotta minden hívás bemenetét, benne a képekkel. Mindhármat javítottuk: a képeket küldés előtt kicsinyítjük, és minden hívás képeit elengedjük, amint a hívás véget ér.

Hogyan látja az ügynök a képeket

A Mythexen az ügynök a projekted felhős sandboxában dolgozik. Képeket nézhet meg: egy képernyőképet, amit csatolsz, egy makettet, egy fájlt a projektedben, vagy egy képet, amelyet épp maga készített. Ezt úgy teszi, hogy a képeket a beszélgetéssel együtt elküldi a modellnek.

Egy kör mindaz, amit az ügynök egy üzenetedre válaszul csinál. Egy körön belül az ügynök sokszor hív modellt: gondolkodik, lefuttat egy eszközt, megnézi az eredményt, újra gondolkodik. Minden ilyen hívás elküldi az eddigi beszélgetést, benne a kör képeivel, szöveges formában kódolva (base64, ami kb. egyharmadával nagyobbá teszi őket).

Az összeomlott kör ésszerűen viselkedett. Hat katalógusszkennelést vett, egyenként kb. 2,4 MB-osat, ezekből egyes termékeket vágott ki, és újra meg újra visszaolvasta a kivágásokat ellenőrzés céljából. Ez sok modellhívás, mindegyik több nagy képpel.

1. ok: minden hívás teljes méretben küldte újra a képeket

Minden modellhívás újraépítette a kérés törzsét, benne a kör képeivel teljes méretben — hívásonként kb. 20 MB base64. A törzs egy szövegként épül fel az ügynök memóriájában, így minden hívás újabb ~20 MB-ot foglalt.

A teljes méretű küldés semmit nem hozott. A modell maga kb. 1300 pixelre kicsinyíti a képeket a hosszabb oldalon, így a plusz pixelek csak memóriát és feltöltési időt kóstáltak.

A javítás: egyszer kicsinyíts, kicsit küldj

  • A 400 KB-nál nagyobb képeket a küldés előtt legfeljebb 1568 pixeles hosszú oldalú JPEG-gé alakítjuk. A kisebbek változatlanul mennek.
  • Az átalakítás az ImageMagickkel történik, amely minden Mythex-sandboxban megtalálható, és fájlonként egyszer fut le. Az a kör, amely minden hívásban ugyanazokat a szkenneléket mutatja, a kicsinyített másolatot újrahasználja. A gyorsítótárat a fájl elérési útja, mérete és módosítási ideje azonosítja, így a szerkesztett fájl újra átalakul, és a gyorsítótárnak saját méretkorlátja van, hogy ne a memóriát töltse meg.
  • Egy hívás képeire vonatkozó keretet 16 MB-ról 6 MB-ra csökkentettük.

Ugyanez a hat szkennelés most hívásonként 4,4 MB-ba kerül a korábbi 19,7 MB helyett.

2. ok: a modellkliens sosem engedte el a kérést

A kérések mérete csak egy része volt a problémának. A memória hívásról hívásra is nőtt. A staging környezetünkon ugyanilyen kör 369 MB élő memóriát tartott akkor is, miután egy teljes szemétgyűjtés lefutott — ez az a pont, ahol minden elérhetetlen objektum fel van szabadítva. A heap-mintavétel az összes növekedést a modellkliens-könyvtárnak arra a részére helyezte, amely a kérés törzsét kódolja.

Az ok egy megszakítás-figyelő volt. Ha megnyomod a Leállítás gombot, a kör megszakítási jele tüzel, és minden figyelő kérés megszakad. Mi ugyanazt a körszintű jelet adtuk át minden kérésnek. A kliens könyvtár „abort” figyelőt tesz arra a jelre, amit kap — és sosem távolítja el.

Vagyis a kör minden kérése elérhető maradt a körjelről, a kör egész ideje alatt: a figyelő tartotta a vezérlőt, a vezérlő a kérést, a kérés pedig az egész kérés-törzset a képekkel együtt.

A javítás: egy jel kérésenként

Minden kérés most saját jelet kap. Ez csak addig kapcsolódik a kör jeléhez, amíg az adott kérés fut — streamelt válasz esetén az utolsó darab beolvasásáig —, utána azonnal leválasztjuk. A Leállítás továbbra is eléri a folyamatban lévő kérést, de a körjel egyszerre csak egy figyelőt tart.

A tesztek mindhárom részt lefedik:

  • 12 hívás után nem marad figyelő a körjelen. A javítás előtt 12 volt.
  • 8 MB-os, 15 kérés esetén a memória egyenes marad. Előtte 128 MB-tal nőtt.
  • A Leállítás továbbra is megszakít egy kérést a streamje közepén.

3. ok: a nyomkövetés megtartotta minden hívás bemenetét

Egy heap-pillanatkép harmadik tartót mutatott: hívásonként kb. 6 MB-ot. Ez az ügynökkeretrendszer eseményfolyamából származott. Minden modellhívást a körön belül gyermekként rögzít, a bemenetével együtt, egészen a kör végéig. Minden képet, amely bármelyik hívásnak csatolva volt, mellette tartott a memóriában.

A javítás: a képek ürítése, amint a hívás visszatér

A képek csak az adott modellhíváshoz készített üzenetekhez kerülnek hozzá. Sosem kerülnek a beszélgetés mentett állapotába. Ezért miután a hívás visszatért, biztonságosan kiüríthetjük az üzenetek képadatait. A nyomkövetés megtartja a hívás szöveges nyilvántartását; a pixelek eltűnnek.

Egy részlet fontos volt: a képeket helyben kell kiüríteni. A nyomkövető ugyanahhoz a képadathoz több hivatkozáson keresztül is hozzáférhet egy üzeneten belül, ezért egy új, üres lista behelyezése az eredetit — pixelekkel együtt — elérhetően hagyná. A mentett beszélgetési állapotot sosem módosítjuk.

Egy teszt lefuttatja az ügynök gráfját ugyanezzel az eseményfolyam-követéssel, minden hívásnál 4 MB-os képpel. A javítás nélkül a memória 16 hívás alatt 77 MB-tal nőtt. A javítással egyenes marad.

Mit vittünk ebből magunkkal

  • A memóriaproblémák rétegekben jöhetnek. Három külön ok tartotta túl sokáig a képeket, és mindháromnak el kellett tűnnie, hogy a kör a memórián belül maradjon.
  • Bármit átadsz egy könyvtárnak, megtarthatja. Egy jel és egy nyomkövetés is túlélte a hívásokat, amelyeknek átadtuk őket. Ha a memória hívásonként nő, nézd meg, milyen hosszú életű objektumokat ér el a hívás.
  • Ne küldj olyat, amit a másik fél eldob. A pixelek, amelyeket a modell úgyis eldobna, hívásonként memóriát kóstáltak.
  • Teszteld közvetlenül a memóriát. Minden javításhoz tartozik egy teszt, amely a heap-növekedést vagy a figyelőszámot méri, így egy visszaesés szám formájában jelentkezik, nem összeomlásként.

Ez rövid időn belül a második memóriatörténet az ügynök kimenetéből: az első egy állapotjelző címke, amely 41 000-szer lett újra elküldve. Ha többet szeretnél tudni arról, mi az ügynök és hogyan működik, nézd meg az AI-ügynökök útmutatónkat és a chat dokumentációt.

Mythex · Pricing · Építs bármit AI-val · Weboldal- és alkalmazássablonok · A Mythex összehasonlítva · AI-alapú alkalmazásépítési szószedet · Ingyenes eszközök AI-alapú alkalmazásépítéshez · English

English አማርኛ العربية Български বাংলা Bosanski Català Čeština Dansk Deutsch Ελληνικά Español Español (España) Eesti فارسی Suomi Français Français (Canada) ગુજરાતી हिन्दी Hrvatski Հայերեն 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 Srpski Svenska Kiswahili தமிழ் తెలుగు ไทย Tagalog Türkçe Українська اردو Tiếng Việt 简体中文 繁體中文(香港) 繁體中文(台灣)