API Anda mengembalikan 400 Bad Request dengan badan {"error": "invalid input"}. Seorang pengembang manusia membuka dokumentasi, memeriksa payload, menemukan bidang yang hilang, dan memperbaikinya dalam semenit. Agen membaca dua kata yang sama, tidak memiliki tindakan apa pun, dan melakukan satu-satunya hal yang bisa dilakukannya: mengirim permintaan yang sama lagi. Lalu lagi. Kemudian menyerah dan memberi tahu pengguna bahwa API rusak.
Respons kesalahan adalah bagian dari API yang paling diandalkan oleh agen dan yang paling akhir dirancang oleh tim. Kesalahan yang baik memberitahu pemanggil apa yang salah, apakah mencoba lagi dapat membantu, dan apa yang harus diubah. Agen dapat bertindak atas ketiga hal tersebut. Kesalahan yang tidak jelas mengubah masalah yang dapat dipulihkan menjadi tugas yang gagal.
Panduan ini ditulis untuk sisi API dari hubungan tersebut. Postingan kami tentang pemulihan kesalahan agen AI mencakup apa yang harus dilakukan klien dengan percobaan ulang, backoff, dan circuit breaker. Yang ini mencakup apa yang harus dikembalikan oleh API Anda agar logika klien tersebut dapat berfungsi sama sekali.
Apidog penting di sini karena respons kesalahan adalah bagian yang paling sedikit diuji pada sebagian besar API. Anda dapat mendefinisikannya dalam spesifikasi, membuat mock-nya, dan menegaskan (assert) mereka di tempat yang sama Anda menguji jalur yang sukses (happy path).
Tiga pertanyaan yang harus dijawab oleh kesalahan
Setiap respons kesalahan yang diterima agen harus memungkinkannya menjawab tiga hal tanpa menebak.
Apakah ini kesalahan saya atau Anda? Kode 4xx berarti permintaan salah dan mengulanginya tanpa perubahan akan gagal lagi. Kode 5xx berarti ada sesuatu di server yang salah dan permintaan yang sama mungkin berhasil nanti. Agen yang tidak dapat membedakan ini akan mencoba ulang selamanya pada kesalahan validasi atau menyerah pada gangguan sementara.
Haruskah saya mencoba lagi, dan kapan? Beberapa kesalahan 4xx dapat dicoba ulang dan beberapa tidak. Kode 429 dapat dicoba ulang setelah menunggu. Kode 409 mungkin dapat dicoba ulang setelah membaca ulang status. Kode 422 tidak dapat dicoba ulang tanpa mengubah payload. Katakan secara eksplisit.
Apa yang sebenarnya harus saya ubah? Ini adalah bidang yang diabaikan oleh sebagian besar API. "Validasi gagal" tidak berguna. "Bidang customer.postal_code wajib diisi ketika country adalah US" adalah perbaikan yang dapat diterapkan agen pada percobaan berikutnya.
Sertakan ketiga hal ini dalam setiap kesalahan dan sebagian besar badai percobaan ulang agen akan hilang.
Gunakan format kesalahan terstruktur
Jangan mengarang bentuk. RFC 9457, Detail Masalah untuk API HTTP, mendefinisikan satu dan itu didukung dengan baik:
{
"type": "https://api.example.com/errors/validation-failed",
"title": "Validation failed",
"status": 422,
"detail": "The field 'customer.postal_code' is required when 'country' is 'US'.",
"instance": "/v1/orders",
"errors": [
{
"field": "customer.postal_code",
"code": "required_conditional",
"message": "Required when country is US. Provide a 5-digit or 9-digit US postal code.",
"example": "94107"
}
],
"retryable": false,
"next_action": "Add customer.postal_code to the request body and send again."
}
Empat bagian menanggung beban bagi agen.
detail adalah kalimat lengkap yang menyebutkan bidang sebenarnya dan aturan sebenarnya. Bukan kategori. Hal spesifik yang gagal pada permintaan ini.
Array errors dapat dibaca mesin, satu entri per masalah, dengan jalur bidang yang dapat dipetakan agen kembali ke payload yang dikirimnya. Kembalikan setiap kegagalan sekaligus. Mengembalikannya satu per satu mengubah satu perbaikan menjadi lima bolak-balik.
retryable adalah boolean, bukan sesuatu yang disimpulkan dari kode status. Ini adalah ekstensi yang paling membantu agen, dan biayanya hanya satu bidang.
next_action adalah teks instruksi biasa. Model mengikuti instruksi eksplisit dalam badan respons lebih andal daripada mereka mengambil kesimpulan dari kode kesalahan, dan satu kalimat di sini sering mengubah tugas yang gagal menjadi yang selesai.
Panduan desain kesalahan API Google API error design guide mencapai kesimpulan serupa dari arah yang berbeda, terutama bahwa detail kesalahan termasuk dalam daftar terstruktur daripada dalam bentuk narasi.
Katakan kapan harus kembali
Untuk hal yang bersifat sementara, katakan kapan. Agen yang tahu harus menunggu 30 detik akan menunggu 30 detik. Agen yang tidak tahu akan memilih sesuatu, dan sesuatu itu biasanya terlalu singkat.
HTTP/1.1 429 Too Many Requests
Retry-After: 30
Content-Type: application/problem+json
{
"type": "https://api.example.com/errors/rate-limited",
"title": "Rate limit exceeded",
"status": 429,
"detail": "You have used 1000 of 1000 requests in the current minute window.",
"retryable": true,
"retry_after_seconds": 30,
"next_action": "Wait 30 seconds before sending this request again. Do not retry sooner."
}
Header Retry-After menerima penundaan dalam detik atau tanggal HTTP; detik lebih mudah bagi klien untuk bertindak. Kirimkan sebagai header untuk klien standar dan ulangi di badan (body) untuk model. Duplikasi itu murah dan kedua konsumen mendapatkan apa yang paling baik mereka baca. Spesifik batas laju (rate-limit) dibahas dalam panduan batas laju terlampaui kami dan dalam cara mengimplementasikan pembatasan laju API jika Anda berada di sisi server.
Pola yang sama berlaku untuk 503 selama pemeliharaan dan 409 pada sumber daya yang terkunci. Setiap kesalahan di mana menunggu adalah respons yang benar harus membawa angka.
Jangan pernah membocorkan internal, jangan pernah mengembalikan apa-apa
Dua mode kegagalan berada pada ekstrem yang berlawanan, dan keduanya merugikan agen.
Yang pertama adalah stack trace. Mengembalikan teks pengecualian internal mengekspos versi framework, jalur file, dan terkadang fragmen kueri. Ini adalah masalah keamanan sebelum menjadi masalah agen, dan kekhawatiran dalam postingan kami tentang menguji API terhadap input yang tidak tepercaya berlaku secara langsung. Ini juga membanjiri jendela konteks dengan teks yang tidak dapat ditindaklanjuti oleh model.
Yang kedua adalah kesalahan kosong: kode 500 tanpa badan (body), atau {"error": true}. Agen tidak belajar apa-apa, dan satu-satunya pilihannya adalah mencoba ulang atau berhenti.
Jalur tengah adalah kesalahan publik yang stabil dengan ID korelasi:
{
"type": "https://api.example.com/errors/internal",
"title": "Internal error",
"status": 500,
"detail": "The order could not be created due to an internal error. No order was created.",
"retryable": true,
"retry_after_seconds": 5,
"request_id": "req_01J8ZK3M2Q",
"next_action": "Retry once after 5 seconds. If it fails again, stop and report request_id req_01J8ZK3M2Q."
}
Kalimat "Tidak ada pesanan yang dibuat" adalah bagian yang paling berharga. Agen yang menghadapi penulisan yang ambigu harus memutuskan apakah mencoba lagi berisiko duplikasi, dan sebagian besar memutuskan dengan buruk. Beri tahu mereka status Anda. Jika Anda tidak dapat menjamin itu, buat operasi bersifat idempoten dan katakan demikian, yang merupakan pola dalam postingan kami tentang kunci idempotensi untuk agen AI.
request_id memberi Anda alur kembali ke log Anda ketika manusia akhirnya membaca transkripnya. Pasangkan dengan praktik dalam panduan observabilitas API kami agar ID tersebut benar-benar mengarah ke sesuatu.
Kesalahan termasuk dalam spesifikasi
Jika bentuk kesalahan tidak ada dalam dokumen OpenAPI Anda, itu tidak ada sejauh menyangkut klien yang dihasilkan, mock, dan alat agen. Sebagian besar spesifikasi menjelaskan kode 200 secara rinci dan kemudian mengabaikan yang lainnya.
responses:
'201':
description: Order created
content:
application/json:
schema: { $ref: '#/components/schemas/Order' }
'422':
description: >
Validation failed. Not retryable without changing the request body.
The errors array names each invalid field.
content:
application/problem+json:
schema: { $ref: '#/components/schemas/Problem' }
'429':
description: >
Rate limited. Retryable. Wait for retry_after_seconds before sending again.
content:
application/problem+json:
schema: { $ref: '#/components/schemas/Problem' }
Deskripsi tersebut bukan hiasan. Ketika Anda menghasilkan alat agen dari spesifikasi, seperti dalam panduan kami untuk mengubah spesifikasi OpenAPI menjadi alat agen, teks itu menjadi apa yang dibaca model tentang kasus kegagalan. Deskripsi yang mengatakan "dapat dicoba ulang, tunggu dulu" menghasilkan perilaku yang lebih baik daripada yang mengatakan "Terlalu Banyak Permintaan".
Uji kesalahan, bukan hanya kesuksesan
Jalur kesalahan adalah tempat cakupan pengujian runtuh, karena memicunya membutuhkan usaha. Mocking menghilangkan usaha tersebut.

