# Agent Skills di Claude API: cara menggunakan skill siap pakai tanpa Claude Code

> Cara menghubungkan skill pptx siap pakai ke Claude API: container.skills, alat eksekusi kode, memeriksa respons, dan mengunduh presentasi melalui Files API.

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


<div class="aside" data-semantic="key-takeaway" role="note" aria-label="Poin utama bagian ini">

Poin utama

Agent Skills siap pakai untuk dokumen dapat digunakan melalui Claude API langsung: tentukan skill di `container.skills` dan aktifkan `code_execution`. Untuk permintaan pertama, gunakan pasangan model dan alat yang kompatibel dari contoh resmi. Unduh file yang dihasilkan secara terpisah menggunakan `file_id`-nya; contoh ini menggunakan kunci API yang sama untuk permintaan dan pengunduhan.

</div>



Anda dapat menemukan instruksi tambahan di [dokumentasi Ailoot](https://ailoot.ai/docs/).

## Yang Anda perlukan

Panduan ini ditujukan untuk memanggil API langsung dari sebuah program, bukan memasang skill di Claude Code. Anda memerlukan kunci Claude API, akses ke model yang dipilih, dan Python 3. Kode di bawah menggunakan pustaka standar Python dan HTTP, jadi tidak bergantung pada versi SDK yang telah Anda pasang. Kunci diteruskan melalui variabel lingkungan `ANTHROPIC_API_KEY`; jangan masukkan ke dalam teks program atau percakapan.

API ini menyediakan skill Anthropic siap pakai: `pptx` untuk presentasi, `xlsx` untuk spreadsheet, `docx` untuk dokumen Word, dan `pdf` untuk PDF. Skill tersebut dihubungkan menggunakan `type: "anthropic"`. Panduan ini menggunakan skill siap pakai, tanpa mengunggah skill kustom.

[Quickstart resmi](https://platform.claude.com/docs/en/agents-and-tools/agent-skills/quickstart.md), yang dibuka saat materi ini disiapkan, menggunakan pasangan `claude-opus-5-5` dan `code_execution_20260521`. Pasangan itulah yang digunakan di bawah. Contoh ini telah diperiksa terhadap dokumentasi; ini bukan laporan penggunaan API berbayar.

## Header beta apa yang diperlukan

Contoh ini mengikuti kontrak HTTP quickstart saat ini: header-nya adalah `x-api-key`, `anthropic-version: 2023-06-01`, dan `content-type: application/json`; contoh ini tidak mengirim `anthropic-beta`. Jangan gabungkan model, metode pemanggilan, dan format respons dari generasi dokumentasi yang berbeda.

Dokumentasi [Files API](https://platform.claude.com/docs/en/build-with-claude/files.md) juga menyatakan bahwa API ini sudah keluar dari beta. Header lama `files-api-2025-04-14` mempertahankan format respons lama; menghapus header tersebut beralih ke format saat ini. Itulah sebabnya contoh lama yang menggunakan `client.beta.files` tidak dapat begitu saja digabungkan dengan contoh baru.

Di sini kita tidak sedang memigrasikan layanan yang sudah ada dari kontrak beta lama. Jika Anda sudah memiliki layanan seperti itu, periksa header dan format responsnya terlebih dahulu. Kata `beta` dalam nama metode SDK saja tidak cukup: dokumentasi Files API menjelaskan secara terpisah bagaimana berbagai versi SDK berperilaku.





## Buat presentasi dan unduh file

Contoh ini mengirim tugas untuk membuat lima slide tentang energi terbarukan, menyimpan seluruh respons ke `skill-response.json`, lalu mengambil ID file yang dihasilkan. Contoh ini tidak mengambil jalur penyimpanan dari respons model: file disimpan di folder lokal baru bernama `skill-output`. Jika folder itu sudah ada, program berhenti agar tidak menimpa hasil sebelumnya. Folder dibuat sebelum panggilan API, jadi folder tetap ada setelah panggilan gagal. Periksa dan pertahankan upaya tersebut sebelum mengulangi apa pun; jangan menghapusnya hanya agar proses ulang lolos.

```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": "Buat presentasi tentang energi terbarukan dengan 5 slide dalam bahasa pilihan saya.",
    }],
    "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)
```

Nama `result-1.pptx` dan seterusnya dipilih untuk tugas presentasi ini. Ekstensi file tidak membuktikan isi file: buka dokumen yang diunduh dan periksa format, jumlah slide, serta teksnya. Jangan menganggap HTTP 200 saja, atau keberadaan `file_id`, sebagai hasil yang berhasil.

Program ini mencetak `stop_reason`, yaitu alasan respons berhenti, dan menyimpan seluruh respons untuk diperiksa. Program ini tidak melanjutkan percakapan atau otomatis mengulangi permintaan berbayar. Memiliki file yang sudah diunduh tidak berarti seluruh tugas selesai: periksa respons yang tersimpan dan dokumennya sendiri sebelum memutuskan apakah permintaan lain diperlukan.

Untuk upaya yang gagal, periksa `skill-error.json` jika ada. File itu merekam status HTTP, ID permintaan bila diberikan, serta pesan galat penyedia yang panjangnya dibatasi dan nilai kunci API terkonfigurasi telah dihapus. Periksa pesan untuk konten pribadi lain sebelum membagikannya. Bandingkan galat autentikasi, izin/model, batas penagihan, dan format permintaan dengan [referensi galat resmi](https://platform.claude.com/docs/en/api/errors); jangan menyimpulkan semua kegagalan memerlukan generasi berbayar lagi.

Jika `skill-response.json` sudah berisi nilai `file_id` hasil generasi dan hanya pengunduhan yang gagal, pertahankan respons itu dan diagnosis langkah metadata/pengunduhan dengan akses ruang kerja terotorisasi yang sama. Jangan menjalankan blok generasi lagi hanya untuk mengunduh keluaran yang sudah ada. Jika hasil permintaan belum diketahui, simpan ID permintaannya dan pastikan statusnya sebelum mengirim generasi lain. Hanya setelah memutuskan generasi baru diperlukan, ubah baris keluaran lokal ke jalur yang belum dipakai, misalnya `out = Path("skill-output-attempt-2")`, dan pertahankan `exist_ok=False`. Folder baru mencegah penimpaan; folder itu tidak mencegah tagihan API ganda.

## Izin file apa yang diperlukan

Files API mengaitkan file dengan sebuah ruang kerja, bukan dengan pengguna individual aplikasi Anda atau percakapan. Menurut dokumentasi, kunci API apa pun yang memiliki akses ke ruang kerja tersebut dapat mengakses file yang diunggah di sana. Contoh ini menggunakan kunci yang sama untuk mengunduh dan menghasilkan file. Jangan pernah menerima `file_id` dari pengguna akhir atau sumber lain yang tidak tepercaya. Simpan ID ini di server dan kelola pemetaan antara pengguna dan file mereka di aplikasi Anda sendiri.

Periksa metadata file secara terpisah: metadata harus memuat `downloadable: true`. Dokumentasi mengizinkan pengunduhan file yang dihasilkan oleh skill atau alat eksekusi kode; file yang Anda unggah memiliki `downloadable: false`, dan upaya mengunduhnya akan mengembalikan 400. Akses ke ruang kerja dan kemampuan mengunduh file tertentu merupakan persyaratan yang terpisah.

Untuk aplikasi multi-pengguna, dokumentasi Files API merekomendasikan ruang kerja terpisah untuk setiap klien sebagai batas isolasi file. Rekomendasi ini khusus untuk file; jangan memperluasnya ke semua entitas dan izin tanpa memeriksa API yang relevan.

## Skill siap pakai dan skill kustom

Skill siap pakai memiliki ID `pptx`, `xlsx`, `docx`, dan `pdf`. Dalam [referensi daftar skill](https://platform.claude.com/docs/en/api/skills/list.md), sumber `custom` dijelaskan sebagai privat untuk ruang kerja, sedangkan `anthropic` dibagikan dan hanya dapat dibaca.

`version: "latest"` pada contoh pertama berarti versi skill terbaru yang dipublikasikan. Untuk integrasi yang dapat direproduksi, perlu diingat bahwa pilihan ini dapat berubah; untuk beralih ke versi tetap, pilih versi skill yang sudah ada dan Anda gunakan, bukan ID rekaan dari sebuah contoh.

## Batasan dan langkah selanjutnya

Contoh ini hanya mencakup pembuatan presentasi dengan skill siap pakai dan pengunduhannya. Mengunggah skill kustom, menghapusnya, dan mengakses layanan pihak ketiga belum diuji di sini. Tugas-tugas tersebut memerlukan pemeriksaan API terkait secara terpisah.

Jika tugas Anda melibatkan file di antarmuka Claude, ada panduan terpisah tentang [cara mengunggah file ke Claude](https://ailoot.ai/blog/id/claude-file-upload/). Untuk pemanggilan langsung, lihat [cara menghitung penggunaan token API](https://ailoot.ai/blog/id/api-token-usage-calculation/). Untuk pekerjaan dengan agen terminal, baca [cara memilih skill Claude Code](https://ailoot.ai/blog/id/choose-claude-code-skills/): skill tersebut dihubungkan dengan cara yang berbeda.

Untuk pemeriksaan pertama, satu skill siap pakai `pptx` sudah cukup: periksa respons, unduh file yang diizinkan untuk diunduh, lalu buka file tersebut. Tambahkan skill kustom dan pemisahan akses antarklien setelah pemeriksaan itu.





Saat Anda siap, kenali [Ailoot](https://ailoot.ai/).

## Pertanyaan tentang Agent Skills di Claude API: cara menggunakan skill siap pakai tanpa Claude Code

### Mengapa file_id saja belum cukup untuk menyatakan presentasi selesai?

ID menunjukkan bahwa sebuah file dikembalikan, bukan bahwa file itu merupakan presentasi yang dapat digunakan. Periksa metadata `downloadable: true`, unduh dengan akses ruang kerja, lalu buka untuk memverifikasi format file, jumlah slide, dan teksnya.

### Bisakah saya mengunduh setiap file yang diunggah ke Claude Files API?

Tidak. Panduan membedakan file hasil generasi dengan `downloadable: true` dari file unggahan dengan `downloadable: false`. Akses ruang kerja dan izin mengunduh file tertentu merupakan pemeriksaan terpisah; jangan terima ID file sembarang dari pengguna akhir.


## Ailoot · Perusahaan dan portofolio proyeknya

Ailoot bertumpu pada pengalaman operasional yang teruji, basis pelanggan yang besar, layanan yang stabil, dan pemantauan KPI berkelanjutan.

Perusahaan dan portofolio proyeknya: jutaan pelanggan; penjualan miliaran setiap bulan.

Ailoot memanfaatkan pengalaman operasional ini untuk akses API ke fitur AI dalam produk pelanggan, agen, aplikasi, dan otomatisasi.
