Claude Tool Use: Zo Geef Ik Mijn AI-Agents Echte Mogelijkheden
Claude tool use laat uw agent acties ondernemen — niet alleen tekst genereren. U definieert tools als JSON-schema's, Claude beslist wanneer ze worden aangeroepen, en uw code voert de echte actie uit. De lus heeft drie stappen: stuur bericht → ontvang tool_use-blok → voer uit en stuur resultaat terug. Ik heb dit geïmplementeerd in 15+ productie-agents op Cloudflare Workers. Het faalpatroon ligt bijna nooit bij de AI — het zijn onduidelijke tool-resultaten die terugkomen.
Elke woensdag. 28.400+ operators. Geen opvulling.
✓ Controleer je inbox — klik op de bevestigingslink om je aanmelding te voltooien.
✓ Je bent aangemeld!
✓ Je staat al op de lijst.
Inhoudsopgave
Bijgewerkt juli 2026.
TL;DR: Claude tool use laat uw agent acties ondernemen — niet alleen tekst genereren. U definieert tools als JSON-schema’s, Claude beslist wanneer ze worden aangeroepen, en uw code voert de echte actie uit. De lus heeft drie stappen: stuur bericht → ontvang tool_use-blok → voer uit en stuur resultaat terug. Ik heb dit geïmplementeerd in 15+ productie-agents op Cloudflare Workers. Het faalpatroon ligt bijna nooit bij de AI — het zijn onduidelijke tool-resultaten die terugkomen.
[Operatorperspectief] Ik beheer 30+ productie-AI-agents verspreid over een consultancymerk en Pickleland, een pickleballaccommodatie in Pflugerville, TX. Ongeveer de helft gebruikt tool use — de Claude API-functie die het model in staat stelt functies aan te roepen die uw code definieert. Dit is het patroon waar ik op ben uitgekomen na implementeren en itereren in productie.
Waarom tool use verandert wat een agent kan doen
Zonder tools kan een agent alleen tekst genereren. Dat is nuttig voor samenvattingen, opstellen en classificeren — maar dat is niet wat de meeste bedrijfsautomatiseringen echt nodig hebben. Bedrijfsautomatiseringen moeten informatie opzoeken, naar databases schrijven, API’s aanroepen, berichten sturen.
Tool use is hoe u Claude die toegang geeft. U definieert een set tools als JSON-schema’s. Claude leest de schema’s, beslist welke tool aan te roepen en met welke argumenten, en geeft een gestructureerd tool_use-inhoudsblok terug. Uw code voert de eigenlijke functie uit. Claude krijgt het resultaat en beslist wat er daarna moet gebeuren — inclusief het aanroepen van een andere tool of het produceren van een definitief tekstantwoord.
De sleutel: Claude beslist wanneer en of een tool wordt aangeroepen. U definieert de mogelijkheden. Het model redeneert over wanneer ze te gebruiken.
Hoe de API-stroom werkt
De tool use-lus heeft drie stappen. U doorloopt deze lus één of meerdere keren afhankelijk van hoeveel tool-aanroepen het model maakt.
Stap 1: Stuur uw bericht met gedefinieerde tools
const response = await anthropic.messages.create({
model: "claude-haiku-4-5-20251001",
max_tokens: 1024,
tools: [
{
name: "check_court_availability",
description:
"Check if a court is available at a given date, time, and duration",
input_schema: {
type: "object",
properties: {
date: {
type: "string",
description: "Date in YYYY-MM-DD format",
},
time: {
type: "string",
description: "Start time in HH:MM format (24h)",
},
duration_minutes: {
type: "number",
description: "Duration of the booking in minutes",
},
},
required: ["date", "time", "duration_minutes"],
},
},
],
messages: [
{
role: "user",
content: "Is a court available tomorrow at 2pm for 90 minutes?",
},
],
});Stap 2: Controleer of Claude een tool wil aanroepen
if (response.stop_reason === "tool_use") {
const toolUseBlock = response.content.find(
(block): block is Anthropic.ToolUseBlock => block.type === "tool_use"
);
if (!toolUseBlock) throw new Error("Expected tool_use block");
// Run your actual function
const toolResult = await checkCourtAvailability(
toolUseBlock.input as CourtAvailabilityInput
);
// Step 3: Return the result to Claude
const finalResponse = await anthropic.messages.create({
model: "claude-haiku-4-5-20251001",
max_tokens: 1024,
tools: [
/* same tools as before */
],
messages: [
{
role: "user",
content: "Is a court available tomorrow at 2pm for 90 minutes?",
},
{ role: "assistant", content: response.content },
{
role: "user",
content: [
{
type: "tool_result",
tool_use_id: toolUseBlock.id,
content: JSON.stringify(toolResult),
},
],
},
],
});
// finalResponse.content now has the text answer
}Dat is het volledige patroon. Drie API-interacties per tool-aanroep: tools definiëren → tool_use-blok ontvangen → resultaat teruggeven.
Echt voorbeeld: de Pickleland beschikbaarheidscontrole
Pickleland is een pickleballaccommodatie. We ontvangen boekingsverzoeken op Facebook Messenger, in reacties en via een chatbot. De vraag is bijna altijd een variatie van “zijn jullie zaterdag om 15:00 open?” of “kan ik een baan boeken voor mijn groep van 8 personen?”
De beschikbaarheidscontroler-agent gebruikt tool use om het echte boekingssysteem in real-time te raadplegen in plaats van een standaardantwoord te geven.
Hier is de volledige agent — vereenvoudigd maar productiegetrouw:
// workers/availability-checker.ts
import Anthropic from "@anthropic-ai/sdk";
const anthropic = new Anthropic();
const AVAILABILITY_TOOLS: Anthropic.Tool[] = [
{
name: "check_availability",
description:
"Check court availability for a date, time, and group size. Returns available courts and their prices.",
input_schema: {
type: "object",
properties: {
date: { type: "string", description: "YYYY-MM-DD" },
start_time: { type: "string", description: "HH:MM (24h)" },
duration_minutes: { type: "number" },
players: { type: "number", description: "Number of players" },
},
required: ["date", "start_time", "duration_minutes"],
},
},
{
name: "get_pricing",
description:
"Get current pricing for court rentals and open play sessions",
input_schema: {
type: "object",
properties: {
session_type: {
type: "string",
enum: ["court_rental", "open_play", "clinics"],
},
},
required: ["session_type"],
},
},
];
export async function handleInquiry(
userMessage: string,
env: Env
): Promise<string> {
const messages: Anthropic.MessageParam[] = [
{ role: "user", content: userMessage },
];
// Agentic loop — keep going until stop_reason is "end_turn"
while (true) {
const response = await anthropic.messages.create({
model: "claude-haiku-4-5-20251001",
max_tokens: 512,
system:
"You are the booking assistant for Pickleland, a pickleball facility in Pflugerville, TX. " +
"Use the tools to look up real availability and pricing. Never make up availability or prices. " +
"If the customer wants to book, direct them to pickleland.com/book.",
tools: AVAILABILITY_TOOLS,
messages,
});
// Push the assistant's response into message history
messages.push({ role: "assistant", content: response.content });
if (response.stop_reason === "end_turn") {
const textBlock = response.content.find(
(b): b is Anthropic.TextBlock => b.type === "text"
);
return (
textBlock?.text ??
"I wasn't able to answer that — please call us directly."
);
}
if (response.stop_reason === "tool_use") {
// Process ALL tool calls in this response (Claude can request multiple at once)
const toolResults: Anthropic.ToolResultBlockParam[] = [];
for (const block of response.content) {
if (block.type !== "tool_use") continue;
let result: unknown;
switch (block.name) {
case "check_availability":
result = await checkAvailability(
block.input as AvailabilityInput,
env
);
break;
case "get_pricing":
result = await getPricing(block.input as PricingInput, env);
break;
default:
result = { error: `Unknown tool: ${block.name}` };
}
toolResults.push({
type: "tool_result",
tool_use_id: block.id,
content: JSON.stringify(result),
});
}
// Return all tool results in a single user message
messages.push({ role: "user", content: toolResults });
}
}
}Twee dingen om hier te noemen.
De agentische lus. Ik ga door tot stop_reason === "end_turn". Claude kan check_availability aanroepen, beslissen dat het ook de prijs nodig heeft, get_pricing aanroepen, en dan het definitieve antwoord produceren — dat zijn drie API-aanroepen voor één gebruikersbericht. De lus handelt dit af zonder speciale logica.
Meerdere tool-aanroepen per beurt. Claude kan meerdere tool_use-blokken in één enkel antwoord retourneren. Ik verwerk ze allemaal en geef alle resultaten terug in één enkel user-bericht. Als u ze één voor één verwerkt en individueel terugstuurt, onderbreekt u de gespreksstroom en verspilt u tokens.
Echt voorbeeld: de lead-onderzoeksagent
Mijn consultancymerk gebruikt een onderzoeksagent die inkomende leads verrijkt voordat ik met ze praat. Wanneer iemand het contactformulier invult, onderzoekt de agent het bedrijf en extraheert wat ik moet weten voor het gesprek.
De tooldefinities hiervoor bevatten een schrijftool — en hier wordt het patroon interessant:
const RESEARCH_TOOLS: Anthropic.Tool[] = [
{
name: "search_company",
description: "Search for information about a company",
input_schema: {
type: "object",
properties: {
company_name: { type: "string" },
website: { type: "string", description: "Company website if known" },
},
required: ["company_name"],
},
},
{
name: "save_research",
description:
"Save the completed research summary to Airtable. Call this when all research is complete.",
input_schema: {
type: "object",
properties: {
company_summary: { type: "string" },
estimated_size: {
type: "string",
enum: ["1-10", "11-50", "51-200", "200+"],
},
likely_use_case: { type: "string" },
priority: { type: "string", enum: ["high", "medium", "low"] },
notes: { type: "string" },
},
required: [
"company_summary",
"estimated_size",
"likely_use_case",
"priority",
],
},
},
];save_research is wat ik een schrijftool noem — het doel is niet informatie ophalen, maar de output van Claude in gestructureerde vorm in een database vastleggen. Ik gebruik dit patroon in plaats van te proberen JSON te parsen uit een tekstantwoord. Claude weet wanneer het onderzoek klaar is en roept save_research aan met correct getypeerde velden. Ik schrijf nooit een parser.
Dit is de schoonste toepassing van tool use: definieer een tool voor een “definitieve actie” met het exacte schema dat u wilt, en Claude levert gestructureerde output via de tool-aanroep. Geen tekstparsing, geen regex, geen JSONSchema-validatie van vrije tekstoutput.
Één tool vs. meerdere
Het instinct bij het starten met tool use is een grote tool te bouwen die alles doet. Weersta dit. Kleine, gefocuste tools zijn beter om drie redenen:
-
Claude redeneert beter over kleine tools. Een tool genaamd
get_court_statusdie beschikbaarheid retourneert is gemakkelijker voor het model te verwerken dan een tool genaamdmanage_facilitydie eenmode-parameter neemt en intern aftakt. -
Kleine tools zijn makkelijker te testen. Elke tool is een TypeScript-functie die u onafhankelijk van de LLM unit kunt testen. Dat moet u doen — tool-bugs zijn moeilijk te debuggen in een live gesprek.
-
Claude kan kleine tools parallelliseren. Als twee tools niet van elkaar afhankelijk zijn, kan Claude ze in hetzelfde antwoord aanroepen en verwerkt u ze parallel. Dit werkt alleen als de tools echt onafhankelijk zijn.
De uitzondering: tools die toegang nodig hebben tot veel gedeelde interne state. Als de functie 10 variabelen van dezelfde gegevensbron nodig heeft, klopt één tool met een rijker schema beter dan 10 tools die elk afzonderlijk de database benaderen.
Mijn vuistregel: begin met één tool per afzonderlijke mogelijkheid. Voeg tools samen alleen wanneer u ziet dat Claude ze bij elk verzoek samen aanroept.
Kostenimplicaties
Tool use voegt tokens toe. Elke tooldefinitie gaat in de systeempromptcontext. Elk tool_use- en tool_result-blok verbruikt tokens in de gespreksgeschiedenis. Voor een agentische multi-beurt-lus stapelt dit snel op.
Voor de Pickleland beschikbaarheidscontrole voert een typisch gesprek in totaal 3–4 API-aanroepen uit (initieel bericht + 1–2 tool-aanroepen + eindantwoord), elk met 600–900 tokens. Tegen Haiku-prijzen kost dit minder dan $0,001 per verzoek. Zoals ik uitleg in de post over AI-agenten kostenberekening, verwerkt Haiku goed gedefinieerde tool-aanroepopdrachten betrouwbaar en is het 10× goedkoper dan Sonnet voor hetzelfde tokenvolume.
De lead-onderzoeksagent draait op Sonnet omdat de beoordelingsbeslissingen — een lead prioriteren, fit inschatten — meer redeneerkapaciteit vereisen dan Haiku betrouwbaar levert op open invoer. De berekening werkt nog steeds omdat het zelden wordt uitgevoerd (een paar keer per week, niet duizenden per dag). De modelkeuze volgt de taakcomplexiteit, niet persoonlijke voorkeur.
Het faalpatroon waar niemand over spreekt
Het meest voorkomende faalpatroon dat ik zie bij tool use in productie is niet Claude die de verkeerde tool aanroept. Het is de tool die iets teruggeeft waar Claude niet duidelijk over kan redeneren.
Als uw tool een ruwe database-object met 40 velden teruggeeft, raakt Claude in de war over welke velden belangrijk zijn. Als uw tool een uitzondering gooit (die verschijnt als een Worker-crash in plaats van een tool-resultaat), breekt de lus stil af. Als uw tool null retourneert wanneer het “geen resultaten” bedoelt, weet Claude niet of het opnieuw moet proberen of opgeven.
Drie regels voor tool-resultaten:
Geef compacte, expliciete resultaten terug. { available: true, courts: ["Court 3", "Court 5"], price_per_hour: 20 } — niet de volledige databaserij.
Vang fouten op binnen de tool-functie en geef ze terug als gestructureerde resultaten. { error: "booking system timeout", retry: true } — geen gegooide uitzondering die de Worker laat crashen.
Maak “geen resultaten” expliciet. { available: false, next_available: "2026-07-23T14:00:00Z" } — niet null of een lege array zonder context.
Claude redeneert veel beter over duidelijke signalen dan over onduidelijke retourwaarden. Elk uur dat ik heb besteed aan het debuggen van tool use in productie ging over onduidelijke resultaten, niet over het redeneren van het model.
De conclusie van de operator
Tool use is de functie die Claude transformeert van een tekstgenerator in een operator. Definieer gefocuste tools met duidelijke invoerschema’s. Verwerk alle tool_use-blokken in één enkel antwoord aan het model. Voer de agentische lus uit totdat stop_reason === "end_turn". Geef schone, compacte resultaten terug van uw tool-functies — geen ruwe data-objecten, geen gegooide uitzonderingen, geen onduidelijke nulls.
Het model handelt het redeneren af. Uw code handelt de echte acties af. Houd die twee taken duidelijk gescheiden en de architectuur blijft onderhoudbaar zelfs als u tools toevoegt.
Als u uw eerste tool use-agent bouwt, begin dan met het bovenstaande patroon van de beschikbaarheidscontrole — één tool, één doel, één agentische lus. Zet dat in productie. Voeg dan de tweede tool toe.
Gerelateerd: De agent-stack die ik gebruik om 30+ productie-agents te draaien · Haiku vs Sonnet: de kostenberekening voor agent-taken · Event-getriggerde vs geplande agents: welk patroon voor welke taak
Bouwt u een tool use-agent en loopt u vast? Neem contact op — ik ontwerp en bouw productie-agentarchitecturen voor operatorteams.
FAQ
Werkt Claude tool use met alle modellen?
Ja — tool use wordt ondersteund door alle huidige Claude-modellen. Claude Haiku verwerkt goed gedefinieerde tools met duidelijke schema’s betrouwbaar en is de goedkoopste optie voor taaktypen met hoog volume. Sonnet verwerkt meer ambigue of open tool-aanroepbeslissingen beter. Begin met Haiku; ga hoger als de outputkwaliteit onvoldoende is.
Wat is het verschil tussen Claude tool use en OpenAI function calling?
Mechanisch identiek. OpenAI bedacht “function calling”; Anthropic noemt het “tool use”. In beide gevallen: u definieert JSON-schema’s, het model geeft gestructureerde aanroepen terug, uw code voert de functie uit. De API-vorm verschilt maar het concept is hetzelfde.
Kan Claude meerdere tools aanroepen in één enkel antwoord?
Ja. Claude kan meerdere tool_use-blokken in één enkel assistant-antwoord retourneren. Verwerk ze allemaal en geef alle resultaten terug in één enkel user-bericht. Zie het agentische luspatroon in het Pickleland-voorbeeld hierboven — de for-lus over response.content handelt dit correct af.
Hoeveel tools moet ik definiëren per agent?
Ik blijf onder 8–10 tools per agent. Daarboven heb ik Claude soms de verkeerde tool zien kiezen bij de eerste poging, wat tokens verspilt in een correctielus. Als u meer dan 10 mogelijkheden nodig heeft, splits de agent in meerdere agents met gespecialiseerde toolsets in plaats van één agent te bouwen die alles weet.
Moet ik tool use gebruiken voor gestructureerde output?
Ja — het save_research-schrijftool-patroon is schoner dan Claude te vragen JSON in een tekstblok te retourneren en dat vervolgens te parsen. Definieer een tool voor een “definitieve actie” met het exacte schema dat u wilt. Claude roept het aan met correct getypeerde velden wanneer het klaar is. Geen parser nodig.
Elke woensdag. 28.400+ operators. Geen opvulling.
✓ Controleer je inbox — klik op de bevestigingslink om je aanmelding te voltooien.
✓ Je bent aangemeld!
✓ Je staat al op de lijst.
Gerelateerde berichten
AI-Agenten met Menselijke Controle: Wanneer een Goedkeuringspoort Bouwen (en Wanneer Niet)
Bijgewerkt voor 2026. Het beslissingskader dat ik gebruik om te bepalen wanneer een AI-agent in productie een menselijke goedkeuringsstap nodig heeft — en wanneer het toevoegen ervan de adoptie stil saboteert.
AI AgentsClaude vs ChatGPT voor Bedrijven in 2026: Een Eerlijke Kijk van een Operator
Bijgewerkt voor 2026. Ik draai 30+ productie-AI-agents op Claude. Hier is mijn eerlijke vergelijking van Claude vs ChatGPT voor zakelijk gebruik — waar elke wint, waar elke faalt en hoe de juiste te kiezen voor jouw stack.
AI AgentsHoe ik Courtlines bouwde: een SaaS voor clubbeheer, ontwikkeld met Claude
Het verhaal achter Courtlines, het besturingssysteem voor racketsportclubs en -studio's — waarom ik het bouwde, wat het doet, en hoe Claude als mijn belangrijkste engineering-partner één operator in staat stelde om een volledige multi-tenant SaaS te lanceren.
Ontvang het AI-playbook in je inbox
Elke woensdag. 28.400+ operators. Geen opvulling.
Controleer je inbox.
We hebben je een bevestigingsmail gestuurd — klik op de link om je aanmelding te voltooien. Controleer je spam als je hem niet binnen een minuut ziet.
Je bent aangemeld.
Welkom — de volgende editie valt binnenkort in je inbox.
Je staat al op de lijst — kijk er elke woensdag naar uit.