AI Agent Tool Use: MCP, CLI, Skills en code execution
Automatische vertaling Dit artikel is automatisch vertaald vanuit de oorspronkelijke Engelse versie.
Artikelupdate
Oorspronkelijk gepubliceerd op 24 maart 2026. Gereviewd en bijgewerkt op 6 september 2026. De update behandelt de herziene MCP-specificatie, programmatic tool calling en nieuwer bewijs over de kosten en beperkingen van tool use.
Een agent heeft een manier nodig om te handelen: een JSON tool call, een MCP-service, een CLI-command of code in een sandbox. Mogelijk heeft de agent ook instructies nodig om dat mechanisme te kiezen en te gebruiken. Skills leveren die instructies. De harness is het gewone programma rond het model: het bouwt prompts, controleert een voorgestelde call, voert een goedgekeurde call uit en bepaalt wanneer de taak klaar is.
Dit derde artikel in de serie voegt de actielaag toe aan de reasoning loops uit Part 1 en de memory uit Part 2. Part 4 onderzoekt de policy check vóór execution, en Part 6 behandelt de harness die zowel de call als die check uitvoert.
Het toolinglandschap veranderde in 2025–2026. MCP, het Model Context Protocol, gaf vendors één gedeelde manier om externe services beschikbaar te maken. Agents die code uitvoeren lieten zien dat een model soms efficiënter een klein programma kan samenstellen dan een lange reeks JSON calls kan uitsturen. Anthropic rapporteerde een 98,7% reductie in tokens voor één Google Drive-to-Salesforce-workflow, en het CodeAct-paper rapporteerde verbeteringen in task success tot 20 procentpunten binnen zijn benchmarkopzet. Die resultaten beschrijven hun taken en harnesses, geen universeel voordeel van code execution.
Ik vergelijk JSON tool calling, MCP, CLI-tools en code execution, en laat vervolgens zien waar Skills daarin passen. Een latere sectie past de ontwerpprincipes van de Agent-Computer Interface (ACI) toe op de Market Analyst Agent, een kleine LangGraph research agent die ik voor Part 1 heb gebouwd en die marktdata ophaalt en een analyst report schrijft.
Zie AI Agent Tool Interfaces voor de korte interfacebeslissing.
Execution surfaces en procedurele guidance
De reasoning loop stelt een call voor. De harness controleert de argumenten en of de call is toegestaan, stuurt die vervolgens naar een tool of sandbox en retourneert het resultaat. JSON-schema’s, MCP-transport, CLI-wrappers en code runners kunnen inputs beperken, maar geen daarvan bepaalt of de gevraagde actie is toegestaan. Skills leveren instructies voor dat pad. Deze execution surfaces maken verschillende afwegingen tussen tokenkosten, flexibiliteit en enforcement.
1. JSON tool calling: de baseline
Het oorspronkelijke patroon: je definieert tool-schema’s als JSON, de LLM emit gestructureerde function calls en je code voert die uit. Het patroon is goed begrepen en werkt prima voor kleine toolsets.
# Schema cost depends on its text, structure, and the model tokenizer
tools = [
{
"name": "get_stock_price",
"description": "Get the current stock price for a ticker symbol",
"input_schema": {
"type": "object",
"properties": {
"ticker": {"type": "string", "description": "Stock ticker (e.g., NVDA)"}
},
"required": ["ticker"]
}
}
]
Tel de tokens in je daadwerkelijke schema’s. De kosten hangen af van hun lengte en van het aantal schema’s dat de host laadt; een compacte price lookup en een diep genest API-contract zijn geen equivalente eenheden. Deferred discovery kan voorkomen dat het volledige registry wordt geladen.
2. MCP voor gedeelde integraties
MCP is de standaard waar de meeste vendors naartoe zijn geconvergeerd. Een MCP-server is een process dat via een gedefinieerd wire protocol een lijst tools adverteert — stdio voor een lokaal process, HTTP voor een remote process. Je agent draait een MCP-client die verbinding maakt, de server vraagt welke tools beschikbaar zijn en de calls van het model doorstuurt, zodat dezelfde server werkt met elke client die het protocol spreekt. Anthropic schonk het protocol in december 2025 aan de Linux Foundation, onder de Agentic AI Foundation die het samen met OpenAI en Block oprichtte. Google, Microsoft en AWS steunen de foundation als platinum members. OpenAI voegde MCP-support toe aan zijn Responses API. Volgens Anthropic’s aankondiging van de donatie in december 2025 telde het ecosysteem meer dan 10.000 actieve publieke MCP-servers en meer dan 97 miljoen maandelijkse SDK-downloads over de Python- en TypeScript-SDKs.
MCP past bij SaaS-integratie over meerdere vendors heen (Figma, Notion, Salesforce), services zonder CLI-equivalenten en omgevingen die OAuth orchestration nodig hebben. De waarde zit in een gedeelde discovery- en transportlaag. Governance blijft afhankelijk van de authentication-, authorization-, logging- en deployment-controls van de server.
De protocolversie is nu een praktische migratiebeslissing. De revisie van 28-07-2026 verandert gedrag waarvan oudere tutorials uitgaan:
| Wijziging | Wat je in een integratie moet controleren |
|---|---|
| Stateless requests vervangen de initialization handshake en transport sessions | Stuur protocolmetadata per request; gebruik server/discover om support te inspecteren. Verifieer de versies van zowel client als server. |
Multi Round-Trip Requests retourneren InputRequiredResult | Verwerk requests voor aanvullende input en retry daarna de oorspronkelijke operatie met de responses en continuation state. |
| Tasks verhuizen naar de officiële tasks extension | Controleer support voor de extension in plaats van uit te gaan van de oudere experimentele core task API. |
| SSE resumability wordt verwijderd | Een onderbroken response stream vereist een nieuwe request. Voorkom duplicate business effects onafhankelijk hiervan. |
Dezelfde revisie markeert Roots, Sampling, Logging en OAuth Dynamic Client Registration als deprecated; deprecated betekent niet onmiddellijk verwijderd. Huidige client registration geeft de voorkeur aan Client ID Metadata Documents. Bestaande integraties kunnen nog een oudere revisie gebruiken, dus inspecteer de geïnstalleerde SDK en het servercontract voordat je een nieuwe feature adopteert.
De production story is rommeliger dan de headline numbers suggereren.
Het Vulnerable MCP Project verzamelt reports over prompt injection, input validation, authentication en network controls. Zo’n verzameling helpt bij het identificeren van testcases; zonder exposure denominator kan ze MCP niet rangschikken ten opzichte van shell- of directe API-calls.
Tool poisoning is de attack class waar ik me het meest zorgen over maak. Invariant Labs liet zien dat poisoned MCP-tools data kunnen exfiltreren, zelfs wanneer ze nooit worden aangeroepen. Het lezen van de metadata van de tool door het model is al voldoende om de aanval te triggeren. MCPTox-benchmarks die 20 LLM agents tegen 45 MCP-servers uit de praktijk testten, rapporteerden 72,8% gemiddelde attack success voor o1-mini binnen hun tool-poisoning-opzet. Dat is het benchmarkresultaat van één model, geen gemiddelde over de 20 agents en geen incident rate uit de praktijk.
Token overhead is het operationele probleem. Een team dat MCP-servers voor GitHub, Slack en Sentry draaide (~40 tools in totaal) vond 55.000 tokens aan schema-definities die werden geïnjecteerd voordat een gebruiker iets vroeg. Een ander team rapporteerde dat 143.000 van de 200.000 beschikbare tokens (72%) alleen al door tool-definities werd gebruikt.
Anthropic’s Tool Search Tool-report rapporteerde context-endpoints van ongeveer 77.000 tokens voordat het werk begon en 8.700 na deferred discovery, bij ongeveer 72.000 tokens aan tool-definities in de traditionele setup. Er worden slechts drie tot vijf tools geladen die een request nodig heeft, maar dit voegt een discovery-stap vóór invocation toe; voor kleine, compacte toolsets waarvan de tools in elke session vaak worden gebruikt, is dit minder nuttig.
3. Skills verpakken expertise, niet execution
Agent skills zijn een open format voor het verpakken van instructies en ondersteunende bestanden. Tools leveren capabilities (wat agents kunnen doen), en Skills leveren expertise (wat agents weten over hoe ze complexe taken moeten uitvoeren).
Het SKILL.md-format definieert een skill als een markdown-bestand met YAML-frontmatter. De open standaard vereist alleen name en description; het voorbeeld hieronder gebruikt ook twee Claude Code-extensies, argument-hint en user-invocable, plus de $0-placeholder voor positionele argumenten:
---
name: deploy
description: Deploy the application to production
argument-hint: "[environment]"
user-invocable: true
---
Deploy the application to the $0 environment (default: staging).
Steps:
1. Run the test suite
2. Build the production bundle
3. Deploy using the deploy script
4. Verify the deployment health check
Skills gebruiken progressive disclosure. Bij startup krijgt de agent ongeveer 100 tokens aan name en description. De volledige SKILL.md wordt pas geladen wanneer de agent de skill nodig heeft; daarna worden gerefereerde scripts, documenten of assets naar behoefte geladen. Die startup-kost is veel kleiner dan de ongeveer 55.000 tokens die circa 40 MCP-tools kunnen verbruiken voordat reasoning begint. Een actieve skill voegt nog steeds zijn instructies en resources toe aan de context.
Gebruik Skills voor domeinkennis, multi-step procedures en terugkerend werk, zoals database migrations of payment integrations. Ze passen bij taken waarin de agent instructies nodig heeft over hoe een bestaande capability moet worden gebruikt.
4. CLI en shell-tools
CLI-interfaces kunnen veel goedkoper zijn in context wanneer het model het command al kent. Scalekit rapporteerde over 75 runs een verschil van 4–32x in tokens tussen zijn CLI- en MCP-paden. Die case study meet zijn tools en taken; ze vervangt geen vergelijking met je eigen tool-definities en command-output.
Goed gedocumenteerde commands zoals git, docker, kubectl, gh, curl en jq hebben vaak weinig inleidende schema-tekst nodig. Minder gebruikelijke of interne CLIs hebben nog steeds discoverable help, voorbeelden en stabiele machine-readable output nodig.
Ugo Enyioha’s guide “Writing CLI Tools That AI Agents Actually Want to Use” legde acht ontwerpregels vast:
- Structured output is verplicht — support
--json - Exit codes zijn control flow — gebruik verschillende codes voor verschillende error types
- Commands moeten idempotent zijn
- Self-documenting
--helpmet realistische voorbeelden - Ontwerp voor composability —
--quietvoor bare values, stdin-support - Bied
--dry-runen--yesflags - Ondersteun version introspection
- Verwerk auth via environment variables
CLI heeft geen protocol-level discovery. JSON tool calling kan getypeerde schema’s meesturen, terwijl MCP tool discovery en voor HTTP-transports een authorization model standaardiseert. Geen van beide levert op zichzelf governance: de host, server of harness moet policy afdwingen en de calls registreren die voor auditing nodig zijn. Een praktische default is CLI voor development en lokale operations, en MCP voor gedeelde integratie met externe services wanneer cross-client discovery of OAuth orchestration de server overhead waard is.
5. Code execution voor multi-step werk
Dit is de verandering in agent tooling die ik het meest ingrijpend vind. In plaats van gestructureerde JSON te emitten om vooraf gedefinieerde functies één voor één aan te roepen, schrijft de agent een Python- of bash-script. Het script roept meerdere tools aan, verwerkt resultaten met loops en conditionals en retourneert alleen de uiteindelijke samenvatting naar de modelcontext.
Anthropic introduceerde Programmatic Tool Calling (PTC) in beta. De huidige API-guide gebruikt de reguliere Messages API met code_execution_20260120 of later; de oorspronkelijke beta-launch is historische context. De academische basis is het CodeAct-paper (Wang et al., ICML 2024), dat tests uitvoerde met 17 LLMs en vond dat code actions tot 20 procentpunten hogere task success en 30% minder actions opleverden dan JSON-alternatieven.
Drie case studies van first-party vendors laten zien waar dit patroon kan helpen: Vercel en Cloudflare hieronder, gevolgd door Anthropic’s expense-analysis-voorbeeld. Behandel ze als vendor evidence en voer de vergelijking opnieuw uit voor je eigen taken.
-
Vercel herbouwde d0, zijn natural-language-to-SQL data agent. Het oude codevoorbeeld noemt 17 tools; het nieuwe codevoorbeeld stelt
ExecuteCommandenExecuteSQLbeschikbaar. Vercel beschrijft het redesign als het verwijderen van 80% van zijn tools, maar die uitspraak is Vercels headline en geen percentage dat uit de genoemde tools in de voorbeelden volgt. Over vijf representatieve queries rapporteert Vercel dat task success steeg van 4/5 naar 5/5, de gemiddelde execution time 3,5x daalde (274,8 s naar 77,4 s) en het gemiddelde tokengebruik 37% daalde (~102k naar ~61k). Hun formulering: “The best agents might be the ones with the fewest tools.” -
Cloudflare ontwikkelde “Code Mode,” waarmee agents TypeScript kunnen schrijven om hun API aan te roepen in plaats van tool-schema’s te definiëren, wat de context overhead verlaagt. Hun redenering: “LLMs have an enormous amount of real-world TypeScript in their training set, but only a small set of contrived examples of tool calls.”
Dit is het patroon uit Anthropic’s PTC-documentatie. In Anthropic’s sequential expense-analysis-illustratie vereist traditioneel tool calling meer dan 20 afzonderlijke inference passes, waarbij intermediate data door de context stroomt. Na de team lookup kan een host die parallel tool calls ondersteunt de onafhankelijke expense requests batchen; de 20+-waarde maakt dat niet onmogelijk. Anthropic rapporteert dat gegenereerde code die dezelfde vraag beantwoordt, wat de context bereikt terugbrengt van 200 KB aan ruwe expense rows — meer dan 2.000 line items — naar 1 KB aan resultaten. Het onderstaande script illustreert die control flow met custom async Python adapters: deze accepteren positionele argumenten en retourneren gedecodeerde lijsten en dictionaries. Het is niet het native PTC-wrappercontract.
# Custom decoded Python adapters, not native Claude PTC wrappers.
import asyncio
import json
async def main() -> None:
team = await get_team_members("engineering")
levels = list(set(member["level"] for member in team))
budgets = dict(zip(
levels,
await asyncio.gather(*(get_budget_by_level(level) for level in levels)),
))
expenses = await asyncio.gather(
*(get_expenses(member["id"], "Q3") for member in team)
)
over_budget = []
for member, employee_expenses in zip(team, expenses):
total = sum(expense["amount"] for expense in employee_expenses)
limit = budgets[member["level"]]["travel_limit"]
if total > limit:
over_budget.append(
{"name": member["name"], "spent": total, "limit": limit}
)
# Only this final summary returns to the LLM context
print(json.dumps(over_budget))
asyncio.run(main())
Gebruik voor native Claude PTC-wrappers één argument-dictionary per tool, decodeer de geretourneerde JSON-string en gebruik top-level await in de managed execution environment in plaats van een event loop te starten met asyncio.run. Het custom-adaptervoorbeeld hierboven gaat uit van een gewone Python-script runtime; het is ook geen drop-in native MCP-connectorvoorbeeld. De huidige PTC API-constraints sluiten strict: true-tools en native MCP connector tools uit van programmatic calling en beperken recursive schemas. Een custom code-to-MCP bridge is een afzonderlijke integratie. allowed_callers beschrijft hoe Claude een tool aanroept; het is geen authorization boundary. De host moet elke geretourneerde invocation valideren, inclusief een onverwachte directe call.
De LLM ziet alleen de uiteindelijke JSON-samenvatting, niet de duizenden expense line items die in de sandbox zijn verwerkt. De besparing is niet specifiek voor expense reports: Anthropic’s afzonderlijke write-up over code execution noemt het scherpste getal bij dit patroon, een Google Drive-to-Salesforce-workflow die daalde van ~150.000 tokens naar ~2.000, een reductie van 98,7%.
De huidige PTC-guide rapporteert ook een counterexample: op de airline-, retail- en telecomtaken van tau2-bench veranderde PTC de scores niet en kostte het ongeveer 8% meer. Op een afzonderlijke benchmark voor project management met 75 tools verlaagde het de billed input tokens met ongeveer 38% zonder de accuracy te veranderen. Deze interne evaluaties noemen alleen een production Claude-model, geen exact ID. Kleine sequential workflows besparen mogelijk niet genoeg om de overhead van container en code generation te compenseren.
Token efficiency is een mogelijke winst. Loops en conditionals kosten niets extra’s, en code execution kan fouten afhandelen met expliciete handlers in plaats van het model over failures in natuurlijke taal te laten redeneren. Een code-executionpad kan gevoelige intermediate data buiten de modelcontext houden, maar dat is geen confidentiality: isolation, egress controls, scoped credentials en logging moeten afzonderlijk worden afgedwongen.
Wanneer JSON tool calling nog steeds logisch is: single atomic operations, omgevingen zonder sandboxing-infrastructure, kleinere modellen met zwakke code generation of audit requirements waarbij elke afzonderlijke tool invocation moet worden gelogd.
Vergelijking van AI-agent tool execution
| Dimensie | JSON Tool Calling | MCP | Skills (SKILL.md) | CLI/Bash | Code Execution (PTC) |
|---|---|---|---|---|---|
| Het meest geschikt voor | Simple, single actions | Cross-vendor SaaS | Herbruikbare procedures die een surface selecteren | Dev workflows, local ops | Multi-step orchestration |
| Token overhead | Geladen schema-tokens | Geladen of deferred schema’s | ~100-token discovery-metadata; actieve instructions/resources voegen context toe | Help-, command- en output-tokens | Entry-schema’s, code en output |
| Task evidence | Baseline in geciteerde studies | Afhankelijk van server en taak | N/A (expertiselaag) | Meten op CLI-native taken | CodeAct: tot +20 punten |
| Composability | Door harness aangestuurd; dependent calls voegen turns toe | Door harness aangestuurd; dependent calls voegen turns toe | Begeleidt een onderliggende surface | Hoog (pipes, chaining) | Zeer hoog (flow/filtering aan de codekant) |
| Security surface | Argument- en effect authority | Server identity en tool authority | Afhankelijk van host/resources | Shell, paths, credentials | Code, data access en egress |
| Setup complexity | Laag | Medium (server deployment) | Laag voor de instructies; afhankelijk van de surface | Zeer laag (bestaande CLIs) | Medium (sandbox infra) |
| Latency voor dependent calls | Gewoonlijk 1 modelturn/call | Gewoonlijk 1 modelturn + transport/call | Geërfd van de surface | Gewoonlijk 1 modelturn/call | 1 script-generation turn; host voert de flow uit |
| Debugging | Goed (structured I/O) | Matig (transportlaag) | Goed (leesbare markdown) | Uitstekend (zichtbaar) | Goed (leesbare code) |
JSON tool calling, MCP, CLI en code execution zijn execution surfaces. Skills zijn instructies die een van die surfaces aansturen; hun latency, context en setup hangen dus af van het geselecteerde mechanisme. “Meta-tools” betekent de enkele generieke entry points die een code-executing agent nodig heeft — bijvoorbeeld Vercels ExecuteCommand en ExecuteSQL — in plaats van één schema voor elke operatie. De rijen over composability en latency beschrijven calls waarvan latere argumenten afhankelijk zijn van eerdere resultaten. JSON tool calling en MCP kunnen onafhankelijke calls tegelijk uitvoeren, maar dependent calls vereisen meestal een nieuwe modelturn. PTC verplaatst die dependent control flow en filtering naar een script en retourneert vervolgens een samenvatting naar het model. De token- en task-success-cellen vatten geciteerde voorbeelden samen, geen gecontroleerde benchmark over alle vijf kolommen.
De Agent-Computer Interface (ACI) voor AI-agenttools
De term “Agent-Computer Interface” (ACI) werd bedacht door John Yang, Carlos E. Jimenez en collega’s aan Princeton in hun SWE-agent-paper (NeurIPS 2024). De kwaliteit van human interfaces heeft een volledige discipline die eraan is gewijd — human-computer interaction, oftewel HCI. Het paper stelt dat language-model agents dezelfde behandeling verdienen: ze zijn “a new category of end users with their own needs and abilities, and would benefit from specially-built interfaces.”
Hun ablation results geven daar een getal aan. Met hetzelfde GPT-4 Turbo-basemodel bereikte de SWE-bench Lite-ablation van het paper 18,0% met SWE-agent’s volledige ACI op 300 taken, tegenover 7,3% voor de shell-only-conditie zonder worked demonstration en 11,0% met één demonstration. De vergelijking laat zien dat de interface- en demonstrationcondities de prestaties in deze setup wezenlijk veranderden; ze isoleert interface design niet van elk ander verschil en laat niet zien dat het model geen werk deed. Binnen dezelfde interface-ablation verhoogde linting de edit-conditie van 15,0% naar 18,0%; over de volledige SWE-bench-testset raakte 51,7% van SWE-agent’s runs minstens één edit die de linter afwees voordat die kon worden doorgegeven.
Anthropic adopteerde ACI als een fundamenteel concept in hun guide “Building Effective Agents”, waar het als een van drie core principles wordt genoemd: “Carefully craft your agent-computer interface through thorough tool documentation and testing.” Hun praktische advies: “One rule of thumb is to think about how much effort goes into human-computer interfaces, and plan to invest just as much effort in creating good agent-computer interfaces.”
Vier ACI-principes in de praktijk
1. Acties moeten eenvoudig en gemakkelijk te begrijpen zijn. De meest voorkomende fout is het één-op-één wrappen van API-endpoints. Implementeer in plaats van list_users, list_events en create_event één schedule_event die availability vindt en in één call plant. Implementeer in plaats van read_logs een search_logs die alleen de relevante regels met context retourneert.
2. Acties moeten compact en efficiënt zijn. Consolideer belangrijke operations in zo weinig mogelijk acties. In de Market Analyst Agent combineer ik het ophalen van prijzen met basic metrics in één get_stock_snapshot-tool, in plaats van afzonderlijke calls voor price, volume, market cap en PE ratio te vereisen.
3. Feedback uit de omgeving moet informatief maar beknopt zijn. Vermijd raw HTML of volledige API-payloads. Vertaal cryptische IDs naar semantic names. Anthropic’s testing voegde een response_format-enum toe, zodat de agent een concise (~72 tokens) of detailed (~206 tokens) response kan vragen, ongeveer een verschil van 3x in tokenkosten.
4. Validation moet error propagation beperken. Automatische error detection helpt agents om fouten snel te herkennen en te corrigeren. In SWE-agent weigert een custom file editor met geïntegreerde linting automatisch syntax errors — de validation step achter de 51,7%-waarde hierboven. Dit is validation op de inputs en outputs van een tool, niet de content filtering rond een model call die de guardrail-products in Part 4 uitvoeren; hetzelfde woord wordt voor beide gebruikt. Ik pas hetzelfde principe toe in de Market Analyst Agent door tool-argumenten vóór execution met Pydantic-schema’s te valideren:
from pydantic import BaseModel, Field, field_validator
from market_analyst.utils import normalize_ticker
class StockQuery(BaseModel):
"""Validated input for stock queries.
Pydantic catches malformed tickers before the API call,
preventing error propagation through the reasoning loop.
"""
ticker: str = Field(description="Stock ticker symbol (e.g., NVDA)")
@field_validator("ticker")
@classmethod
def validate_ticker(cls, v: str) -> str:
return normalize_ticker(v)
class StockHistoryQuery(StockQuery):
"""Validated input for price history queries."""
period: str = Field(default="1mo", description="Time period: 1d, 5d, 1mo, 3mo, 6mo, 1y")
@field_validator("period")
@classmethod
def validate_period(cls, v: str) -> str:
valid = {"1d", "5d", "1mo", "3mo", "6mo", "1y"}
if v not in valid:
raise ValueError(f"Invalid period: {v}. Must be one of {valid}")
return v
De shared normalizer trimt de waarde en maakt die uppercase; vervolgens accepteert hij ticker digits en dotted of hyphenated suffixes zoals BRK.B en BF-B; StockHistoryQuery, niet StockQuery, beheert period.
AI-agent tool design patterns die werken
Anthropic’s guide “Writing effective tools for agents” beschrijft tools als “a new kind of software which reflects a contract between deterministic systems and non-deterministic agents.”
Behandel tool descriptions als prompt engineering
Descriptions moeten minstens drie of vier zinnen bevatten, waarin staat wanneer je de tool gebruikt, welke parameters vereist of optioneel zijn, wat het outputformat is en welke edge cases er zijn. Anthropic rapporteert dat de keuze tussen prefix- en suffix-based namespacing (asana_search tegenover search_asana) “non-trivial effects” had op zijn eigen tool-use-evaluaties. Het zegt niet welke aanpak wint, dus test beide op je toolset in plaats van prefixes als vanzelfsprekend te nemen. Anthropic voerde de transcripts van zijn evaluation agents ook terug aan Claude Code en liet het de tools herschrijven. Op held-out testsets vond die loop verdere verbeteringen “even beyond what we achieved with ‘expert’ tool implementations” — ongeacht of die tools handmatig door zijn researchers of door Claude waren geschreven.
# Bad: vague, no context for when to use
tools = [{
"name": "search",
"description": "Search for items",
}]
# Good: specific, with input examples and edge cases
tools = [{
"name": "search_news",
"description": (
"Search for recent news articles about a specific stock or company. "
"Use this tool when the user asks about recent events, earnings, "
"announcements, or market-moving news for a specific ticker. "
"Returns up to 10 articles sorted by relevance. "
"For company competitors rather than news, use search_competitors instead."
),
"input_schema": {
"type": "object",
"properties": {
"query": {
"type": "string",
"description": "Search query. Examples: 'NVDA earnings Q3 2025', 'Tesla delivery numbers'"
},
"max_results": {
"type": "integer",
"description": "Max articles to return (1-10, default 5)",
"default": 5
}
},
"required": ["query"]
}
}]
Anthropic’s interne testing liet zien dat het toevoegen van een input_examples-field de accuracy op complexe parameter handling verhoogde van 72% naar 90%.
Retourneer high-signal, machine-readable output
Gebruik semantic labels in plaats van low-level identifiers (uuid, mime_type) in de default response. Behoud een ID wanneer een latere tool die nodig heeft, of bied een detailed response aan waarin die ID staat. Een search result voor Jane kan bijvoorbeeld compact zijn om te lezen, terwijl een detailed result de ID bevat die send_message nodig heeft. Structureer de response zo dat de agent erover kan redeneren zonder boilerplate te hoeven parsen:
# Bad: raw API response dumped to agent
def get_stock_snapshot(ticker: str) -> dict:
response = api.get(f"/v1/quotes/{ticker}")
return response.json() # 500+ tokens of nested JSON
# Good: high-signal summary the agent can immediately reason about
def get_stock_snapshot(ticker: str) -> dict:
data = api.get(f"/v1/quotes/{ticker}").json()
return {
"ticker": ticker,
"price": data["regularMarketPrice"],
"change_pct": round(data["regularMarketChangePercent"], 2),
"volume": data["regularMarketVolume"],
"market_cap_b": round(data["marketCap"] / 1e9, 1),
"pe_ratio": data.get("trailingPE"),
"summary": f"{ticker} at ${data['regularMarketPrice']:.2f} "
f"({'up' if data['regularMarketChangePercent'] > 0 else 'down'} "
f"{abs(data['regularMarketChangePercent']):.1f}%)"
}
Retourneer errors waarop de loop kan handelen
Error handling heeft vier afzonderlijke mechanismen nodig, omdat ze verschillende failure classes afhandelen:
- Retry met exponential backoff voor transient errors
- Model fallback chains voor provider outages
- Error classification routing — transient errors worden opnieuw geprobeerd, LLM-recoverable errors gaan met context terug naar de agent en human-required errors worden geëscaleerd
- Checkpoint recovery voor crash survival
Anthropic’s “Writing effective tools for agents” bepleit duidelijke tool errors en evaluation-driven tool design, maar geeft geen universeel getal voor wat deze vier mechanismen herstellen. Meet recovery rate, retries en escalations op je eigen task suite.
import httpx
from tenacity import retry, retry_if_exception, stop_after_attempt, wait_exponential
def is_transient_error(error: BaseException) -> bool:
if isinstance(error, (httpx.TimeoutException, httpx.NetworkError)):
return True
if isinstance(error, httpx.HTTPStatusError):
return error.response.status_code == 429 or 500 <= error.response.status_code < 600
return False
@retry(
retry=retry_if_exception(is_transient_error),
stop=stop_after_attempt(3),
wait=wait_exponential(multiplier=1, min=2, max=10),
reraise=True,
)
def call_stock_api(ticker: str) -> dict:
"""Fetch stock data with automatic retry on transient failures.
Mechanism 1 of the four above: exponential backoff for rate limits
and network blips.
This only retries transient transport failures. If attempts are exhausted,
Tenacity re-raises the original httpx exception.
"""
response = httpx.get(
f"https://api.example.com/v1/quotes/{ticker}",
timeout=10.0,
)
response.raise_for_status()
return response.json()
De caller of harness heeft nog steeds de volgende stap nodig: maak van die exception een stabiel resultaat dat aangeeft welke operation faalde, of er een retry moet komen en wat er daarna moet gebeuren. Een non-retryable 4xx slaat deze decorator over en vereist dezelfde behandeling. Een request opnieuw proberen classificeert de error niet en herstelt geen checkpoint.
De patronen toepassen op de Market Analyst Agent
De Market Analyst Agent uit Part 1 maakt het effect van de interface zichtbaar.
Tool consolidation
De oorspronkelijke toolmodules definieerden get_stock_price, get_company_metrics, get_price_history, twee search tools en execute_trade. Voor een basic analysis moest de agent zowel de price- als de metrics-call kiezen; market cap en P/E waren velden van get_company_metrics, geen standalone tools. De source van vóór consolidation laat die eerdere surface zien.
Ik heb de market-data-surface hervormd tot 5 high-level tools, volgens het ACI-principe van compacte, efficiënte acties. De ReAct tool list van de repo bevat daarnaast nog vier andere — een skill loader, twee CLI-wrappers en een restricted in-process Python evaluator (een AST-allowlist, geen sandbox; Part 4 behandelt dit) — die drie van de vijf bovenstaande modaliteiten afdekken. MCP verschijnt als sidecar en niet als tool in deze lijst:
| Voorheen (oorspronkelijke tools) | Daarna (market-data tools) | Waarom |
|---|---|---|
get_stock_price + get_company_metrics | get_stock_snapshot | Eén call retourneert de basic price- en valuation-snapshot |
get_price_history | get_price_history | Behouden met gevalideerde periods en average-volume summary |
search_news | search_news | Retourneert structured items met geëxtraheerde key points |
search_competitors | search_competitors | Behoudt de competitor-focused search action |
| Geen financial-statement-tool | get_financials | Selecteert income-, balance-sheet- of cash-flow-data via een parameter |
Hierdoor komen price en valuation samen in één task-shaped definition en worden financial statements als expliciete action toegevoegd. Of dit de tool selection verbetert, moet worden getest met representatieve requests en traces.
Structured outputs voor tool results
De stock- en news-tools retourneren Pydantic-gevalideerde responses. De CLI- en code-execution-wrappers retourneren str, dus de onderstaande modellen beschrijven de structured tool results en niet elke wrapper in de repository:
from pydantic import BaseModel
class StockSnapshot(BaseModel):
"""Structured tool response — the agent never sees raw API noise."""
ticker: str
price: float
change_pct: float
volume: int
market_cap_b: float
pe_ratio: float | None
summary: str # Human-readable one-liner for direct use in reports
class NewsItem(BaseModel):
"""One news item pre-processed for agent consumption."""
headline: str
source: str
date: str
relevance_score: float # Pre-ranked so the agent doesn't waste tokens sorting
key_points: list[str] # Extracted by the tool, not the agent
class NewsSearchResult(BaseModel):
query: str
results: list[NewsItem]
summary: str
Het veld summary geeft de agent een direct bruikbare string voor een report. NewsItem.key_points besparen het model het parsen van article bodies. Als een latere action een ID nodig heeft, behoud die dan in de detailed response of bied concise en detailed modes aan; verwijder de ID niet overal.
Trade-offs en overwegingen
Naast de caveats die specifiek zijn voor elk van de bovenstaande patterns, beïnvloeden enkele cross-cutting concerns de keuze:
-
Operationele kosten variëren per dimensie. Code execution bespaart tokens, maar voegt sandbox cold-start-latency toe. MCP bespaart development time voor SaaS-integrations, maar voegt server deployment overhead toe. CLI is gratis om te starten, maar moeilijker op schaal te governen. Optimaliseer voor je werkelijke bottleneck, of dat nu tokenkosten, latency of operationele complexiteit is.
-
Team skills doen ertoe. Code execution veronderstelt dat je agents (en de modellen erachter) betrouwbare Python of TypeScript kunnen genereren. CLI veronderstelt bekendheid met Unix-conventies. MCP vereist begrip van transportprotocols en OAuth-flows. Stem de modaliteit af op de sterke punten van je team.
-
Tool consolidation kan te ver gaan. Als één tool ongerelateerde modes en arguments verzamelt, krijgt de agent binnen het schema een ander selection problem. Gebruik tool-selection- en task-success-evaluaties om de juiste surface voor je workload te vinden.
-
Skills zijn prompt-based en niet enforced. Een skill bevat instructies die de agent zou moeten volgen, geen guardrails die de agent moet volgen. Een skill bundle kan willekeurige bestanden en executable scripts bevatten; vertrouw daarom de bron, review de bundle en laat de host permissions afdwingen voor elke resource die de agent kan lezen, wijzigen of uitvoeren. Combineer Skills bij kritieke workflows met deterministic validation.
-
Audit requirements beïnvloeden de keuze. Structured MCP- en JSON-calls zijn handige events om te loggen, maar geen van beide protocollen creëert out of the box een volledige audit trail. De host, server of harness moet invocations en results registreren en vervolgens authorization, policy, retention en review afdwingen. Code execution heeft dezelfde instrumentation rond de sandbox nodig; het script en de output alleen vormen geen compliance record.
Drie richtingen voor AI-agent tooling op schaal
De eerste is tool RAG voor scaling. Voordat het model een tool kiest, haal je de enkele tool descriptions op die bij de request passen en laat je het model uit die subset kiezen in plaats van uit het volledige registry. In de benchmarktaken en MCP-stresstest van RAG-MCP was de baseline-tool-selection-accuracy 13,62%; retrieval verhoogde dit naar 43,13%, een verbetering van 3,2x, en verlaagde de prompt-tokens van 2.133,84 naar 1.084 (ongeveer 49,2%). Het abstract van het paper zegt “over 50%”, en de beschrijvingen van generator en evaluator verschillen per sectie; die inconsistenties beperken de interpretatie. Het resultaat is evidence voor die evaluation setup, geen universele rate voor naive selection wanneer toolsets groeien.
De tweede richting is agents die hun eigen tools maken. Het LATM-framework (“LLMs As Tool Makers”) introduceerde een two-phase paradigm waarin een krachtige LLM herbruikbare Python-functies maakt en een lightweight LLM die gebruikt. Op de ToolMaker-benchmark met 15 taken rond papers met publieke code repositories, aangeleverd als GitHub-URLs en korte task descriptions, implementeerde het 12 van de 15 taken correct; de benchmark bevat in totaal meer dan 100 tests. Die kleine repository-task-benchmark bewijst geen production reliability. Beide wijzen voorbij tool use naar tool creation, en vervolgens naar het beheren van een library met gegenereerde tools.
De derde richting is de dual-protocol stack van A2A + MCP. Google droeg A2A in juni 2025 over aan de Linux Foundation. De documentatie van het A2A-protocol scheidt hun verantwoordelijkheden: MCP verbindt een agent met tools en resources, terwijl A2A onafhankelijke agents elkaar laat discoveren, interactions laat onderhandelen, gedeelde tasks laat beheren en werk laat delegeren.
Vergelijk interfaces op identieke taken en toegestane operations. Registreer discovery-tokens, cached en uncached input, execution output, retries, latency en final-state success. Test zowel gemiste discovery als tokenbesparingen; tel bij gegenereerde programma’s syntax errors, runtime errors en partial completion.
Belangrijkste conclusies
- Kies de execution surface op basis van de action: JSON calls voor kleine getypeerde operations, MCP voor gedeelde services, CLI voor bestaande commands en sandboxed code voor lokale compositie. Gebruik Skills om te documenteren hoe je die surface kiest en gebruikt.
- Houd benchmarkcondities gekoppeld aan het resultaat. CodeAct, Anthropic, Vercel, Cloudflare, Apideck en Scalekit maten verschillende modellen, taken, tools en harnesses.
- ACI-kwaliteit blijft relevant ondanks protocolwijzigingen. Duidelijke acties, compacte feedback, validation en bruikbare errors helpen elke modaliteit.
- Consolideer overlappende tools alleen wanneer evaluaties laten zien dat de kleinere surface de selection of task success verbetert.
- Security beweegt mee met execution power. Shell- en code-interfaces hebben sandboxing nodig; MCP heeft scoped identity en server policy nodig; Skills blijven instructies en geen enforcement.
De volgende laag is policy
Part 4, AI Agent Security, behandelt de harness-check tussen een voorgestelde tool call en execution. Part 5 plaatst de tool en zijn sandbox in een recoverable runtime. Part 6 voegt een contract toe dat het model niet ziet: een effect category, retry rule en structured result die een acceptance check kan lezen zonder prose te parsen.
Referenties
Papers
- Executable Code Actions Elicit Better LLM Agents (CodeAct) — Wang et al., ICML 2024 — Code-based actions rapporteren in de taken van het paper tot 20 procentpunten hogere task success
- SWE-agent: Agent-Computer Interfaces Enable Automated Software Engineering — Yang, Jimenez et al., NeurIPS 2024 — ACI-ontwerpprincipes en SWE-bench-evaluatie (18,0% voor SWE-agent tegenover 7,3% voor shell-only zonder demonstration in de 300-task SWE-bench Lite-ablation van het paper; interface- en demonstrationcondities verschillen)
- RAG-MCP: Mitigating Prompt Bloat in LLM Tool Selection — De benchmarktaken en MCP-stresstest verhoogden selection accuracy van 13,62% naar 43,13%
- LLMs As Tool Makers (LATM) — Cai et al., 2023 — Two-phase paradigm voor agent tool creation
- ToolMaker: LLM Agents Making Agent Tools — Wolflein et al., ACL 2025 — 80% op zijn benchmark met 15 taken rond papers met publieke code repositories
- MCPTox: A Benchmark for Tool Poisoning Attack on Real-World MCP Servers — 72,8% gemiddelde attack success voor o1-mini in een benchmark met 20 agents en 45 servers
Anthropic engineering
- Advanced Tool Use / Programmatic Tool Calling — Tool Search (approximate context endpoints ~77K en ~8,7K), PTC en voorbeelden van tool use
- Code Execution with MCP — 98,7% tokenreductie (150K naar 2K tokens) via code-based tool orchestration
- Writing Effective Tools for Agents — Tool-description engineering; input examples verbeteren accuracy; response_format-enum (72 tegenover 206 tokens)
- Building Effective Agents — ACI als fundamenteel ontwerpprincipe
Protocolspecificaties
- Google Cloud donates A2A to Linux Foundation — Aankondiging van 23 juni 2025 over de overdracht van het protocol, de SDK en tooling
- A2A and MCP: Detailed Comparison — Documentatie van het A2A-protocol over de complementaire verantwoordelijkheden van agent-to-agent en agent-to-tool
Industry case studies
- Vercel: We Removed 80% of Our Agent’s Tools — oud voorbeeld noemt 17 tools; nieuw voorbeeld stelt
ExecuteCommandenExecuteSQLbeschikbaar; Vercel beschrijft het redesign als het verwijderen van 80%; success van 4/5 naar 5/5 over vijf representatieve queries, 3,5x sneller, 37% minder tokens - Cloudflare: Code Mode — TypeScript-gedreven API-calls ter vervanging van tool-schema’s
- Apideck: MCP Server Eating Your Context Window — 550–1.400 tokens/tool, 55K tokens voor ~40 MCP-tools, 143K/200K context gebruikt
- Scalekit: MCP vs CLI Token Benchmark — 4–32x token overhead voor MCP tegenover CLI over 75 benchmarkruns
Security
- Vulnerable MCP Project — Vulnerability reports voor het opstellen van threat-modeltests
- AuthZed: Timeline of MCP Breaches — 9 grote MCP-security-incidenten (april–oktober 2025)
- Invariant Labs: MCP Tool Poisoning Attacks — Tool poisoning, rug pulls en cross-origin escalation
- Pivot Point Security: MCP Security Analysis — 43% command injection, 43% OAuth-authentication flaws
CLI design
- Writing CLI Tools That AI Agents Actually Want to Use — Ugo Enyioha — Acht ontwerpregels voor agent-friendly CLIs
Demo-project
- Market Analyst Agent — Volledige implementatie met tool consolidation en ACI-patterns
De volledige code van de Market Analyst Agent, inclusief de tool designs die in dit artikel worden beschreven, staat op GitHub.