# app.py - KODE BERSIH DAN SIAP JALAN import pandas as pd from sentence_transformers import SentenceTransformer from sklearn.metrics.pairwise import cosine_similarity import numpy as np import gradio as gr import os # --- Konfigurasi --- MODEL_NAME = 'paraphrase-multilingual-mpnet-base-v2' FILE_PATH = 'perpustakaan_faq.csv' THRESHOLD = 0.70 # Batasan similarity # Inisialisasi model print(f"Mengunduh/Memuat model: {MODEL_NAME}...") try: model = SentenceTransformer(MODEL_NAME) print("Model berhasil dimuat.") except Exception as e: print(f"Gagal memuat model. Error: {e}") import sys sys.exit(1) # --- 1. Persiapan Data dan Embeddings --- def load_and_embed_data(file_path): """ Memuat data FAQ dari file, dan membuat embeddings untuk setiap query. """ if not os.path.exists(file_path): print(f"Error: File {file_path} tidak ditemukan. Tidak dapat melanjutkan.") return None, None, None # Memuat data FAQ dari CSV df = pd.read_csv(file_path) # Ambil kolom 'user_query' sebagai basis pengetahuan (Knowledge Base) faq_queries = df['user_query'].tolist() print(f"Membuat embeddings untuk {len(faq_queries)} Knowledge Base items...") # Encoding semua pertanyaan dari data FAQ corpus_embeddings = model.encode(faq_queries, convert_to_tensor=False) print("Embeddings Knowledge Base selesai dibuat.") return df, faq_queries, corpus_embeddings # Memuat dan memproses data df_faq, faq_queries, faq_embeddings = load_and_embed_data(FILE_PATH) if df_faq is None: print("Gagal memuat data. Mohon periksa file CSV.") import sys sys.exit(1) # --- 2. Fungsi Retrieval Chatbot --- def chatbot_response(user_input): """ Fungsi utama chatbot yang menerima input pengguna, mencari query paling mirip di Knowledge Base, dan mengembalikan jawaban yang relevan. """ if df_faq is None: return "Chatbot belum siap. Data FAQ tidak dimuat." if not user_input or len(user_input.strip()) == 0: return "Halo! Saya adalah Chatbot Layanan Perpustakaan. Silakan ajukan pertanyaan (contoh: Syarat buat kartu anggota?)." # Encoding input pengguna query_embedding = model.encode([user_input], convert_to_tensor=False)[0] # Hitung Cosine Similarity similarities = cosine_similarity([query_embedding], faq_embeddings)[0] # Temukan indeks dengan similarity tertinggi most_similar_index = np.argmax(similarities) max_similarity_score = similarities[most_similar_index] if max_similarity_score >= THRESHOLD: # Ambil query terbaik yang cocok best_match_query = faq_queries[most_similar_index] # Ambil jawaban yang sesuai response = df_faq.loc[df_faq['user_query'] == best_match_query, 'chatbot_response'].iloc[0] return response else: # Jawaban default jika tidak ada kecocokan yang kuat return ("Maaf, saya tidak menemukan jawaban yang relevan di data FAQ saya. " "Coba pertanyaan lain yang lebih spesifik atau hubungi meja informasi perpustakaan.") # --- 3. Antarmuka Pengguna (UI) dengan Gradio --- iface = gr.Interface( fn=chatbot_response, inputs=gr.Textbox( lines=3, placeholder="Ketik pertanyaan Anda di sini... (Contoh: Berapa denda kalau telat mengembalikan buku?)", label="Pertanyaan Pengunjung" ), outputs=gr.Textbox(label="Jawaban Chatbot Perpustakaan"), title="🤖 Chatbot Layanan Informasi Perpustakaan (FAQ Retrieval)", description=( "Chatbot ini menggunakan teknik **FAQ Retrieval** berbasis **Similarity Search** " "dengan model pra-latih Bahasa Indonesia. Pertanyaan Anda akan dicocokkan dengan pertanyaan di data FAQ " "yang paling mirip untuk memberikan jawaban yang relevan. " "\n\n**Contoh pertanyaan:** Syarat buat kartu anggota? | Sampai jam berapa perpustakaan buka? | Bagaimana cara perpanjang pinjaman?" ), live=True, theme="soft" ) # --- 4. Launching Aplikasi --- # Baris ini menjalankan UI Gradio secara lokal if __name__ == "__main__": iface.launch()