Keď sme u klienta z energetiky nasadzovali agenta na automatizovanie reportov z SCADA systému, prvé dni prebehli bez problémov. Potom začali tichý zlyhania: agent zavolal správny nástroj, ale odoslal argumenty v nesprávnom formáte — číslo kde sa čakal reťazec, null kde sa čakala hodnota. Výsledok? Nástroj vrátil chybu, agent ju ignoroval a pokračoval ďalej, akoby nič. Report bol vygenerovaný, vyzeralo to funkčne, ale čísla boli nepresné. Trvalo nám niekoľko dní, kým sme príčinu odhalili.
Tool calling — volanie externých nástrojov a systémov cez LLM — je základná schopnosť každého produkčného agenta. A zároveň jeho najväčší zdroj tichých zlyhaní. Tento článok sa zameriava na konkrétne vzory: ako dizajnovať schémy nástrojov, validovať argumenty, spracovávať chyby a budovať retry logiku, ktorá funguje v reálnych podmienkach.
Prečo tool calling zlyháva — nie tak, ako si myslíte
Keď vývojári riešia nespoľahlivosť agentov, zvyčajne hľadajú príčinu v modeli. Zlý reasoning, nedostatočné uvažovanie, nesprávne pochopenie zadania. V praxi sme zistili, že väčšina produkčných incidentov má inú príčinu: zlý dizajn schémy nástroja, chýbajúca validácia argumentov, nespracované chyby nástroja.
Štyri najčastejšie vzory zlyhania, ktoré vídame:
- Agent zavolá zlý nástroj — pretože popisy nástrojov sú príliš podobné, vágne alebo nerozlišujúce
- Agent zavolá správny nástroj so zlými argumentmi — pretože schéma nepopisuje presne, aké hodnoty sú platné
- Agent ignoruje chybu nástroja — pretože nikto neošetril prípad, kedy nástroj vráti výnimku
- Agent sa dostane do retry slučky — pretože retry logika nie je obmedzená a nemá exponenciálny backoff
Žiaden z týchto problémov nesúvisí s inteligenciou modelu. Všetky sa dajú riešiť na úrovni inžinieringu. A všetky sa opakujú bez ohľadu na použitú architektúru agenta.
Dizajn schémy nástroja: presnosť pred stručnosťou
Schéma nástroja je to, čo agent vidí, keď sa rozhoduje, čo zavolať. Ak je schéma nepresná, agent odhaduje — a odhad v deterministickom systéme je problém.
Základné pravidlá dizajnu schémy, ktoré platia v praxi:
Meno nástroja musí byť akciové sloveso + objekt. get_sensor_reading je dobré. sensor je zlé. data je veľmi zlé. LLM sa orientuje podľa mena — ak mená dvoch nástrojov znejú podobne, agent ich bude zamieňať bez ohľadu na kvalitu popisu.
Popis musí rozlišovať, kedy nástroj použiť a kedy nie. Nestačí napísať "vráti údaje zo senzora". Napíšte: "Volaj len keď potrebuješ živé hodnoty z konkrétneho zariadenia podľa ID. Nepoužívaj na historické dáta — na to je get_sensor_history." Explicitná negácia je rovnako dôležitá ako pozitívny popis.
Každý parameter musí mať typ, popis a príklad. Nestačí sensor_id: string. Napíšte: "ID senzora vo formáte PLANT_ZONE_NNN, napr. A_LINE1_042. Nikdy nezadávaj len číslo bez prefixu." Model si nedomyslí formát — musíte mu ho ukázať.
Voliteľné parametre označujte explicitne — a uveďte, aká je predvolená hodnota a čo sa stane, ak ich vynecháte. Bez tohto agent opakovane generuje null alebo predpokladá nesprávnu hodnotu.
Príklad schémy pred a po:
# Pred (typické zlé schema)
{
"name": "sensor_data",
"description": "Gets sensor data",
"parameters": {
"id": {"type": "string"},
"from": {"type": "string"},
"to": {"type": "string"}
}
}
# Po (produkčné schema)
{
"name": "get_sensor_reading",
"description": "Reads current live value from a field sensor.
Use ONLY for real-time values. For historical ranges use get_sensor_history instead.
Returns {value, unit, timestamp, status}. Throws SensorOfflineError if device unreachable.",
"parameters": {
"sensor_id": {
"type": "string",
"description": "Sensor identifier in format PLANT_ZONE_NNN, e.g. A_LINE1_042"
},
"unit": {
"type": "string",
"enum": ["raw", "normalized"],
"description": "Output unit type. Default: 'raw'",
"default": "raw"
}
},
"required": ["sensor_id"]
}Rozdiel nie je v elegancii — je v miere, ktorou agent volá správny nástroj s platnými argumentmi. Z praxe: opravou schém sme znížili mieru nesprávnych volaní o viac ako polovicu bez akejkoľvek zmeny v modeli.
Validácia argumentov: netreba veriť modelu na slovo
Aj keď schéma je dobrá, model príležitostne vygeneruje argumenty, ktoré sú syntakticky platné, ale sémanticky nesprávne. from_date: "2026-13-45" je platný reťazec, ale neplatný dátum. count: -5 je platné číslo, ale nedáva zmysel.
Validácia argumentov pred samotným volaním nástroja je povinnosť, nie optimalizácia.
Tri vrstvy validácie, ktoré odporúčame:
1. JSON Schema validácia — najjednoduchšia vrstva. Overte, že agent odoslal správny typ pre každý parameter. Väčšina frameworkov (LangGraph, LangChain) toto robí automaticky ak máte schému, ale explicitná vrstva je istejšia.
2. Doménová validácia — overenie, že hodnoty dávajú zmysel v kontexte vašej domény. Dátumy v rozumnom rozsahu, ID v správnom formáte, číselné hodnoty v platnom rozsahu. Toto si musíte naprogramovať sami — žiaden generický framework to za vás neurobí.
3. Referenčná integrita — overenie, že referenced entita existuje. sensor_id: "A_LINE1_042" musíte overiť voči skutočnému registru senzorov — model nemá ako vedieť, ktoré ID sú platné.
Keď validácia zlyhá, nehádzajte len výnimku. Vráťte štruktúrovanú chybovú správu, ktorá modelu hovorí *čo* bolo zlé a *ako* to opraviť:
# Zlé
raise ValueError("Invalid sensor_id")
# Dobré
return {
"error": "INVALID_ARGUMENT",
"parameter": "sensor_id",
"received": "A_LINE_42",
"message": "Format must be PLANT_ZONE_NNN. Did you mean A_LINE1_042?",
"hint": "Call list_sensors() to get valid IDs for this plant"
}Táto chybová správa je vstupom do ďalšieho kroku agenta — čím je informatívnejšia, tým väčšia šanca, že agent sa opraví sám bez zbytočnej eskalácie.
Error handling: chyby nástroja sú normálna situácia, nie výnimka
Jeden z najväčších konceptuálnych problémov, ktorý vídame v produkčných agentoch: kód bol napísaný pre happy path. Keď nástroj vráti chybu, agent sa zachová nepredvídateľne — buď sa zasekne, alebo pokračuje s chybným stavom.
Produkčná realita: nástroje zlyhávajú. API má výpadky. Databázy sú dočasne nedostupné. SCADA systémy vracajú timeout. Toto nie sú edge-casy — sú to bežné udalosti v priemyselnom prostredí.
Základný error handling vzor pre každý nástroj:
def call_tool_safely(tool_fn, args, max_retries=3):
for attempt in range(max_retries):
try:
result = tool_fn(**args)
return {"status": "ok", "data": result}
except TransientError as e:
if attempt == max_retries - 1:
return {
"status": "error",
"type": "TRANSIENT",
"message": str(e),
"hint": "Service temporarily unavailable, retry later"
}
time.sleep(2 ** attempt) # exponential backoff
except PermanentError as e:
return {
"status": "error",
"type": "PERMANENT",
"message": str(e),
"hint": "Do not retry. Escalate to human operator."
}
except Exception as e:
return {
"status": "error",
"type": "UNKNOWN",
"message": str(e),
"hint": "Unexpected error. Log and escalate."
}Kľúčové princípy:
- Rozlišujte prechodné vs trvalé chyby. Timeout je prechodná chyba (retry). Autorizačná chyba je trvalá (neretry, eskaluj). Model musí vedieť, čo robiť ďalej.
- Exponenciálny backoff — nie pevná pauza. Každý retry čaká 2× dlhšie (1s, 2s, 4s...). Zabraňuje preťaženiu systémov pri výpadkoch.
- Maximálny počet retries — vždy obmedzený. Bez limitu sa agent môže dostať do nekonečnej slučky. Z praxe: retry rate okolo 12 % je bežný v produkčných systémoch — ak ho nemáte pod kontrolou, môžete zdvojnásobiť celkové volania a náklady.
- Štruktúrovaná chybová správa — agent musí dostať informáciu o type chyby a odporúčanom ďalšom kroku.
Viac o nákladových dôsledkoch retry logiky sa dozviete v článku o nákladoch AI agenta v produkcii.
Idempotencia: zabudnutá podmienka spoľahlivosti
Keď agent retryuje volanie nástroja, musí byť bezpečné zavolať ho viackrát s rovnakými argumentmi. Ak nie je — máte problém.
Idempotentné volanie: volanie get_sensor_reading(sensor_id="A_LINE1_042") viackrát vráti rovnakú (alebo ekvivalentnú) hodnotu bez vedľajšieho efektu. Bezpečné na retry.
Neídempotentné volanie: volanie create_work_order(equipment_id="P-042", type="inspection") viackrát vytvorí viacero pracovných príkazov. Katastrofa pri retry.
Pravidlo pre produkčné systémy: každý nástroj, ktorý vykonáva zápis, mutáciu alebo akciu s vedľajším efektom, musí byť chránený pred duplicitným volaním.
Vzory ochrany:
Idempotency key — agent generuje jedinečný kľúč pre každú úlohu a odošle ho s volaním. Backend zaregistruje kľúč a druhé volanie s rovnakým kľúčom vráti výsledok prvého bez vykonania akcie znova:
def create_work_order(equipment_id, type, idempotency_key):
existing = db.find_by_key(idempotency_key)
if existing:
return existing # Vrátime predchádzajúci výsledok
result = actually_create_work_order(equipment_id, type)
db.store(idempotency_key, result)
return resultKontrola stavu pred akciou — pred write operáciou overiť, či stav už nezodpovedá cieľu. Ak pracovný príkaz pre zariadenie P-042 na dnes už existuje, nevytvárať nový. Toto je jednoduchšie ako idempotency key a vhodné pre biznis domény s prirodzenou unikátnosťou.
Explicitná dokumentácia v schéme — každý nástroj so vedľajším efektom musí mať v popise: "Táto akcia je nevratná / vytvára záznam. Zavolaj len ak si istý, že podmienky sú splnené." Model, ktorý dostane túto informáciu, je opatrnejší.
Prečo agent volá zlý nástroj — a ako to znížiť
Jeden zo záhadnejších problémov: agent konzistentne volá tool_A namiesto tool_B napriek tomu, že správny je tool_B. Príčin je niekoľko a každá má iné riešenie.
Príliš podobné mená a popisy. Ak máte get_equipment_data a fetch_equipment_info, agent bude tieto nástroje zamieňať. Riešenie: prejdite celú sadu nástrojov a skontrolujte, či sú mená a popisy jednoznačne rozlišujúce. Ak dvaja kolegovia nevedia povedať rozdiel bez prečítania kódu, model to tiež nevie.
Príliš veľa nástrojov naraz. LLM má obmedzenú kapacitu pozornosti. Keď agentovi predhodíte 30 nástrojov v jednom promte, pravdepodobnosť nesprávneho výberu rastie. Vzor riešenia: toolset routing — agent najprv zvolí skupinu nástrojov (napr. "senzorové nástroje" vs "reportovacie nástroje"), potom z tejto skupiny vyberie konkrétny. Toto je súvislosť s MCP protokolom — servery slúžia ako prirodzené skupiny nástrojov.
Chýbajúci kontext v prompte. Ak systemový prompt nehovorí agentovi, v akom kontexte pracuje, model odhaduje vhodný nástroj z histórie konverzácie. Explicitný kontext v systemovom prompte — "Pracuješ v systéme správy výroby, nie v HR systéme" — znižuje chyby výberu nástroja.
Tréningová predpojatosť modelu. Niektoré modely majú tréningové dáta, ktoré uprednostňujú určité vzory volaní. Ak agent opakovane volá nesprávny nástroj napriek správnej schéme, skúste zmeniť meno nástroja — niekedy pomôže aj to.
Retry logika: päť pravidiel, ktoré zachránia produkciu
Retry je neoddeliteľná súčasť spoľahlivého tool callingu. Ale zle implementovaný retry je horší ako žiaden retry — môže zmeniť prechodný výpadok na kaskádové zlyhanie.
Pravidlo 1: Retry len prechodné chyby. HTTP 503 (Service Unavailable) a timeout sú prechodné. HTTP 400 (Bad Request) a 403 (Forbidden) sú trvalé — retry nepomôže, len plytváte.
Pravidlo 2: Exponenciálny backoff s jitter. Fixná pauza (retry každú sekundu) preťaží systém vo výpadku. Exponenciálny backoff s náhodným jitterom (±20 %) rozloží záťaž:
delay = min(base_delay * (2 ** attempt) + random.uniform(0, 0.3), max_delay)Pravidlo 3: Absolútny limit pokusov. Tri pokusy sú väčšinou dostatok. Päť je maximum. Viac retries → väčší risk retry storm (všetci agenti zároveň retryujú výpadnutý systém).
Pravidlo 4: Circuit breaker pre opakujúce sa výpadky. Ak daný nástroj zlyhá viackrát za sebou, dočasne ho "odpojiť" a všetky ďalšie volania okamžite vrátiť ako CIRCUIT_OPEN. Po cooldown perióde pustiť jedno testné volanie. Toto chráni aj vaše backendové systémy.
Pravidlo 5: Fallback akcia. Keď retry aj circuit breaker zlyhajú, čo agent urobí? Eskaluje na ľudského operátora, pokračuje bez tejto informácie, alebo sa zastaví? Každý kritický nástroj musí mať definovanú fallback stratégiu. Bez nej je agent nepredvídateľný pri zlyhaní — čo je priamou motiváciou pre HITL gates.
Testovanie tool callingu pred produkciou
Spoľahlivosť tool callingu sa nedá overiť len manuálnym testovaním happy path. Niekoľko testovacích vzorov, ktoré odporúčame:
Mock toolset testing — vytvorte mock verzie všetkých nástrojov, ktoré vracajú rôzne kombinácie odpovedí: úspech, prechodná chyba, trvalá chyba, malformovaný výstup. Spustite agenta voči týmto mockom a sledujte správanie.
Boundary testing argumentov — manuálne testujte, aké argumenty model generuje pre hraniční vstupy: prázdny reťazec, null hodnoty, extrémne čísla, dátumy v minulosti/budúcnosti. Schéma musí tieto prípady explicitne vylúčiť alebo agent na nich opakovane zlyháva.
Chaos testing — s určitou pravdepodobnosťou (napr. 20 %) inject chybu do nástroja počas testu. Overuje, či retry logika a fallback správanie fungujú v praxi, nie len v unit testoch.
Trace review — pre produkčné nasadenie je nevyhnutná observability a tracing. Každé volanie nástroja musí byť zaznamenané s argumentmi, výsledkom, latenciou a prípadnou chybou. Bez tohto neviete ani kde hľadať problém pri produkčnom incidente.
Časté otázky
Koľko nástrojov môže mať agent naraz?
Z praxe: nad 15–20 nástrojov v jednom kontexte sa spoľahlivosť výberu výrazne zhoršuje. Riešenie je toolset routing alebo MCP servery — agent si najprv vyberie správnu skupinu nástrojov, potom konkrétny nástroj z tejto skupiny. Ak máte 50+ nástrojov, hierarchická navigácia je nutnosť, nie optimalizácia.
Čo robiť, ak agent generuje halucinované argumenty — hodnoty, ktoré neexistujú?
Dva kroky: po prvé, schéma musí explicitne ukázať formát platných hodnôt vrátane príkladov. Po druhé, validácia musí overiť existenciu referenced entít (napr. sensor_id voči registru) a vrátiť štruktúrovanú chybu s nápovede ako nájsť platné hodnoty. Doplnkovo: nástroj list_available_X() (napr. list_sensors()) pomáha agentovi sám vyhľadať platné ID bez halucinácie.
Je bezpečné nechať agenta vykonávať nevratné akcie automaticky?
Záleží na kontexte. Pre nízkorizikové akcie (čítanie dát, generovanie reportov) je plná automatizácia v poriadku. Pre nevratné akcie (vytváranie objednávok, úprava konfigurácií, odosielanie správ) odporúčame explicitnú HITL bránu — agent navrhne akciu, ľudský operátor schváli. EU AI Act od augusta 2026 vyžaduje human oversight pre high-risk AI systémy — toto priamo implikuje HITL pre akcie s potenciálne vážnymi dôsledkami.
Čo je najrýchlejší spôsob, ako znížiť mieru chybných volaní?
Z praxe najväčší efekt má oprava schém nástrojov — konkrétne rozlišujúce popisy, príklady platných hodnôt a explicitné negatívne vymedzenie ("toto nepoužívaj na..."). Druhý veľký efekt má zníženie počtu nástrojov v jednom kontexte. Tieto dve zmeny nevyžadujú zmenu modelu ani architektúry.
Ako sledovať kvalitu tool callingu v produkcii?
Zaznamenávajte každé volanie s: timestamp, tool_name, argumenty (bez PII), status (ok/error), typ chyby, latencia, attempt number. Sledujte mieru chýb per nástroj — ak jeden nástroj má chybovosť 3× vyššiu ako priemer, je to signál na audit schémy. Nástroje ako Langfuse (self-hostable) alebo LangSmith toto umožňujú bez vlastnej observability infraštruktúry.
Záver
*Tool calling je miesto, kde sa väčšina spoľahlivostných problémov agentov začína — a zároveň kde ich možno riešiť čisto na inžinierskiej úrovni, bez zmeny modelu. Dobre navrhnuté schémy, validácia argumentov, štruktúrované error handling a obmedzená retry logika menia agenta z nepredvídateľného systému na prevádzkovateľný nástroj. Ak sa chystáte nasadiť agenta do produkcie alebo práve riešite spoľahlivostné problémy s existujúcim systémom, radi posúdime váš konkrétny prípad — navrhneme dizajn nástrojov, validácie a error handling pre vaše prostredie.*
