Kita telah menempuh seluruh siklus deployment: artefak tersimpan, pipeline terangkai, layanan hidup, batch terjadwal, model dipantau, diperbarui dengan aman. Chapter penutup section ini berisi pengakuan yang jujur: model bukan software biasa, dan tidak semua masalah layak dijawab dengan model produksi. Software yang lolos uji hari ini akan berperilaku sama tahun depan; model yang lolos uji hari ini bisa diam-diam meluruh karena dunia yang dibacanya berubah. Kita rangkum empat batasan tersebut, lengkap dengan kewajiban yang melekat begitu model dipakai orang lain — dan tutup dengan daftar kapan deployment sebaiknya tidak dilakukan sama sekali.

Model Bukan Software Biasa #

Perbedaan mendasarnya bisa dirangkum dalam satu tabel:

AspekSoftware biasaModel machine learning
Perilaku seiring waktustabil, berubah hanya bila kode diubahmeluruh pelan bila data bergeser — kode tidak berubah pun
Cara mengujiunit test yang mengunci perilaku persisevaluasi statistik pada sampel; jawaban benar sebagian besar, tidak selalu
Cara memperbaikiperbaiki kode yang salah, rilis ulanglatih ulang dengan data terbaru, lewati prosedur juara-penantang
Yang membuatnya rusakkesalahan pemrogramankesalahan pemrograman dan perubahan dunia

Baris pertama tabel itulah sebabnya babak deployment tidak pernah benar-benar selesai: pemantauan, deteksi perubahan, dan pembaruan model bukan proyek tambahan, melainkan konsekuensi dari sifat model itu sendiri. Tim yang menganggap rilis model sebagai garis akhir akan menemukan garis akhirnya di tempat lain — biasanya pada laporan pemantauan yang memburuk tanpa ada yang membaca.

Dua konsekuensi lain mengikuti. Biaya komputasi berjalan terus: layanan real-time menuntut mesin yang hidup sepanjang waktu, prediksi batch menghabiskan sumber daya setiap jadwalnya, dan pelatihan ulang menambah tagihan tepat saat datanya membesar. Kedua, dependensi harus terkunci: artefak model bukan barang mandiri, ia hanya hidup pada lingkungan yang sama dengan yang membentuknya.

Dependensi yang Harus Terkunci #

Kode berikut mencetak versi library pada lingkungan tempat artefak churn kita dibuat — empat baris yang murah ditulis dan mahal dilupakan:

python
import joblib
import numpy
import pandas
import sklearn

print("versi lingkungan tempat artefak dibuat:")
print(f"  scikit-learn : {sklearn.__version__}")
print(f"  pandas       : {pandas.__version__}")
print(f"  NumPy        : {numpy.__version__}")
print(f"  joblib       : {joblib.__version__}")

Output yang Dihasilkan:

text
versi lingkungan tempat artefak dibuat:
  scikit-learn : 1.5.2
  pandas       : 2.2.3
  NumPy        : 2.1.3
  joblib       : 1.5.3

Mari kita telaah bagian-bagian pentingnya:

  1. Baris 6-10 (versi sebagai fakta lingkungan): keempat angka ini adalah sidik jari lingkungan pelatihan — sama pentingnya dengan metadata.json pada chapter Menyimpan Model .
  2. Makna praktisnya: memuat artefak joblib dengan scikit-learn versi lain bisa gagal atau, lebih buruk, berhasil diam-diam dengan perilaku berbeda. Praktik amannya: kunci versi pada berkas dependensi (pola yang diperkenalkan chapter Manajemen Dependensi ) dan gunakan satu lingkungan konsisten untuk melatih serta melayani model.

Human-in-the-Loop untuk Keputusan Berisiko #

Batasan yang paling sering diabaikan bukan teknis, melainkan soal siapa yang memutuskan. Prediksi model adalah usulan, bukan putusan; semakin besar dampaknya kepada manusia, semakin besar porsi penilaian manusia yang harus dipertahankan — pola human-in-the-loop. Kode berikut membagi jalur keputusan berdasarkan dua hal: seberapa yakin model, dan seberapa besar dampak tindakannya.

python
import numpy as np
from sklearn.linear_model import LogisticRegression

rng = np.random.default_rng(42)
n = 60
kunjungan = rng.integers(1, 15, n)
belanja = rng.integers(50, 350, n)
skor = 0.8 * (8 - kunjungan) + 0.02 * (belanja - 180) + rng.normal(0, 3, n)
churn = (skor > np.quantile(skor, 0.6)).astype(int)
X = np.column_stack([kunjungan, belanja])
model = LogisticRegression(max_iter=1000).fit(X, churn)


