Claude Architect · Les

tool_use voor gegarandeerde structuur

Elimineer syntaxfouten en dwing verplichte velden af

Les 1 van 413 stappen

tool_use voor gegarandeerde structuur is een gratis Claude Architect-les op CoddyKit. Dit is les 1 van 4. Je kunt 3 lessen uit dit leerpad gratis volledig lezen — daarna ontgrendelt CoddyKit PRO alle lessen, plus praktische oefeningen met een ingebouwde code-editor en een AI-tutor die 24/7 beschikbaar is. Deze les maakt deel uit van het leertraject Claude Architect. Je voortgang wordt gesynchroniseerd op het web en in de CoddyKit-app. De cursus Claude Architect bevat in totaal 4 lessen.

Waarom vrije tekst faalt

Je vroeg Claude om JSON en verwerkte het antwoord met json.loads(). Het werkte 95% van de tijd. De overige 5%? Een los markdown-codeblok, een afsluitende komma, een breedsprakige inleiding zoals "Hier is de gevraagde JSON:" — en je pijplijn loopt vast.

Voor een Claude Certified Architect is die 5% het hele probleem. Productieprocessen voor extractie, classificatie en routering kunnen er niet van afhangen dat het model toevallig tekst correct opmaakt. In deze les zie je hoe tool_use plus een JSON Schema een probabilistisch formaat omzet in een gegarandeerd formaat — waarbij syntaxfouten worden geëlimineerd en verplichte velden worden afgedwongen.

Het kernidee

Een tool is niet alleen bedoeld om acties uit te voeren. Een tooldefinitie is ook een getypeerd uitvoercontract. Wanneer je een tool met een input_schema declareert, vertel je Claude precies welke vorm de argumenten moeten hebben — en de API valideert de toolaanroep aan de hand van dat schema.

In plaats van in proza om JSON te vragen en te hopen, definieer je dus een tool waarvan de parameters de gewenste structuur vormen en dwing je Claude om die aan te roepen. Het model vult de velden in; het schema garandeert de vorm. Volgens het factsheet: tool_use + JSON Schema elimineert syntaxfouten en dwingt verplichte velden af.

De schematool definiëren

Dit is een extractietool. Let op de drie pijlers van een goede tooldefinitie: een duidelijke name, een beschrijvende description en een nauwkeurig input_schema met beschrijvingen per eigenschap en een lijst required.

Het onderstaande schema extraheert een supportticket. We verplichten alleen de velden die altijd aanwezig zijn — binnenkort meer over die keuze.

ticket_tool = {
    "name": "record_ticket",
    "description": "Record a structured support ticket extracted from the user message.",
    "input_schema": {
        "type": "object",
        "properties": {
            "summary": {
                "type": "string",
                "description": "One-line summary of the issue",
            },
            "priority": {
                "type": "string",
                "enum": ["low", "medium", "high", "urgent"],
                "description": "Triage priority",
            },
        },
        "required": ["summary", "priority"],
    },
}

tool_choice: de structuur afdwingen

De tool declareren is niet genoeg — met de standaardinstelling kan Claude in plaats daarvan tekst antwoorden. De parameter tool_choice bepaalt die keuze:

  • {"type": "auto"} — Claude kiest tekst of een tool (de standaardinstelling).
  • {"type": "any"} — Claude moet een tool aanroepen. Dit garandeert gestructureerde uitvoer.
  • {"type": "tool", "name": "X"} — dwingt één specifieke tool af op naam.

Als je precies één schematool hebt en een gegarandeerde aanroep daarvan wilt, dwing je die op naam af. Daarmee verwijder je de uitweg om volledig in proza te antwoorden.

response = client.messages.create(
    model="claude-opus-4-8",
    max_tokens=1024,
    tools=[ticket_tool],
    tool_choice={"type": "tool", "name": "record_ticket"},
    messages=[{"role": "user", "content": ticket_text}],
)

De invoer van de tool teruglezen

Wanneer Claude de tool aanroept, bevat het antwoord een inhoudsblok tool_use. De gestructureerde gegevens staan in block.input — al door de SDK verwerkt tot een Python-dict die aan je schema voldoet.

Een discipline uit het factsheet: verwerk altijd het door de SDK verwerkte object en vergelijk nooit ruwe tekenreeksen met de geserialiseerde invoer. Recente modellen kunnen Unicode of schuine strepen op verschillende manieren escapen, dus behandel block.input als gestructureerde gegevens, niet als tekst.

