fix: vision model hanya deskripsi, tidak memutuskan moderasi

Root cause: vision model diminta untuk 'flag' dan 'menilai' gambar,
sehingga screenshot terminal/chat biasa diklaim sebagai 'situs perjudian'.

Fix:
- vision prompt: HANYA deskripsi objektif (objek, teks, layout, jenis gambar)
- larang tegas kata 'gambling', 'judi', 'pelanggaran', 'harus dihapus'
- tambah buildGeneralImageVisionPrompt di discord-gateway stickerPrompt
- MEDIA_INSTRUCTIONS: tegaskan batch LLM adalah hakim, vision hanya saksi mata
- deskripsi netral (terminal, chat, editor kode) tidak boleh jadi dasar flag

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
MythEclipse
2026-06-02 11:08:41 +07:00
co-authored by Claude Opus 4.8
parent 5f419a6f0f
commit 55ee8ade16
5 changed files with 88 additions and 82 deletions
@@ -22,6 +22,7 @@ import {
} from "./stickerCache.js";
import {
buildCustomEmojiVisionPrompt,
buildGeneralImageVisionPrompt,
buildStickerTextOnlyWarning,
buildStickerVisionPrompt,
} from "./stickerPrompt.js";
@@ -587,34 +588,7 @@ const analyzeSingleMediaImage = async (
? buildStickerVisionPrompt(image.stickerName, messageId)
: image.customEmojiName
? buildCustomEmojiVisionPrompt(image.customEmojiName, messageId)
: [
`Analisis media Discord berikut sebagai evidence moderasi. ${image.sourceLabel}`,
``,
`Jelaskan SECARA SPESIFIK apa yang TERLIHAT di gambar (objek, teks, warna dominan, layout).`,
`Jangan menebak-nebak atau mengasumsikan konten yang tidak terlihat langsung.`,
``,
`HANYA flag jika gambar secara JELAS dan TIDAK AMBIGU menampilkan:`,
`- Antarmuka situs judi yang JELAS TERLIHAT (ada chip, kartu, meja taruhan, odds, deposit/withdraw)`,
`- Konten seksual eksplisit/NSFW/pornografi`,
`- Darah/luka/gore nyata (BUKAN kartun/meme/animasi)`,
`- Narkoba atau obat terlarang yang bisa diidentifikasi spesifik`,
`- Simbol kebencian (swastika, simbol teroris) yang JELAS`,
`- Ajakan bunuh diri atau self-harm eksplisit`,
`- Informasi pribadi (alamat, nomor telepon, KTP) yang bocor`,
``,
`Jika gambar HANYA berisi: chat biasa, meme lucu, foto makanan, selfie,`,
`screenshot discord/wa/media sosial biasa, landscape, hewan, screenshot game,`,
`atau konten sehari-hari lainnya → JELASKAN ISI YANG TERLIHAT dan KONFIRMASI AMAN.`,
``,
`JANGAN PERNAH mengklaim gambar adalah "antarmuka judi" atau "situs perjudian"`,
`KECUALI ada BUKTI VISUAL SPESIFIK seperti chip, kartu remi, meja taruhan,`,
`odds, deposit/withdraw, atau logo situs judi yang DIKENALI.`,
`Screenshot aplikasi chat atau media sosial BUKAN situs judi.`,
``,
`Jawab Bahasa Indonesia, maksimal 3 kalimat. Berikan deskripsi objektif,`,
`bukan asumsi. Jika aman, katakan "aman" dengan jelas.`,
].join("\n");
: buildGeneralImageVisionPrompt(image.sourceLabel, messageId);
try {
const completion = await withLlmConcurrency(async () =>
@@ -63,26 +63,24 @@ Jangan pernah flag hanya berdasarkan kecurigaan atau ketidakjelasan konteks.
// ---------------------------------------------------------------------------
const MEDIA_INSTRUCTIONS = `## Instruksi Analisis Media
Gambar, sticker, embed image, preview link, dan attachment sudah dianalisis lewat request media terpisah sebelum batch utama.
Baris "Media analysis" memberikan DESKRIPSI VISUAL tentang apa yang terlihat di gambar, BUKAN keputusan moderasi final.
Gambar, sticker, embed image, preview link, dan attachment sudah DIDESKRIPSIKAN oleh vision model sebelum batch utama.
Baris "Media analysis" berisi DESKRIPSI OBJEKTIF tentang apa yang terlihat di gambar, BUKAN keputusan moderasi.
Vision model TIDAK memutuskan apakah gambar melanggar atau tidak — ia hanya mendeskripsikan isi visual.
## ATURAN KRITIS — Jangan Flag Gambar Biasa sebagai Judi
- **Screenshot Discord/WhatsApp/Telegram/media sosial biasa BUKAN situs judi.** Jangan pernah mengklaim screenshot chat sebagai "antarmuka perjudian".
- **Foto makanan, selfie, pemandangan, hewan, meme, screenshot game BUKAN konten melanggar.**
- **Gambar dengan teks bahasa Indonesia biasa BUKAN promosi judi.**
- HANYA flag "gambling" jika Media analysis secara SPESIFIK menyebutkan melihat elemen judi NYATA: chip, kartu remi, meja taruhan, odds, deposit/withdraw, atau logo situs judi yang DIKENALI.
- Jika Media analysis hanya mendeskripsikan "antarmuka aplikasi" atau "tampilan web" tanpa menyebutkan elemen judi spesifik → jangan flag gambling.
- Jika Media analysis bilang "aman" atau "tidak ada konten melanggar" → percaya itu.
- **Bukti teks LEBIH PENTING dari bukti visual.** Jika teks pesan adalah percakapan biasa ("Aku suka nasgor loh", "Halo guys", "Pagi semua") dan tidak mengandung promosi judi/narkoba/scam, maka gambar tersebut SANGAT TIDAK MUNGKIN adalah pelanggaran. JANGAN kontradiksi antara teks dan gambar — percaya teks terlebih dahulu.
- **Cross-check wajib**: Jika teks pesan clean/aman, maka analisis gambar yang mengklaim ada pelanggaran berat HARUS diabaikan kecuali ada bukti visual yang SANGAT JELAS dan TIDAK TERBANTAHKAN.
## ATURAN KRITIS — Kamu yang Memutuskan, Bukan Vision Model
- **KAMU adalah moderator.** Deskripsi dari vision model adalah SAKSI MATA, bukan hakim.
- Jika deskripsi vision menyebutkan "screenshot terminal", "aplikasi chat", "tampilan website", "foto makanan" → itu BUKAN bukti pelanggaran apapun.
- HANYA flag "gambling" jika KAMU menyimpulkan dari deskripsi bahwa gambar menunjukkan situs judi (chip, kartu remi, meja taruhan, odds, deposit/withdraw).
- **Bukti teks LEBIH PENTING dari deskripsi gambar.** Jika teks pesan adalah percakapan biasa ("Aku suka nasgor loh", "Halo guys") dan tidak mengandung promosi judi, maka gambar tersebut TIDAK MUNGKIN adalah pelanggaran judi.
- **Jika teks clean dan deskripsi gambar biasa → wajib clean.** Tidak peduli seberapa "mencurigakan" gambar terlihat bagi vision model.
- Deskripsi vision yang menyebutkan hal-hal netral (terminal, chat, editor kode, website, grafik, chart) TIDAK BOLEH dijadikan dasar untuk flag gambling.
## Panduan Khusus Sticker
- Sticker Discord adalah media kartun/meme/ilustrasi, BUKAN foto atau video nyata.
- Sticker sering bersifat humor, satir, atau ekspresi emosi yang dilebih-lebihkan.
- Gambar sticker bisa menampilkan adegan kartun yang terlihat "keras" — itu SENI KARTUN, bukan dokumentasi kekerasan nyata.
- Nama sticker yang terdengar provokatif (mis. "Singa injek pejabat") adalah konteks satir/humor. JANGAN flag berdasarkan nama sticker saja.
- Terapkan standar yang lebih longgar untuk konten kartun/meme dibanding foto/video nyata.
- Sticker yang berhasil diunduh WAJIB diperlakukan sebagai image evidence, bukan sekadar nama sticker.`;
- Terapkan standar yang lebih longgar untuk konten kartun/meme dibanding foto/video nyata.`;
// ---------------------------------------------------------------------------
// Section: Few-Shot Examples
@@ -94,3 +94,42 @@ export function buildCustomEmojiTextOnlyFallback(emojiName: string): string {
`Custom emoji di Discord adalah ekspresi/emosi umum, bukan konten ofensif.]`
);
}
/**
* Prompt for analyzing regular images (attachments, embeds, links).
*
* VISION MODEL ONLY DESCRIBES — it does NOT decide moderation.
* The main text LLM makes all moderation decisions using the description.
*/
export function buildGeneralImageVisionPrompt(
sourceLabel: string,
_messageId: string,
): string {
return [
`Deskripsikan gambar ini secara objektif dan spesifik.`,
`${sourceLabel}`,
``,
`Jelaskan HANYA apa yang kamu LIHAT:`,
`- Objek utama apa yang ada di gambar?`,
`- Teks apa yang terlihat? (tulis persis jika bisa dibaca)`,
`- Warna dominan dan layout/tata letak?`,
`- Apakah ini screenshot, foto, meme, kartun, atau dokumen?`,
`- Konteks: apakah terlihat seperti aplikasi chat, terminal/console,`,
` media sosial, game, website, editor kode, dokumen, atau lainnya?`,
``,
`PENTING — Deskripsi saja, JANGAN MEMUTUSKAN MODERASI:`,
`- JANGAN sebut "gambling", "judi", "pelanggaran", "melanggar", atau flag apapun.`,
`- JANGAN bilang "harus dihapus", "harus diblokir", atau rekomendasi tindakan.`,
`- Tugasmu HANYA mendeskripsikan isi gambar. BUKAN menilai.`,
`- Screenshot terminal/console/shell/editor kode → deskripsikan sebagai "terminal/console".`,
`- Screenshot aplikasi chat (Discord/WA/Telegram/dll) → deskripsikan sebagai "aplikasi chat".`,
`- Screenshot website dengan grafik/chart → deskripsikan kontennya secara faktual.`,
`- JANGAN PERNAH mengklaim gambar adalah "situs judi" atau "antarmuka perjudian".`,
` Itu BUKAN tugasmu. Kamu hanya perlu menyebutkan: "tampilan website dengan grafik",`,
` "screenshot terminal", "aplikasi chat dengan teks percakapan", dll.`,
``,
`Format jawaban: Deskripsi singkat 2-3 kalimat dalam Bahasa Indonesia.`,
`Mulai dengan menyebutkan JENIS gambar (screenshot/foto/kartun/dokumen).`,
`Akhiri dengan "Deskripsi selesai."`,
].join("\n");
}