TIFNGK_E41222722/AGENTS.md

21 KiB
Raw Blame History

AGENTS.md — Panduan AI untuk Sistem Deteksi PMK

File ini adalah satu-satunya sumber kebenaran untuk AI agent yang bekerja pada project ini. WAJIB diperbarui setiap kali ada perubahan arsitektur, dependensi, struktur database, atau alur sistem.


1. GAMBARAN PROYEK

Sistem Deteksi dan Diagnosis Penyakit Mulut dan Kuku (PMK / FMD) pada Sapi

  • Bahasa: Python 3.12.5
  • Framework Web: Flask (Bootstrap 5 UI)
  • Desktop (Legacy): Tkinter (main.py, predict_image.py)
  • Deployment: Railway (Nixpacks + gunicorn)
  • Repository: https://github.com/livindra/deteksi_PMK

Dua jalur utama:

  1. Deteksi Berbasis Gambar — ML (KNN) multi-class (sehat + tiap jenis PMK) + Computer Vision (color moments + GLCM texture)
  2. Sistem Pakar — Forward chaining inference engine (29 gejala, 5 penyakit, 5 aturan)

Dataset: Folder dataset/ berisi healthy/ dan folder pmk_* per jenis penyakit. train_model.py otomatis mendeteksi semua folder berawalan pmk_* sebagai kelas terpisah.


2. STRUKTUR PROYEK

deteksi_PMK/
├── app.py                     # Main Flask app (~1000 baris) — routing, prediksi, sistem pakar
├── expert_system.py           # Forward chaining engine + KnowledgeBase + Evaluator
├── train_model.py             # Training KNN model (k=5, euclidean, uniform)
├── setup_db.py                # Inisialisasi database MySQL
├── main.py                    # LEGACY — Tkinter desktop menu
├── predict_image.py           # LEGACY — Tkinter prediction GUI
├── test_forward_chaining.py   # Unit test expert system
├── test_env.py                # Test environment variables & DB connection
├── show_scaler_params.py      # Utility: lihat parameter scaler
├── requirements.txt           # Python dependencies
├── Procfile                   # gunicorn app:app
├── railway.json               # Railway Nixpacks builder config
├── .env                       # Environment variables (TIDAK DI-COMMIT)
├── .env.example               # Template env
├── .gitignore
├── .python-version            # 3.12.5
│
├── QUICK_START.md             # Panduan cepat (Bahasa Indonesia)
├── AGENTS.md                  # ← FILE INI — panduan AI, HARUS DIUPDATE
│
├── dataset/                   # Dataset gambar training
│   ├── healthy/               #   ~200 gambar sapi sehat
│   ├── pmk_oral/              #   Gambar PMK oral
│   ├── pmk_podal/             #   Gambar PMK podal (kaki)
│   ├── pmk_laktasi/           #   Gambar PMK laktasi (ambing)
│   └── pmk_akut_general/      #   Gambar PMK akut general
│
├── features/                  # CSV fitur hasil ekstraksi
│   ├── dataset.csv
│   ├── data_train.csv
│   └── data_test.csv
│
├── models/                    # Model terlatih (.pkl)
│   ├── knn_model.pkl          # BINARY — KNeighborsClassifier (sehat/sakit)
│   ├── scaler.pkl             # BINARY — StandardScaler
│   ├── label_encoder.pkl      # BINARY — LabelEncoder
│   ├── multiclass_knn_model.pkl    # MULTI — KNeighborsClassifier (jenis PMK)
│   ├── multiclass_scaler.pkl       # MULTI — StandardScaler
│   ├── multiclass_label_encoder.pkl# MULTI — LabelEncoder
│   └── pca.pkl                # TIDAK DIGUNAKAN (legacy)
│
├── uploads/                   # Gambar hasil upload user
│   └── resize/                # Hasil resize
│   └── threshold/             # Hasil threshold
│
├── utils/
│   ├── __init__.py
│   ├── mysql_db.py            # SQLAlchemy ORM — models, CRUD, seed data (916 baris)
│   ├── preprocessing.py       # Validasi sapi + preprocessing pipeline (340 baris)
│   ├── feature_extraction.py   # Ekstraksi fitur: RGB avg + HSV + GLCM + histogram + Hu (44 fitur)
│   └── helpers.py             # Load/save model, dataset prep, confidence estimation (237 baris)
│
├── templates/                 # Jinja2 templates
│   ├── base.html              # Layout utama (Bootstrap 5, navbar, footer)
│   ├── index.html             # Halaman utama
│   ├── upload.html            # Form upload multi-file (JS sederhana)
│   ├── result.html            # Hasil deteksi (sehat/sakit)
│   ├── riwayat_deteksi.html   # Riwayat (client localStorage + MySQL)
│   ├── detail_deteksi.html    # Detail satu prediksi + diagnosis
│   ├── expert_system.html     # Sistem pakar — pilih gejala + hasil
│   └── diagnosis_history.html # Riwayat diagnosis sistem pakar
│
└── static/
    ├── css/style.css          # Custom CSS (gradient, animasi, responsive)
    └── js/main.js             # JS — tooltips, file preview, API fetch, dark mode

