import pandas as pd from transformers import pipeline, AutoModelForQuestionAnswering, AutoTokenizer import gradio as gr import re import os # --- 1. Persiapan Data dan Model --- # Nama file CSV yang diunggah CSV_FILE = "perpustakaan_faq.csv" questions = [] answers = [] MODEL_LOADED = False qa_pipeline = None # Memuat data dari CSV try: df = pd.read_csv(CSV_FILE) # Kolom 'chatbot_response' akan dijadikan Konteks utama (Basis Pengetahuan) questions = df['user_query'].tolist() answers = df['chatbot_response'].tolist() except FileNotFoundError: print(f"Error: File '{CSV_FILE}' tidak ditemukan. Pastikan file berada di direktori yang sama.") except Exception as e: print(f"Error saat memuat atau memproses data CSV: {e}") # Inisialisasi Model Question Answering Bahasa Indonesia # Catatan: Jika model ini tetap gagal dimuat, sistem akan otomatis menggunakan fallback. try: model_name = "indobenchmark/indobert-base-uncased-squad" # Coba muat model dan tokenizer model = AutoModelForQuestionAnswering.from_pretrained(model_name) tokenizer = AutoTokenizer.from_pretrained(model_name) # Inisialisasi pipeline QA qa_pipeline = pipeline( "question-answering", model=model, tokenizer=tokenizer ) MODEL_LOADED = True print(f"Model {model_name} berhasil dimuat.") except Exception as e: print(f"Error memuat model Question Answering ({model_name}): {e}") MODEL_LOADED = False print("Menggunakan fallback (pencocokan kata kunci sederhana) karena model gagal dimuat.") # --- 2. Fungsi Logika Chatbot --- def preprocess_query(query): """Membersihkan dan menormalkan query.""" query = query.lower().strip() query = re.sub(r'[^\w\s]', '', query) return query def get_answer_from_qa_model(query): """ Mencari jawaban menggunakan Model Question Answering dari semua konteks (Answers). """ best_answer = "Maaf, saya tidak menemukan informasi yang relevan untuk pertanyaan Anda. Silakan coba pertanyaan lain atau hubungi meja informasi perpustakaan." best_score = 0.0 for original_answer in answers: try: result = qa_pipeline( question=query, context=original_answer ) if result['score'] > best_score: best_score = result['score'] best_answer = result['answer'] if best_score > 0.95: break except Exception: continue if best_score < 0.3: return "Maaf, saya tidak menemukan informasi yang relevan untuk pertanyaan Anda. Silakan coba pertanyaan lain atau hubungi meja informasi perpustakaan." return best_answer def get_answer_fallback(query): """ Fungsi fallback sederhana berdasarkan pencocokan kata kunci. """ if not answers: return "Maaf, data FAQ perpustakaan belum termuat." preprocessed_query = preprocess_query(query) best_match_answer = "Maaf, saya tidak menemukan informasi yang relevan untuk pertanyaan Anda. Silakan coba pertanyaan lain atau hubungi meja informasi perpustakaan." max_matches = 0 query_words = set(word for word in preprocessed_query.split() if len(word) > 3) for q_data, a_data in zip(questions, answers): q_data_words = set(word for word in preprocess_query(q_data).split() if len(word) > 3) matches = len(query_words.intersection(q_data_words)) if matches > max_matches: max_matches = matches best_match_answer = a_data if max_matches < 1: return "Maaf, saya tidak menemukan informasi yang relevan untuk pertanyaan Anda. Silakan coba pertanyaan lain atau hubungi meja informasi perpustakaan." return best_match_answer def chatbot_response(user_query, history): """ Fungsi utama yang dipanggil oleh Gradio. """ if not user_query or not user_query.strip(): return "Halo! Silakan ajukan pertanyaan seputar layanan perpustakaan." if MODEL_LOADED: response = get_answer_from_qa_model(user_query) else: response = get_answer_fallback(user_query) return response # --- 3. Implementasi Gradio Interface --- # Deskripsi Interface title = "🤖 Chatbot Layanan Perpustakaan" # Informasi model untuk ditampilkan di deskripsi model_info = ( "Model QA: **" + ("indobenchmark/indobert-base-uncased-squad" if MODEL_LOADED else "Fallback Keyword Match") + "** | " "Data Sumber: `perpustakaan_faq.csv`" ) description = ( "Ini adalah Chatbot Tanya Jawab (Question Answering) yang dibuat dari data " "FAQ Perpustakaan. Silakan ajukan pertanyaan seputar keanggotaan, peminjaman, kunjungan, atau fasilitas." f"\n\n---\n\n{model_info}" ) # Contoh pertanyaan untuk memandu pengguna examples = [ ["Berapa lama batas waktu peminjaman buku?"], ["Apa syarat utama jika saya mau buat kartu anggota perpustakaan?"], ["Apakah ada loker penitipan barang di sini?"], ["Bolehkah saya membawa laptop pribadi ke dalam perpustakaan?"] ] # Pembuatan Gradio Interface iface = gr.ChatInterface( fn=chatbot_response, title=title, description=description, examples=examples, chatbot=gr.Chatbot( height=400, label="Asisten Perpustakaan", # --- PERBAIKAN FATAL: Menghapus parameter 'type' yang menyebabkan TypeError --- # type="messages", ), ) if __name__ == "__main__": iface.launch()