chatbot-model / app.py
khaerulilman's picture
Create app.py
ea9025a verified
Raw
History Blame Contribute Delete
7.06 kB
from flask import Flask, request, jsonify
from flask_cors import CORS
import torch
from sentence_transformers import SentenceTransformer, util
from openai import OpenAI
import os
from dotenv import load_dotenv
# Muat variabel dari file .env
load_dotenv()
# Dataset informasi untuk platform (diperluas untuk contoh)
faq = {
"apa itu mamacare?": "mamacare adalah aplikasi buatan putra fuazan fatah kang , ia dikenal sebagai kang refferal",
# another data
"apa itu leverage di bybit dan bagaimana cara kerjanya?": "Leverage memungkinkan Anda untuk membuka posisi lebih besar dari modal yang dimiliki. Misalnya, leverage 10x memungkinkan Anda mengendalikan $1000 hanya dengan $100 margin.",
"berapa leverage maksimal yang tersedia di bybit?": "Leverage maksimal tergantung pada pasangan trading. Untuk BTC/USDT biasanya hingga 100x, sedangkan untuk altcoin umumnya lebih rendah.",
"bagaimana cara menghindari likuidasi di bybit?": "Untuk menghindari likuidasi, gunakan leverage dengan bijak, pasang stop loss, dan selalu pantau rasio margin Anda.",
"apakah bybit aman digunakan?": "Bybit memiliki standar keamanan tinggi seperti 2FA, cold wallet untuk penyimpanan aset, dan sistem pemantauan aktivitas mencurigakan.",
"apa itu isolated dan cross margin di bybit?": "Isolated margin berarti hanya margin di posisi tersebut yang dipertaruhkan, sedangkan cross margin menggunakan seluruh saldo di akun Anda sebagai margin.",
"bagaimana cara membuka posisi trading di bybit?": "Pilih pasangan trading, pilih jenis order (limit/market), masukkan jumlah dan leverage, lalu klik 'Open Long' atau 'Open Short'.",
"apa yang harus dilakukan jika akun saya terkunci?": "Jika akun terkunci, Anda bisa menghubungi customer support Bybit melalui email resmi atau live chat di website untuk proses verifikasi identitas.",
"bagaimana cara menggunakan fitur stop loss dan take profit di bybit?": "Saat membuka posisi, Anda bisa langsung mengatur stop loss dan take profit. Atau, Anda bisa mengaturnya setelah posisi dibuka melalui tab 'Positions'.",
"apakah bybit memiliki aplikasi mobile?": "Ya, Bybit tersedia untuk Android dan iOS. Anda bisa mengunduhnya dari Google Play Store atau App Store untuk melakukan trading di mana saja.",
}
# Ambil API key dari environment
api_key = os.getenv("OPENAI_API_KEY")
# Inisialisasi OpenAI client
openai_client = OpenAI(api_key=api_key)
class HybridFAQChatbot:
def __init__(self, model_name="intfloat/e5-large-v2", threshold=0.85):
"""
Inisialisasi chatbot dengan model embedding dan threshold kemiripan
Args:
model_name (str): Nama model sentence transformer yang akan digunakan
threshold (float): Nilai ambang batas kemiripan (0-1)
"""
print(f"Memuat model {model_name}...")
self.model = SentenceTransformer(model_name, device='cpu')
self.threshold = threshold
# Precompute embeddings untuk semua pertanyaan FAQ
self.faq_questions = list(faq.keys())
self.faq_answers = list(faq.values())
# Preprocess pertanyaan dengan format yang diharapkan oleh e5
preprocessed_questions = [f"query: {q}" for q in self.faq_questions]
self.faq_embeddings = self.model.encode(preprocessed_questions, convert_to_tensor=True)
print("Chatbot siap digunakan!")
def get_openai_response(self, query):
"""
Mendapatkan respons dari OpenAI API
Args:
query (str): Pertanyaan dari pengguna
Returns:
str: Jawaban dari OpenAI
"""
try:
response = openai_client.chat.completions.create(
model="gpt-3.5-turbo",
messages=[
{"role": "system", "content": "Anda adalah asisten AI yang membantu menjawab pertanyaan pengguna dengan ramah dan informatif. Berikan jawaban singkat dan padat."},
{"role": "user", "content": query}
],
max_tokens=150,
temperature=0.7
)
return response.choices[0].message.content
except Exception as e:
print(f"Error when calling OpenAI API: {e}")
return "Maaf, saya tidak dapat menjawab pertanyaan Anda saat ini."
def get_response(self, query):
"""
Mendapatkan respons berdasarkan pertanyaan pengguna
Args:
query (str): Pertanyaan dari pengguna
Returns:
str: Jawaban dari FAQ atau OpenAI
"""
# Periksa apakah query kosong atau terlalu pendek
if not query or len(query.strip()) < 3:
return "Mohon masukkan pertanyaan yang lebih lengkap"
# Preprocess query dengan format yang diharapkan oleh e5
preprocessed_query = f"query: {query}"
# Encode query pengguna
query_embedding = self.model.encode(preprocessed_query, convert_to_tensor=True)
# Hitung skor kemiripan cosine dengan semua pertanyaan FAQ
cosine_scores = util.cos_sim(query_embedding, self.faq_embeddings)[0]
# Dapatkan indeks dengan skor tertinggi
best_idx = torch.argmax(cosine_scores).item()
best_score = cosine_scores[best_idx].item()
print(f"Pertanyaan: {query}")
print(f"Kemiripan tertinggi: {best_score:.4f} dengan '{self.faq_questions[best_idx]}'")
# Implementasi validasi semantik tambahan
query_words = set(query.lower().split())
faq_words = set(self.faq_questions[best_idx].lower().split())
# Hitung overlap kata-kata kunci
common_words = query_words.intersection(faq_words)
common_words = {word for word in common_words if len(word) > 3} # Fokus pada kata-kata penting
# Jika skor kemiripan di atas threshold DAN ada kata kunci yang sama, berikan jawaban dari FAQ
if best_score >= self.threshold and (len(common_words) > 0 or best_score > 0.95):
print("Menggunakan jawaban dari FAQ")
return self.faq_answers[best_idx]
else:
# Jika tidak ada kemiripan yang cukup, gunakan OpenAI untuk menjawab
print("Tidak ada kemiripan yang cukup, menggunakan OpenAI")
return self.get_openai_response(query)
# Inisialisasi Flask app
app = Flask(__name__)
CORS(app) # Enable CORS untuk semua domain
# Inisialisasi chatbot
chatbot = HybridFAQChatbot(threshold=0.85)
@app.route('/api/chat', methods=['POST'])
def chat():
data = request.json
user_message = data.get('message', '')
if not user_message:
return jsonify({'error': 'Message is required'}), 400
response = chatbot.get_response(user_message)
return jsonify({'response': response})
if __name__ == '__main__':
print("Memulai API chatbot pada http://localhost:5000")
app.run(debug=True, host='0.0.0.0', port=5000)