3. ARSITEKTUR & ALUR DATA

3.1 Jalur Deteksi Gambar

User upload gambar
  │
  ▼
[app.py] validate_cattle_image()
  ├─ Tolak wajah manusia (Haar cascade)
  ├─ Deteksi mata (HoughCircles) — bonus scoring
  ├─ Validasi warna HSV (coklat, merah, hitam, putih)
  ├─ Analisis tekstur (Laplacian variance)
  ├─ Edge detection (Canny)
  └─ Final: weighted confidence (eye 15%, color 40%, texture 30%, edge 15%), threshold ≥ 65%
  │
  ├─ Gagal → tolak dengan pesan error
  │
  ▼
[preprocessing.py] preprocess_pipeline()
  → resize 128×128 → grayscale → Otsu threshold → mask → masked RGB + masked gray
  │
  ▼
[feature_extraction.py] FeatureExtractor.extract_all_features()
  → 44 fitur: [RGB avg (3), HSV mean+std (6), GLCM (4), histogram 24, Hu (7)]
  │
  ▼
[helpers.py] scaler.transform() → [BINARY MODEL] predict()
  │
  ├  ─ 'sehat' → Simpan ke MySQL
  │
  ▼ sakit
[helpers.py] multiclass_scaler.transform() → [MULTI-CLASS MODEL] predict()
  → label_encoder.inverse_transform()
  │
  ▼
[helpers.py] estimate_prediction_confidence()
  → weighted neighbor confidence (clipped 50.0  98.5)
  │
  ▼
Simpan ke MySQL (primary) + CSV (fallback)
  │
  ▼
Semua gambar diproses — jika ada yang sakit:
  → Redirect ke expert-system?symptoms=G01,G02,...&mode=image
  → Gejala otomatis tercentang sesuai jenis PMK — hanya gejala yang relevan dengan body part PMK type tersebut (tidak cross-category)
Jika semua sehat:
  → Flash "Semua X gambar sehat" → /result/healthy

3.2 Jalur Sistem Pakar

User memilih gejala di web form
  │
  ▼
[expert_system.py] ForwardChaining.tambah_gejala(gejala_list)
  │
  ▼
ForwardChaining.inferensi()
  → Untuk setiap aturan:
    - Hitung coverage = matched_count / total_count
    - Hitung support_ratio = matched_rules / total_rules_for_disease
    - Hitung evidence_strength = min(best_matched / 4, 1.0)
    - Combined score = best_coverage*0.5 + avg_coverage*0.25 + support_ratio*0.15 + evidence_strength*0.1 + exact_bonus
    - Threshold minimum: 0.35
  │
  ▼
ForwardChaining.get_diagnosis()
  → Urutkan penyakit berdasarkan score
  → Kembalikan top diagnosis + matched rules + solusi
  → Severity map: P01=oral, P02=podal, P03=laktasi, P05=akut umum
  │
  ▼
Simpan ke MySQL (tabel predictions + diagnosis_history)
  │
  ▼
Render expert_system.html

3.3 Storage Hybrid

  • MySQL (primary): tabel predictions, diagnosis_history, expert_symptoms, expert_diseases, expert_rules, join table expert_rules_expert_symptoms
  • localStorage (browser): menyimpan array ID prediksi untuk ditampilkan di halaman riwayat
  • CSV fallback: results/predictions.csv, results/diagnosis_history.csv