Definisikan setiap respons kesalahan dalam proyek API Anda, lalu buat mock-nya agar agen dapat memenuhi setiap kasus sesuai permintaan. Di Apidog Anda dapat menambahkan respons kegagalan ke definisi endpoint dan beralih mock di antaranya, yang memberi Anda cara yang berulang untuk menjalankan agen terhadap 422, 429, dan 500 tanpa merusak apa pun yang nyata. Postingan kami tentang menjalankan agen terhadap mock alih-alih produksi mencakup kebiasaan yang lebih luas.
Lima kasus untuk dibangun:
- Kegagalan validasi dengan beberapa bidang yang salah sekaligus. Pastikan setiap masalah kembali dalam satu respons, dan bahwa percobaan berikutnya dari agen memperbaiki semuanya daripada satu per satu.
- Batas laju dengan penundaan. Pastikan agen menunggu setidaknya
retry_after_secondsalih-alih terus-menerus mencoba. - Kesalahan server pada operasi tulis. Pastikan agen tidak diam-diam membuat duplikat saat mencoba ulang.
- Kegagalan otentikasi. Pastikan agen berhenti alih-alih mencoba ulang, karena tidak ada jumlah penantian yang akan memperbaiki token yang buruk. Postingan kami tentang kunci API hak istimewa terkecil untuk agen mencakup sisi kredensial.
- Badan (body) kesalahan yang salah format. Kembalikan sesuatu yang bukan JSON yang valid dan konfirmasikan bahwa agen menangani dengan baik. Proksi upstream pada akhirnya akan melakukan ini kepada Anda.
Simpan set tersebut sebagai skenario agar berjalan di CI. Penanganan kesalahan sering kali menurun secara diam-diam, biasanya ketika seseorang melakukan refactor serializer, dan rangkaian pengujian happy-path tidak akan menyadarinya.
Nilai dari kesalahan yang lebih baik
Nilai tersebut muncul di tiga tempat, dan mudah diukur setelah Anda melihatnya.
Lebih sedikit percobaan ulang yang sia-sia. Agen yang menghadapi {"error": "invalid input"} biasanya mencoba ulang payload yang sama dua atau tiga kali sebelum berhenti. Setiap percobaan memakan giliran model dan seluruh percakapan sebagai konteks. Respons yang menyebutkan bidang yang hilang biasanya menghasilkan satu percobaan yang diperbaiki. Itu adalah perbedaan antara empat panggilan dan dua pada kesalahan validasi rutin.
Lebih sedikit eskalasi. Agen yang tidak dapat pulih menyerahkan tugas kepada manusia. Setiap serah terima yang dapat dihindari adalah hasil yang mahal yang seharusnya dicegah oleh agen. Kesalahan yang menyebutkan perbaikan menjaga proses tetap dalam otomatisasi.
Debugging yang lebih singkat. Ketika sesuatu memang membutuhkan seseorang, request_id ditambah detail yang tepat mengubah pencarian melalui log menjadi satu pencarian. Ini adalah argumen yang sama yang dibuat oleh panduan observabilitas API kami tentang korelasi, diterapkan pada saat sebuah proses gagal.
Ada manfaat keempat yang mudah terlewatkan: peningkatan yang sama juga membantu pengembang manusia. Tidak ada yang pernah mengeluh bahwa pesan kesalahan terlalu spesifik tentang bidang mana yang salah.
Rancang juga untuk eskalasi
Beberapa kesalahan memang tidak dapat dipulihkan oleh agen. Lingkup yang hilang, akun yang ditutup, aturan yang membutuhkan keputusan manusia. Untuk kasus-kasus tersebut, tugas kesalahan adalah menyerahkan dengan rapi: katakan apa yang terjadi, katakan apa yang perlu dilakukan seseorang, dan bawa ID korelasi yang membuat serah terima menjadi murah.
Balasan itu harus sampai ke tempat yang dibaca manusia. Jika agen adalah runtime pengkodean yang mengerjakan tugas yang ditetapkan, platform di sekitarnya biasanya adalah tempat ia mendarat. Sharkly menyimpan hasil agen dan jejak eksekusi pada Tugas dan mengarahkan item yang membutuhkan balasan atau tinjauan ke Kotak Masuk, sehingga proses yang diblokir terlihat sebagai pekerjaan daripada sebagai baris dalam log. Teks kesalahan Anda adalah yang membuat serah terima itu berguna, karena pesan yang berbunyi "input tidak valid" tidak memberi peninjau lebih dari yang diberikannya kepada agen.

