Skip to content
Konsultasi

Tabel RAMP yang Menghantui Scheduler Artikel

Adityo Guni Waluyo

Dari tabel RAMP 6+6 per hari ke trigger event-driven: cursor per-entry, budget siklus, dan embedding dedup lokal bge-m3.

Tabel RAMP yang Menghantui Scheduler

Sore itu, lagi ngeliat articles.py, ada tabel RAMP yang nganggur di baris 42. Isinya jadwal naik-tahap artikel harian: minggu pertama 2+2, minggu kedua 4+4, minggu ketiga 6+6. Target final: 12 URL per hari, 6 Indonesia, 6 Inggris. Scheduler dibangunin di jadwal tetap tiap hari, ngecek cap --strict, lalu bangunin agent walau nggak ada commit baru. Wake-up kosong = token terbuang percuma.

Awalnya gue pikir, "Ya udah, biarin aja, kan targetnya jelas." Tapi pas jalan beberapa hari, gue sadar ada yang aneh: agent nulis artikel padahal nggak ada bahan. Commit terakhir masih sama dari kemarin, tapi scheduler tetep jalan, ngecek cap, lalu nge-spawn agent. Token LLM kebakar cuma buat nulis ulang artikel yang udah ada.

Cursor yang Jujur

Gue putusin buat hapus tabel RAMP sama command cap --strict dari tool. Gantiin dengan trigger event-driven: monitor tanpa LLM ngecek timeline commit internal tiap 15 menit, nggak pake jadwal harian. Tick monitor semahal itu murah karena nggak ada LLM yang dipanggil, cuma bandingin output dan maju kalau ada entri baru. Entri baru itu masuk antrian, diproses batch maksimal 3 per siklus, urut dari yang paling lama. Cursor advance <id> cuma jalan setelah publish sukses, dua bahasa sekaligus. Kalau crash di tengah, entri yang sama diproses ulang siklus berikutnya. Gagal publish dua kali retry? Langsung fail --reason validation, masuk index permanen biar nggak nge-loop bangunin agent terus.

Lock anti-overlap juga gue pasang: kalau siklus sebelumnya masih jalan, siklus baru nggak bakal mulai. Budget dibatesin: maksimal 3 entri per siklus, 15 menit riset per entri. Ini biar agent nggak kebablasan ngejar quota, tapi fokus ke kualitas.

Dedup yang Nggak Ribet

Tiga lapisan dedup gue susun:

  1. Exact-match meta.source_commit kalau udah pernah diproses, skip.
  2. Covered index cek apakah commit udah ke-cover artikel published.
  3. Embedding similarity bandingin pesan commit baru vs topik artikel yang udah ada.

Lapisan ketiga penting karena judul commit sering nggak nulis keyword yang sama persis sama artikel lama. Keyword matching gampang bocor. Makanya gue pilih embedding: Ollama lokal, model bge-m3 (1024 dim, context 8K token, dukung 100+ bahasa; spesifikasinya ada di halaman modelnya), jadi judul commit bahasa Indonesia vs artikel bahasa Inggris tetep bisa dibandingin. Vektor dari endpoint /api/embed otomatis L2-normalized, jadi cosine similarity tinggal dot product, nggak perlu library tambahan. Skor 0.75 sampai 0.90 dianggap ambiguous dan agent yang putusin manual; di atas itu rencananya auto-skip, tapi sekarang masih mode kalibrasi: semua skor cuma dicatat ke log. Tujuannya ngumpulin distribusi skor beneran dulu dua-tiga minggu, baru ambang finalnya dipasang. Nggak ada API eksternal, nggak ada biaya token.

Sisi trigger-nya juga murah. Vercel Cron Jobs jalan lewat HTTP GET ke path di vercel.json dan cuma aktif di production deployment. Plan Hobby dijatah 2 cron job dengan jeda minimal sehari tiap job, sedangkan Pro bisa sampai 40 job dengan frekuensi tiap menit, sesuai changelog peluncurannya. Gue cuma butuh satu job yang nge-poll tiap 15 menit, jadi plan apa pun cukup. Polling GitHub-nya juga murah: rate limit REST terautentikasi 5.000 request/jam per user (rate limit docs), jadi ngecek beberapa repo tiap 15 menit nggak akan nyentuh batas.

Alternatif yang sempat gue pertimbangkan: webhook dari forge internal biar nggak perlu polling sama sekali. Tapi infrastruktur yang gue pakai belum nyediain, dan polling 15 menit udah cukup responsif buat pipeline yang siklusnya sendiri makan belasan menit per entri. Nggak worth it nambah komponen baru cuma buat hemat beberapa menit latensi.

Target "6+6 artikel per hari" itu masuk akal buat jadwal editorial manusia, tapi buat pipeline otomatis quota harian itu vanity metric: bikin agent nulis walau nggak ada bahan, dan scheduler jadwal-tetap bakar token buat wake-up kosong. Event-driven dengan cursor + budget itu lebih jujur: kerja cuma saat ada commit baru, maju cuma setelah ada bukti publish. Gue lebih suka sistem yang jujur gitu. Kalau nggak ada bahan, ya nggak usah dipaksa.

Artikel terkait