Ugrás a tartalomhoz
07

Tool engineering

Egy agent pontosan annyira jó, amennyire a toolok, amelyeket a kezébe adsz. Hiába a legokosabb modell és a leggondosabban megírt prompt, ha a tool félreérthető nevű, strukturálatlan választ ad, vagy csendben elnyeli a hibákat — a modell ezekből nem tud jó döntést hozni. Itt végigvesszük, mitől lesz egy tool megbízható építőelem, és mikor jobb, ha az agent kódot ír és futtat sok tool-hívás helyett.

🔵 Alkalmazásépítés ⏱ ~18 perc olvasás Felülvizsgálva:

Miért érdekel ez téged?

A tool az a felület, ahol az agent kilép a saját fejéből és hatást gyakorol a világra: lekérdez egy adatbázist, elküld egy e-mailt, kiszámol egy összeget. A modell ezeket az eszközöket a nevük, a leírásuk és a válaszuk alapján használja — vagyis a tool minősége közvetlenül határozza meg, hogy az agent okosnak vagy ügyetlennek tűnik-e.

A gyakorlatban a legtöbb agent nem azért bukik el, mert a modell buta, hanem mert a toolok rosszul vannak megtervezve: kétértelmű a nevük, túl sokat vagy túl keveset adnak vissza, néma hibát dobnak. Gondolj a toolokra úgy, mint egy szakember szerszámosládájára: egy jól felcímkézett, éles szerszámmal a közepes mesterember is jó munkát végez, egy rozsdás, jelöletlen kupacból viszont a mester is csak találgat.

Egy konkrét szám, ami megvilágítja a tétet: ha egy agentnek 40 tool áll rendelkezésére, és mindegyik leírása átlagosan 300 token, akkor már 12 000 token elmegy pusztán arra, hogy a modell egyáltalán tudjon a toolokról — még mielőtt egyetlen felhasználói kérést látott volna. Ez a context window jelentős része (lásd 2. Context engineering), és minden hívásnál újra elküldöd. A tool engineering tehát nemcsak helyességi, hanem költség- és latency-kérdés is.

Tool vs. függvény: mi a különbség?

Egy tool technikailag gyakran egy sima függvény, amit a modell meghívhat. A lényegi különbség az, hogy a hívó fél nem determinisztikus. Egy hagyományos API-t egy programozó hív, aki elolvasta a dokumentációt és pontosan tudja, mit csinál. Egy toolt egy nyelvi modell hív, ami valószínűségi alapon dönt a név és a leírás alapján. Ezért a tool tervezésénél nem elég, hogy a függvény „helyes" legyen — annak félreérthetetlennek is kell lennie egy olyan hívó számára, aki bármikor félreértheti.

Ez a szemléletváltás a kulcs: nem kódot írsz egy fordítónak, hanem interfészt tervezel egy intelligens, de hibázó ügynöknek. Minden döntésed — a névtől a hibaüzenetig — azt szolgálja, hogy csökkentsd a félreértés valószínűségét.

Egy jó tool

A tool a modell és a külvilág közötti szerződés. Minél tisztább ez a szerződés, annál kevesebbet kell a modellnek találgatnia. Az alábbi tulajdonságok mindegyike egy-egy hibalehetőséget szüntet meg — nézzük végig, miért számít mindegyik.

