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ı ===
|