Merilis fitur AI pertamamu — apa yang salah kulakukan

Sebuah retrospektif tentang fitur AI nyata pertama yang aku rilis: demo yang berhasil, production yang tidak, dan empat hal yang ingin kusampaikan ke diriku yang lebih muda.

6 menit baca
  • ai
  • retrospective
  • craft
  • shipping

Itu hari Selasa. Ruang rapat itu punya cahaya khas sore Bandung — oranye menembus kisi-kisi jendela, semua orang masih agak lesu setelah makan siang. Kami berlima di meja: CEO, CPO, dua product manager, dan aku. Laptop sudah terbuka, rekaman Loom sudah siap sebagai cadangan, jaga-jaga kalau demo langsung macet.

Tidak macet. Itu indah.

Aku sudah membangun sebuah fitur yang membaca tiket support pengguna — teks bebas, bahasa apa pun yang mereka ketik — lalu menyusun respons pertama. Model itu menangkap konteks, mencocokkan nada, menyarankan langkah penyelesaian. Dalam demo, setiap kasus yang kulemparkan ditangani dengan ketenangan dan kompetensi yang membuat ruangan hening.

CEO bersandar ke kursinya. “Ship it.”

Aku tersenyum. Aku bilang staging-nya siap Kamis.

Dan aku tidak mengatakan apa-apa tentang hal yang sudah menggangguku sepanjang minggu: bahwa aku baru mengujinya pada 100 tiket yang sudah kupilih sendiri. Bahwa aku tidak tahu apa yang akan dilakukannya terhadap 40.000 tiket lainnya.

Apa yang rusak

Fitur itu tayang hari Jumat. Senin pagi, sudah ada dua belas eskalasi.

Bukan dari kasus yang sudah kuuji. Tapi dari satu jenis input yang memalukan — yang tidak terpikirkan untuk kumasukkan: tiket di mana pengguna salah mengetik nama produk.

Produk kami bernama “Solvr.” Pengguna menulis “Solver,” “Solvir,” “Slvr,” “SOLVR,” “solvr.ai.” System prompt-ku berbunyi: You are a support agent for Solvr. Respond only to issues related to Solvr products. Ketika nama tidak cocok persis, model — GPT-4-turbo waktu itu, pertengahan 2024 — kadang memutuskan tiket itu di luar topik dan membalas dengan pesan sopan yang menyatakan pertanyaan itu bukan urusannya. Kepada pengguna yang baru saja membayar langganan dan salah mengetik satu huruf.

Satu tiket berbunyi: “Hi, I can’t log in to Solvir, been trying for 20 minutes.” Model membalas: “It looks like your question may be about a different product. For Solvr support, please visit our help centre.” Balasan pengguna tiga kata. Tidak ada yang bisa dicetak.

Aku sudah menguji 100 kasus. Setiap kasus menggunakan nama produk yang tepat. Aku tanpa sengaja mengevaluasi titik butaku sendiri.

Modus kegagalannya bukan bencana dalam artian kehilangan data atau kebocoran keamanan. Justru lebih buruk, dalam caranya sendiri. Ini diam-diam, konsisten, dan merendahkan. Membuat produk terasa rusak bagi pengguna yang paling membutuhkannya — yang sudah frustrasi, yang paling tidak mungkin mengetik dengan hati-hati.

Itulah masalah sistem probabilistik. Mereka tidak gagal secara seragam. Mereka gagal di tepi. Dan tepi itu persis tempat di mana pengguna berada saat paling rentan.

Pivot

Kami menarik fitur respons otomatis itu. Aku menghabiskan seminggu membangun ulang dengan langkah human-review di dalam loop.

Arsitektur barunya: model menyusun respons, tapi masuk ke antrean agen support dulu — tidak langsung ke pengguna. Agen melihat draftnya, mengedit kalau perlu, lalu mengirimnya. Kalau skor confidence model (aku sudah menambahkan langkah eval — sebentar lagi kujelaskan) di bawah ambang batas, tiket itu melewati draft sama sekali dan langsung masuk antrean dengan flag penanganan manual.

Ini lebih lambat. Pitch awalnya adalah “mengurangi first-response time sebesar 60%.” Dengan langkah review, kami hanya sampai sekitar 35%. CEO bertanya kenapa. Aku menjelaskan. Dia paham. Tapi aku harus berkata lantang, dalam sebuah rapat, bahwa aku merilis tanpa pengujian yang cukup dan angka yang aku janjikan tidak bisa dicapai pada standar kualitas yang kami butuhkan.

Percakapan itu tidak nyaman dengan cara yang ingin kunamai: aku sudah mencampuradukkan demo velocity dengan production reliability. Dalam demo, akulah manusia dalam loop. Aku yang memilih tiket mana yang ditampilkan, dan aku yang membaca output-nya sebelum ke mana pun. Aku mengeluarkan diri dari loop saat merilis. Aku lupa bahwa selama ini akulah yang melakukan itu.

Langkah eval yang kutambahkan tidak canggih. Aku menggunakan pendekatan Simon Willison — panggilan model kedua yang menilai draft respons berdasarkan tiga kriteria: relevansi dengan tiket, tidak adanya detail produk yang hallucinated, dan nada yang tepat. Apa pun yang di bawah composite threshold 0,75 masuk antrean. Ini menambah latency 400–600ms. Dalam bulan pertama, sekitar 8% draft tertangkap. Setiap satu dari mereka adalah draft yang tidak ingin kukirim.