for block in response.content:
    if block.type == "tool_use":
        ticket = block.input  # dict, matches the schema
        print(ticket["summary"], ticket["priority"])
        # Do NOT json.loads a re-serialized string here —
        # block.input is already the structured object.

De valkuil van required

Dit is de belangrijkste beslissing die in deze les wordt getoetst. De regel uit het factsheet is duidelijk:

Markeer een veld ALLEEN als required als het altijd aanwezig is. Maak een veld dat kan ontbreken NOOIT verplicht — het model verzint een waarde om aan het schema te voldoen.

Als customer_id soms niet in de brontekst staat maar je het onder required vermeldt, geeft Claude geen leeg resultaat terug — het verzint een aannemelijk ID om de toolaanroep geldig te maken. Dat is een stille fout in de gegevensintegriteit. Verplicht betekent "door de bron gegarandeerd", niet "mooi meegenomen".

Optionele velden correct afhandelen

Velden die kunnen ontbreken, laat je simpelweg weg uit de array required. Claude laat ze weg wanneer de bron de gegevens niet bevat, in plaats van te hallucineren.

Hier zijn customer_id en attachments optioneel; alleen summary en priority — die we altijd kunnen afleiden — zijn verplicht.

"properties": {
    "summary": {"type": "string"},
    "priority": {"type": "string",
                 "enum": ["low", "medium", "high", "urgent"]},
    "customer_id": {"type": "string",
                    "description": "Only if explicitly stated"},
    "attachments": {"type": "array", "items": {"type": "string"}},
},
"required": ["summary", "priority"]  # NOT customer_id / attachments

Enumeraties met een uitweg

Enumeraties beperken een veld tot een vaste verzameling waarden — ideaal voor categorieën, labels en prioriteiten. Maar een rigide enumeratie dwingt elke invoer in een van je vooraf bepaalde categorieën, waardoor randgevallen die je niet had voorzien verkeerd worden verwerkt.

Het patroon uit het factsheet voor uitbreidbaarheid: gebruik enumeraties met een waarde "other" plus een veld met vrije tekst voor details. Wanneer Claude iets tegenkomt dat buiten je categorieën valt, kiest het other en legt het dit uit in het detailveld — in plaats van het verkeerd te labelen.

"category": {
    "type": "string",
    "enum": ["billing", "bug", "account", "other"],
    "description": "Use 'other' if none of the named categories fit",
},
"category_detail": {
    "type": "string",
    "description": "Free-text explanation, required only when category is 'other'",
}

Valideren en daarna opnieuw proberen met feedback

Het schema garandeert de syntactische vorm, maar je valideert nog steeds de semantiek — totalen die kloppen, datums binnen het bereik en consistentie tussen velden. Gebruik een validator in de stijl van Pydantic op block.input.

Wanneer de validatie mislukt door een opmaak-, structurele of rekenfout, gebruik je retry-with-feedback: stuur de oorspronkelijke bron, de onjuiste uitvoer en de exacte validatiefout opnieuw. Belangrijk: het factsheet waarschuwt dat opnieuw proberen NIET helpt wanneer de informatie simpelweg ontbreekt in de bron — opnieuw proberen nodigt dan alleen uit tot verzinnen.

from pydantic import BaseModel, ValidationError

class Ticket(BaseModel):
    summary: str
    priority: str

try:
    ticket = Ticket(**block.input)
except ValidationError as e:
    # Resend: original text + wrong output + this exact error.
    # Only worth it for format/arithmetic faults, not missing data.
    retry(ticket_text, block.input, str(e))

Zelfcorrectie voor getallen

Bij numerieke extractie is het een krachtige truc om Claude met het schema zijn werk te laten tonen, zodat afwijkingen detecteerbaar worden. Volgens het factsheet: extraheer zowel een calculated_total als een stated_total om afwijkingen te detecteren.

Als het document "Totaal: $1,200" vermeldt maar de afzonderlijke regels optellen tot $1,150, maken twee afzonderlijke velden de afwijking zichtbaar — je validator detecteert die in plaats van één getal te vertrouwen. Het schema wordt zo een controle-instrument, niet alleen een container.

"properties": {
    "line_items": {"type": "array", "items": {"type": "number"}},
    "calculated_total": {"type": "number",
        "description": "Sum you computed from the line items"},
    "stated_total": {"type": "number",
        "description": "Total as literally written in the document"},
},
"required": ["line_items", "calculated_total", "stated_total"]

