Membangun Agent yang Bisa Berkata “Saya Tidak Tahu”
AI kadang lebih memilih menjawab, menyetujui, dan terdengar yakin daripada mengakui bukti yang kurang. Gue bahas abstention, confidence calibration, citation requirement, dan fallback ke manusia.
0xNN · · 10 min read
Agent yang selalu menjawab bukan berarti agent yang bagus
Gue pernah melihat agent menjawab pertanyaan dengan sangat percaya diri, padahal input yang diberikan belum cukup untuk mengambil kesimpulan.
Masalahnya bukan hanya hallucination. Kadang agent memang tahu bahwa datanya kurang, tetapi tetap memilih menyusun jawaban karena seluruh alur sistem memberi hadiah pada satu hal: harus ada respons.
User bertanya. Agent menjawab. Test dianggap lewat. Dashboard mencatat success.
Padahal untuk banyak kasus, respons terbaik seharusnya:
“Saya belum bisa memastikan. Saya butuh address contract, versi dokumen, atau bukti tambahan.”
Kalimat itu terlihat sederhana. Membuat sistem yang berani mengucapkannya jauh lebih sulit.
---
Kenapa agent suka terdengar yakin?
Model bahasa dilatih untuk menghasilkan kelanjutan teks yang masuk akal. Ia bukan detektor kebenaran bawaan. Ketika prompt berbentuk pertanyaan, pola yang paling mudah adalah memberikan jawaban yang terdengar lengkap.
Beberapa hal membuat masalah ini lebih parah:
• system prompt terlalu menekankan “always be helpful”;
• tidak ada state insufficient_evidence;
• evaluator hanya memberi nilai pada jawaban, bukan kejujuran;
• tool gagal tetapi error disembunyikan dari agent;
• user menyampaikan premis yang salah dan agent langsung menyetujuinya;
• confidence ditulis model sendiri tanpa dikaitkan dengan bukti.
Kalau seluruh pipeline menghukum jawaban kosong dan tidak menghukum jawaban salah, agent akan belajar bahwa menebak lebih aman daripada berhenti.
---
Abstention: kemampuan untuk tidak menjawab
Abstention berarti agent sengaja tidak memberi kesimpulan ketika syarat minimal belum terpenuhi. Ini bukan tombol global yang berkata “selalu ragu”. Agent tetap harus menjawab pertanyaan yang bisa dijawab.
Gue biasanya memisahkan tiga kondisi:
| Kondisi | Respons yang tepat |
|---|---|
| Data cukup dan bukti mendukung | Jawab dengan sumber |
| Data ada tetapi konflik | Jelaskan konflik dan minta konteks |
| Data tidak cukup atau tool gagal | Abstain dan sebutkan data yang kurang |
Abstention yang baik bukan hanya “saya tidak tahu”. Ia harus memberi alasan operasional:
{
"status": "insufficient_evidence",
"answer": null,
"missing": ["contract_address", "chain"],
"next_step": "Ask the user for the chain and address"
}
Dengan format ini, UI dapat menampilkan pertanyaan lanjutan dan sistem dapat membedakan abstention yang sehat dari error.
---
Confidence bukan hiasan angka
Angka confidence: 0.92 sering terlihat ilmiah, tetapi angka yang dihasilkan model sendiri belum tentu terkalibrasi. Model bisa yakin pada jawaban yang salah dan ragu pada jawaban yang benar.
Confidence seharusnya dihitung dari sinyal yang bisa diperiksa, misalnya:
• apakah sumber primer ditemukan;
• apakah dua sumber independen setuju;
• apakah tool selesai tanpa error;
• apakah input berada dalam scope data;
• apakah klaim cocok dengan hasil query;
• apakah pertanyaan membutuhkan prediksi atau fakta.
Lebih baik memakai label yang punya arti jelas:
verified = ada bukti langsung yang cocok
supported = didukung sumber, tetapi ada batasan
uncertain = bukti tidak lengkap atau konflik
unverified = belum ada bukti yang bisa diperiksa
Kalau angka tetap dibutuhkan, dokumentasikan bagaimana angka itu dibuat dan uji calibration-nya dengan dataset yang benar-benar terpisah dari data prompt.
---
Citation requirement: klaim tanpa sumber bukan fakta
Untuk agent riset, citation bukan dekorasi di akhir jawaban. Citation adalah bagian dari kontrak output.
Setiap klaim penting sebaiknya punya:
1. URL atau identifier sumber;
2. bagian atau halaman yang relevan;
3. kutipan atau data yang mendukung;
4. batasan yang tidak didukung sumber.
Agent tidak boleh membuat URL hanya agar formatnya terlihat lengkap. Jika sumber tidak ditemukan, statusnya harus unverified.
Contoh output yang lebih jujur:
{
"claim": "Contract source is verified",
"status": "supported",
"evidence": [{
"url": "https://example.com/explorer",
"note": "Explorer reports verified source at block 123"
}],
"limitation": "This does not prove the contract is safe"
}
Citation juga tidak otomatis membuat klaim benar. Sumber harus dibaca dan cocok dengan klaimnya.
---
Fallback ke manusia bukan tombol panik
Fallback yang buruk hanya berkata “hubungi admin”. Fallback yang baik menyiapkan paket keputusan untuk manusia:
• pertanyaan asli;
• data yang ditemukan;
• data yang hilang;
• langkah yang sudah dicoba;
• sumber yang dipakai;
• risiko jika keputusan salah;
• pertanyaan yang perlu dijawab manusia.
Untuk deploy production, transfer uang, penghapusan data, keputusan hukum, atau temuan security high severity, agent seharusnya berhenti pada draft dan meminta approval.
Manusia tidak perlu mengulang seluruh investigasi. Tugas agent adalah membuat keputusan manusia lebih mudah diperiksa, bukan diam-diam menggantikannya.
---
Cara menguji agent yang bisa abstain
Jangan hanya menguji pertanyaan yang jawabannya ada di dataset. Buat empat kelompok eval:
1. Answerable — semua data tersedia dan jawaban bisa diverifikasi.
2. Missing context — parameter wajib hilang.
3. False premise — pertanyaan mengandung asumsi yang salah.
4. Conflicting evidence — dua sumber memberi hasil berbeda.
Ukur setidaknya:
• akurasi jawaban;
• precision ketika agent menyatakan verified;
• recall untuk kasus yang seharusnya abstain;
• kualitas citation;
• jumlah tool call yang tidak perlu;
• apakah agent melakukan escalation pada risiko tinggi.
Agent yang selalu menjawab bisa mendapat skor completion tinggi tetapi skor trust rendah. Evaluasi harus memberi penghargaan pada keputusan berhenti yang tepat.
---
Kontrak output sederhana
Salah satu pola yang bisa gue pakai:
{
"status": "verified | supported | uncertain | insufficient_evidence | needs_human",
"answer": "string or null",
"confidence": "high | medium | low",
"evidence": [],
"limitations": [],
"next_step": "string or null"
}
Yang penting bukan nama field-nya. Yang penting aplikasi tidak memaksa semua request berakhir sebagai paragraf jawaban.
---
Penutup
Saya tidak ingin agent yang selalu mengatakan “benar” hanya karena user terdengar yakin. Saya ingin agent yang bisa membedakan fakta, dugaan, dan data yang belum ada.
“Saya tidak tahu” bukan kegagalan jika kalimat itu mencegah keputusan yang salah. Kegagalan sebenarnya adalah agent menyembunyikan ketidakpastian di balik jawaban yang rapi.
Mulai dari hal kecil: tambahkan state insufficient_evidence, wajibkan citation untuk klaim penting, simpan alasan abstention, dan buat jalur approval untuk aksi berisiko.
Agent yang bisa berhenti pada waktu yang tepat mungkin terlihat kurang pintar saat demo. Di production, justru itu yang membuatnya layak dipercaya.
---
Sumber
• Anthropic: Demystifying evals for AI agents
• NIST AI Risk Management Framework
• Google Search: Guidance on using generative AI content
• OWASP Securing Agentic Applications Guide
*Ditulis setelah melihat agent yang lebih takut terlihat tidak membantu daripada takut memberikan jawaban yang salah.*