Jangan buat agen menguraikan prosa
Satu anti-pola terakhir, umum di API yang tumbuh secara organik. Kode statusnya benar, badannya adalah kalimat, dan setiap kegagalan yang berbeda mendapatkan kata-kata yang berbeda:
{ "message": "Sorry, that didn't work. Please check your details and try again." }
Agen hanya dapat merespons ini dengan menebak. Lebih buruk lagi, tim sering memasangkannya dengan status 200, sehingga pustaka klien bahkan tidak melihat kegagalan.
Dua aturan memperbaikinya. Berikan setiap kegagalan yang berbeda kode yang stabil dan dapat dibaca mesin, sehingga agen dapat bercabang pada insufficient_funds daripada pada frasa "tidak cukup". Dan jangan pernah mengembalikan kegagalan dengan kode status sukses, apa pun argumen kenyamanan sisi klien. Kode 200 dengan kesalahan di dalamnya tidak terlihat oleh setiap kebijakan percobaan ulang, setiap dashboard, dan setiap peringatan yang Anda miliki.
Daftar periksa untuk kesalahan yang dapat dibaca agen
- Setiap kesalahan menggunakan satu format terstruktur yang konsisten di seluruh API.
detailmenyebutkan bidang atau kondisi spesifik, bukan kategori.- Kesalahan validasi mengembalikan setiap masalah sekaligus, dengan jalur bidang.
- Boolean
retryablemuncul di setiap kesalahan. - Kesalahan yang dapat dicoba ulang membawa penundaan dalam detik, di header dan badan (body).
- Kegagalan penulisan menyatakan apakah ada yang dibuat atau diubah.
- Setiap kesalahan membawa ID korelasi yang dapat dilacak di log Anda.
- Tidak ada stack trace, tidak ada string framework, tidak ada SQL.
- Respons kesalahan didokumentasikan dalam spesifikasi dengan deskripsi yang dapat dibaca agen.
- Mock ada untuk setiap kesalahan, dan pengujian tersimpan menjalankannya di CI.
Kesalahan adalah antarmuka. Rancang mereka untuk pemanggil yang benar-benar Anda miliki, yang semakin sering adalah model yang akan melakukan persis seperti yang dikatakan badan respons Anda. Unduh Apidog untuk mendefinisikan bentuk kesalahan dan membuat mock-nya sebelum agen menghadapinya secara nyata.
Pertanyaan yang sering diajukan
Haruskah saya menggunakan RFC 9457 atau format kesalahan saya sendiri? Gunakan RFC 9457 kecuali Anda sudah memiliki format yang konsisten dalam produksi. Konsistensi mengalahkan standardisasi: mengganti setengah endpoint Anda ke bentuk baru lebih buruk daripada mempertahankan satu bentuk di mana pun. Tambahkan ekstensi retryable dan next_action ke mana pun yang Anda gunakan.
Apakah teks next_action aman untuk diletakkan dalam respons API? Ya, ketika layanan Anda menghasilkannya dari kumpulan template tetap. Jangan pernah mengulang konten yang disediakan pengguna ke dalam bidang itu, karena agen membacanya sebagai instruksi dan itu adalah jalur injeksi prompt. Postingan kami tentang menguji API terhadap input yang tidak tepercaya mencakup risiko tersebut.
Haruskah kesalahan validasi berupa 400 atau 422? Gunakan 400 ketika permintaan salah format, seperti JSON yang rusak, dan 422 ketika permintaan terurai tetapi gagal aturan bisnis. Agen mendapat manfaat dari pemisahan ini karena perbaikannya berbeda. Jika Anda sudah menggunakan salah satu untuk keduanya, dokumentasikan saja daripada mengubahnya.
Seberapa banyak detail yang terlalu banyak? Berhenti pada titik di mana pemanggil memiliki cukup informasi untuk bertindak. Nama bidang, aturan, dan nilai contoh biasanya sudah cukup. Pengidentifikasi internal, teks kueri, dan stack frame sudah melewati batas.
Apakah pesan kesalahan dihitung terhadap jendela konteks? Ya, dan kesalahan verbose yang diulang di seluruh percobaan ulang akan menumpuk dengan cepat. Pertahankan mereka di bawah beberapa ratus token. Postingan kami tentang memangkas respons API untuk agen berlaku untuk kegagalan maupun keberhasilan.
Bagaimana cara menghentikan agen mencoba ulang kesalahan yang tidak dapat dicoba ulang? Atur retryable: false, nyatakan demikian di next_action, dan terapkan di pembungkus alat (tool wrapper) sehingga penilaian model bukan satu-satunya penjaga. "Belt and braces" (berhati-hati secara berlebihan) adalah pendekatan yang tepat di sini.
