# Agent Skills via de Claude API: een presentatie maken en downloaden

> Een kant-en-klare pptx-skill koppelen aan de Claude API: container.skills, de tool voor code-uitvoering, de reactie controleren en de presentatie downloaden via de Files API.

Source: https://ailoot.ai/blog/nl/claude-api-agent-skills/
Canonical: https://ailoot.ai/blog/nl/claude-api-agent-skills/
Language: nl
Publisher: Ailoot (https://ailoot.ai/)
Translation: guide-039
Revision: sha256-e836bc034d0fbbebef62ac92f099faa6d11343f68928fe273cf5761e9021ff95


<div class="aside" data-semantic="key-takeaway" role="note" aria-label="Belangrijkste punt van deze sectie">

Belangrijkste punt

Kant-en-klare Agent Skills voor documenten kunnen rechtstreeks via de Claude API worden gebruikt: vermeld de skill in `container.skills` en schakel `code_execution` in. Gebruik voor je eerste verzoek de combinatie van model en tool uit het officiële voorbeeld. Download het gegenereerde bestand apart met de bijbehorende `file_id`; in het voorbeeld wordt voor het verzoek en de download dezelfde API-sleutel gebruikt.

</div>



Meer instructies vind je in de [Ailoot-documentatie](https://ailoot.ai/docs/).

## Wat heb je nodig om Agent Skills via de Claude API te gebruiken?

Deze handleiding gaat over het rechtstreeks vanuit een programma aanroepen van de API, niet over het installeren van een skill in Claude Code. Je hebt een Claude API-sleutel, toegang tot het gekozen model en Python 3 nodig. De onderstaande code gebruikt de standaardbibliotheek van Python en HTTP, dus de versie van de SDK die je hebt geïnstalleerd maakt niet uit. De sleutel wordt doorgegeven via de omgevingsvariabele `ANTHROPIC_API_KEY`; zet deze niet in de programmatekst of in een gesprek.

De API biedt kant-en-klare Anthropic-skills: `pptx` voor presentaties, `xlsx` voor spreadsheets, `docx` voor Word-documenten en `pdf` voor pdf’s. Ze worden gekoppeld met `type: "anthropic"`. Deze handleiding gebruikt een kant-en-klare skill en uploadt geen aangepaste skill.

De [officiële quickstart](https://platform.claude.com/docs/en/agents-and-tools/agent-skills/quickstart.md), geraadpleegd bij de voorbereiding van dit materiaal, gebruikt de combinatie `claude-opus-5-5` en `code_execution_20260521`. Dat is de combinatie die hieronder wordt gebruikt. Dit voorbeeld is gecontroleerd aan de hand van de documentatie; het is geen verslag van een betaalde API-aanroep.

## Welke headers gebruik je voor Agent Skills en de Files API?

Het voorbeeld volgt het huidige HTTP-contract uit de quickstart: de headers zijn `x-api-key`, `anthropic-version: 2023-06-01` en `content-type: application/json`; het verstuurt geen `anthropic-beta`. Combineer geen model, aanroepmethode en antwoordformaat uit verschillende generaties van de documentatie.

De [documentatie van de Files API](https://platform.claude.com/docs/en/build-with-claude/files.md) vermeldt ook dat de API niet meer in bèta is. De oude header `files-api-2025-04-14` behoudt de oude antwoordformaten; als je de header verwijdert, worden de huidige formaten gebruikt. Daarom kun je een oud voorbeeld met `client.beta.files` niet zomaar combineren met een nieuw voorbeeld.

We migreren hier geen bestaande service van het oude beta-contract. Heb je zo’n service al, controleer dan eerst de headers en antwoordformaten. Het woord `beta` in de naam van een SDK-methode is op zichzelf niet voldoende: de documentatie van de Files API legt afzonderlijk uit hoe verschillende SDK-versies zich gedragen.





## Hoe maak je een presentatie en download je het bestand?

Het voorbeeld verstuurt een opdracht om vijf dia’s over hernieuwbare energie te maken, slaat het volledige antwoord op in `skill-response.json` en haalt vervolgens de ID’s van de gegenereerde bestanden eruit. Het haalt geen opslagpad uit het antwoord van het model: de bestanden worden opgeslagen in een nieuwe lokale map met de naam `skill-output`. Als die map al bestaat, stopt het programma om te voorkomen dat het vorige resultaat wordt overschreven. De map wordt vóór de API-aanroep gemaakt en blijft dus ook na een mislukte aanroep bestaan. Bekijk en bewaar die poging voordat je opnieuw iets uitvoert; verwijder de map niet alleen om een herhaling te laten slagen.

```python
import json
import os
from pathlib import Path
from urllib.error import HTTPError
from urllib.request import Request, urlopen

API = "https://api.anthropic.com/v1"
KEY = os.environ["ANTHROPIC_API_KEY"]
HEADERS = {
    "x-api-key": KEY,
    "anthropic-version": "2023-06-01",
    "content-type": "application/json",
}

def request(path, payload=None, binary=False):
    data = None if payload is None else json.dumps(payload).encode("utf-8")
    req = Request(API + path, data=data, headers=HEADERS)
    try:
        with urlopen(req, timeout=600) as result:
            body = result.read()
    except HTTPError as error:
        try:
            details = json.loads(error.read().decode("utf-8"))
        except (ValueError, UnicodeError):
            details = {}
        info = details.get("error", {})
        request_id = error.headers.get("request-id") or details.get("request_id")
        diagnostic = {
            "http_status": error.code,
            "request_id": request_id,
            "error_type": info.get("type"),
            "message": str(info.get("message", "No JSON error message")).replace(KEY, "[REDACTED]")[:1000],
        }
        (out / "skill-error.json").write_text(
            json.dumps(diagnostic, ensure_ascii=False, indent=2), encoding="utf-8"
        )
        raise RuntimeError(
            f"Claude API HTTP {error.code}; request_id={request_id}; inspect skill-error.json"
        ) from None
    return body if binary else json.loads(body)

out = Path("skill-output")
out.mkdir(exist_ok=False)
response = request("/messages", {
    "model": "claude-opus-5-5",
    "max_tokens": 16000,
    "container": {
        "skills": [{"type": "anthropic", "skill_id": "pptx", "version": "latest"}]
    },
    "messages": [{
        "role": "user",
        "content": "Maak een presentatie over hernieuwbare energie met 5 dia’s in mijn voorkeurstaal.",
    }],
    "tools": [{"type": "code_execution_20260521", "name": "code_execution"}],
})
(out / "skill-response.json").write_text(
    json.dumps(response, ensure_ascii=False, indent=2), encoding="utf-8"
)
print("stop_reason:", response.get("stop_reason"))

file_ids = []
for block in response["content"]:
    if block["type"] == "bash_code_execution_tool_result":
        result = block["content"]
        if result["type"] == "bash_code_execution_result":
            for item in result["content"]:
                file_id = item.get("file_id")
                if file_id and file_id not in file_ids:
                    file_ids.append(file_id)
if not file_ids:
    raise RuntimeError("No generated file_id; inspect skill-response.json")

for index, file_id in enumerate(file_ids, start=1):
    from urllib.parse import quote
    file_path = "/files/" + quote(file_id, safe="")
    metadata = request(file_path)
    if metadata.get("downloadable") is not True:
        raise RuntimeError("This file cannot be downloaded through Files API")
    target = out / f"result-{index}.pptx"
    target.write_bytes(request(file_path + "/content", binary=True))
    print("Saved:", target)
```

De namen `result-1.pptx` enzovoort zijn voor deze presentatietaak gekozen. Een bestandsextensie bewijst niet wat het bestand bevat: open het gedownloade document en controleer de indeling, het aantal dia’s en de tekst. Beschouw alleen een HTTP 200-status of de aanwezigheid van een `file_id` niet als een geslaagd resultaat.

Het programma geeft `stop_reason`, de reden waarom de reactie is gestopt, weer en slaat het volledige antwoord op om het te kunnen controleren. Het zet het gesprek niet voort en herhaalt het betaalde verzoek niet automatisch. Een gedownload bestand betekent niet dat de hele taak is afgerond: controleer het opgeslagen antwoord en het document zelf voordat je beslist of er nog een verzoek nodig is.

Bekijk na een mislukte poging `skill-error.json` als dat bestand bestaat. Het bevat de HTTP-status, een eventueel door de aanbieder geleverde verzoek-ID en een begrensde foutmelding waaruit de ingestelde API-sleutel is verwijderd. Controleer de melding op andere privégegevens voordat je haar deelt. Vergelijk authenticatiefouten, rechten- en modelfouten, factureringslimieten en fouten in de verzoekindeling met de [officiële foutreferentie](https://platform.claude.com/docs/en/api/errors); niet elke fout vraagt om een nieuwe betaalde generatie.

Staan er al gegenereerde `file_id`-waarden in `skill-response.json` en is alleen een download mislukt, hervat dan die download met de bekende ID’s in plaats van de presentatie opnieuw te genereren. Is de uitkomst van de generatie onbekend, zoek dan eerst uit wat er met de oorspronkelijke poging is gebeurd. Een `FileExistsError` voor `skill-output` is een lokaal mapconflict, geen API-fout. Kies pas voor een gemotiveerde nieuwe generatie bewust een nieuwe, ongebruikte uitvoermap; behoud `exist_ok=False` en overschrijf de eerdere poging niet. Een andere map voorkomt geen dubbele generatie of dubbele kosten.

## Welke bestandsrechten zijn nodig

De Files API koppelt bestanden aan een workspace, niet aan een afzonderlijke gebruiker van je applicatie of aan een gesprek. Volgens de documentatie kan elke API-sleutel met toegang tot die workspace de bestanden daarin benaderen. In het voorbeeld wordt dezelfde sleutel gebruikt om het bestand te genereren en te downloaden. Accepteer nooit een `file_id` van eindgebruikers of andere niet-vertrouwde bronnen. Bewaar deze ID’s op de server en houd in je eigen applicatie bij welke bestanden bij welke gebruikers horen.

Controleer de bestandsmetadata afzonderlijk: daarin moet `downloadable: true` staan. Volgens de documentatie kun je bestanden downloaden die door skills of de tool voor code-uitvoering zijn gegenereerd; bestanden die je zelf uploadt, hebben `downloadable: false` en een poging om ze te downloaden geeft een 400-fout. Toegang tot de workspace en toestemming om een specifiek bestand te downloaden zijn afzonderlijke vereisten.

Voor een applicatie met meerdere gebruikers beveelt de documentatie van de Files API een aparte workspace per klant aan als grens voor bestandsisolatie. Deze aanbeveling betreft specifiek bestanden; pas haar niet toe op alle entiteiten en rechten zonder de relevante API te controleren.

## Kant-en-klare skills en aangepaste skills

De ID’s van kant-en-klare skills zijn `pptx`, `xlsx`, `docx` en `pdf`. In de [referentie voor de skillslijst](https://platform.claude.com/docs/en/api/skills/list.md) wordt de bron `custom` beschreven als privé voor de workspace, terwijl `anthropic` gedeeld en alleen-lezen is.

`version: "latest"` in het eerste voorbeeld betekent de nieuwste gepubliceerde versie van de skill. Houd er bij een reproduceerbare integratie rekening mee dat deze selectie kan veranderen; om over te stappen op een vaste versie moet je een bestaande versie kiezen van de skill die je gebruikt, en geen ID uit een voorbeeld verzinnen.

## Beperkingen en de volgende stap

Het voorbeeld behandelt alleen het maken van een presentatie met een kant-en-klare skill en het downloaden ervan. Het uploaden en verwijderen van aangepaste skills en toegang tot diensten van derden zijn hier niet getest. Voor die taken moet je de relevante API afzonderlijk controleren.

Als je taak betrekking heeft op bestanden in de Claude-interface, is er een aparte handleiding over [hoe je een bestand naar Claude uploadt](https://ailoot.ai/blog/nl/claude-file-upload/). Voor rechtstreekse aanroepen, zie [hoe je het API-tokengebruik berekent](https://ailoot.ai/blog/nl/api-token-usage-calculation/). Voor werk in een terminalagent, lees [hoe je Claude Code-skills kiest](https://ailoot.ai/blog/nl/choose-claude-code-skills/): die worden op een andere manier gekoppeld.

Voor de eerste controle is één kant-en-klare `pptx`-skill voldoende: controleer de reactie, download een bestand dat mag worden gedownload en open het. Voeg aangepaste skills en toegangsisolatie tussen klanten daarna toe.





Maak kennis met [Ailoot](https://ailoot.ai/) wanneer je er klaar voor bent.

## Vragen en antwoorden

### Waarom volstaat een file_id niet om de presentatie afgerond te noemen?

De ID laat zien dat een bestand is teruggegeven, niet dat het een bruikbare presentatie is. Controleer of de metadata downloadable: true bevat, download met toegang tot de werkruimte en open het bestand om formaat, aantal dia’s en tekst te controleren.

### Kan ik elk bestand downloaden dat naar de Claude Files API is geüpload?

Nee. De gids onderscheidt gegenereerde bestanden met downloadable: true van geüploade bestanden met downloadable: false. Werkruimtetoegang en toestemming om een bepaald bestand te downloaden zijn afzonderlijke controles; accepteer geen willekeurige bestands-ID’s van eindgebruikers.


## Ailoot · Het bedrijf en zijn projectenportefeuille

Ailoot bouwt op opgebouwde operationele ervaring, een groot klantenbestand, een stabiele dienst en doorlopende KPI-controle.

Het bedrijf en zijn projectenportefeuille: miljoenen klanten; maandelijkse verkopen in de miljarden.

Ailoot gebruikt die operationele ervaring voor API-toegang tot AI-functies in klantproducten, agents, applicaties en automatiseringen.