Batch upload: Semua gambar dari satu sesi upload disimpan dalam 1 baris tabel predictions. Data per-gambar (filename, prediction, pmk_type, confidence) disimpan sebagai JSON di kolom images_data. Field prediction diisi 'sakit' jika ada gambar sakit, 'sehat' jika semua sehat.


4. DATABASE (MySQL via SQLAlchemy)

4.1 Tabel

-- Tabel prediksi hasil deteksi gambar
predictions
  id              INT AUTO_INCREMENT PK
  original_filename VARCHAR(255)
  filename        VARCHAR(255)
  image_path      VARCHAR(500)
  prediction      VARCHAR(50)        -- 'sehat' / 'sakit'
  confidence      FLOAT
  features        TEXT               -- JSON string dari extracted features
  images_data     TEXT               -- JSON array dari per-gambar (batch upload)
  timestamp       DATETIME

-- Tabel riwayat diagnosis sistem pakar
diagnosis_history
  id              INT AUTO_INCREMENT PK
  prediction_id   INT FK  predictions.id (nullable)
  diagnosis       TEXT               -- JSON string detail diagnosis
  severity        VARCHAR(50)        -- 'ringan' / 'sedang' / 'berat'
  timestamp       DATETIME

-- Master gejala (29 gejala)
expert_symptoms
  id              INT AUTO_INCREMENT PK
  code            VARCHAR(10) UNIQUE -- G01G29
  description     TEXT
  category        VARCHAR(50)        -- umum, mulut, kaki, ambing, berat
  display_order   INT

-- Master penyakit (5 penyakit)
expert_diseases
  id              INT AUTO_INCREMENT PK
  code            VARCHAR(10) UNIQUE -- P01P05
  name            VARCHAR(120)
  description     TEXT
  solutions       TEXT               -- JSON array of strings
  display_order   INT

-- Aturan forward chaining (5 aturan)
expert_rules
  id              INT AUTO_INCREMENT PK
  code            VARCHAR(20) UNIQUE -- FC01FC04
  symptom_codes   TEXT               -- JSON array of symptom codes
  result_disease_code VARCHAR(10) FK  expert_diseases.code
  description     TEXT
  is_active       BOOLEAN
  display_order   INT

-- Join table many-to-many
expert_rules_expert_symptoms
  rule_id         INT FK  expert_rules.id (ON DELETE CASCADE)
  symptom_id      INT FK  expert_symptoms.id (ON DELETE CASCADE)

4.2 Knowledge Base Default

29 Gejala (G01G29) per kategori:

  • umum (7): G01 demam >39.5°C, G11 nafsu makan turun, G12 lesu, G17 demam >40.5°C, G25 lebih sering berbaring, G28 takikardia, G29 sesak napas
  • mulut (9): G02 air liur berlebih, G03 luka lidah/gusi, G04 nyeri setelah lepuh, G10 hidung berair, G14 lepuh moncong, G18 lepuh lidah meluas, G19 sulit mengunyah, G20 lepuh bantalan gigi, G21 bau mulut
  • kaki (6): G05 lepuh celah kuku, G06 pincang, G15 nyeri kaki, G22 edema/radang, G23 bengkak celah kuku, G24 telapak kaki longgar
  • ambing (5): G07 lepuh puting, G08 lesi puting, G09 produksi susu turun, G26 puting retak, G27 susu menggumpal
  • berat (2): G13 miokarditis/kematian mendadak, G16 abortus/infertilitas

5 Penyakit (P01P05):

  • P01 = PMK_ORAL (gejala mulut)
  • P02 = PMK_PODAL (gejala kaki/kuku)
  • P03 = PMK_LAKTASI (gejala ambing)
  • P05 = PMK_AKUT_GENERAL (gejala umum berat)

4 Aturan (FC01FC04):

  • FC01 → P01 (oral): [G01, G02, G03, G04, G11, G18, G19, G20, G21]
  • FC02 → P02 (podal): [G01, G02, G05, G06, G15, G22, G23, G24, G25]
  • FC03 → P03 (laktasi): [G01, G02, G07, G08, G09, G26, G27]
  • FC04 → P05 (akut umum): [G01, G02, G03, G04, G05, G06, G07, G09, G11, G12, G14, G18, G20, G22, G23, G24, G26]

