Geavanceerd Tool Calling Dat Mijn AI Agent-kosten Halveerde
Ik zat op een donderdagavond om 23:00 naar mijn Langfuse-dashboard te kijken toen ik iets zag wat me deed opstaan en mijn laptop dichtklapte. Eén agent-run -- één taak, één gebruikersvraag -- had 76.000 tokens verbruikt en 56 afzonderlijke tool calls gemaakt. Het ergste? Het antwoord was toch nog fout. Twee teamleden die hun budgetlimiet hadden overschreden werden gemist, en de klant zou dat rapport de volgende ochtend zien.
Die agent had toegang tot 60 tools verdeeld over twee MCP-servers. Elke tool-definitie werd aan het begin van elk gesprek in het context window geladen. Dertienduizend tokens weg voordat de agent ook maar begon na te denken over de eigenlijke taak. Ik dacht een capabel systeem te hebben gebouwd. Wat ik had gebouwd was een token-verbrandingsoven met een nauwkeurigheidsprobleem.
De oplossing kwam van twee functies die ik wekenlang in de documentatie van Anthropic had genegeerd: tool search en programmatisch tool calling. Wat er daarna gebeurde is de reden dat ik dit artikel schrijf. Maar het echte verhaal gaat niet over tokens besparen -- het gaat over een fundamentele verschuiving in de manier waarop ik denk over agent-architectuur.
Het Probleem Dat Niemand Bespreekt Totdat de Rekening Arriveert
Dit is het scenario dat de meeste AI-agent-ontwikkelaars goed kennen, of ze het nu toegeven of niet. Je begint een agent te bouwen. Die moet bestanden lezen, databases bevragen, API's aanroepen, misschien interacteren met GitHub of Slack. Elke mogelijkheid betekent een extra tool. Je eerste prototype heeft 8 tools en werkt prachtig. Schone context, snelle antwoorden, nauwkeurige resultaten.
Dan stromen de feature-aanvragen binnen. De agent moet kalenderafspraken beheren. Voeg drie tools toe. Hij moet Jira-tickets aanmaken. Nog twee tools. Slack-integratie? Nog vijf. Voor je het weet zit je op 35, 40, 60 tools -- en je agent heeft een persoonlijkheidsstoornis ontwikkeld. Hij pakt de helft van de tijd de verkeerde tool, hallucineert parameterwaarden en kost drie keer zoveel als begroot.
Ik liep hier keihard tegenaan in een project voor een klant die een uniforme operationele agent wilde. De agent moest toegang hebben tot hun GitHub-repos, Notion-werkruimte, Slack-kanalen, kalender en een aangepaste inventaris-API. In totaal 60 tools als je alles van beide MCP-servers meerdede.
Drie dingen brachten me om:
De tool-definities alleen al verbruikten per gesprek zo'n 13.000 tokens. Dat is context window-ruimte die had kunnen worden gebruikt voor het daadwerkelijke redeneerproces. Op Claude 3.5 Sonnet is dat niet niks -- en bij langere gesprekken naderde ik de contextlimieten voordat de agent zijn werk had afgerond.
Tussenliggende uitvoer van opeenvolgende tool calls vervuilde de context. Wanneer de agent budgetten over een heel team moest controleren, riep hij eerst "haal teamleden op", dan "haal uitgaven op" voor elke persoon, dan "haal budget op per niveau" voor de functie van elke persoon. Elk antwoord dumpte ruwe JSON in de context. Tegen de tijd dat hij bij het laatste teamlid was, werd eerdere data buiten het effectieve aandachtsgebied gedrukt.
De nauwkeurigheid van tool-selectie nam af naarmate het aantal tools toenam. Met 60 tool-definities in de context moest het model ze allemaal doorzoeken elke keer dat het besliste welke tool te gebruiken. Stel je voor dat je iemand een menu van 60 pagina's geeft in een restaurant en verwacht dat hij snel en correct bestelt. Zelfde probleem.
Ik probeerde de voor de hand liggende oplossingen. Betere tool-beschrijvingen. Minder tools met meer parameters. Tools categoriseren in groepen. Niets loste het fundamentele probleem op: te veel definities die te vroeg geladen werden, en te veel tussenliggende data die te snel accumuleerde.
Toen vond ik de twee functies die alles veranderden in de manier waarop ik agents bouw.
Tool Search: Laden Wat Je Nodig Hebt, Wanneer Je Het Nodig Hebt
Het concept achter tool search is zo eenvoudig dat het bijna beledigend is dat ik er zelf niet op gekomen ben. In plaats van alle 60 tool-definities aan het begin in de context te laden, stel je de meeste ervan uit. De agent krijgt een kleine set essentiële tools plus één speciale tool: de tool search tool zelf. Wanneer de agent een mogelijkheid nodig heeft die hij momenteel niet heeft, zoekt hij op trefwoord of naam naar de juiste tool, laadt alleen het schema van die ene tool, en gaat verder.
De wiskunde is overtuigend. Mijn setup met 60 tools verbruikte zo'n 13.000 tokens aan tool-definities. Na het implementeren van tool search en het upfront laden van slechts 12 essentiële tools, daalde dat aantal naar 6.300 tokens. Bijna de helft van de definitie-overhead, weg.
Maar de tokenbesparingen waren niet eens de belangrijkste verbetering. De nauwkeurigheid van tool-selectie steeg dramatisch. Als de agent slechts 12 tools in context heeft in plaats van 60, kiest hij veel consistenter de juiste. Het is hetzelfde als waarom een gefocuste vakman met 5 tools op de werkbank nauwkeuriger werkt dan iemand omringd door 50 -- minder ruis, beter signaal.
Zo ziet de workflow er in de praktijk uit. Stel dat de agent recente commits van een GitHub-repository moet ophalen. Met de traditionele aanpak zijn de GitHub MCP-tools al geladen -- alle 35 ervan, goed voor zo'n 26.000 tokens in definities (hoewel nieuwere MCP-versies dit hebben teruggebracht naar circa 4.000 tokens, een enorme verbetering waarover ik later meer zal zeggen). De agent moet ze allemaal doorscannen om de juiste tool te vinden en vervolgens de juiste parameters te bepalen.
Met tool search zijn die GitHub-tools helemaal niet geladen. De agent herkent dat hij commit-data nodig heeft, roept de tool search tool aan met een zoekopdracht als "list commits", krijgt de specifieke tool terug die hij nodig heeft en laadt alleen dat schema. Eén tool. Een paar honderd tokens. En zodra die tool geladen is, blijft hij in context voor eventuele vervolgaanroepen -- geen herhaald laden, geen verspilde tokens.
Ik wil specifiek zijn over hoe dit werkt, want de implementatiedetails zijn belangrijk. De tool search tool accepteert een trefwoord-zoekopdracht of een directe toolnaam. Trefwoordzoeken is fuzzy -- je kunt zoeken op "slack message" en krijgt relevante Slack-tools terug, gerangschikt op relevantie. Directe selectie gebruikt een "select:"-prefix als je precies weet welke tool je wilt. Beide benaderingen laden de gevonden tools onmiddellijk, dus er is geen tweestappenproces van zoeken en daarna apart laden.
Iets wat ik op de harde manier leerde: je moet goed nadenken over welke tools in de "altijd geladen" set blijven en welke worden uitgesteld. Tools die de agent in bijna elk gesprek gebruikt, moeten geladen blijven. Tools die alleen voor specifieke taken nodig zijn, moeten worden uitgesteld. Als je deze verdeling verkeerd maakt, verspilt je agent tijd met zoeken naar veelgebruikte tools of laadt hij nog steeds te veel definities upfront.
Voor mijn operationele agent hield ik kerntools zoals bestandslezen, basis-API-aanroepen en de tool search tool zelf in de altijd-geladen set. Al het andere -- GitHub-operaties, Slack-berichten, kalenderbeheer, Notion-queries -- werd uitgesteld. De agent leerde er op een natuurlijke manier naar te zoeken, en de gespreksflow veranderde nauwelijks vanuit het perspectief van de gebruiker.
Dat loste het probleem van definitie-bloat op. Maar ik had nog steeds het probleem van tussenliggende uitvoer -- al die ruwe JSON van opeenvolgende tool calls die zich ophoopte in de context. Daarvoor had ik de tweede functie nodig.
Programmatisch Tool Calling: Schrijf Code, Geen Aanroepketens
Hier wordt het echt interessant, en eerlijk gezegd een beetje verwarrend als je agents tot nu toe op de traditionele manier hebt gebouwd.
Standaard tool calling werkt zo: het LLM besluit dat het data nodig heeft, maakt een tool call, ontvangt het resultaat, verwerkt het, besluit dat het meer data nodig heeft, maakt nog een tool call, ontvangt dat resultaat, enzovoort. Elke aanroep en elk antwoord leeft in de gesprekcontext. Voor eenvoudige taken met twee of drie tool calls is dit prima. Voor complexe taken die data van tientallen bronnen vereisen, is het een ramp.
Programmatisch tool calling keert het model om. In plaats van individuele tool calls via het gesprek te maken, genereert de agent een codescript -- Python, doorgaans -- dat de volledige workflow programmatisch afhandelt. Het script draait in een sandboxed omgeving, maakt intern alle benodigde tool calls, verwerkt de data met echte codelogica en retourneert alleen het eindresultaat aan de gesprekcontext.
Laat me het verschil tonen met een concreet voorbeeld dat daadwerkelijk plaatsvond in mijn budget-compliance project.
De taak was eenvoudig: controleer of de uitgaven van teamleden hun geautoriseerde budget voor hun functieniveau overschreden. Drie tools waren beschikbaar: haal teamleden op (retourneert een lijst van mensen en hun rollen), haal uitgaven op (retourneert uitgavendata voor een specifieke persoon) en haal budget per niveau op (retourneert het geautoriseerde budgetplafond voor een rol).
Met traditioneel tool calling riep de agent eerst "haal teamleden op" aan. Kreeg een lijst van, zeg, 15 mensen terug. Daarna riep hij "haal uitgaven op" aan voor persoon één. Kreeg hun uitgavendata terug. Riep "haal budget per niveau op" aan voor de rol van persoon één. Vergeleek de cijfers. Ging naar persoon twee. Riep "haal uitgaven op" aan. Riep "haal budget per niveau op" aan. En zo maar door. In totaal 56 tool calls. Elk antwoord -- 15 teamlid-records, 15 uitgavenrapporten, 15 budgetopzoekopdrachten -- zat in de gesprekcontext en at tokens.
Het resultaat? Ongeveer 76.000 tokens verbruikt. En de agent miste één teamlid dat zijn budget had overschreden, waarschijnlijk omdat de aandacht voor eerdere data was afgenomen tegen de tijd dat hij de laatste paar mensen verwerkte. Aandacht in het context window is niet uniform -- modellen besteden minder aandacht aan informatie in het midden van lange contexten, en mijn opeenvolgende tool calls hadden precies de omstandigheden gecreëerd waarbij die zwakte toeslaat.
Met programmatisch tool calling zag dezelfde taak er compleet anders uit. De agent analyseerde wat er bereikt moest worden en genereerde vervolgens een Python-script. Het script riep "haal teamleden op" eenmaal aan, itereerde programmatisch door de lijst, riep "haal uitgaven op" en "haal budget per niveau op" aan voor elke persoon binnen een lus, vergeleek de waarden in code en retourneerde een overzichtelijke samenvatting van wie het budget had overschreden en met hoeveel.
De cijfers vertellen het verhaal. Tokengebruik daalde naar ergens tussen de 45.000 en 58.000 tokens over meerdere runs. Tool calls daalden van 56 naar tussen de 4 en 12. En nauwkeurigheid? Perfect. De code had geen aandacht-degradatieproblemen. Een for-lus verwerkt het vijftiende item even goed als het eerste.
Ik moet hier eerlijk over zijn. De programmatische aanpak was niet elke keer een schone one-shot. Over mijn testruns heen genereerde de agent soms code met bugs bij de eerste poging. Een verkeerde variabelenaam, een ontbrekende null-check, een onjuiste aanname over de datastructuur. De sandbox gaf een fout terug, de agent analyseerde de fout, herstelde de code en probeerde het opnieuw. Deze iteratieve cyclus is onderdeel van het ontwerp, geen fout. Echte softwareontwikkeling werkt precies zo -- schrijven, uitvoeren, debuggen, verfijnen.
Sommige runs kostten twee iteraties, sommige vier. Maar zelfs met de iteratie-overhead was het totale tokengebruik en het aantal tool calls aanzienlijk lager dan bij de traditionele aanpak. En de nauwkeurigheid was consistent beter omdat de vergelijkingslogica in echte code stond in plaats van in het werkgeheugen van het LLM.
Die iteratieve aard is eigenlijk een van de dingen die ik het meest waardeer aan deze aanpak. Het weerspiegelt hoe ik als ontwikkelaar werk. Ik schrijf ook geen perfecte code bij de eerste poging. Ik schrijf iets redelijks, test het, herstel wat kapot is en itereer. Programmatisch tool calling geeft de agent dezelfde workflow, en het blijkt dat LLMs verrassend goed zijn in het debuggen van hun eigen gegenereerde code als ze duidelijke foutmeldingen van de sandbox krijgen.
De Sandbox-architectuur Die Dit Veilig Maakt
Als je beveiligingsinstincten net aangeslagen zijn na het lezen van dat vorige gedeelte, goed. Een AI-agent willekeurige code laten genereren en uitvoeren is het soort ding dat beveiligingsingenieurs 's nachts wakker houdt. De architectuur achter deze functie maakt het haalbaar voor productiegebruik, en het begrijpen ervan is essentieel voordat je iets implementeert.
Het systeem gebruikt sandboxed Docker-containers. Elke code-uitvoering draait in een geïsoleerde container zonder internettoegang. Het gegenereerde Python-script kan de buitenwereld niet bereiken, heeft geen toegang tot het bestandssysteem van de host, kan geen omgevingsvariabelen van de host lezen en kan niets doen wat een kwaadaardig script zou willen doen.
Maar wacht -- het script moet tools aanroepen. Het moet API's bereiken. Hoe doet het dat zonder internettoegang?
Dit is waar de tool bridge om de hoek komt kijken, en dat is een slimme architectuurkeuze. De sandbox heeft toegang tot één enkel eindpunt: de tool bridge-server die op de host draait (of in een sidecar-container). Wanneer het Python-script binnen de sandbox een tool moet aanroepen -- zeg, "haal uitgaven op" voor een teamlid -- stuurt het een verzoek naar de tool bridge. De bridge authenticeert het verzoek via een sessie-ID, verifieert dat de tool call is toegestaan, voert namens de sandbox de daadwerkelijke API-aanroep uit en retourneert het resultaat.
De kritieke beveiligingseigenschap hier is dat de sandboxcode nooit API-credentials, tokens of geheimen te zien krijgt. De tool bridge bewaart al het authenticatiemateriaal. De sandbox kent alleen het bridge-eindpunt en zijn sessie-ID. Als de gegenereerde code op de een of andere manier kwaadaardig zou zijn of zou lekken, worden er geen credentials blootgesteld.
Ik heb mijn sandbox opgezet met de LLM sandbox GitHub-repository, die het grootste deel van de Docker-beheercomplexiteit abstraheert. Het ondersteunt Python kant-en-klaar en regelt de container-levenscyclus, uitvoervastlegging en opschoning. Voor teams die dit in productie draaien, raad ik sterk aan om GVisor bovenop standaard Docker-isolatie toe te voegen. Docker-containers delen de host-kernel, wat betekent dat een kernel-exploit theoretisch uit de sandbox kan ontsnappen. GVisor biedt een extra isolatielaag door systeemaanroepen te onderscheppen via zijn eigen user-space kernel, waardoor dat aanvalsoppervlak aanzienlijk wordt verkleind.
Iets wat ik pas begreep nadat ik dit had gebouwd: de sandbox-aanpak is in principe taalagnostisch. De LLM sandbox-repo ondersteunt meerdere talen, zodat je agent JavaScript, Go of zelfs shellscripts kan genereren afhankelijk van de taak. In de praktijk ben ik bij Python gebleven omdat LLMs de beste Python-code genereren -- ze hebben de meeste Python-trainingsdata gezien, en Python's syntax maakt het voor het model makkelijker om procedurele logica te uiten.
Tools Ontwerpen Die Je Contextbudget Niet Verspillen
Tool search en programmatisch calling lossen twee grote problemen op: definitie-bloat en tussenliggende uitvoer-bloat. Maar er is een derde optimalisatielaag die ik bijna over het hoofd zag, en die maakte een groter verschil dan ik verwachtte: het ontwerp van de tools zelf.
Toen ik de GitHub MCP-server voor het eerst verbond met mijn agent, verbruikte de volledige set van 35 tools zo'n 26.000 tokens aan definities. Dat is absurd. De nieuwere versie van dezelfde MCP-server levert equivalente functionaliteit in ongeveer 4.000 tokens. Het verschil? Compactere beschrijvingen, geconsolideerde parameters en het verwijderen van redundante tool-varianten.
Als je aangepaste tools bouwt voor je agents, telt elke token in je tool-definitie. Schrap beschrijvingen tot de essentiële informatie. Gebruik duidelijke, bondige parameternamen waarvan het model het gebruik kan afleiden. Verwijder velden die de agent zelden gebruikt -- je kunt ze altijd weer toevoegen via tool search als dat nodig is.
En hier is een tip die de nauwkeurigheid van mijn agent bij het verwerken van parameters dramatisch verbeterde: voeg voorbeelden van tool-gebruik toe. Het bieden van één enkel voorbeeld van correct toolgebruik -- met de verwachte waarden voor elke parameter -- verhoogde mijn parameternauwkeurigheid van ongeveer 72% naar circa 90%. Dat is geen kleine verbetering. Dat is het verschil tussen een agent die grotendeels werkt en een die betrouwbaar werkt.
Beschouw tool-gebruiksvoorbeelden als multi-shot prompting voor tool calls. Wanneer het model een voorbeeld ziet zoals {"date": "2026-01-15"}, begrijpt het dat het verwachte formaat jaar-maand-dag is. Zonder dat voorbeeld genereert het misschien "January 15, 2026" of "01/15/2026" of "15-01-2026" -- allemaal geldige datumrepresentaties, maar slechts één komt overeen met wat de API verwacht. Eén enkel voorbeeld elimineert die ambiguïteit bijna volledig.
Ik beschouw tool-definitie-optimalisatie nu als een eersteklas engineeringtaak, geen bijzaak. Voordat ik een tool aan een agent toevoeg, stel ik mezelf de volgende vragen: Hoeveel tokens verbruikt deze definitie? Kan ik de beschrijving korter maken zonder helderheid te verliezen? Heb ik een gebruiksvoorbeeld opgenomen? Kan deze tool worden uitgesteld achter tool search, of moet hij altijd geladen zijn?
Die vragen besparen duizenden tokens per gesprek, wat zich opstapelt tot echt geld over duizenden agent-runs.
Alles Samenvoegen: De Architectuur Die Daadwerkelijk Werkt in Productie
Hier verbind ik de draden, want deze functies zijn geen onafhankelijke schakelaars die je omzet. Ze werken het best als lagen in een doordachte architectuur.
Laag 1: Tool Search voor definitiebeheer. Stel alles uit dat niet in elk gesprek nodig is. Houd je altijd-geladen set klein en gefocust. Laat de agent gespecialiseerde tools op aanvraag ontdekken. Dit lost definitie-bloat op.
Laag 2: Programmatisch tool calling voor complexe workflows. Elke taak die iteratie over data vereist, het vergelijken van waarden van meerdere bronnen, of meer dan vijf opeenvolgende tool calls vereist, is een kandidaat voor programmatische uitvoering. Stuur die workflows naar de sandbox. Dit lost tussenliggende uitvoer-bloat op en verbetert de nauwkeurigheid voor data-intensieve taken.
Laag 3: Tool-gebruiksvoorbeelden voor parameternauwkeurigheid. Elke tool die niet-voor-de-hand-liggende parameterformaten accepteert -- datums, enums, ID's, geneste objecten -- krijgt minimaal één gebruiksvoorbeeld in zijn definitie. Dit pakt de stille nauwkeurigheidsverslechtering aan die de meeste ontwikkelaars niet eens meten.
Toen ik alle drie de lagen op mijn operationele agent toepaste, waren de resultaten opvallend. Gesprekken die vroeger 80.000+ tokens verbruikten, daalden naar het bereik van 35.000-50.000. Tool call-aantallen voor complexe taken gingen van 40-60 naar 5-15. Parameterfouten verdwenen vrijwel. En de agent begon taken correct af te handelen bij de eerste poging waarvoor hij eerder menselijke tussenkomst nodig had.
Maar ik wil duidelijk zijn: dit is niet gratis. Het implementeren van tool search vereist het heroverwegen van je tool-organisatie en het beslissen wat je uitstelt. Programmatisch calling vereist het opzetten en onderhouden van sandbox-infrastructuur. Tool-gebruiksvoorbeelden vereisen testen om de juiste voorbeelden te vinden die de nauwkeurigheid daadwerkelijk verbeteren. Elke laag voegt implementatiecomplexiteit toe.
Mijn aanbeveling is om ze incrementeel toe te voegen. Begin met tool search als je meer dan 15-20 tools hebt. Voeg programmatisch calling toe als je specifieke workflows identificeert waar opeenvolgende tool calls nauwkeurigheidsproblemen of kostenproblemen veroorzaken. Voeg tool-gebruiksvoorbeelden toe aan elke tool waarbij je parameterfouten ziet in je logs.
Wat Ik Fout Deed en Wat Ik Anders Zou Doen
Ik wil drie fouten delen die ik tijdens deze overgang maakte, omdat ik denk dat het fouten zijn die de meeste mensen zullen maken.
Ten eerste stelde ik te agressief uit met tool search. Ik verplaatste bijna alles achter search, inclusief tools die de agent in 80% van de gesprekken gebruikte. Het gevolg was dat de meeste gesprekken begonnen met de agent die onmiddellijk zocht naar tools die hij bijna altijd nodig had. Het werkte nog steeds, maar de zoekstap voegde latentie en een klein aantal extra tokens toe. Ik moest de altijd-geladen set over ongeveer twee weken van het monitoren van daadwerkelijke gebruikspatronen finetunen om de juiste balans te vinden.
Ten tweede nam ik aan dat programmatisch tool calling altijd goedkoper zou zijn. Voor eenvoudige taken met twee of drie tool calls kost de overhead van het genereren van code, het opstarten van een sandbox en het uitvoeren van het script daadwerkelijk meer dan het direct maken van de tool calls. Programmatisch calling schittert wanneer de traditionele aanpak meer dan ongeveer vijf opeenvolgende aanroepen zou vereisen. Onder die drempelwaarde is de traditionele methode eenvoudiger en vaak goedkoper.
Ten derde onderschatte ik hoeveel tijd ik zou besteden aan het schrijven van goede tool-gebruiksvoorbeelden. Een slecht voorbeeld is erger dan geen voorbeeld, omdat het het model kan misleiden. Ik had een tool waarbij ik een voorbeeld met een datum in het formaat "2025-12-01" gaf, maar de API verwachtte eigenlijk Unix-timestamps. Het model volgde trouw mijn voorbeeld en stuurde geformatteerde datums, die de API elke keer afwees. Het testen van je voorbeelden tegen de daadwerkelijke API is niet-onderhandelbaar.
Er is ook een bredere architectuurles die ik nog steeds verwerk. Deze functies duwden me ertoe om agents minder te denken als chatbots die toevallig tools gebruiken en meer als orkestratiesystemen die toevallig LLMs gebruiken. De taak van de agent is niet om een gesprek te voeren -- het is om een taak te decomposseren, de juiste uitvoerstrategie te selecteren voor elke deeltaak en resultaten samen te stellen. Tool search gaat over dynamisch laden van mogelijkheden. Programmatisch calling gaat over efficiënte uitvoering. Als je het zo bekijkt, zijn dit geen Claude-specifieke functies. Het zijn ontwerppatronen die van toepassing zijn op elk agent-framework.
Dit Toepassen Buiten Claude
Ik zei dat dit ontwerppatronen zijn, niet alleen Claude-functies, en ik wil daar specifiek over zijn, want het is belangrijk.
Tool search is fundamenteel een lazy-loading patroon. Als je agents bouwt op LangChain, CrewAI of een aangepast framework, kun je hetzelfde concept implementeren. Onderhoud een register van beschikbare tools met lichtgewicht metadata. Geef je agent een "zoek tools" functie die het register op trefwoord bevraagt. Laad tool-schema's in de prompt alleen wanneer ze zijn geselecteerd. De implementatiedetails verschillen, maar de architectuur is overdraagbaar.
Programmatisch tool calling is een code-generatie-en-uitvoering patroon. Elk agent-framework kan worden uitgebreid om Python-scripts te genereren, ze in een sandbox uit te voeren en resultaten terug te sturen. De Docker-gebaseerde sandbox-aanpak werkt ongeacht welk LLM je gebruikt. De tool bridge-architectuur is model-agnostisch -- het is gewoon een HTTP-server die geauthenticeerde API-aanroepen proxied.
Zelfs tool-gebruiksvoorbeelden zijn overdraagbaar. Elk LLM profiteert van het zien van voorbeeldparameterwaarden. Of je nu Claude, GPT-4, Gemini of een open-source model gebruikt, het opnemen van voorbeelden in je tool-beschrijvingen verbetert de parameternauwkeurigheid. De specifieke verbetering varieert per model, maar de richting is consistent.
Ik ben deze patronen gaan toepassen op een nevenproject dat een mix van Claude en GPT-4o gebruikt afhankelijk van de taakcomplexiteit. De tool search-laag werkt identiek voor beide modellen. De programmatische calling-sandbox geeft niet om welk model de code heeft gegenereerd. Het enige modelspecifieke stuk is het finetunen van de tool-definities voor de specifieke sterke en zwakke punten van elk model in codegeneratie.
Als je vastzit aan een specifiek framework of model, wijs deze technieken dan niet af als "alleen-Anthropic-functies". Extraheer de patronen, pas de implementatie aan en pas ze toe overal waar je agents bouwt.
De Cijfers Na 30 Dagen in Productie
Ik draai de geoptimaliseerde agent-architectuur al ongeveer een maand, en ik wil echte productiecijfers delen omdat ik het zat ben blogposts te lezen die cherry-picked benchmarks tonen.
Het gemiddelde tokengebruik per gesprek daalde 42% vergeleken met de vorige architectuur. Voor de operationele agent specifiek is dat ruwweg €0,027 per gesprek in plaats van €0,045. Bij ongeveer 200 gesprekken per dag over alle gebruikers heen bespaart dat zo'n €3,60/dag of ruwweg €108/maand. Geen levensveranderende bedragen, maar een besparing van 42% die geen enkele verandering in de mogelijkheden van de agent vereiste.
Tool call-fouten -- gevallen waarbij de agent de verkeerde tool aanriep of ongeldige parameters doorgaf -- daalden van ongeveer 8% van de aanroepen naar minder dan 2%. De meeste resterende fouten zijn randgevallen met ambigue toolnamen die ik nog aan het verfijnen ben.
De end-to-end taakafrondings-nauwkeurigheid voor de budget-compliance workflow verbeterde van ruwweg 85% (de traditionele aanpak miste soms randgevallen) naar 97% met programmatisch calling. De faalrate van 3% is bijna volledig afkomstig van de sandbox die tijdslimieten bereikt bij ongewoon grote datasets, wat ik aanpak door de container-timeout te verhogen.
De door gebruikers waargenomen latentie nam licht toe voor eenvoudige vragen -- zo'n 200ms overhead van tool search bij eerste gebruik. Voor complexe vragen die voorheen 30+ opeenvolgende tool calls vereisten, nam de latentie aanzienlijk af omdat de sandbox tool calls sneller uitvoert dan de seriële redeneerloop van het LLM.
Deze cijfers zijn niet hypothetisch. Ze zijn afkomstig van Langfuse-traces op een productiesysteem dat echte gebruikersvragen verwerkt. Je specifieke cijfers zullen afhangen van je tool-aantallen, taakcomplexiteit en gesprekspatronen. Maar de richtingsverbetering zou vergelijkbaar moeten zijn voor iedereen die te maken heeft met tool-count-bloat of opeenvolgende aanroep-overhead.
De Vraag Die Je Moet Blijven Motiveren
Zes maanden geleden dacht ik dat de weg naar betere AI-agents betere prompting was. Schrijf duidelijkere instructies, bied meer context, gebruik geavanceerdere systeem-prompts. En prompting is belangrijk -- ik stel het niet ter discussie. Maar prompting alleen kan architectuurproblemen niet oplossen. Je kunt je niet uit een 13.000-token tool-definitie-overhead promaten. Je kunt je niet naar nauwkeurige dataverwerking promaten wanneer tussenliggende resultaten je context window overspoelen.
De echte winsten liggen in de uitvoeringsarchitectuur: hoe tools laden, hoe data stroomt, hoe code draait en hoe de agent beslist tussen strategieën. Tool search, programmatisch calling en doordacht tool-ontwerp zijn de eerste generatie van deze architecturale tools. Ze zullen niet de laatste zijn.
De vraag die ik mezelf blijf stellen -- en waarmee ik jou uitdaag te zitten -- is deze: Hoe zou jouw agent-architectuur eruit zien als je hem had ontworpen voor 500 tools in plaats van 50? Want dat is waar we naartoe gaan. Het ecosysteem van MCP-servers, API-integraties en aangepaste tools groeit snel. De agents die gedijen zullen niet degenen zijn met de slimste prompts. Het zullen degenen zijn met architecturen die soepel schalen wanneer het tool-aantal verdubbelt, en dan nog eens verdubbelt.
Begin met de drie lagen. Meet je tokengebruik. Houd je nauwkeurigheidsstatistieken in de gaten. En bouw nu het fundament, want de complexiteit gaat alleen maar toenemen.
Laten We Samenwerken
Wil je AI-systemen bouwen, workflows automatiseren of je technische infrastructuur opschalen? Ik help je graag.
- Fiverr (maatwerk builds & integraties): fiverr.com/s/EgxYmWD
- Portfolio: mejba.me
- Ramlit Limited (enterprise oplossingen): ramlit.com
- ColorPark (design & branding): colorpark.io
- xCyberSecurity (beveiligingsdiensten): xcybersecurity.io