Spaces:
Running
Running
| title: Prompt Builder | |
| emoji: 🧠 | |
| colorFrom: green | |
| colorTo: blue | |
| sdk: docker | |
| app_port: 7860 | |
| pinned: false | |
| license: mit | |
| short_description: Indonesian prompt builder with real-time NLP detectors | |
| # Prompt Builder | |
| Prompt Builder adalah web app berbasis Bahasa Indonesia untuk membantu pengguna menyusun prompt AI yang efektif, bersih, dan bertanggung jawab. Setiap field prompt dianalisis secara real-time oleh sembilan detektor NLP sebelum prompt dikirimkan ke model AI. | |
| ## Fitur Utama | |
| - 9 field prompt terstruktur: Task, Context, References, Role, Audience, Tone, Constraints, Output Format, dan Example. | |
| - 9 detektor NLP: PII, Word Quality, Konten Berisiko, NER, Profanity, Filler, Special Char, Syntax, dan Field-Fit. | |
| - Fokus Bahasa Indonesia, dengan dukungan lintas bahasa pada PII, NER, dan Profanity (identifier, entitas, dan kata kasar berlaku untuk teks Inggris juga). Teks yang terdeteksi Inggris hanya diproses ketiga detektor itu; enam detektor lain Indonesia-only. | |
| - Lexicon dipisah di `resources/lexicons/` agar dapat diperbarui tanpa mengubah kode detektor. | |
| - Highlight inline untuk kata atau frasa bermasalah. | |
| - Saran perbaikan otomatis (replace) untuk PII, slang, alay, dan typo. | |
| - Backend Python sederhana berbasis stdlib `http.server` — tanpa framework web. | |
| - Frontend statis berbasis HTML dan Tailwind CSS — tanpa SPA framework. | |
| - Hot-reload detektor saat file berubah; auto-restart proses jika file inti pipeline berubah. | |
| ## Arsitektur | |
| ```text | |
| web/index.html | |
| | | |
| | POST /api/evaluate | |
| v | |
| src/core/pipeline_server.py | |
| | | |
| +-- pii (NIK, NPWP, email, HP, ... + SSN_US, NIN_UK, IBAN, MAC) [lintas bahasa] | |
| +-- word_quality (slang, alay, l33tspeak, typo) | |
| +-- risky_content (injection, harmful, academic dishonesty, sensitive topic) | |
| +-- ner (transformer NER + rule-based booster Indonesia + entitas Inggris) [lintas bahasa] | |
| +-- profanity (lexicon kata kasar Indonesia + Inggris) [lintas bahasa] | |
| +-- filler (sapaan, basa-basi, referensi samar) | |
| +-- special_char (zero-width, bidi, Unicode tag, homoglyph, full-width, repeated punct) | |
| +-- syntax (urutan kata janggal via perplexity IndoBERT) | |
| +-- field_fit (deteksi salah field: persona di Task + embedding lintas-field) | |
| Routing bahasa: teks yang terdeteksi Inggris hanya melewati pii, ner, dan | |
| profanity; enam detektor lain Indonesia-only dan dilewati. | |
| ``` | |
| Semua detektor dimuat saat server start dan digunakan ulang untuk setiap request. | |
| ## Struktur Folder | |
| ```text | |
| prompt-builder/ | |
| src/ | |
| core/ | |
| pipeline_server.py # orchestrator utama | |
| language.py # deteksi bahasa via wordfreq (id/en/unknown) | |
| lexicons.py # loader lexicon terpusat | |
| config.py # konfigurasi global (mode produksi, ambang ML) | |
| pii/ | |
| pii_detector.py | |
| pii_server.py | |
| word_quality/ | |
| word_quality_detector.py | |
| word_quality_server.py | |
| risky_content/ | |
| risky_content_detector.py | |
| risky_content_server.py | |
| profanity/ | |
| profanity_detector.py | |
| profanity_server.py | |
| filler/ | |
| filler_detector.py | |
| filler_server.py | |
| special_char/ | |
| special_char_detector.py | |
| special_char_server.py | |
| ner/ | |
| ner_detector.py | |
| ner_server.py | |
| syntax/ | |
| syntax_detector.py | |
| syntax_server.py | |
| field_fit/ | |
| field_fit_detector.py | |
| field_fit_server.py | |
| thesaurus/ | |
| thesaurus.py | |
| web/ | |
| index.html | |
| *-test.html | |
| resources/ | |
| lexicons/ | |
| language/ | |
| word_quality/ | |
| profanity/ # Indonesia (high/medium) + Inggris (high_en/medium_en) | |
| ner/ | |
| special_char/ # homoglyph, smart-quote, pesan alasan | |
| field_fit/ # prototipe & label field (untuk ML embedding) | |
| scripts/ | |
| import_lexicons.py | |
| audit_detectors.py | |
| tests/ | |
| cache/ # cache lokal (gitignored): SymSpell, KBBI, tesaurus, model ML | |
| pyproject.toml | |
| package.json | |
| tailwind.config.js | |
| Dockerfile | |
| ``` | |
| ## Instalasi | |
| ### Prasyarat | |
| - Python 3.10+ | |
| - Node.js (hanya untuk build Tailwind CSS) | |
| ### Clone Repository | |
| ```bash | |
| git clone https://github.com/ArielJoe/Prompt-Builder.git | |
| cd Prompt-Builder | |
| ``` | |
| ### Install Dependensi Python | |
| Minimal untuk NLP ringan (tanpa model ML): | |
| ```bash | |
| pip install -e ".[nlp]" | |
| ``` | |
| Lengkap dengan model ML (NER, Syntax, Field-Fit, plus lapis opsional Word Quality dan Profanity): | |
| ```bash | |
| pip install -e ".[full]" | |
| ``` | |
| Development tools: | |
| ```bash | |
| pip install -e ".[dev]" | |
| ``` | |
| Model NER, Syntax Checker, dan Field-Fit akan diunduh otomatis dari HuggingFace Hub saat pertama kali digunakan. | |
| ## Cara Menjalankan | |
| Pipeline utama (dengan semua detektor): | |
| ```bash | |
| python src/core/pipeline_server.py | |
| ``` | |
| Mode cepat — tanpa model ML berat (semua model berat dinonaktifkan): | |
| ```bash | |
| python src/core/pipeline_server.py --fast | |
| ``` | |
| Tanpa lapis ML ringan (Word Quality & Profanity) saja: | |
| ```bash | |
| python src/core/pipeline_server.py --no-resp-ml | |
| ``` | |
| Port dan host custom: | |
| ```bash | |
| python src/core/pipeline_server.py --port 8080 --host 0.0.0.0 | |
| ``` | |
| Setelah server berjalan, buka `http://127.0.0.1:8000` di browser. | |
| Saat development, server otomatis memuat ulang perubahan detektor. Jika file inti pipeline | |
| (`pipeline_server.py`, `language.py`, `lexicons.py`) berubah, proses akan restart sendiri | |
| dengan argumen yang sama. Matikan dengan `--no-auto-reload` jika diperlukan. | |
| ## Deploy ke Hugging Face Spaces | |
| Space ini dikonfigurasi sebagai Docker Space (port 7860). Dockerfile menjalankan pipeline: | |
| ```bash | |
| python3 src/core/pipeline_server.py --host 0.0.0.0 --port ${PORT:-7860} ${PIPELINE_FLAGS} | |
| ``` | |
| `PORT` dan `PIPELINE_FLAGS` dapat diatur lewat `Settings > Variables` pada Space tanpa | |
| mengubah Dockerfile. `PIPELINE_FLAGS` kosong secara default sehingga pipeline penuh | |
| (semua detektor, termasuk model ML) yang berjalan. Untuk Free CPU Space yang terbatas | |
| RAM-nya, set `PIPELINE_FLAGS=--fast` agar model transformer besar tidak dimuat. | |
| `--fast` setara dengan `--no-resp-ml --no-ner-ml --no-syntax-ml --no-fieldfit-ml`. | |
| Untuk deployment publik, set environment variable `PROMPT_BUILDER_ENV=production`. | |
| Pada mode produksi: auto-reload dimatikan, sub-server halaman test tidak dijalankan, | |
| dan header CORS tidak dikirim karena frontend disajikan satu origin dengan backend. | |
| ## Privasi Data | |
| Prompt yang dimasukkan hanya diproses di memori selama evaluasi berlangsung dan | |
| tidak disimpan ke penyimpanan permanen, basis data, atau log. Server tidak menulis | |
| isi prompt ke berkas. Meski demikian, pengguna tetap disarankan tidak memasukkan | |
| data pribadi yang sebenarnya, dan detektor PII berfungsi sebagai pengingat bila | |
| data semacam itu terdeteksi. | |
| Push ke Space: | |
| ```bash | |
| git remote add space https://huggingface.co/spaces/ArielJoe/Prompt-Builder | |
| git push space main | |
| ``` | |
| ### Auto Deploy dari GitHub | |
| Workflow `.github/workflows/deploy-hf-space.yml` akan push ke Hugging Face Space secara | |
| otomatis setiap ada push ke `main` yang mengubah file pipeline, frontend, lexicon, | |
| Dockerfile, atau dependency. | |
| Setup sekali: | |
| 1. Buat token di `https://huggingface.co/settings/tokens` dengan permission write. | |
| 2. Di GitHub repo: `Settings > Secrets and variables > Actions`. | |
| 3. Tambahkan secret: `HF_TOKEN=hf_...` | |
| ## Server Detektor Individual | |
| Setiap detektor memiliki server test mandiri: | |
| ```bash | |
| python -m src.pii.pii_server | |
| python -m src.word_quality.word_quality_server | |
| python -m src.risky_content.risky_content_server | |
| python -m src.profanity.profanity_server | |
| python -m src.filler.filler_server | |
| python -m src.special_char.special_char_server | |
| python -m src.ner.ner_server | |
| python -m src.syntax.syntax_server | |
| python -m src.field_fit.field_fit_server | |
| ``` | |
| Halaman test tersedia di `web/*-test.html`. | |
| ## Pengujian | |
| Unit test fungsi murni (validator PII, normalisasi teks, skeleton konsonan): | |
| ```bash | |
| python -m pytest tests/ | |
| ``` | |
| ## Audit Detektor | |
| Uji semua detektor dengan skenario positif, negatif, dan bypass: | |
| ```bash | |
| python scripts/audit_detectors.py | |
| ``` | |
| Termasuk layer ML opsional: | |
| ```bash | |
| python scripts/audit_detectors.py --include-ml | |
| ``` | |
| Audit menampilkan status kasus, label temuan, latency, serta proxy precision, | |
| recall, dan F1 per detector. Untuk rencana evaluasi etika, risiko, efisiensi | |
| komputasi, serta DOI paper rujukan, lihat `docs/detector_evaluation.md`. | |
| Seed dataset untuk fine-tuning/evaluasi lanjutan tersedia di | |
| `resources/evaluation/`. Validasi schema dan distribusi label: | |
| ```bash | |
| python scripts/validate_evaluation_sets.py | |
| ``` | |
| ## Tailwind CSS | |
| ```bash | |
| npm install | |
| npm run dev # watch mode | |
| npm run build # CSS minified untuk produksi | |
| ``` | |
| ## Lexicon Resources | |
| | Folder | Isi | | |
| | --- | --- | | |
| | `language/` | Stopwords Indonesia untuk filter entitas dan konteks. | | |
| | `word_quality/` | Slang, alay, dan data koreksi typo Bahasa Indonesia. | | |
| | `profanity/` | Kata kasar curated Indonesia (`high`/`medium`) + Inggris (`high_en`/`medium_en`). Tanpa whitelist — kurasi di sumber lexicon. | | |
| | `ner/` | Nama orang, organisasi, sufiks badan usaha & akronim global, nama tempat, kata pemicu (gelar, etnis) untuk rule NER. | | |
| | `special_char/` | Peta homoglyph, smart-quote, dan pesan alasan per kategori. | | |
| | `field_fit/` | Prototipe contoh dan label tiap field untuk centroid embedding. | | |
| Update lexicon dari sumber online: | |
| ```bash | |
| python scripts/import_lexicons.py --all | |
| ``` | |
| Import selektif: | |
| ```bash | |
| python scripts/import_lexicons.py --slang-id | |
| python scripts/import_lexicons.py --profanity-id | |
| python scripts/import_lexicons.py --stopwords | |
| python scripts/import_lexicons.py --geonames --ssa-names | |
| ``` | |
| ## API Reference | |
| ### `GET /api/status` | |
| ```json | |
| { | |
| "ready": true, | |
| "detectors": { | |
| "pii": true, | |
| "word_quality": true, | |
| "risky_content": true, | |
| "ner": true, | |
| "profanity": true, | |
| "filler": true, | |
| "special_char": true, | |
| "syntax": true, | |
| "field_fit": true | |
| } | |
| } | |
| ``` | |
| ### `POST /api/evaluate` | |
| Request: | |
| ```json | |
| { | |
| "fields": { | |
| "task": "Jelaskan konsep fotosintesis", | |
| "context": "Untuk siswa kelas 7 SMP", | |
| "references": "Buku IPA Kurikulum Merdeka", | |
| "role": "Guru IPA", | |
| "audience": "Siswa usia 12-13 tahun" | |
| } | |
| } | |
| ``` | |
| Response: | |
| ```json | |
| { | |
| "issues": [ | |
| { | |
| "field_id": "task", | |
| "field_label": "Task", | |
| "css_class": "slang", | |
| "severity": "MEDIUM", | |
| "word": "nemenin", | |
| "start": 5, | |
| "end": 12, | |
| "reason": "Kata informal; padanan baku: \"menemani\".", | |
| "action": "replace", | |
| "replacement": "menemani" | |
| } | |
| ], | |
| "final_prompt": "Task: ...", | |
| "final_prompt_sections": [] | |
| } | |
| ``` | |
| Field issue yang dikirim hanya yang dipakai frontend. Atribut internal seperti | |
| `source`, `issue_type`, dan `confidence` tidak disertakan dalam respons; status | |
| detektor tersedia di `GET /api/status`. Temuan konten berisiko menambahkan field | |
| `recommendation` berisi saran reformulasi. | |
| Severity: `HIGH` | `MEDIUM` | `LOW`, dikirim pada tiap issue tetapi tidak dipakai untuk | |
| mengelompokkan tampilan. Semua temuan bersifat saran dan ditampilkan sebagai satu daftar, | |
| dikelompokkan per kategori (css_class) sesuai urutan kepentingan pada frontend. | |
| Action: `replace` (ada saran penggantian; `replacement` kosong berarti hapus) | |
| atau `select` (hanya sorot). | |
| ## Ringkasan Detektor | |
| | Detektor | File Utama | Fungsi | | |
| | --- | --- | --- | | |
| | PII | `src/pii/pii_detector.py` | NIK, NPWP, BPJS, SIM, plat nomor, email, telepon, rekening, kartu kredit, IP, tanggal lahir, alamat Indonesia + identifier internasional (SSN_US, NIN_UK, IBAN, MAC, TELEPON_US). **Lintas bahasa.** | | |
| | Word Quality | `src/word_quality/word_quality_detector.py` | Slang, alay, l33tspeak, typo — dengan saran perbaikan dan reklasifikasi kontekstual. | | |
| | Konten Berisiko | `src/risky_content/risky_content_detector.py` | Prompt injection, self-harm, konten seksual eksplisit, diskriminasi, academic dishonesty, framing berbahaya, sensitive topic. | | |
| | NER | `src/ner/ner_detector.py` | Named entity recognition via transformer + rule-based booster Indonesia + entitas Inggris (gelar, sufiks badan usaha, akronim global). **Lintas bahasa.** | | |
| | Profanity | `src/profanity/profanity_detector.py` | Kata kasar berbasis leksikon Indonesia + Inggris + classifier toksisitas opsional. **Lintas bahasa.** | | |
| | Filler | `src/filler/filler_detector.py` | Sapaan ke AI, basa-basi, ucapan terima kasih, permintaan maaf, referensi samar. | | |
| | Special Char | `src/special_char/special_char_detector.py` | Zero-width (termasuk BOM, word joiner, soft hyphen), kontrol arah teks (bidi), Unicode tag, homoglyph, control char, non-breaking space, full-width ASCII, repeated punct, spasi berlebih. | | |
| | Syntax | `src/syntax/syntax_detector.py` | Deteksi urutan kata janggal via pseudo-log-likelihood IndoBERT. | | |
| | Field-Fit | `src/field_fit/field_fit_detector.py` | Deteksi salah field: aturan persona di Task + ML embedding kemiripan lintas-field (sentence-transformers). | | |
| ## Field Prompt | |
| | Field | ID | Wajib | | |
| | --- | --- | --- | | |
| | Task | `task` | Ya | | |
| | Context | `context` | Ya | | |
| | References | `references` | Ya | | |
| | Role | `role` | Tidak | | |
| | Audience | `audience` | Tidak | | |
| | Tone | `tone` | Tidak | | |
| | Constraints | `constraints` | Tidak | | |
| | Output Format | `outputFormat` | Tidak | | |
| | Example | `example` | Tidak | | |
| Field wajib yang kosong dilaporkan sebagai issue `MISSING` dengan severity `HIGH`. | |
| ## Dependensi | |
| | Grup | Isi | | |
| | --- | --- | | |
| | `nlp` | `wordfreq`, `symspellpy` | | |
| | `ml` | `transformers`, `torch`, `sentencepiece`, `accelerate`, `protobuf`, `huggingface-hub` | | |
| | `full` | `nlp` + `ml` | | |
| | `dev` | `pytest`, `pytest-cov`, `ruff` | | |
| Node.js: `tailwindcss` (build CSS frontend). | |
| ## Lisensi | |
| Lihat `LICENSE`. | |
| --- | |
| ```yaml | |
| title: Prompt Builder | |
| emoji: 🧩 | |
| colorFrom: green | |
| colorTo: blue | |
| sdk: docker | |
| app_port: 7860 | |
| pinned: false | |
| license: mit | |
| ``` | |