Auto-check gejala dari hasil deteksi gambar (di app.py:pmk_to_symptoms): Mapping ini digunakan saat redirect ke expert system via mode=image. Hanya gejala spesifik body part yang diikutkan (tanpa gejala umum):

  • pmk_oral → gejala mulut: [G02, G03, G04, G10, G14, G18, G19, G20, G21]
  • pmk_podal → gejala kaki: [G05, G06, G15, G22, G23, G24]

Jika menambah/mengubah gejala, penyakit, atau aturan, update data di:

  1. utils/mysql_db.py — constants DEFAULT_EXPERT_SYMPTOMS, DEFAULT_EXPERT_DISEASES, DEFAULT_EXPERT_RULES
  2. File ini (AGENTS.md) — bagian ini
  3. Jalankan ulang seed_expert_knowledge(force=True) atau hapus tabel agar di-reseed

5. API ENDPOINTS (Flask)

Method Route Deskripsi
GET / Homepage — model status + recent history
GET /upload Halaman upload gambar
POST /predict Upload + prediksi gambar multi-file. Semua gambar disimpan sbg 1 baris di DB. Jika sakit → redirect ke expert-system dgn gejala otomatis + semua gambar ditampilkan. Jika sehat → /result/healthy
GET /result/healthy Hasil sehat
GET /result/sick Hasil sakit (legacy, tidak dipakai di alur baru)
GET /riwayat_deteksi Halaman riwayat deteksi
GET /detail-deteksi/<int:pred_id> Detail prediksi + diagnosis
POST /api/validate-image Validasi gambar real-time (apakah sapi)
POST /api/get_data_riwayat_deteksi Ambil riwayat berdasarkan localStorage IDs
POST /api/diagnosis API diagnosis sistem pakar
GET/POST /expert-system Halaman sistem pakar (GET=form dgn param symptoms untuk pre-check, POST=diagnosis)
GET /expert-system/from-prediction Redirect ke expert system mode gambar
GET /riwayat-diagnosis Halaman riwayat diagnosis
GET /export/csv Export prediksi ke CSV
GET /export/excel Export prediksi ke Excel
GET /clear-session Bersihkan Flask session

6. ML MODEL DETAILS

Arsitektur Hierarchical (2-level):

Input image → 44 fitur (RGB+HSV+GLCM+Histogram+Hu)
                   │
            ┌──────┴──────┐
            ▼              ▼
      [BINARY MODEL]     [selamat — end]
      sehat vs sakit      
            │ (sakit)
            ▼
      [MULTI-CLASS MODEL]
      pmk_oral / pmk_podal / pmk_laktasi / pmk_akut_general

Binary Model (prefix='')

Parameter Value
Task sehat vs sakit
Algorithm K-Nearest Neighbors (KNN)
k Hyperparameter tuned (115)
Distance Hyperparameter tuned (euclidean/manhattan)
Weight Hyperparameter tuned (uniform/distance)
Accuracy ±98%
Model file models/knn_model.pkl

Multi-class Model (prefix='multiclass_')

Parameter Value
Task Jenis PMK (hanya data sakit)
Algorithm K-Nearest Neighbors (KNN)
k Hyperparameter tuned (115)
Distance Hyperparameter tuned (euclidean/manhattan)
Weight Hyperparameter tuned (uniform/distance)
Accuracy ±60%
Model file models/multiclass_knn_model.pkl

Common

Parameter Value
Features 44: avg_red, avg_green, avg_blue, hsv_h_mean, hsv_h_std, hsv_s_mean, hsv_s_std, hsv_v_mean, hsv_v_std, contrast, homogeneity, correlation, energy, 8-bin histogram × 3 channels (24), hu_moment_0..6 (7)
Image size 256×256
Preprocessing Otsu threshold, mask, resize
Scaling StandardScaler
Output Binary: sehat / sakit; Multi-class: pmk_oral, pmk_podal, pmk_laktasi, pmk_akut_general, ...
Confidence Custom weighted neighbor, clipped 50.089.5%
Class detection Auto-detect all folders under dataset/healthysehat, pmk_* → nama folder

Jika menambah/mengubah fitur, update:

  1. utils/feature_extraction.pyFeatureExtractor.feature_names
  2. train_model.py — feature export dimensions
  3. Retrain model (python train_model.py)
  4. AGENTS.md ini

Jika menambah kelas penyakit baru (folder pmk_*):

  1. Buat folder dataset/pmk_nama_baru/ — otomatis terdeteksi oleh prepare_dataset()
  2. Retrain model (python train_model.py)
  3. Update AGENTS.md

