Pengujian Anda lulus pada hari Senin: masukan sama, kode sama, temperature=0. Pada hari Selasa, pengujian gagal tanpa perubahan kode. Assertion membandingkan string persis sama, tetapi model mengembalikan jawaban dengan sedikit perbedaan kata. Rangkaian pengujian menjadi merah, agen sebenarnya baik-baik saja, dan Anda akhirnya men-debug pengujian alih-alih produk.
Ini adalah biaya dari setiap pengujian yang memanggil model bahasa. Output dapat berubah bahkan saat suhu diatur ke nol. Sebagian besar tim akhirnya menulis ulang strategi pengujian mereka: jangan menguji kata-kata yang persis sama, tetapi uji kontrak yang tetap stabil. Panduan ini membahas mode kegagalan ketiga dari panduan tentang mengapa agen AI rusak dalam produksi.
Mengapa temperature=0 tidak berarti deterministik
Suhu mengontrol cara model memilih token berikutnya. Pada temperature=0, model memilih token dengan probabilitas tertinggi. Secara intuitif, hasilnya terlihat seharusnya dapat direproduksi, tetapi kenyataannya tidak selalu demikian.
Penyebabnya ada di seluruh tumpukan inferensi:
- Operasi floating-point pada GPU tidak selalu asosiatif. Urutan penjumlahan yang berbeda dapat menghasilkan perbedaan kecil pada digit desimal terakhir.
- Perbedaan kecil tersebut dapat mengubah token dengan peringkat tertinggi.
- Penyedia dapat mengubah pengelompokan permintaan, perangkat keras, kernel, pustaka inferensi, kuantisasi bobot, atau wilayah eksekusi.
- Satu token yang berbeda pada awal respons dapat mengubah seluruh token setelahnya.
Sebuah diskusi vLLM menjelaskan mengapa seed tetap dan temperature=0 tetap tidak menjamin reproduktibilitas bitwise. Determinisme adalah properti seluruh sistem, bukan hanya flag pada request.
Anggap output model sebagai jawaban dengan makna yang serupa, bukan string yang identik. Pengujian Anda harus dirancang untuk itu.
Mengapa assertion string persis sama membuat pengujian rapuh
Assertion berikut terlihat masuk akal:
assert(response === "Total pesanan Anda adalah $42.00.");
Namun, model dapat mengembalikan respons berikut yang tetap benar:
Total Anda menjadi $42.00.
Pengujian gagal, padahal tidak ada regresi produk.
Pengujian yang gagal pada jawaban benar lebih buruk daripada tidak memiliki pengujian. Tim akan mulai menganggap kegagalan sebagai kebisingan, menjalankan ulang pipeline sampai hijau, lalu berhenti menyelidiki kegagalan nyata. Ini adalah salah satu penyebab utama pengujian flaky, sebagaimana dibahas dalam penyebab pengujian yang rapuh.
Jangan memperketat snapshot atau memperluas perbandingan string. Itu hanya mengikat pengujian pada hal yang memang akan berubah: pilihan kata model.
Tegaskan struktur dan makna, bukan teks yang persis sama
Output dapat bervariasi, tetapi kontraknya seharusnya tetap.
Misalnya, agen dukungan dapat merumuskan konfirmasi refund dengan banyak cara. Namun, respons valid tetap harus membawa fakta yang sama:
- jumlah refund;
- ID pesanan;
- status refund;
- tidak ada data internal yang bocor.
Alih-alih bertanya:
Apakah model mengatakan kalimat ini?
Tanyakan:
Apakah respons memiliki bentuk, bidang, tipe, dan nilai yang benar?
Berikut strategi praktisnya.
Validasi respons terhadap skema JSON
Jika agen mengembalikan data terstruktur, definisikan JSON Schema dan validasi setiap respons terhadap skema tersebut.
Contoh kontrak respons refund:
{
"type": "object",
"required": ["order_id", "status", "amount"],
"properties": {
"order_id": {
"type": "string",
"pattern": "^ORD-[0-9]+$"
},
"status": {
"type": "string",
"enum": ["refunded", "pending", "denied"]
},
"amount": {
"type": "number",
"minimum": 0
}
},
"additionalProperties": false
}
Skema ini akan gagal jika model:
- menghilangkan
order_id; - mengirim
amountsebagai string; - menghasilkan status yang tidak diizinkan;
- mengembalikan prosa ketika API mengharapkan JSON;
- menambahkan bidang yang tidak diharapkan.
Muat skema respons ke Apidog dan validasi respons agen langsung terhadap kontrak tersebut. Saat gagal, Anda melihat bidang yang rusak, bukan diff string ratusan karakter.
Tegaskan bentuk dan target panggilan alat
Saat agen memanggil alat atau API, uji request-nya, bukan kalimat yang mengarah ke request tersebut.
Untuk agen pemesanan, misalnya, validasi bahwa agen:
- Memilih endpoint yang tepat:
POST /reservations. - Mengirim target yang tepat.
- Mengirim payload sesuai skema.
Contoh payload yang diharapkan:
{
"guests": 2,
"date": "2025-06-12"
}
Contoh assertion:
assert(request.method === "POST");
assert(request.path === "/reservations");
assert(Number.isInteger(request.body.guests));
assert(/^\d{4}-\d{2}-\d{2}$/.test(request.body.date));
Periksa juga bahwa parameter wajib tersedia dan tidak ada parameter buatan model yang ikut terkirim. Metode end-to-end untuk menguji panggilan API agen AI membahas pendekatan ini lebih lanjut.
Gunakan rentang numerik, bukan nilai persis
Untuk angka yang dihasilkan atau diteruskan model, gunakan batas bawah dan batas atas.
Misalnya, agen keranjang belanja menghitung total. Anda mungkin tidak ingin mengunci nilai total tertentu untuk semua variasi keranjang, pajak, dan pengiriman. Namun, Anda tahu total tidak boleh negatif dan tidak boleh lebih tinggi dari batas bisnis yang valid.
assert(response.total >= 0);
assert(response.total <= cartSubtotal + maxShipping + maxTax);
Pemeriksaan ini menangkap kegagalan penting:
- total negatif;
- total nol untuk keranjang berisi item;
- total terlalu besar;
- angka yang salah format.
Gunakan pola yang sama untuk:
- skor kepercayaan;
- jumlah item;
- penggunaan token;
- anggaran latensi;
- angka turunan lainnya.
Pilih batas yang cukup longgar untuk menerima variasi valid, tetapi tetap cukup ketat untuk menangkap bug nyata.
Periksa bidang wajib dan bidang terlarang
Dua assertion sederhana memberikan perlindungan besar:
- Bidang yang diperlukan harus ada dan tidak boleh
null. - Bidang yang dilarang tidak boleh muncul.
Contoh untuk agen dukungan:
assert(response.resolution != null);
assert(!("internal_notes" in response));
assert(!("raw_prompt" in response));
Pemeriksaan ini tidak bergantung pada pilihan kata. Selain itu, ia melindungi dari kelas masalah privasi ketika model menyertakan data internal yang seharusnya tidak terlihat oleh pengguna.
Gunakan pemeriksaan semantik untuk teks bebas
Kadang respons memang harus berupa prosa. Dalam kasus ini, jangan membandingkan seluruh string.
Uji properti yang relevan:
assert(response.message.includes(orderId));
assert(response.message.length <= 500);
assert(!response.message.includes("internal_notes"));
Jika Anda perlu menguji kesamaan makna, bandingkan embedding respons dengan jawaban referensi dan gunakan ambang batas:
assert(semanticSimilarity(response.message, expectedMessage) >= 0.85);
Gunakan pemeriksaan semantik sebagai gerbang kasar. Pemeriksaan ini dapat menangkap respons yang melenceng dari topik, tetapi tidak selalu mendeteksi kesalahan faktual yang halus. Tetap pasangkan dengan validasi struktur, tipe, dan rentang.
Snapshot rentang, bukan snapshot teks
Snapshot tetap berguna jika yang Anda snapshot adalah bagian stabil dari respons.
Snapshot yang baik mencatat:
- kumpulan kunci;
- tipe data;
- nilai enum;
- struktur objek;
- rentang numerik.
Hindari snapshot seperti ini:
"Pesanan Anda telah berhasil diproses dengan total $42.00."
Lebih baik snapshot kontrak seperti ini:
{
"required_keys": ["order_id", "status", "total"],
"status_enum": ["pending", "confirmed", "cancelled"],
"total_range": [0, 10000]
}
Dengan begitu, snapshot gagal saat ada perubahan struktural yang perlu ditinjau, bukan hanya karena model memilih sinonim.
Status dan memori membuat pengujian lebih sulit
Semua strategi di atas paling mudah diterapkan pada pola satu request, satu response. Agen biasanya memiliki memori dan status lintas giliran.
Jawaban agen dapat berubah karena:
- dokumen retrieval diberi peringkat berbeda;
- memori sebelumnya berubah;
- ringkasan percakapan pada giliran awal memengaruhi keputusan berikutnya;
- urutan percakapan berubah.
Artinya, variasi berasal dari dua sumber:
- Non-determinisme model.
- Perbedaan status awal agen.
Pelajari sumber status ini melalui panduan tentang cara kerja memori agen AI.
Gunakan dua kebiasaan berikut:
1. Reset status ke kondisi awal yang diketahui
Sebelum setiap pengujian, setel memori agen ke fixture yang konsisten.
beforeEach(async () => {
await resetAgentMemory({
userId: "test-user-001",
messages: []
});
});
Dengan begitu, pengujian hanya mengukur perilaku yang sedang diuji, bukan efek dari percakapan sebelumnya.
2. Uji invarian yang tidak bergantung pada jalur
Untuk agen stateful, jangan selalu menguji urutan kata atau langkah internal. Uji kondisi akhir yang harus selalu benar.
Contoh:
assert(account.balance >= 0);
assert(reservations.filter(r => r.flightId === flightId).length === 1);
Percakapan dapat mengambil jalur berbeda, tetapi agen yang memesan satu penerbangan tetap harus menghasilkan tepat satu reservasi.
Mock dependensi agar pengujian dapat diulang
Jangan menjalankan seluruh suite terhadap API pihak ketiga yang aktif. API eksternal dapat:
- membatasi laju request;
- mengubah data;
- mengalami downtime;
- menambahkan sumber variasi di luar perilaku agen.
Mock setiap dependensi yang bukan fokus pengujian.
Contoh:
mockPaymentApi.reply({
status: 200,
body: {
receipt_id: "rcpt_test_001",
status: "paid"
}
});
mockSearchApi.reply({
status: 200,
body: {
results: [
{ id: "doc-1", title: "Kebijakan Refund" },
{ id: "doc-2", title: "Status Pesanan" },
{ id: "doc-3", title: "Bantuan Pembayaran" }
]
}
});
Dengan mock:
- API pembayaran selalu mengembalikan receipt yang sama;
- API pencarian selalu mengembalikan hasil yang sama;
- Anda dapat memaksa kasus ekstrem;
- variasi yang tersisa lebih fokus pada perilaku agen.
Gunakan Apidog untuk menyiapkan mock dependency dengan body yang stabil dan dapat dikontrol, lalu pasangkan dengan assertion skema. Ini adalah bagian dari praktik pengujian AI agentic, tempat mocking dan assertion bekerja bersama.
Di mana Apidog cocok, dan di mana tidak
Gunakan alat sesuai perannya.
Apidog adalah platform untuk desain, pengujian, dan mocking API. Apidog bukan:
- framework agen;
- host model;
- runtime agen;
- orkestrator langkah agen;
- platform evaluasi penalaran;
- platform observabilitas agen.
Apidog cocok pada lapisan API tempat agen berkomunikasi. Gunakan untuk:
- memvalidasi skema respons agen;
- memeriksa bentuk payload panggilan alat;
- menguji rentang numerik;
- memeriksa bidang wajib dan terlarang;
- membuat mock dependency yang stabil.
Singkatnya: gunakan Apidog untuk menguji kontrak request dan response, bukan untuk menilai model yang menghasilkan respons tersebut.
Uji kontraknya, bukan kata-katanya
Non-determinisme bukan bug yang dapat dihilangkan hanya dengan konfigurasi. temperature=0 tidak menjamin output identik.
Agen yang andal diuji berdasarkan hal-hal yang tetap konstan:
- skema;
- struktur respons;
- tipe data;
- rentang nilai;
- enum;
- bidang wajib;
- bidang terlarang;
- invarian status;
- kontrak request alat.
Mulailah minggu ini dengan satu assertion rapuh. Ubah assertion string persis sama menjadi validasi skema dan rentang. Dengan pendekatan ini, rangkaian pengujian tetap hijau saat kata-kata berubah, lalu menjadi merah hanya ketika kontrak benar-benar rusak.
Top comments (0)