Jalur demo: Input, Model, OK. Jalur produksi: Input, Eval, Model, Cek keyakinan, Fallback, Logging, Output
Jalur demo lurus. Jalur produksi adalah jalur demo plus semua yang belum kamu bangun.

Empat hal yang ingin kusampaikan ke diriku yang lebih muda

Soal demo velocity versus production reliability. Demo bukan bukti konsep. Demo adalah skenario terbaik yang kamu konstruksi dengan bias seleksi. Test set-mu akan selalu lebih mudah dari dunia nyata, karena kamu membuatnya sebelum memahami dunia nyata. Pertanyaan yang harus ditanyakan sebelum merilis bukan “apakah ini berhasil?” — tapi “apa yang terjadi saat ini tidak berhasil?” Aku tidak punya jawaban untuk pertanyaan itu. Aku seharusnya menolak merilis sampai aku punya.

Soal “mostly works” sebagai jawaban yang berbahaya dalam sistem probabilistik. Kode tradisional entah menangani input atau melempar exception. Kamu tahu soal kegagalannya. Sistem probabilistik melakukan hal yang lebih buruk: mereka menangani input dengan percaya diri dan salah, lalu terus berjalan. Andrej Karpathy menyinggung ini saat menulis tentang Software 2.0 — modus kegagalan sistem yang dipelajari secara kualitatif berbeda dari kode yang ditulis. “Mostly works” dalam sistem deterministik artinya 95% pengguna punya pengalaman baik. “Mostly works” dalam sistem probabilistik artinya 5% pengguna punya pengalaman yang begitu buruk sampai mereka eskalasi. Yang 5% itu tidak tersebar acak. Mereka mengelompok di tepi, di input yang tidak biasa, di pengguna yang frustrasi. Di situlah reputasi produkmu sesungguhnya hidup.

Soal evaluation sebagai product surface, bukan pekerjaan backend. Aku memperlakukan eval sebagai sesuatu yang dilakukan sebelum merilis untuk meyakinkan diri sendiri bahwa semuanya berjalan. Itu terbalik. Eval adalah detak jantung yang berkelanjutan dari sebuah fitur AI. Panduan Anthropic tentang evaluating AI systems menyatakan ini dengan jelas: evaluasi bukan gerbang pra-deployment, melainkan disiplin yang terus-menerus. Eval suite-mu harus berkembang setiap kali kamu menemukan modus kegagalan baru. Punyaku dimulai dari 100 kasus pilihan dan kini sudah 2.300, sebagian besar disumbang oleh kegagalan production nyata. Fiturnya secara terukur lebih baik karenanya. Aku seharusnya memulai disiplin ini sebelum merilis, bukan sesudahnya.

Soal kerendahan hati yang menghadap pengguna. Fitur itu seharusnya bisa berkata “aku tidak yakin.” Seharusnya menunjukkan kepada pengguna kapan ia beroperasi dengan confidence rendah, memberi mereka jalan jelas ke manusia, membuat fallback-nya terlihat. Alih-alih, aku merilis fitur yang sama yakinnya entah benar atau benar-benar salah. Itu bukan sekadar masalah UX kecil — itu masalah kepercayaan. Ketika pengguna tidak bisa membedakan kapan harus mempercayai AI dan kapan tidak, mereka belajar untuk tidak mempercayainya sama sekali. Bangun ketidakpastian ke dalam tampilan. Biarkan fitur itu jujur tentang batasnya. Pengguna jauh lebih baik menangani ketidakpastian yang jujur daripada kesalahan yang percaya diri.

Pelajaran yang tidak mencolok

Semua yang salah kulakukan, salah karena aku memperlakukan ini sebagai masalah rekayasa baru yang membutuhkan pemikiran baru. Tidak begitu.

Merilis fitur AI adalah merilis produk. Disiplin yang sama berlaku: pahami modus kegagalanmu sebelum kamu ada di dalamnya; uji di tepi, bukan hanya di tengah; masukkan manusia ke dalam loop sampai kamu mempercayai sistemnya; bangun observability dari hari pertama. Tidak ada dari itu yang saran khusus AI. Itu hanya rekayasa.

Hal yang benar-benar baru adalah bentuk modus kegagalannya. Kegagalan probabilistik lebih diam, lebih tersebar, dan lebih sulit ditangkap dalam review daripada exception atau null pointer. Itu membutuhkan strategi pengujian yang berbeda — lebih banyak cakupan, kasus adversarial, eval suite yang berkembang terus-menerus. Tapi kerigorannya sama. Aku hanya lupa menerapkannya karena demo-nya begitu bagus dan CEO berkata “ship it” dan aku ingin menjadi orang yang merilis itu.


Kalau aku bisa kembali ke ruang rapat itu — Selasa sore, cahaya oranye, semua orang masih agak lesu setelah makan siang — aku tidak akan membatalkan demo-nya. Demo itu sungguh bagus. Aku akan menunggu ruangan tenang, lalu berkata:

“Ini bekerja dengan indah pada kasus yang sudah kuuji. Aku butuh dua minggu lagi untuk memahami apa yang dilakukannya pada kasus yang belum.”

CEO pasti akan bilang ya. Mereka selalu bilang ya ketika kamu terdengar tahu apa yang kamu lakukan. Dan tahu apa yang kamu lakukan artinya tahu apa yang belum kamu ketahui.

Itulah versi diriku yang sedang aku coba rilis.