7. CATTLE IMAGE VALIDATION

Lokasi: utils/preprocessing.py:validate_cattle_image()

Layer validasi berlapis:

  1. Face rejection — Haar cascade face detection (tolak foto manusia)
  2. Eye detection — HoughCircles (bonus scoring)
  3. Color validation — HSV threshold (brown, red, black, white)
  4. Texture analysis — Laplacian variance (range 453500)
  5. Edge detection — Canny edge density (range 0.010.35)

Final confidence = eye_score*0.15 + color_score*0.40 + texture_score*0.30 + edge_score*0.15 Threshold: ≥ 65% untuk lolos sebagai sapi.


8. DEPLOYMENT

Railway

  • Builder: Nixpacks (railway.json)
  • Start: gunicorn app:app --bind 0.0.0.0:$PORT
  • Env: FLASK_SECRET, DATABASE_URL atau MYSQLHOST/PORT/USER/PASSWORD/DATABASE
  • opencv-python-headless — tidak butuh GUI library

Local

# 1. Setup database
python setup_db.py

# 2. (Opsional) Training model
python train_model.py

# 3. Jalankan app
python app.py
# Buka http://localhost:5000

9. TESTING

# Test environment & database
python test_env.py

# Test expert system forward chaining
python test_forward_chaining.py

Jika menambah fitur baru, tambahkan test case di file terkait. Jika menambah test file baru, update bagian ini.


10. CONFIGURATION

Environment Variables (.env)

DB_HOST=localhost
DB_PORT=3306
DB_USER=root
DB_PASSWORD=
DB_NAME=deteksi_pmk
MYSQLHOST=          # Railway
MYSQLPORT=          # Railway
MYSQLUSER=          # Railway
MYSQLPASSWORD=      # Railway
MYSQLDATABASE=      # Railway
DATABASE_URL=       # Railway
FLASK_SECRET=deteksi-pmk-secret-key-2026
FLASK_DEBUG=0

11. ATURAN UNTUK AI AGENT

  1. Jangan pernah mengubah fungsionalitas tanpa memperbarui file ini.
  2. Jika menambah variabel environment, tambahkan ke .env.example dan dokumentasikan di sini.
  3. Jika mengubah struktur tabel, update: (a) model SQLAlchemy di utils/mysql_db.py, (b) skema di AGENTS.md, (c) constants DEFAULT_EXPERT_*.
  4. Jika menambah endpoint, dokumentasikan di bagian API ENDPOINTS.
  5. Jika mengubah fitur ML, update feature_names, retrain model, update AGENTS.md.
  6. Jika menambah dependensi, tambahkan ke requirements.txt dan update tabel dependensi.
  7. File ini WAJIB dibaca sebelum melakukan perubahan signifikan.
  8. Gunakan Bahasa Indonesia untuk komentar, UI, dan dokumentasi end-user karena target pengguna adalah peternak/inspektur Indonesia.

12. DEPENDENSI (requirements.txt)

Package Version Kegunaan
opencv-python-headless 4.9.0.80 Image processing, validasi sapi
numpy <2 Numerical operations
pandas ≥2.1.0 Data manipulation
scikit-learn ≥1.3.2 KNN, StandardScaler, LabelEncoder
scikit-image ≥0.22.0 GLCM texture features
matplotlib ≥3.8.0 Feature analysis plots
pillow ≥10.1.0 Image loading fallback
joblib ≥1.3.2 Model serialization
Flask ≥2.3.3 Web framework
SQLAlchemy ≥2.0.0 ORM MySQL
PyMySQL ≥1.1.0 MySQL driver
python-dotenv ≥1.0.0 Environment loading
gunicorn ≥21.2.0 WSGI production server
pytz ≥2024.1 Timezone (Asia/Jakarta)
cryptography ≥3.4.8 MySQL password encryption

13. LEGACY CODE (TIDAK DIGUNAKAN LAGI)

File berikut adalah kode legacy desktop (Tkinter) yang tidak aktif di web app:

  • main.py — Menu utama desktop
  • predict_image.py — Prediksi gambar via GUI Tkinter
  • models/pca.pkl — PCA model tidak digunakan (legacy)

Jika ada refactoring besar, pertimbangkan untuk menghapus file-file ini atau tandai secara eksplisit.