Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -566,17 +566,18 @@ def generate_answer(question: str, chatbot_history: List[List[str]]) -> Tuple[st
|
|
| 566 |
print("ERROR: Model, tokenizer, embedder veya RL Agent başlatılmamış.")
|
| 567 |
return generate_alternative_response(question), []
|
| 568 |
|
| 569 |
-
try:
|
| 570 |
gen_params = rl_agent.get_generation_params()
|
| 571 |
-
|
| 572 |
# Bağlamı al (hem metin hem de doküman listesi olarak)
|
|
|
|
|
|
|
|
|
|
| 573 |
retrieved_docs, context_text = retrieve_context(question, chatbot_history, k=2)
|
| 574 |
|
| 575 |
history_text = ""
|
| 576 |
# Son 3 konuşma çiftini geçmişe dahil et (emojileri temizleyerek)
|
| 577 |
if chatbot_history:
|
| 578 |
-
recent_dialogue = []
|
| 579 |
-
# Sadece gerçek Q&A çiftlerini geçmişe dahil et
|
| 580 |
for user_msg, assistant_msg in chatbot_history[-3:]:
|
| 581 |
if user_msg and not (("Montag düşünüyor..." in user_msg) or ("saniyede üretildi" in user_msg) or user_msg.strip() == ""):
|
| 582 |
cleaned_user_msg = user_msg.replace('📚', '').replace('🧠', '').replace('🔥', '').strip()
|
|
@@ -593,18 +594,18 @@ def generate_answer(question: str, chatbot_history: List[List[str]]) -> Tuple[st
|
|
| 593 |
f"Kullanıcı: {question}\n"
|
| 594 |
f"Montag: "
|
| 595 |
)
|
| 596 |
-
|
| 597 |
-
# Prompt uzunluğunu kontrol et ve gerekirse kısalt
|
| 598 |
encoded_inputs = tokenizer.encode_plus(
|
| 599 |
prompt,
|
| 600 |
return_tensors="pt",
|
| 601 |
-
truncation=True,
|
| 602 |
-
max_length=512,
|
| 603 |
).to(DEVICE)
|
| 604 |
|
| 605 |
inputs = encoded_inputs["input_ids"]
|
| 606 |
attention_mask = encoded_inputs["attention_mask"]
|
| 607 |
-
|
| 608 |
outputs = model.generate(
|
| 609 |
inputs,
|
| 610 |
attention_mask=attention_mask,
|
|
@@ -612,21 +613,33 @@ def generate_answer(question: str, chatbot_history: List[List[str]]) -> Tuple[st
|
|
| 612 |
do_sample=True,
|
| 613 |
top_p=0.9,
|
| 614 |
temperature=gen_params["temperature"],
|
| 615 |
-
repetition_penalty=gen_params["repetition_penalty"],
|
| 616 |
-
no_repeat_ngram_size=6,
|
| 617 |
num_beams=1,
|
| 618 |
pad_token_id=tokenizer.eos_token_id,
|
| 619 |
eos_token_id=tokenizer.eos_token_id,
|
| 620 |
)
|
| 621 |
-
|
| 622 |
raw_response_with_prompt = tokenizer.decode(outputs[0], skip_special_tokens=True)
|
| 623 |
response = raw_response_with_prompt # Tüm temizlikler bu 'response' değişkeni üzerinde yapılacak
|
| 624 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 625 |
# --- ADIM 1: Önceki Montag Cevabını Temizleme (En yüksek öncelik) ---
|
| 626 |
last_assistant_response_in_history = ""
|
| 627 |
-
# Chatbot geçmişi boş değilse, son öğe bir tuple ise ve ikinci elemanı (cevap) boş değilse
|
| 628 |
if chatbot_history and len(chatbot_history[-1]) > 1 and chatbot_history[-1][1] is not None:
|
| 629 |
-
# Geçmişteki son Montag cevabını al ve emojileri, meta bilgileri temizle
|
| 630 |
last_assistant_response_in_history = chatbot_history[-1][1]
|
| 631 |
last_assistant_response_in_history = (
|
| 632 |
last_assistant_response_in_history.replace('📚', '')
|
|
@@ -635,147 +648,102 @@ def generate_answer(question: str, chatbot_history: List[List[str]]) -> Tuple[st
|
|
| 635 |
.replace('✅', '')
|
| 636 |
.strip()
|
| 637 |
)
|
| 638 |
-
# Eğer önceki cevap "Cevap X saniyede üretildi" gibi bir metin içeriyorsa, onu atla
|
| 639 |
if "saniyede üretildi" in last_assistant_response_in_history.lower():
|
| 640 |
-
last_assistant_response_in_history = ""
|
| 641 |
|
| 642 |
if last_assistant_response_in_history:
|
| 643 |
-
# Modelin ham çıktısının ve önceki cevabın boşluklarını normalleştir
|
| 644 |
cleaned_raw_response_norm_space = re.sub(r'\s+', ' ', raw_response_with_prompt).strip()
|
| 645 |
cleaned_last_response_norm_space = re.sub(r'\s+', ' ', last_assistant_response_in_history).strip()
|
| 646 |
|
| 647 |
-
# Eğer ham cevap, önceki cevabın normalleştirilmiş haliyle başlıyorsa
|
| 648 |
if cleaned_raw_response_norm_space.lower().startswith(cleaned_last_response_norm_space.lower()):
|
| 649 |
-
# Orijinal ham cevaptan, temizlenmiş önceki cevabın uzunluğu kadarını kes
|
| 650 |
-
# (Dikkat: Buradaki uzunluk hesabı, boşluk normalizasyonu nedeniyle biraz karmaşıklaşabilir.
|
| 651 |
-
# En güvenlisi, regex ile kesmektir, ancak basit string kesimi de denenebilir.)
|
| 652 |
-
|
| 653 |
-
# Daha güvenli kesim için, normalleştirilmiş metin üzerinden indeksleme yapıp sonra orijinal metne dönmek
|
| 654 |
-
# veya direkt regex ile kesmek daha iyi olabilir. Şimdilik basit kesimi bırakıyoruz.
|
| 655 |
-
# Eğer hatalar devam ederse burayı regex ile baştan kesme şeklinde değiştirebiliriz.
|
| 656 |
response = raw_response_with_prompt[len(last_assistant_response_in_history):].strip()
|
| 657 |
print(f"DEBUG: Önceki Montag cevabı tespit edildi ve temizlendi: '{last_assistant_response_in_history[:50]}...'")
|
| 658 |
-
# else: response zaten raw_response_with_prompt olarak ayarlı, bir şey yapmaya gerek yok
|
| 659 |
-
|
| 660 |
|
| 661 |
# --- ADIM 2: İlk "Montag:" Etiketini ve Prompt Kalıntılarını Temizleme ---
|
| 662 |
-
# Önceki temizlikten sonra kalan 'response' üzerinde işlem yapıyoruz
|
| 663 |
match = re.search(r'(?i)Montag:\s*(.*)', response, re.DOTALL)
|
| 664 |
if match:
|
| 665 |
response = match.group(1).strip()
|
| 666 |
else:
|
| 667 |
-
# Eğer 'Montag:' etiketi bulunamazsa, prompt'un tamamını veya başlangıcını temizlemeye çalış
|
| 668 |
prompt_decoded_for_comparison = tokenizer.decode(inputs[0], skip_special_tokens=True)
|
| 669 |
if response.startswith(prompt_decoded_for_comparison):
|
| 670 |
response = response[len(prompt_decoded_for_comparison):].strip()
|
| 671 |
-
# else: response zaten temizlenmeye çalışılmıştı, bir şey yapmaya gerek yok
|
| 672 |
-
|
| 673 |
|
| 674 |
# --- ADIM 3: Persona Talimatları ve Genel Gürültüyü Temizleme ---
|
| 675 |
-
# Persona talimatlarının cevapta tekrarlanmasını engelle (güncel MONTAG_PERSONA'ya göre)
|
| 676 |
persona_lines = [line.strip() for line in MONTAG_PERSONA.split('\n') if line.strip()]
|
| 677 |
for line in persona_lines:
|
| 678 |
-
# Sadece cevabın başında tekrar eden persona talimatlarını temizle
|
| 679 |
if response.lower().startswith(line.lower()):
|
| 680 |
response = response[len(line):].strip()
|
| 681 |
|
| 682 |
-
# Fazladan "Kullanıcı: " veya "Montag: " tekrarlarını ve anlamsız tokenleri temizle
|
| 683 |
response = response.replace("<unk>", "").strip()
|
| 684 |
response = response.replace(" .", ".").replace(" ,", ",").replace(" ?", "?").replace(" !", "!")
|
| 685 |
|
| 686 |
-
# Ek olarak, cevabın içinde hala kalmış olabilecek "Kullanıcı:" veya "Montag:" etiketlerini temizle
|
| 687 |
response = re.sub(r'Kullanıcı:\s*', '', response, flags=re.IGNORECASE)
|
| 688 |
response = re.sub(r'Montag:\s*', '', response, flags=re.IGNORECASE)
|
| 689 |
|
| 690 |
-
# Cevabın içinde "ETİKETLER:" gibi ifadeler varsa temizle
|
| 691 |
if "ETİKETLER:" in response:
|
| 692 |
response = response.split("ETİKETLER:", 1)[0].strip()
|
| 693 |
|
| 694 |
-
# Cevabın sonundaki "[...]" gibi ifadeleri temizle
|
| 695 |
response = re.sub(r'\[\s*\.{3,}\s*\]', '', response).strip()
|
| 696 |
|
| 697 |
# --- ADIM 4: Spesifik Tekrar Eden ve İstenmeyen Kalıpları Temizleme ---
|
| 698 |
irrelevant_dialogue_patterns = [
|
| 699 |
-
# Modelin sürekli tekrarladığı "Nasılsın, iyi misin" ve devamı kalıbı (regex'e escape ekli)
|
| 700 |
re.escape("Nasılsın, iyi misin \" diye sordu Sesin oldukça tizdi, hatta neredeyse boğuluyordu Sesi artık iyice boğuklaşmıştı Gözlerindeki donukluk ve akıl almaz kararlılık, Montag'ın aklını karıştırıyordu Ne söyleyeceğini bilemiyormuş gibiydi"),
|
| 701 |
re.escape("Ne düşünüyorsun ', sorusuna, — İyi değil miyim (Tıslayarak) Hayır, kötü değil miyim diyerek cevabı yapıştırdı"),
|
| 702 |
-
|
| 703 |
-
re.escape("
|
| 704 |
-
# Montag'ın önceki metinlerinden tekrar eden spesifik cümleler
|
| 705 |
-
re.escape("Bu soruda ne kadar samimi olduğumu bilmiyorum "), # Boşluklara dikkat!
|
| 706 |
re.escape("diyor Bunu söyleyen kişi siz misiniz yoksa o mu Tuhaf bir insan gibi görünüyordu Sanki Montag'dan önce hiç kimse cevap vermemiş gibiydi Bana sanki sadece bir şaka yapıyordu ve gülüp eğleniyorduk ✅"),
|
| 707 |
re.escape("'Kitabı yakamazsınız, eğer yaktığınız kanıtlanırsa, kitabı yakmayı bırakırsınız ' Ben bunun için bir sebep yok diyorum Ve sonra, bana, 'Neden ' diye soruyorsunuz — çünkü'sadece' demek istiyorum Neden olmasın ki Bu sorunun bir cevabı var 📚 ✅"),
|
| 708 |
-
|
| 709 |
-
|
| 710 |
-
r'içir unidur', r'aligutat fakdam', r'tetal inlay', r'pessotim elgun',
|
| 711 |
r'nisman tarejoglu', r'faksom', r'achisteloy vandleradia', r'vęudis',
|
| 712 |
r'eltareh', r'eldlar', r'fotjid', r'zuhalibalyon',
|
| 713 |
r'ne zaman kendimi, her şeyi daha iyi anlayabileceğim, daha gerçekleştirebileceğim ve her şeyin üstesinden geleceğim bir yere koysam, daha sonra o yerin bana hiçbir şey öğretmediğini ve hiçbir şeyi öğretmediğini fark ediyorum. Ben kendimi daha fazla kandırmak istemiyorum. Ama ben, beni gerçekten etkileyen başka biri tarafından yönetilen bir.',
|
| 714 |
r'her şeyi en ince ayrıntısına kadar anladım ama aynı zamanda da inanılmaz derecede utanıyorum. İnan bana, ben çok utangaçım.',
|
| 715 |
-
|
| 716 |
-
|
| 717 |
-
r'
|
| 718 |
-
r' 📚',
|
| 719 |
]
|
| 720 |
-
|
| 721 |
for pattern in irrelevant_dialogue_patterns:
|
| 722 |
response = re.sub(pattern, '', response, flags=re.IGNORECASE).strip()
|
| 723 |
-
|
| 724 |
-
# Fazla boşlukları tek boşluğa indirge (Tüm temizliklerden sonra son kez)
|
| 725 |
response = re.sub(r'\s+', ' ', response).strip()
|
| 726 |
|
| 727 |
-
# --- Filtreleme
|
| 728 |
rejection_score = 0
|
| 729 |
filter_reasons = []
|
| 730 |
|
| 731 |
-
# 1. Kısa Cevap Kontrolü (Daha esnek, örneğin 5 kelime)
|
| 732 |
if len(response.split()) < 5:
|
| 733 |
-
rejection_score += 2
|
| 734 |
filter_reasons.append(f"Çok kısa ({len(response.split())} kelime).")
|
| 735 |
-
|
| 736 |
-
# 2. Sadece Harf İçermiyor Kontrolü (Bu genellikle iyi bir filtre)
|
| 737 |
if not any(char.isalpha() for char in response):
|
| 738 |
-
rejection_score += 10
|
| 739 |
filter_reasons.append("Hiç harf içermiyor (sadece noktalama/sayı).")
|
| 740 |
-
|
| 741 |
-
# 3. Genel/Anlamsız İfade Kontrolü (Listeyi yukarıda temizlemiştik)
|
| 742 |
-
generic_or_nonsense_phrases = [
|
| 743 |
-
"içir unidur", "aligutat fakdam", "tetal inlay", "pessotim elgun", # Modelin ürettiği anlamsız tokenler
|
| 744 |
-
"nisman tarejoglu", "faksom", "achisteloy vandleradia", "vęudis",
|
| 745 |
-
"eltareh", "eldlar", "fotjid", "zuhalibalyon",
|
| 746 |
-
"etiketler:", # Meta bilgi sızıntısı
|
| 747 |
-
# Sadece gerçekten anlamsız olanları bırakın
|
| 748 |
-
]
|
| 749 |
triggered_generic_phrases = [phrase for phrase in generic_or_nonsense_phrases if phrase in response.lower()]
|
| 750 |
if triggered_generic_phrases:
|
| 751 |
-
rejection_score += len(triggered_generic_phrases) * 3
|
| 752 |
filter_reasons.append(f"Anlamsız/istenmeyen ifade tespit edildi: {triggered_generic_phrases}.")
|
| 753 |
|
| 754 |
-
# 4. Montag Karakteriyle Alaka Kontrolü (Daha esnek)
|
| 755 |
-
# Montag'ın iç dünyasına ve genel temalara uygun yeni anahtar kelimeler eklendi
|
| 756 |
-
montag_keywords = ["kitap", "yakmak", "itfaiyeci", "clarisse", "faber", "beatty", "bilgi", "sansür", "düşünce", "gerçek", "televizyon", "alev", "kül", "mildred", "yangın", "fireman",
|
| 757 |
-
"düşünmek", "anlamak", "hissetmek", "arayış", "isyan", "toplum", "cehalet", "yalnızlık", "monotonluk", "gerçeklik"]
|
| 758 |
has_montag_relevance = any(keyword in response.lower() for keyword in montag_keywords)
|
| 759 |
-
|
| 760 |
-
|
| 761 |
-
|
| 762 |
-
rejection_score += 1 # Cezayı düşürdük
|
| 763 |
filter_reasons.append("Montag/bağlamsal anahtar kelime yok ve cevap uzun.")
|
| 764 |
-
|
| 765 |
-
# 5. Agresif Kelime Kontrolü
|
| 766 |
aggressive_words_found = [word for word in aggressive_words if word in response.lower()]
|
| 767 |
if aggressive_words_found:
|
| 768 |
-
rejection_score += 5
|
| 769 |
filter_reasons.append(f"Agresif/istenmeyen kelime tespit edildi: {aggressive_words_found}.")
|
| 770 |
-
|
| 771 |
-
|
| 772 |
-
if rejection_score >= 5: # Bu eşik değerini test ederek ayarlamanız gerekebilir.
|
| 773 |
print(f"DEBUG: FİLTRELEME - Cevap YETERSİZ/ANLAMSIZ/ALAKASIZ. Toplam Puan: {rejection_score}")
|
| 774 |
for reason in filter_reasons:
|
| 775 |
print(f" - Sebep: {reason}")
|
| 776 |
print(f"INFO: Üretilen cevap ('{response}') filtreleri geçemedi. Alternatif üretiliyor.")
|
| 777 |
-
return generate_alternative_response(question), retrieved_docs
|
| 778 |
-
|
| 779 |
# Cümle Bölme ve Limitleme Mantığı
|
| 780 |
sentences = []
|
| 781 |
split_by_punctuation = re.split(r'[.!?]', response)
|
|
@@ -783,21 +751,21 @@ def generate_answer(question: str, chatbot_history: List[List[str]]) -> Tuple[st
|
|
| 783 |
s_stripped = s.strip()
|
| 784 |
if s_stripped:
|
| 785 |
sentences.append(s_stripped)
|
| 786 |
-
if len(sentences) >= 6:
|
| 787 |
break
|
| 788 |
final_response_text = ' '.join(sentences).strip()
|
| 789 |
-
|
| 790 |
-
# Eğer filtreleri geçerse ve boş değilse
|
| 791 |
if not final_response_text:
|
| 792 |
print("INFO: Filtrelerden geçen cevap boş kaldı. Alternatif üretiliyor.")
|
| 793 |
return generate_alternative_response(question), retrieved_docs
|
| 794 |
-
|
| 795 |
final_response = add_emojis(final_response_text)
|
| 796 |
-
return final_response, retrieved_docs
|
| 797 |
-
|
| 798 |
-
except Exception as e:
|
| 799 |
print(f"Error generating answer: {e}")
|
| 800 |
return generate_alternative_response(question), []
|
|
|
|
| 801 |
|
| 802 |
|
| 803 |
# === Gradio callback fonksiyonları ===
|
|
|
|
| 566 |
print("ERROR: Model, tokenizer, embedder veya RL Agent başlatılmamış.")
|
| 567 |
return generate_alternative_response(question), []
|
| 568 |
|
| 569 |
+
try: # Fonksiyonun tüm ana mantığını kapsayan try bloğu
|
| 570 |
gen_params = rl_agent.get_generation_params()
|
| 571 |
+
|
| 572 |
# Bağlamı al (hem metin hem de doküman listesi olarak)
|
| 573 |
+
# retrieve_context fonksiyonuna chatbot_history'yi doğru bir şekilde iletiyoruz.
|
| 574 |
+
# Eğer retrieve_context kendi içinde previous_paragraphs adında bir değişken bekliyorsa,
|
| 575 |
+
# o fonksiyonun içindeki tanımlama/atama doğru yapılmalı.
|
| 576 |
retrieved_docs, context_text = retrieve_context(question, chatbot_history, k=2)
|
| 577 |
|
| 578 |
history_text = ""
|
| 579 |
# Son 3 konuşma çiftini geçmişe dahil et (emojileri temizleyerek)
|
| 580 |
if chatbot_history:
|
|
|
|
|
|
|
| 581 |
for user_msg, assistant_msg in chatbot_history[-3:]:
|
| 582 |
if user_msg and not (("Montag düşünüyor..." in user_msg) or ("saniyede üretildi" in user_msg) or user_msg.strip() == ""):
|
| 583 |
cleaned_user_msg = user_msg.replace('📚', '').replace('🧠', '').replace('🔥', '').strip()
|
|
|
|
| 594 |
f"Kullanıcı: {question}\n"
|
| 595 |
f"Montag: "
|
| 596 |
)
|
| 597 |
+
|
| 598 |
+
# Prompt uzunluğunu kontrol et ve gerekirse kısalt
|
| 599 |
encoded_inputs = tokenizer.encode_plus(
|
| 600 |
prompt,
|
| 601 |
return_tensors="pt",
|
| 602 |
+
truncation=True,
|
| 603 |
+
max_length=512,
|
| 604 |
).to(DEVICE)
|
| 605 |
|
| 606 |
inputs = encoded_inputs["input_ids"]
|
| 607 |
attention_mask = encoded_inputs["attention_mask"]
|
| 608 |
+
|
| 609 |
outputs = model.generate(
|
| 610 |
inputs,
|
| 611 |
attention_mask=attention_mask,
|
|
|
|
| 613 |
do_sample=True,
|
| 614 |
top_p=0.9,
|
| 615 |
temperature=gen_params["temperature"],
|
| 616 |
+
repetition_penalty=gen_params["repetition_penalty"],
|
| 617 |
+
no_repeat_ngram_size=6,
|
| 618 |
num_beams=1,
|
| 619 |
pad_token_id=tokenizer.eos_token_id,
|
| 620 |
eos_token_id=tokenizer.eos_token_id,
|
| 621 |
)
|
| 622 |
+
|
| 623 |
raw_response_with_prompt = tokenizer.decode(outputs[0], skip_special_tokens=True)
|
| 624 |
response = raw_response_with_prompt # Tüm temizlikler bu 'response' değişkeni üzerinde yapılacak
|
| 625 |
|
| 626 |
+
# --- Filtreleme için Gerekli Listelerin Tanımlaması (BURADA OLMALIDIR) ---
|
| 627 |
+
# "aggressive_words" hatasını çözmek için bu listeler burada tanımlanıyor.
|
| 628 |
+
aggressive_words = ["salak", "gerizekalı", "saçma", "boş konuşma", "kaba", "agresif"]
|
| 629 |
+
|
| 630 |
+
generic_or_nonsense_phrases = [
|
| 631 |
+
"içir unidur", "aligutat fakdam", "tetal inlay", "pessotim elgun",
|
| 632 |
+
"nisman tarejoglu", "faksom", "achisteloy vandleradia", "vęudis",
|
| 633 |
+
"eltareh", "eldlar", "fotjid", "zuhalibalyon",
|
| 634 |
+
"etiketler:",
|
| 635 |
+
]
|
| 636 |
+
|
| 637 |
+
montag_keywords = ["kitap", "yakmak", "itfaiyeci", "clarisse", "faber", "beatty", "bilgi", "sansür", "düşünce", "gerçek", "televizyon", "alev", "kül", "mildred", "yangın", "fireman",
|
| 638 |
+
"düşünmek", "anlamak", "hissetmek", "arayış", "isyan", "toplum", "cehalet", "yalnızlık", "monotonluk", "gerçeklik"]
|
| 639 |
+
|
| 640 |
# --- ADIM 1: Önceki Montag Cevabını Temizleme (En yüksek öncelik) ---
|
| 641 |
last_assistant_response_in_history = ""
|
|
|
|
| 642 |
if chatbot_history and len(chatbot_history[-1]) > 1 and chatbot_history[-1][1] is not None:
|
|
|
|
| 643 |
last_assistant_response_in_history = chatbot_history[-1][1]
|
| 644 |
last_assistant_response_in_history = (
|
| 645 |
last_assistant_response_in_history.replace('📚', '')
|
|
|
|
| 648 |
.replace('✅', '')
|
| 649 |
.strip()
|
| 650 |
)
|
|
|
|
| 651 |
if "saniyede üretildi" in last_assistant_response_in_history.lower():
|
| 652 |
+
last_assistant_response_in_history = ""
|
| 653 |
|
| 654 |
if last_assistant_response_in_history:
|
|
|
|
| 655 |
cleaned_raw_response_norm_space = re.sub(r'\s+', ' ', raw_response_with_prompt).strip()
|
| 656 |
cleaned_last_response_norm_space = re.sub(r'\s+', ' ', last_assistant_response_in_history).strip()
|
| 657 |
|
|
|
|
| 658 |
if cleaned_raw_response_norm_space.lower().startswith(cleaned_last_response_norm_space.lower()):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 659 |
response = raw_response_with_prompt[len(last_assistant_response_in_history):].strip()
|
| 660 |
print(f"DEBUG: Önceki Montag cevabı tespit edildi ve temizlendi: '{last_assistant_response_in_history[:50]}...'")
|
|
|
|
|
|
|
| 661 |
|
| 662 |
# --- ADIM 2: İlk "Montag:" Etiketini ve Prompt Kalıntılarını Temizleme ---
|
|
|
|
| 663 |
match = re.search(r'(?i)Montag:\s*(.*)', response, re.DOTALL)
|
| 664 |
if match:
|
| 665 |
response = match.group(1).strip()
|
| 666 |
else:
|
|
|
|
| 667 |
prompt_decoded_for_comparison = tokenizer.decode(inputs[0], skip_special_tokens=True)
|
| 668 |
if response.startswith(prompt_decoded_for_comparison):
|
| 669 |
response = response[len(prompt_decoded_for_comparison):].strip()
|
|
|
|
|
|
|
| 670 |
|
| 671 |
# --- ADIM 3: Persona Talimatları ve Genel Gürültüyü Temizleme ---
|
|
|
|
| 672 |
persona_lines = [line.strip() for line in MONTAG_PERSONA.split('\n') if line.strip()]
|
| 673 |
for line in persona_lines:
|
|
|
|
| 674 |
if response.lower().startswith(line.lower()):
|
| 675 |
response = response[len(line):].strip()
|
| 676 |
|
|
|
|
| 677 |
response = response.replace("<unk>", "").strip()
|
| 678 |
response = response.replace(" .", ".").replace(" ,", ",").replace(" ?", "?").replace(" !", "!")
|
| 679 |
|
|
|
|
| 680 |
response = re.sub(r'Kullanıcı:\s*', '', response, flags=re.IGNORECASE)
|
| 681 |
response = re.sub(r'Montag:\s*', '', response, flags=re.IGNORECASE)
|
| 682 |
|
|
|
|
| 683 |
if "ETİKETLER:" in response:
|
| 684 |
response = response.split("ETİKETLER:", 1)[0].strip()
|
| 685 |
|
|
|
|
| 686 |
response = re.sub(r'\[\s*\.{3,}\s*\]', '', response).strip()
|
| 687 |
|
| 688 |
# --- ADIM 4: Spesifik Tekrar Eden ve İstenmeyen Kalıpları Temizleme ---
|
| 689 |
irrelevant_dialogue_patterns = [
|
|
|
|
| 690 |
re.escape("Nasılsın, iyi misin \" diye sordu Sesin oldukça tizdi, hatta neredeyse boğuluyordu Sesi artık iyice boğuklaşmıştı Gözlerindeki donukluk ve akıl almaz kararlılık, Montag'ın aklını karıştırıyordu Ne söyleyeceğini bilemiyormuş gibiydi"),
|
| 691 |
re.escape("Ne düşünüyorsun ', sorusuna, — İyi değil miyim (Tıslayarak) Hayır, kötü değil miyim diyerek cevabı yapıştırdı"),
|
| 692 |
+
re.escape("kitaplar neden yasaklanmalı"),
|
| 693 |
+
re.escape("Bu soruda ne kadar samimi olduğumu bilmiyorum "),
|
|
|
|
|
|
|
| 694 |
re.escape("diyor Bunu söyleyen kişi siz misiniz yoksa o mu Tuhaf bir insan gibi görünüyordu Sanki Montag'dan önce hiç kimse cevap vermemiş gibiydi Bana sanki sadece bir şaka yapıyordu ve gülüp eğleniyorduk ✅"),
|
| 695 |
re.escape("'Kitabı yakamazsınız, eğer yaktığınız kanıtlanırsa, kitabı yakmayı bırakırsınız ' Ben bunun için bir sebep yok diyorum Ve sonra, bana, 'Neden ' diye soruyorsunuz — çünkü'sadece' demek istiyorum Neden olmasın ki Bu sorunun bir cevabı var 📚 ✅"),
|
| 696 |
+
|
| 697 |
+
r'içir unidur', r'aligutat fakdam', r'tetal inlay', r'pessotim elgun',
|
|
|
|
| 698 |
r'nisman tarejoglu', r'faksom', r'achisteloy vandleradia', r'vęudis',
|
| 699 |
r'eltareh', r'eldlar', r'fotjid', r'zuhalibalyon',
|
| 700 |
r'ne zaman kendimi, her şeyi daha iyi anlayabileceğim, daha gerçekleştirebileceğim ve her şeyin üstesinden geleceğim bir yere koysam, daha sonra o yerin bana hiçbir şey öğretmediğini ve hiçbir şeyi öğretmediğini fark ediyorum. Ben kendimi daha fazla kandırmak istemiyorum. Ama ben, beni gerçekten etkileyen başka biri tarafından yönetilen bir.',
|
| 701 |
r'her şeyi en ince ayrıntısına kadar anladım ama aynı zamanda da inanılmaz derecede utanıyorum. İnan bana, ben çok utangaçım.',
|
| 702 |
+
|
| 703 |
+
r' ✅',
|
| 704 |
+
r' 📚',
|
|
|
|
| 705 |
]
|
| 706 |
+
|
| 707 |
for pattern in irrelevant_dialogue_patterns:
|
| 708 |
response = re.sub(pattern, '', response, flags=re.IGNORECASE).strip()
|
| 709 |
+
|
|
|
|
| 710 |
response = re.sub(r'\s+', ' ', response).strip()
|
| 711 |
|
| 712 |
+
# --- ADIM 5: Filtreleme Mantığı (Puanlama Sistemi) ---
|
| 713 |
rejection_score = 0
|
| 714 |
filter_reasons = []
|
| 715 |
|
|
|
|
| 716 |
if len(response.split()) < 5:
|
| 717 |
+
rejection_score += 2
|
| 718 |
filter_reasons.append(f"Çok kısa ({len(response.split())} kelime).")
|
| 719 |
+
|
|
|
|
| 720 |
if not any(char.isalpha() for char in response):
|
| 721 |
+
rejection_score += 10
|
| 722 |
filter_reasons.append("Hiç harf içermiyor (sadece noktalama/sayı).")
|
| 723 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 724 |
triggered_generic_phrases = [phrase for phrase in generic_or_nonsense_phrases if phrase in response.lower()]
|
| 725 |
if triggered_generic_phrases:
|
| 726 |
+
rejection_score += len(triggered_generic_phrases) * 3
|
| 727 |
filter_reasons.append(f"Anlamsız/istenmeyen ifade tespit edildi: {triggered_generic_phrases}.")
|
| 728 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 729 |
has_montag_relevance = any(keyword in response.lower() for keyword in montag_keywords)
|
| 730 |
+
|
| 731 |
+
if len(response.split()) > 20 and not has_montag_relevance:
|
| 732 |
+
rejection_score += 1
|
|
|
|
| 733 |
filter_reasons.append("Montag/bağlamsal anahtar kelime yok ve cevap uzun.")
|
| 734 |
+
|
|
|
|
| 735 |
aggressive_words_found = [word for word in aggressive_words if word in response.lower()]
|
| 736 |
if aggressive_words_found:
|
| 737 |
+
rejection_score += 5
|
| 738 |
filter_reasons.append(f"Agresif/istenmeyen kelime tespit edildi: {aggressive_words_found}.")
|
| 739 |
+
|
| 740 |
+
if rejection_score >= 5:
|
|
|
|
| 741 |
print(f"DEBUG: FİLTRELEME - Cevap YETERSİZ/ANLAMSIZ/ALAKASIZ. Toplam Puan: {rejection_score}")
|
| 742 |
for reason in filter_reasons:
|
| 743 |
print(f" - Sebep: {reason}")
|
| 744 |
print(f"INFO: Üretilen cevap ('{response}') filtreleri geçemedi. Alternatif üretiliyor.")
|
| 745 |
+
return generate_alternative_response(question), retrieved_docs
|
| 746 |
+
|
| 747 |
# Cümle Bölme ve Limitleme Mantığı
|
| 748 |
sentences = []
|
| 749 |
split_by_punctuation = re.split(r'[.!?]', response)
|
|
|
|
| 751 |
s_stripped = s.strip()
|
| 752 |
if s_stripped:
|
| 753 |
sentences.append(s_stripped)
|
| 754 |
+
if len(sentences) >= 6:
|
| 755 |
break
|
| 756 |
final_response_text = ' '.join(sentences).strip()
|
| 757 |
+
|
|
|
|
| 758 |
if not final_response_text:
|
| 759 |
print("INFO: Filtrelerden geçen cevap boş kaldı. Alternatif üretiliyor.")
|
| 760 |
return generate_alternative_response(question), retrieved_docs
|
| 761 |
+
|
| 762 |
final_response = add_emojis(final_response_text)
|
| 763 |
+
return final_response, retrieved_docs
|
| 764 |
+
|
| 765 |
+
except Exception as e: # Try bloğunun sonu ve hata yakalama
|
| 766 |
print(f"Error generating answer: {e}")
|
| 767 |
return generate_alternative_response(question), []
|
| 768 |
+
|
| 769 |
|
| 770 |
|
| 771 |
# === Gradio callback fonksiyonları ===
|