def arahkan_keputusan(baris, dampak):
    kunjungan, belanja = baris
    peluang = float(model.predict_proba([[kunjungan, belanja]])[0, 1])
    ragu = 0.35 <= peluang <= 0.65
    if dampak == "tinggi":
        if ragu:
            return f"{baris} peluang {peluang:.3f} (model ragu) -> analisis oleh manusia"
        return f"{baris} peluang {peluang:.3f} (model yakin) -> usulan model, persetujuan manusia"
    return f"{baris} peluang {peluang:.3f} -> tindakan otomatis"


print(arahkan_keputusan([12, 90], "rendah"))
print(arahkan_keputusan([7, 180], "rendah"))
print(arahkan_keputusan([7, 180], "tinggi"))
print(arahkan_keputusan([2, 300], "tinggi"))

Output yang Dihasilkan:

text
[12, 90] peluang 0.007 -> tindakan otomatis
[7, 180] peluang 0.395 -> tindakan otomatis
[7, 180] peluang 0.395 (model ragu) -> analisis oleh manusia
[2, 300] peluang 0.989 (model yakin) -> usulan model, persetujuan manusia

Mari kita telaah bagian-bagian pentingnya:

  1. Baris 17 (zona keraguan): peluang 0,35-0,65 adalah wilayah abu-abu — model tidak cukup yakin ke arah mana pun. Pelanggan [7, 180] dengan peluang 0,395 jatuh tepat di zona ini.
  2. Baris 18-21 (dampak menentukan jalur): keputusan berdampak tinggi tidak pernah sepenuhnya otomatis — model yang ragu diserahkan untuk dianalisis manusia, model yang yakin pun tetap berstatus usulan yang menunggu persetujuan.
  3. Baris 22 (dampak rendah otomatis): untuk tindakan murah dan mudah dibalik (misalnya menandai pelanggan di dasbor), prediksi langsung dieksekusi — menahan semuanya di tangan manusia justru membuat sistem tidak berguna.

Pembagiannya dirancang dari dua pertanyaan: berapa besar kerugian bila model salah, dan berapa mudah kesalahan itu diperbaiki. Menawarkan kupon retensi yang keliru sasaran murah dan terbalik; menolak pengajuan kredit berdasarkan model adalah keputusan yang menyangkut hidup orang — dan tidak selayaknya diserahkan penuh pada model.

Kapan Deployment Tidak Diperlukan #

Daftar terakhir ini sama pentingnya dengan seluruh babak sebelumnya. Empat kondisi berikut adalah tanda bahwa model sebaiknya tidak (dulu) dipasangkan ke produksi:

KondisiMengapa deployment tertunda
Keputusan tidak berulanganalisis sekali-jalan cukup dijawab laporan; membangun layanan untuk satu pemakaian adalah pemborosan
Model tidak mengalahkan aturan sederhanabila aturan “kunjungan di bawah 3 = tindak lanjut” bekerja sama baiknya, kompleksitas model hanya menambah beban perawatan
Tidak ada kapasitas pemantauanmodel tanpa pemantauan adalah masalah yang pasti menganga belakangan — menunda rilis lebih jujur daripada menandatangani pemeliharaan yang tidak akan dijalankan
Dasar penggunaan datanya belum jelasmemproses data pribadi tanpa dasar yang sah adalah persoalan etika dan hukum — bahasan Section berikutnya

Baris terakhir tabel itu mengantar kita ke wilayah yang selama ini berdiri di sisi lain meja. Sepanjang delapan chapter ini kita sibuk dengan pertanyaan teknis — bagaimana menyimpan, melayani, memantau, memperbarui. Padahal setiap keputusan teknis itu menyentuh manusia: pelanggan yang datanya dipakai, pelamar yang skornya dihitung, pasien yang penanganannya diprioritaskan. Pertanyaan “bolehkah kita memakai data ini, dan siapa bertanggung jawab bila salah” tidak bisa dijawab oleh pipeline maupun metrik. Section Etika dan Tata Kelola Data mengambil alih dari sini — dan kita mulai dari yang paling mendasar: privasi data.

Rangkuman #

  • Model bukan software biasa: perilakunya meluruh seiring perubahan data meski kodenya tetap, sehingga pemantauan dan pembaruan adalah bagian tak terpisahkan dari deployment, bukan tambahan.
  • Biaya komputasi berjalan terus dan dependensi wajib terkunci: versi library tempat artefak dibuat adalah bagian dari identitas artefak.
  • Human-in-the-loop menjaga porsi penilaian manusia: semakin berisiko keputusan, semakin kecil kewenangan otomatis model — zona keraguan dan tingkat dampak menentukan jalurnya.
  • Deployment layak ditunda bila keputusan tidak berulang, aturan sederhana sudah cukup, tidak ada kapasitas pemantauan, atau dasar penggunaan datanya belum jelas.

Referensi: