🔧 Wat is een Skill?
In de context van AI-agents is een skill (ook genoemd een tool or function) een verpakte, herbruikbare mogelijkheid die een LLM kan aanroepen om te communiceren met de wereld buiten zijn contextvenster. Skills overbruggen de kloof tussen taalbegrip en echte acties.
Elke skill heeft vier componenten:
- Name — een unieke identifier die het model gebruikt om naar de skill te verwijzen (bijv.,
web_search) - Description — natuurlijke taaltekst die uitlegt wat de skill doet en wanneer deze te gebruiken is; de LLM leest dit om te beslissen wanneer de skill aan te roepen
- Inputschema — een gestructureerde definitie van de argumenten (JSON Schema); het model vult deze in op basis van de taak
- Implementation — de daadwerkelijke code die draait: een API-call, databasequery, shell-commando, of enige andere bewerking
Voorbeeld: A get_weather skill heeft de beschrijving "Haalt de huidige weersvoorspelling voor een stad op", accepteert { "city": "string" } als invoer, en roept een weer-API aan. De LLM ziet nooit de API-sleutel of de HTTP-call — het ontvangt alleen het resultaat terug als tekst.
⚙️ Hoe Tool Calling Werkt
Wanneer een agent toegang heeft tot skills, roept de LLM ze niet direct aan — het requests een oproep door een gestructureerde output te genereren. De runtime (jouw applicatiecode) voert de feitelijke oproep uit en geeft het resultaat terug. Dit is de volledige cyclus:
- Tool-registratie — Je code stuurt het model een lijst van beschikbare skills met hun beschrijvingen en schema's
- Modelredenering — De LLM leest de taak en de beschikbare tools, beslist welke tool aan te roepen en met welke argumenten
- Tool call request — Het model geeft een gestructureerd "tool call" bericht uit (bijv.,
{ "tool": "web_search", "args": { "query": "current Gemini models" } }) - Execution — Jouw runtime-code roept de daadwerkelijke functie, API of service aan
- Resultaatinjectie — Het resultaat wordt weer aan de conversatiecontext toegevoegd
- Voortgezette redenering — Het model leest het resultaat en roept ofwel een andere tool aan, stelt een vervolgvraag, of genereert het definitieve antwoord
Deze lus kan vele malen herhalen in één beurt. Een complexe agent-achtige taak kan 10–20 tools achtereenvolgens aanroepen voordat er een definitief antwoord wordt gegenereerd.
📊 Skills vs Plugins vs MCP Servers
De terminologie heeft zich snel ontwikkeld. Zo verhouden de concepten zich historisch:
| Era | Name | Hoe het werkte | Status |
|---|---|---|---|
| 2023 | ChatGPT Plugins | Door de gebruiker installeerbare extensies met een OpenAPI-spec; ChatGPT riep ze aan via HTTP | Verouderd (vervangen door GPTs + tools) |
| 2023 | OpenAI Function Calling | API-niveau JSON Schema-definities; het model geeft een gestructureerde function call uit, jouw code voert deze uit | Actief — hernoemd naar "tool use" |
| 2023– | Tool Use / Skills | Hetzelfde als function calling; Anthropic introduceerde "tool use", anderen gebruiken "skills" of "functions" | Actief — huidige standaard |
| 2024– | MCP Servers | Gestandaardiseerd protocol (Anthropic, Dec 2024) voor het verpakken en distribueren van tool-servers; elke MCP-client kan verbinden met elke MCP-server | Actief — groeiend ecosysteem |
Belangrijk onderscheid: Traditioneel tool use wordt inline gedefinieerd in je applicatiecode. MCP servers zijn zelfstandige processen die tools blootstellen via een gestandaardiseerd protocol — waardoor ze herbruikbaar zijn over verschillende AI-clients (Claude Desktop, Cursor, VS Code, aangepaste agents). Lees meer: Wat is MCP.
🗂️ Toolcategorieën & Risiconiveaus
Niet alle tools dragen hetzelfde risico. Groeperen op risiconiveau helpt bij het definiëren van de actieruimte en waar HITL-controles toe te voegen:
| Category | Examples | Risk | Recommendation |
|---|---|---|---|
| Read-only | web_search, read_file, get_weather, list_dir | Low | Sta autonoom toe; log alle oproepen |
| Schrijven (lokaal) | write_file, create_dir, edit_code | Medium | Beperk tot een gesandboxte werkmapdirectory |
| Netwerk / Extern | send_email, post_to_slack, call_api | Medium–Hoog | HITL-goedkeuring voor onomkeerbare verzendacties |
| OS / Shell | run_command, execute_script, install_package | High | Beperk tot containerized omgeving; HITL vereist |
| Destructive | delete_file, drop_table, revoke_access | Critical | Altijd expliciete menselijke bevestiging vereisen |
🏗️ Anatomie van een Goede Skill
De belangrijkste ontwerpoverweging voor een skill is zijn description. De LLM leest beschrijvingen om te beslissen welke tool aan te roepen — een slecht geschreven beschrijving leidt tot verkeerde toolkeuze, het missen van oproepen of onduidelijke argumenten.
Wat een beschrijving effectief maakt
- Wees expliciet over wanneer het te gebruiken — "Gebruik deze tool wanneer de gebruiker vraagt naar realtime gegevens of actuele gebeurtenissen" is beter dan "Zoekt op het web"
- Geef aan wat het NIET doet — "Geeft geen historische gegevens ouder dan 30 dagen terug"
- Beschrijf het uitvoerformaat — "Geeft een JSON-array van zoekresultaten terug met title, url en snippet velden"
- Houd het onder 200 woorden — beschrijvingen langer dan ~200 tokens kunnen het model overweldigen wanneer veel tools zijn geregistreerd
Principes voor schema-ontwerp
- Vereist vs optioneel — Markeer velden alleen als vereist als het echt noodzakelijk is; optionele velden met standaardwaarden verminderen model fouten
- Gebruik enums voor beperkte waarden —
"format": {"enum": ["json", "markdown", "text"]}voorkomt gefabriceerde waarden - Geef de voorkeur aan idempotente tools — Tools die veilig opnieuw geprobeerd kunnen worden (lezen, opzoeken) zijn veiliger dan éénmalige acties (verzenden, verwijderen)
- Geef gestructureerde data terug — JSON-antwoorden zijn voor het model gemakkelijker om over te redeneren dan ongestructureerde tekstblokken
💡 Praktijkvoorbeelden
| Skillnaam | Wat het doet | Belangrijke argumenten | Risk |
|---|---|---|---|
web_search | Vraag een zoekmachine en geef de bovenste resultaten terug | query: string, num_results?: number | Low |
read_file | Lees een bestand uit de werkmapdirectory | path: string, offset?: number, limit?: number | Low |
write_file | Maak of overschrijf een bestand | path: string, content: string | Medium |
run_tests | Voer de project test suite uit en geef de resultaten terug | filter?: string | Medium |
browser_screenshot | Navigeer naar een URL en geef een screenshot terug | url: string | Medium |
send_email | Stuur een e-mail naar een of meer ontvangers | to: string[], subject: string, body: string | Hoog — altijd HITL |
run_shell | Voer een willekeurig shell-commando uit | command: string, cwd?: string | Hoog — sandbox vereist |
✅ Best Practices
Minimale permissies
Ken iedere agent alleen de tools toe die hij nodig heeft voor zijn specifieke taak. Een agent die FAQ's beantwoordt heeft geen behoefte aan write_file or send_email. Hoe kleiner de actieruimte, o hoe kleiner de schade als de agent wordt gemanipuleerd. Zie: Excessieve autonomie.
Audit alle tool-oproepen
Log elke tool-aanroep met zijn argumenten en resultaat. Dit maakt debugging, kostentoewijzing, en detectie van afwijkend gedrag mogelijk (bijv., een agent die ~/.ssh/ wanneer hij alleen toegang zou moeten hebben tot de projectdirectory). AgentOps-platforms zoals LangSmith maken dit eenvoudig.
Mens-in-de-lus voor onomkeerbare acties
Elke actie die moeilijk of onmogelijk ongedaan te maken is — berichten verzenden, gegevens verwijderen, aankopen doen — moet expliciete menselijke bevestiging vereisen voordat deze wordt uitgevoerd. Bouw HITL-controles in je agent-runtime, niet alleen in de prompt. Prompts kunnen worden overschreven; code niet.
Pas op voor tool-poisoning
Als je agents toestaat om MCP-servers dynamisch te installeren of te ontdekken, kan een kwaadwillende server een tool registreren met een beschrijving die verborgen instructies bevat. Controleer altijd tool-beschrijvingen voordat je ze toevoegt aan de agent-registratie. Zie: Tool Poisoning.
Schrijf duidelijke foutteruggaves
Wanneer een tool faalt, geef een gestructureerde fout terug met voldoende context zodat het model kan herstellen of esscaleren — geen ruwe exception stacktrace. Voorbeeld: { "error": "rate_limited", "retry_after": 5 }. Een goed beschreven fout laat de agent opnieuw proberen, een fallback-tool gebruiken, of de gebruiker op een nette manier informeren.