Waar dit in de lus past

Gestructureerde uitvoer is één stap in de grotere agentische lus: verzoek → stop_reason inspecteren → bij tool_use de tool afhandelen → herhalen tot end_turn. Een afgedwongen schema-aanroep retourneert stop_reason: "tool_use"; je leest block.input en gaat verder.

Twee herinneringen op architectniveau: beëindig op basis van de stop_reason, nooit door in tekst te zoeken naar woorden als "klaar". Houd ook de herkomst bij — koppel elke geëxtraheerde bewering terug aan de bron (documentnaam, citaat, datum), zodat downstreamgebruikers het gestructureerde resultaat kunnen vertrouwen en controleren.

Korte controle

Je extraheert facturen. De bron-pdf's laten soms een inkoopordernummer weg. Een collega stelt voor om po_number in de array required van het schema te zetten, "zodat we er altijd een krijgen". Wat moet je doen?

Samenvatting: gegarandeerde structuur

Belangrijkste punten voor het examen en voor productie:

  • tool_use + JSON Schema elimineert syntaxfouten en dwingt verplichte velden af — veel betrouwbaarder dan JSON in proza verwerken.
  • tool_choice: "any" garandeert een toolaanroep; {"type":"tool","name":"X"} dwingt een specifieke schematool af; "auto" laat de keuze optioneel.
  • required = altijd aanwezig. Maak een mogelijk ontbrekend veld nooit verplicht — dat veroorzaakt verzinsels. Optionele velden laat je simpelweg weg uit required.
  • Enumeraties hebben een "other"- plus detailveld nodig voor uitbreidbaarheid.
  • Lees gestructureerde gegevens uit block.input; vergelijk nooit ruwe tekenreeksen met de geserialiseerde toolinvoer.
  • Retry-with-feedback herstelt opmaak- en rekenfouten — niet ontbrekende informatie. Gebruik calculated_total tegenover stated_total voor zelfcorrectie en houd de herkomst bij.
Gratis beginnen

Leer Python met een AI-tutor — gratis

Schrijf echte code en voer die uit in je browser, krijg direct hulp van een AI-tutor die 24/7 beschikbaar is en ga verder waar je gebleven bent op het web of in de app.

Cursussen
26
Lessen
104

Veelgestelde vragen

Is de les “tool_use voor gegarandeerde structuur” gratis?

Ja — je kunt hier op het web alle 3 lessen van het leerpad Claude Architect, waaronder “tool_use voor gegarandeerde structuur”, gratis volledig lezen. Daarna ontgrendelt CoddyKit PRO alle lessen, plus interactieve oefeningen met een ingebouwde code-editor en een AI-tutor die 24/7 beschikbaar is. De cursus Claude Architect bevat in totaal 4 lessen.

Wat leer ik in “tool_use voor gegarandeerde structuur”?

Elimineer syntaxfouten en dwing verplichte velden af Je oefent met Claude Architect door code rechtstreeks in de browser uit te voeren. Een AI-begeleider die 24/7 beschikbaar is beantwoordt je vragen terwijl je de les doorwerkt.

Heb ik ervaring nodig om met Claude Architect te beginnen?

Ervaring vooraf is niet nodig. Claude Architect op CoddyKit is opgebouwd voor beginners tot gevorderden, zodat je hier of bij het begin kunt starten en in je eigen tempo kunt leren. Dit is les 1 van 4.

Hoe lang duurt de les “tool_use voor gegarandeerde structuur”?

De meeste lessen van CoddyKit duren ongeveer 5–10 minuten. Elke les is kort en interactief, zodat je gestaag vooruitgaat en op het web en in de app precies verdergaat waar je was gebleven.

Kan ik code schrijven en uitvoeren in deze les over Claude Architect?

Ja. Elke les over Claude Architect bevat een ingebouwde code-editor, zodat je rechtstreeks in je browser echte code kunt schrijven en uitvoeren en direct feedback van AI krijgt — lokale installatie is niet nodig.

Alle lessen in deze cursus

  1. tool_use voor gegarandeerde structuur
  2. Een JSON-schema ontwerpen
  3. Verplichte versus optionele/nullable velden
  4. Enums met 'other' voor uitbreidbaarheid
← Terug naar Claude Architect