AI Disclosure: A cikk elkészítéséhez generatív AI-eszközöket is használtam. A végső tartalomért és annak pontosságáért a szerző vállal felelősséget.
A kísérlet egy végtelenül egyszerű, mégis égető kérdéssel indult: vajon mire használható ma egy kisméretű, helyben futó nyelvi modell, ha nem nyomjuk le a torkán a fél Internetsorozatot minden egyes kérésnél, hanem egy szigorúan mérnöki keretrendszert (harness-t) építünk köré?
A tesztalany egy csaknem tízéves ASUS laptop volt, a maga tiszteletreméltó, i7-es processzorával, 16 GB memóriájával és egy GTX 960M videókártyával. Utóbbira a llama.cpp segítségével 15 réteget sikerült offloadolni a Qwen3-8B modell Q4_K_M verziójából. A cél nem egy újabb általános chatbot megalkotása volt, hanem egy célzott, TypeScript-alapú kódoló- és asszisztens-ágenst hoztunk létre. Ez lett Agent Buksi.
A harness architektúrája: Amikor a kevesebb több
Az első és legfontosabb tapasztalat az volt, hogy a gép lassúságáért nem tisztán a modell paraméterszáma a felelős, hanem a ráöntött, feldolgozatlan kontextusmennyiség. A hagyományos felületi hívásoknál egy több ezer tokenes prompt beolvasása (prefill) percekre megbénította a processzort. A megoldást egy minimális, szigorúan kontrollált környezet jelentette.
Buksi egy egyszerű, JSON-alapú ReAct hurokra épült. Szándékosan minimális eszközkészletet kapott: fájlolvasás (read_file), keresés (grep), sorközi szerkesztés (edit_file), fájlírás (write_file) és a feladat végét jelző done művelet. A szabad shell-hozzáférést elvből megtagadtuk tőle, mivel egy ágensnél a megbízható sandboxolás a túlélés záloga.
A teljesítmény kulcsa a llama.cpp prefix cache funkciójában rejlett. Az üzenetlistát append-only szerkezetűvé alakítottuk, így a változatlan prompt-elejét a szerver azonnal újrahasznosította. A modell válaszait pedig egy kézzel írt GBNF (Grammar) struktúrával szorítottuk korlátok közé: a modell nem költött tokent udvarias körmondatokra vagy szóközökre, kizárólag érvényes, tömör JSON utasításokat generálhatott.
A fejlesztés során hamar szembesültünk a tool-tervezés első alaptörvényével is: a modell szó szerint másolja a kapott kimenetet. Eleinte a read_file sorszámokkal ellátva adta vissza a kódot (8: const x = 1;). A modell ezt látva a sorszámot is bemásolta a cserélendő szövegmezőbe, így az edit_file sosem talált egyezést. Amint a sorszámokat eltávolítottuk az eszköz kimenetéből, a hiba azonnal megszűnt.
[Hibás kimenet] 8: const x = 1; --> A modell bemásolja a 8-ast --> EDIT FAIL [Javított] const x = 1; --> Pontos egyezés a fájlban --> EDIT OK
Zöldmezős siker: Üres HTML-ből működő alkalmazás
Az első igazi megmérettetés egy teljesen üres index.html fájl életre keltése volt. A feladat szerint az ágensnek egy címet, gombot, alapvető CSS stílust és egy olyan JavaScript logikát kellett létrehoznia, ami kattintásra módosítja a fejléc szövegét és színét.
Az objektív kiértékeléshez a válaszokat nem elhinni kellett, hanem mérni: a legenerált oldalt a harness automatikusan betöltötte egy elszigetelt jsdom környezetbe, ahol szimuláltuk a gombnyomást, és nyolc különféle viselkedést ellenőriztünk a DOM-ban.
A kezdeti botlások és útvonal-kezelési hibák csiszolása után az eredmény magáért beszélt:
- 5/5 teljes siker a szintetikus teszteken.
- Átlagosan 2 lépés és mindössze 73 másodperc futási idő.
- Mindez átlagosan csupán 630 tokenes kontextus-csúccsal.
A kísérlet ezen szakasza bebizonyította, hogy tiszta lap esetén, alacsony állapottér mellett egy 8B-s modell is meglepően érett, hasznos kódolási munkára képes.
A fal, aminek nekirohantunk: A 374 soros Reset gomb
A lelkesedés addig tartott, amíg meg nem érkezett a következő benchmark: egy létező, 374 soros, működő pontszámláló webalkalmazás módosítása. A feladat mindössze annyi volt, hogy kerüljön be egy Reset gomb, ami nullázza a pontokat és törli az előzményeket a meglévő működés elrontása nélkül.
Itt a rendszer kíméletlenül elvérzett: 22 próbálkozásból 0 teljes siker született.
A modell nem rosszindulatból vagy lustaságból hibázott, hanem fantáziált. Ahelyett, hogy feltérképezte volna a meglévő state objektumot és a render() függvényt, nem létező API-kat és változókat talált ki. Használt updateUI() függvényt, localStorage-ot, és historyList azonosítót a létező history helyett. Az egyik legszórakoztatóbb hiba az volt, amikor a players nevet használta tömbként a JavaScriptben, miközben az oldalon létezett egy id="players" DOM-elem — a böngésző így a HTML elemet adta vissza, amin a .forEach() metódus természetesen azonnal elszállt.
A kontextus-paradoxon
Amikor láttuk, hogy a modell vakon próbál szerkeszteni, elkövettük a klasszikus hibát: megpróbáltunk „még több segítséget” adni neki. A promptba bekerült a felhívás, hogy kódírás előtt feltétlenül olvassa el a kódot, kapott egy strukturált fájltérképet a függvényekről, és konkrét tippet az állapotkezelés helyéről.
A hatás katasztrofális volt. A modell nem okosabb lett, hanem beragadt egy olvasási hurokba. Ugyanazokat az átfedő sorkartományokat olvasta újra és újra, majd miután kifutott a lépéskeretből, egyetlen edit_file utasításig sem jutott el.
Rendszertervezési tanulság: Egy kisméretű modellnél a több kontextus és a túlmagyarázott útmutatás nem feltétlenül segítség. Gyakran csak újabb bizonytalansági tényezőt és hibalehetőséget visz a rendszerbe.
Korlátok vs. Utasítások: Amikor a tesztelőt is tesztelni kell
A kísérlet legfőbb tanulsága az lett, hogy a modell jóindulatára építő prompt-utasítások helyett a környezetben kikényszerített műszaki korlátok (guardrails) hozzák a valódi stabilitást:
- Felülírás-védelem: Megtiltottuk a
write_fileeszköznek, hogy felülírjon egy létező, nem üres fájlt, ha a modell az adott futás során nem olvasta el annak minden sorát. Ez a szabály három alkalommal mentette meg a projektet attól, hogy a modell egyetlen részlet alapján törölje a teljes fájlt. - Környezeti Sandbox: A fájlrendszerből való kilépést (
.., szimlinkek) nem a promptban kértük szépen, hanem az eszköz szintjén elutasítottuk.
Ugyanakkor a tesztelés során ráébredtünk egy kellemetlen igazságra is: a mérőeszközünk maga is hibás volt. A jsdom környezet nem valósította meg az innerText tulajdonságot, emiatt két olyan futást is bukottnak értékeltünk, ahol a modell valójában tökéletes kódolt. Egy hibás mérőeszközzel az ember gyorsan abba a csapdába esik, hogy egy nem létező modellhibát próbál kétségbeesetten optimalizálni.
[Kód generálva] --> [jsdom teszt: innerText HIÁNYZIK] --> [Hamis negatív hiba]
│
┌───────────────────────────────────────────────────────────────┘
▼
[A fejlesztő a modellt szidja, pedig a tesztelő eszköz a hibás]
Irányváltás: Map-Reduce videóleiratok és a nyelvi finomságok
Látva a meglévő kódok módosításának korlátait, a rendszert átirányítottuk egy olyan feladatra, ahol a kis modellek igazán ragyognak: a strukturált információ-feldolgozásra. A feladat angol nyelvű YouTube-videók időbélyeges leiratainak magyar nyelvű összefoglalása volt egy Map-Reduce csővezetéken keresztül.
- Map fázis: A leiratot ~450 szavas darabokra bontottuk. A modell minden darabból készített egy tömör angol kivonatot és egy szó szerinti idézetet.
- Reduce fázis: Az angol kivonatokból megszületett a végső angol TLDR és a legfontosabb részek kiemelése.
- Fordítási fázis: A kész, strukturált JSON kimenetet egy külön hívással fordítottuk magyarra.
Itt alkalmaztuk a leghatékonyabb védelmi vonalat az időbélyegek kezelésénél: a modelltől nem kértünk időpontokat, mert a kis modellek hajlamosak számokat halucinálni. Ehelyett a modell csak a szöveges idézetet adta vissza, a harness pedig programmatic módon megkereste a pontos mondatot az eredeti leirat szegmensei között, és maga szúrta be a másodpercre pontos időbélyeget.
A fordítási csapda
A videós kísérlet során fény derült egy izgalmas nyelvi korlátra is. A leiratban szereplő „focusing on systems over content” gondolatot az angol Reduce lépésben a modell tökéletesen értette. Ám a végső, JSON -> JSON magyar fordítási fázisban a mondat hirtelen az ellenkezőjére fordult: „a rendszerek helyett a tartalmakra összpontosítsunk”.
Ez kiválóan szemlélteti a Q4-es kvantálású 8B-s modellek határait: a hiba nem a modell gondolkodási vagy logikai képességében keletkezett, hanem a magyar nyelvi transzformáció során csúszott el.
Mit tanított nekünk Buksi?
A hétvégi kísérlet végére nem született meg az az autónom AI-fejlesztő, aki kiváltaná a senior mérnököket. Egy tízéves laptopon, 2–5 token/másodperces generálási sebesség mellett a több lépéses, komplex kódmódosítási feladatok fizikai falakba ütköznek.
A legnagyobb teljesítménynövekedést nem azzal értük el, hogy nagyobb modellt kerestünk, hanem azzal, hogy szigorúbb keretrendszert építettünk köré. A prefix cache, a GBNF grammatika, az intelligens tool-kimenetek, a szigorú sandbox és a modell bizonytalanságait kiváltó programmatic logikák (mint az időbélyeg-keresés) nagyságrendekkel többet nyomtak a latban, mint a prompt-trükkök.
Egy 8B-s helyi modell nem autonóm szoftverfejlesztő. Viszont egy szűk környezetben, Telegram-bot mögé kötve, strukturált adatkinyerésre, célzott dokumentum-összefoglalásra és egyértelmű eszközök vezérlésére már ezen a tízéves hardveren is meglepően stabilan használható.
A tanulság? Néha nem a modellből kell nagyobbat venni — csak a Buksit kell jobban felvértezni.
AI Disclosure: A cikk elkészítéséhez generatív AI-eszközöket is használtam. A végső tartalomért és annak pontosságáért a szerző vállal felelősséget.