Agent (modell) Tool-hívás típusos input Végrehajtás API / sandbox Strukturált válasz (JSON) eredmény értékelése → következő lépés Hiba retryable / permanent retry vagy feladás
Egy tool-hívás életciklusa: az agent típusos inputtal „megrendeli" a hívást, a te kódod hajtja végre (API vagy sandbox), majd strukturált választ ad vissza. A hibát is meg kell különböztetni — retryable esetén az agent javítva újrapróbál, permanentnél felad —, végül az eredmény visszakerül az agenthez a következő lépéshez.
  • Egyértelmű nevű A tool neve önmagában elárulja, mit csinál: get_customer_orders, ne fetch vagy run. A modell elsőként a név alapján dönti el, egyáltalán hozzányúljon-e — pont mint te a szerszámosládában a feliratok alapján. Homályos név esetén rossz eszközt választ, még mielőtt a leírásig eljutna. Használj konzisztens ige_főnév mintát (create_ticket, list_tickets, close_ticket): a modell így mintázatot ismer fel, és kevésbé keveri össze a hasonló toolokat.
  • Szűk és jól definiált feladatú Egy tool egy dolgot csináljon, azt jól. A „svájcibicska-tool", ami húsz paraméterrel húszféle dolgot tud, összezavarja a modellt: nehéz eldönteni, melyik ágat hívja és milyen argumentumokkal. Több kicsi, fókuszált tool szinte mindig jobb, mint egyetlen monstrum. Mikor NE: ha annyira felaprózod, hogy egy tipikus feladat 8-10 egymásra épülő hívást kíván, az növeli a latencyt és a hibalehetőséget — ilyenkor érdemes egy szinttel magasabb, „use-case szintű" toolt adni.
  • Típusos inputot használ Az argumentumoknak legyen explicit típusa és sémája (string, egész szám, enum, dátumformátum). A típusos séma egyszerre vezeti a modellt abban, mit adhat meg, és teszi a kód számára validálhatóvá a bemenetet, mielőtt az bármit végrehajtana. Egy status: "open" | "shipped" | "cancelled" enum például eleve kizárja, hogy a modell kitaláljon egy nemlétező „pending" státuszt. Ez ugyanaz a probléma, mint a 3. Structured output fejezetben — csak most a tool argumentumára alkalmazva.
  • Világos leírással rendelkezik A tool leírása és a paraméterek dokumentációja a modell egyetlen forrása arról, hogyan használja helyesen. Írd meg úgy, mintha egy új kollégának magyaráznád: mit csinál, mikor érdemes hívni, mit ne várj tőle, és mit ad vissza. Egy pontatlan leírás pont annyira drága, mint egy rosszul megírt függvény. Konkrét tipp: ha két tool könnyen összekeverhető, a leírásba írd bele explicit, mikor NE ezt válaszd („ez csak nyitott rendeléseket ad; lezárt rendelésekhez használd a get_order_history toolt").
  • Strukturált választ ad A tool ne emberi olvasásra formázott szövegdömpinget adjon vissza, hanem gépi feldolgozásra alkalmas struktúrát (jellemzően JSON). Így a modell megbízhatóan ki tudja olvasni a konkrét mezőket, ahelyett hogy egy bekezdésből próbálná kihalászni a lényeget. A stabil kulcsnevek (order_id, nem hol „id", hol „orderId") csökkentik a modell értelmezési hibáit is.
  • Nem ad vissza felesleges adatot Minden visszaadott token helyet foglal a context window-ban és pénzbe kerül. Ne adj vissza kétszáz mezős rekordot, ha háromra van szükség. Egy tipikus ügyfélrekord könnyen 50-100 mező, amiből egy „mennyi a nyitott rendelése?" kérdéshez 2-3 kell — a maradék 97 mező zaj, ami el is tereli a modell figyelmét. A contextet véges attention budgetként kezeld (lásd 2. Context engineering), és adj lapozást (limit + cursor) a nagy listákhoz.
  • Idempotens, amikor lehet Ha ugyanazt a toolt ugyanazokkal az argumentumokkal kétszer hívják, ne legyen kétszeres hatás. Analógia: a lift hívógombja — hiába nyomod meg ötször, egy lift jön. Ez azért kritikus, mert az agentek újrapróbálkoznak, és egy nem idempotens írási tool egy retry során duplán utalhat vagy kétszer küldheti el ugyanazt a rendelést. Gyakorlati minta: az írási toolok fogadjanak egy idempotency_key-t, amit ugyanarra a logikai műveletre ugyanazzal az értékkel küldesz.
  • Támogat timeoutot és cancellationt A toolnak legyen felső időkorlátja, és kívülről megszakíthatónak kell lennie. Egy beragadt tool-hívás különben az egész agent-futást blokkolja: ha egy tool 90 másodpercig lóg egy külső API-n, a felhasználó addig egy pörgő ikont néz. Adj értelmes timeoutot (pl. 5-30 s a művelettől függően), és a timeoutot is retryable hibaként add vissza. A cancellation propagáció ugyanolyan fontos, mint bármelyik hosszú kérésnél egy elosztott rendszerben (lásd 13. Production architektúra).
  • Jól kezeli a hibákat Hiba esetén a tool ne nyers stack trace-t vagy néma üres választ adjon, hanem strukturált, a modell számára is értelmezhető hibaüzenetet: mi ment el, és mit lehet tenni ellene. A modell csak akkor tud helyrejönni egy hibából, ha egyáltalán érti, mi történt. Egy jó hibaüzenet gyakran maga a megoldás: „a date formátuma hibás, várt formátum: YYYY-MM-DD" — a modell a következő hívásban simán javítja.
  • Különbséget tesz retryable és permanent error között Nem minden hiba egyforma. A „foglalt a szerver, próbáld újra" (retryable) és a „nincs ilyen ügyfél" (permanent) két teljesen más döntést kíván. Analógia: a telefonban a „foglalt a vonal" jelre újrahívsz, a „nincs ilyen szám" jelre nem. Ha a tool ezt megkülönbözteti, az agent nem pörög feleslegesen egy eleve megoldhatatlan híváson — és nem éget el 5 drága LLM-kört egy olyan hibán, amit soha nem fog megoldani.
  • Auditálható Minden tool-hívásnak nyoma marad: ki, mikor, milyen argumentumokkal hívta, és mi lett az eredmény. Erre szükség van a hibakereséshez, az evalhoz és a biztonsági vizsgálathoz is — a tool-hívás az a pont, ahol az agent tényleges hatást gyakorol a külvilágra. Egy jó trace-ből visszafejthető, hogy egy adott téves művelet melyik lépésből fakadt (lásd 14. Observability).
  • Saját auth contextet kap A tool ne egy mindenható szolgáltatásfiókkal fusson, hanem az adott felhasználó jogosultságával. Így egy felhasználó nem férhet hozzá más adatához pusztán azért, mert az agenten keresztül kéri. Gyakorlatban ez azt jelenti, hogy a felhasználói tokent (vagy annak leszűkített változatát) le kell juttatnod a tool implementációjáig — nem elég a modellre bízni, hogy „csak a jogosult adatot kéri". Ez az alapvédelem a „confused deputy" típusú visszaélés ellen (lásd 15. AI Security).
  • Nem ad az agentnek nagyobb jogot a szükségesnél Minden tool a lehető legszűkebb jogosultsággal fusson (least privilege). Analógia: a szállodai kulcskártya, ami csak a te szobádat nyitja, nem az egész épületet. Ha egy toolnak csak olvasnia kell, ne kapjon írási jogot — a read és write toolok szétválasztása az egyik legolcsóbb biztonsági nyereség. Külön bónusz: a tisztán olvasó toolok mellett bátrabban engedhetsz autonómiát, az írókhoz pedig human-in-the-loop megerősítést tehetsz.

Hogy kézzelfoghatóbb legyen, mit jelent ez a gyakorlatban, íme ugyanaz a képességi cél két tool-tervezésben: ahogy tipikusan nem érdemes, és ahogy érdemes.

Rossz toolJó tool
NévdoStuff — semmit nem árul elget_invoice_by_id — a név a feladat
FeladatkörEgy tool húsz paraméterrel, sokféle műveletEgy tool egy jól körülhatárolt feladatra
InputEgy nyers query stringTípusos, sémázott mezők, enumokkal
VálaszFormázott szöveg vagy a teljes nyers rekordStrukturált JSON, csak a releváns mezők
HibaNéma üres válasz vagy nyers stack traceStrukturált hiba: ok + retryable-e
Ismételt hívásKétszer fut le, dupla hatásIdempotens, biztonságosan újrapróbálható
JogosultságMindenható service accountFelhasználói auth context, least privilege

Kódban a különbség többnyire egyetlen dologban rejlik: a szerződés explicit-e. Egy típusos séma, egy tömör docstring és egy strukturált visszatérési érték már fél siker — ennyiből dolgozik a modell.

Python Egy jól definiált tool: típusos input, világos leírás, strukturált válasz
from pydantic import BaseModel, Field

class GetOrdersInput(BaseModel):
    """Egy ügyfél megrendeléseit adja vissza adott státuszra szűrve.
    Csak olvas; nem módosít semmit. Ismeretlen ügyfélnél permanent hibát ad."""
    customer_id: str = Field(description="Az ügyfél egyedi azonosítója")
    status: str = Field(default="all", description="open | shipped | all")
    limit: int = Field(default=10, ge=1, le=50)

class GetOrdersResult(BaseModel):
    orders: list[dict]        # csak a szükséges mezők, nem a teljes rekord
    truncated: bool           # ha több találat volt, mint a limit

Amit ebből érdemes elvinni: a docstring nemcsak az embernek szól — ez megy át a modellhez tool-leírásként. A ge=1, le=50 korlát és a status enum-szerű leírása eleve kizár egy csomó hibás hívást, a truncated mező pedig őszintén jelzi a modellnek, hogy volt-e több adat.

A tool-leírás mint prompt

Sokan alábecsülik, hogy a tool-leírás valójában prompt engineering. A modell nem látja a kódodat, csak a nevet, a paraméter-sémát és a leírást — ez az egész „API-dokumentáció", amiből dolgozik. Ha a leírás homályos, a modell találgat; ha ellentmondásos, a modell hibázik.

Egy gyakori antipattern a túl szűkszavú leírás ("Gets orders.") — ebből a modell nem tudja, mit vár inputként, mit kap vissza, és mikor NE hívja. A másik véglet a regényszerű leírás, ami elveszik a részletekben és tokent pazarol. A jó leírás 2-4 mondat: mit csinál, mikor hívd, mit ad vissza, és egy explicit határ (mit NE várj tőle).

JSON Ugyanaz a tool provider-agnosztikus JSON Schema formában
{
  "name": "get_customer_orders",
  "description": "Egy ügyfél megrendeléseit adja vissza státusz szerint szűrve. Csak olvas. Lezárt (archivált) rendelésekhez használd a get_order_history toolt.",
  "input_schema": {
    "type": "object",
    "properties": {
      "customer_id": { "type": "string", "description": "Egyedi ügyfél-azonosító" },
      "status": { "type": "string", "enum": ["open", "shipped", "all"], "default": "all" },
      "limit": { "type": "integer", "minimum": 1, "maximum": 50, "default": 10 }
    },
    "required": ["customer_id"]
  }
}

Amit ebből tanulj: az enum és a minimum/maximum nem díszítés — ezek a modell viselkedését szűkítik. A leírásba tett „lezárt rendelésekhez használd a get_order_history toolt" mondat pedig pontosan az a fajta disambiguáció, ami két hasonló tool közti keverést megelőz.

Hány tool az ideális?

Nincs mágikus szám, de van egy nagyságrend, ami segít: tapasztalati szabály, hogy egy agent kb. 10-20 toollal még megbízhatóan válogat, 40-50 fölött viszont romlani kezd a tool selection pontossága, és a leírások tokenköltsége is elszalad. Ha ennél többre van szükség, ne egyszerűen zúdítsd rá mind a modellre.

Tool-katalógus ~200 tool, namespace Retriever / router lépéshez szűr Modell látja ~15 releváns tool feladat / beszélgetés állapota kevesebb token · jobb selection
Dinamikus tool-betöltés: a teljes katalógust nem zúdítod a modellre. Egy retriever vagy router a feladat és a beszélgetés állapota alapján a releváns namespace-t választja ki, így a modell egyszerre csak egy szűk, releváns toolkészletet lát — kevesebb token, pontosabb tool selection.
  • Tool grouping / namespace Csoportosítsd a toolokat logikai domainekbe (billing.*, crm.*), és a lépéstől függően csak a releváns csoportot töltsd be. Egy support-agentnél a számlázási toolok csak akkor kellenek, ha a beszélgetés odaér.
  • Dinamikus tool-betöltés Egy retriever vagy egy „meta-tool" alapján futásidőben töltsd be a feladathoz illő toolkészletet a teljes katalógus helyett. Így 200 elérhető toolból a modell egyszerre csak 15-öt „lát".
  • Use-case szintű toolok Ahelyett hogy 6 alacsony szintű toolt adnál egy gyakori workflow-hoz, adj egy magasabb szintűt, ami befelé láncolja őket. Kevesebb LLM-kör, kisebb hibafelület.

Gyakori hibák

  • Túl sok, egymással átfedő tool Ha három tool is „nagyjából ugyanazt" csinálja, a modell rosszul választ. Vagy vond össze őket, vagy a leírásban élesen határold el a felhasználási esetüket.
  • Nyers külső API átdobása toolként Egy REST endpoint 1:1 toollá tétele ritkán jó ötlet: a REST API-t embernek/programozónak tervezték, gyakran túl sok mezőt kér és túl sokat ad vissza. Csomagold be egy szűk, modellbarát réteggel.
  • Emberi olvasásra formázott válasz A markdown táblázat vagy a „✅ Kész! 3 rendelést találtam..." típusú válasz szép, de a modellnek nehezebb megbízhatóan parse-olni, mint egy JSON-t. A prezentációt bízd a UI-ra, a toolból strukturált adat jöjjön.
  • Csendes csonkolás Ha limitálod a találatokat, de nem jelzed a truncated mezővel, a modell azt hiszi, mindent lát — és téves következtetést von le (pl. „az ügyfélnek csak 10 rendelése van").

Tool szintű eval

Egy tool akkor „jó", ha a gyakorlatban is jól használható — ezt pedig nem elég remélni, mérni kell. A tool szintű eval három, egymástól független kérdést tesz fel, és mindhárom más okból bukhat el. Ha csak a végeredményt méred, nem tudod, melyik lépcsőn csúszott el a dolog.

  • Megfelelő toolt választotta-e? A tool selection az első hibapont. Mérd, hogy egy adott kérésre az agent a helyes toolt hívta-e — nem a szinonimát, nem egy átfedő másikat, és egyáltalán hívott-e toolt, amikor kellett. Ez tipikusan a tool nevén és leírásán múlik: ha romlik a selection, először ott javíts.
  • Helyes argumentumokat adott-e át? Jó tool, rossz paraméter: a modell eltalálja, hogy get_customer_orders kell, de rossz customer_id-t vagy nemlétező státuszt ad. Ezt argument-szinten kell mérni; a típusos séma és az enumok itt drasztikusan csökkentik a hibát.
  • Értelmesen használta-e fel az eredményt? A legalattomosabb hiba: a hívás tökéletes, de a modell rosszul értelmezi a választ — pl. a truncated: true-t ignorálja, vagy a hibaüzenetet ténynek veszi. Ezt end-to-end kell nézni: mit mondott a felhasználónak a tool eredménye alapján.

A gyakorlatban ehhez egy kis, kézzel felcímkézett eval-készlet kell: bemenet → elvárt tool + elvárt argumentumok. A trace-ekből (lásd 14. Observability) folyamatosan gyűjthetsz valós eseteket, főleg a hibásakat, és beemelheted őket az eval-készletbe — így a toolkészlet a valós használattal együtt javul.

Python Egyszerű tool-selection eval eset
cases = [
    {
        "input": "Hány nyitott rendelése van a 4521-es ügyfélnek?",
        "expected_tool": "get_customer_orders",
        "expected_args": {"customer_id": "4521", "status": "open"},
    },
]

for c in cases:
    call = run_agent_capture_first_toolcall(c["input"])
    assert call.name == c["expected_tool"], f"rossz tool: {call.name}"
    assert call.args["status"] == c["expected_args"]["status"]

Amit ebből tanulj: a tool-eval nem a végső szöveges választ nézi, hanem a döntést — melyik toolt, milyen argumentumokkal. Ez a fajta assert gyorsan lefut, olcsó, és pontosan megmutatja, melyik réteget kell javítani.

Code execution

Van, amikor a sok apró tool önmagában is szűk keresztmetszet. Komplex adattranszformációnál gyakran jobb, ha az agent egy sandboxban kódot ír és futtat, mint ha több tucat tool-híváson keresztül másolgatja és szűrögeti az adatot. Egy szűrés–csoportosítás–összegzés lépéssort egyetlen kis Python-szkript pár sorban elintéz — több tíz tool-hívás és a köztük utazgató köztes adat helyett.

Vegyünk egy konkrét példát: „add össze az elmúlt 12 hónap rendeléseit hónapokra bontva, és add vissza a top 3 hónapot". Tool-hívásokkal ez lehet 12 lekérés + kézi összegzés a modell fejében (ami hibázhat a számolásnál). Kóddal egyetlen futás: lekéri az adatot, egy groupby-jal összegzi, rendez, és a top 3-at adja vissza — determinisztikusan, a modell aritmetikai hibái nélkül.

A dolog ára viszont súlyos: a modell által generált kódot futtatni annyi, mint idegen kódot futtatni a rendszereden. Ezért a code execution nem működhet biztonságos sandbox nélkül — ez nem opció, hanem alapfeltétel. Az alábbiak mindegyike egy-egy réteg ebben a védelemben.

microVM / konténer izoláció erőforrás-limit: CPU · RAM · idő · PID FS read-only · egress deny · package/secret Modell írta kód (untrusted) minden réteg lefelé szűkít · minden futás trace-elve
A sandbox védelme defense-in-depth: kívülről befelé a microVM/konténer izoláció, az erőforrás-limitek, a fájlrendszer- és hálózati korlátozás (package- és secret-védelemmel), legbelül a modell által írt, nem megbízható kód. Egyetlen réteg sem elég önmagában — együtt teszik kiszámíthatóvá a legrosszabb esetet is.
  • Izolált sandbox A kód soha ne a fő rendszereden fusson, hanem egy elszigetelt környezetben (konténer vagy microVM), amely nem lát rá a host fájljaira, hálózatára vagy más futásokra. Analógia: a laboratóriumi kesztyűs fülke — bent dolgozhatsz a veszélyes anyaggal, de az nem jut ki. A microVM-alapú izoláció (pl. a gVisor/Firecracker-szerű megközelítések) erősebb határt ad, mint egy sima konténer. Ez az egész code execution alapja.
  • CPU-, memória- és időlimit A generált kód lehet végtelen ciklus vagy memóriazabáló. Kemény erőforráskorlát nélkül egyetlen rossz futás megeszi a gépet. Tipikus értékek: pár száz MB memória, néhány másodperc wall-clock idő, 1 CPU. A limit garantálja, hogy még a legrosszabb eset is kiszámítható és korlátozott maradjon.
  • Read-only vagy ideiglenes filesystem A sandbox fájlrendszere legyen csak olvasható, vagy futásonként eldobott, ideiglenes réteg. Így a kód nem tud tartósan módosítani semmit, és minden új futás tiszta lappal, kiszámítható állapotból indul. Ha kell írási hely, adj egy szűk, futás után törölt /tmp-et méretkorláttal.
  • Hálózati egress control Alapból tiltsd a kimenő hálózati forgalmat, és csak a valóban szükséges célokat engedd át (allowlist). Enélkül a kód adatot szivárogtathat ki vagy tölthet be rosszindulatú tartalmat — ez a data exfiltration egyik fő útja (lásd 15. AI Security). A default legyen „minden tiltva", és onnan nyiss ablakot.
  • Package allowlist Csak előre jóváhagyott csomagok legyenek telepíthetők vagy importálhatók. A tetszőleges csomagtelepítés komoly supply-chain támadási felület: egyetlen rosszindulatú függőség az egész sandboxot kompromittálhatja. Gyakorlatban egy előre összeállított, ismert csomagkészletű image a legbiztonságosabb — futásidejű pip install nélkül.
  • Secret isolation A titkok (API-kulcsok, adatbázis-jelszavak) soha ne legyenek elérhetők a sandboxban futó kód számára. Ha a modell által generált kód látja a secretet — akár csak környezeti változóban —, egy ügyes prompt injection rá tudja venni, hogy kiszivárogtassa. A külső hívásokat egy proxy mögé tedd, ami hozzáteszi a hitelesítést, de a secretet nem adja be a sandboxba.
  • Process limit Korlátozd, hány processzt vagy szálat indíthat a kód — ez a védelem a „fork bomba" ellen. Egy kontroll nélküli process-szaporodás rövid idő alatt megbéníthatja a hostot; egy PID-limit (pl. néhány tíz processz) ezt megfogja.
  • Output size limit A kód kimenete legyen felülről korlátozva: egy több gigabájtos kiírás megtöltené a context window-t és a logokat. A méretkorlát (pl. néhány tíz KB stdout) véd a szándékos és a véletlen elárasztás ellen egyaránt, és megakadályozza, hogy egy print ciklus felrobbantsa a tokenköltséget.
  • Malware scanning A sandboxba behozott fájlokat és csomagokat érdemes ismert kártevőkre átvizsgálni, mielőtt bekerülnek. Ez egy extra védelmi réteg a beszúrt vagy feltöltött rosszindulatú tartalom ellen — főleg ha a felhasználó tölthet fel fájlokat feldolgozásra.
  • Teljes execution trace Rögzítsd, milyen kódot futtatott az agent, milyen inputtal, és mi lett az eredmény. Analógia: a repülőgép fekete doboza — baj esetén ebből derül ki, pontosan mi történt. Kell az audithoz, a reprodukcióhoz és az evalhoz is (lásd 14. Observability).

Mikor code execution, mikor toolok?

A code execution nem váltja ki a jól megtervezett toolokat — kiegészíti őket. A döntés jellemzően azon múlik, hogy determinista, adatnehéz transzformációról van-e szó, vagy diszkrét, jól körülhatárolt műveletekről.

Toolok, ha…

  • diszkrét műveletek jól definiált inputtal (rendelés lekérés, e-mail küldés)
  • írási, mellékhatással járó akciók, ahol az idempotencia és a jogosultság kritikus
  • kevés lépés, előre látható workflow
  • nem akarsz sandbox-infrastruktúrát üzemeltetni

Code execution, ha…

  • komplex adattranszformáció (szűrés, csoportosítás, aggregálás, join)
  • a művelet tíznél több tool-hívásra bomlana szét sok köztes adattal
  • determinista számítás kell, ahol a modell aritmetikája megbízhatatlan
  • van erős sandbox és megvan hozzá az üzemeltetési kapacitás
Sok tool-hívásCode execution
LLM-körök számaSok (lépésenként egy)Kevés (egy kód, egy futás)
Köztes adat a contextbenNagy — minden részeredmény visszafolyikKicsi — csak a végeredmény jön ki
Aritmetika/aggregálásMegbízhatatlan (modell számol)Determinista (kód számol)
Biztonsági felületKisebb, jól körülhatároltNagy — idegen kód fut, sandbox kell
Üzemeltetési igényAlacsonyMagas (izoláció, limitek, monitoring)

Amit ebből érdemes elvinni: a code execution nagy erő, de nagy felelősség. Ott nyersz vele igazán, ahol az adat sok és a transzformáció bonyolult; ahol néhány jól tervezett tool elég, ott a toolok olcsóbbak és biztonságosabbak.

Összefoglalás

A tool az agent szerződése a külvilággal, és ez a szerződés csak annyit ér, amennyire explicit: egyértelmű név, szűk feladatkör, típusos input, világos leírás és strukturált válasz. A jó tool nem ad vissza felesleges adatot, idempotens ahol lehet, támogatja a timeoutot és a cancellationt, megkülönbözteti a retryable és a permanent hibát, auditálható, saját auth contextet kap és a lehető legszűkebb jogosultsággal fut. A tool-leírás valójában prompt: úgy írd, mint egy új, gyors, de a kontextusodat nem ismerő kolléga dokumentációját.

A toolok számával is bánj tudatosan: 40-50 fölött romlik a selection, ezért csoportosíts, tölts be dinamikusan, vagy adj magasabb szintű, use-case toolokat. És bármilyen jó is a toolkészleted, mérd is: tool szinten is kell evalot írni — jó toolt választott-e, jó argumentumokkal, és értelmesen használta-e az eredményt —, különben csak reméled, hogy az agent jól használja őket.

Ha az adattranszformáció túl komplex a tool-hívások láncához, a sandboxolt code execution erős alternatíva — de csak akkor, ha az izolációtól az execution trace-ig minden védelmi réteg a helyén van. A választás nem vagy-vagy: a diszkrét, mellékhatásos akciókhoz toolok, az adatnehéz, determinista transzformációkhoz kód — mindkettőt a helyén használva kapod a legjobb agentet.