lordzukoiroh commited on
Commit
d24b565
·
verified ·
1 Parent(s): d5e1234

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +59 -91
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 (tokenizer'ın truncation'ına güveniyoruz)
598
  encoded_inputs = tokenizer.encode_plus(
599
  prompt,
600
  return_tensors="pt",
601
- truncation=True, # Max_length'i aşarsa kırp
602
- max_length=512, # Modelin alabileceği maksimum token sayısı (modelinizin limitine göre ayarlayın)
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"], # RL ajanından gelen değeri kullanmaya devam ediyoruz
616
- no_repeat_ngram_size=6, # <<< no_repeat_ngram_size'ı 6'ya yükselttik
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 = "" # Bu durumda önceki cevabı temizlemeye çalışma
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
- # Kullanıcının sorusunu doğrudan tekrar etme (önceki örneklerdeki gibi)
703
- re.escape("kitaplar neden yasaklanmalı"), # Bu soruyu dinamik olarak da ekleyebilirsiniz
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
- # Genel anlamsız tokenler ve uzun tekrarlayan metinler
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
- # Sonundaki gereksiz ve 📚 işaretlerini de temizle
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 Mantığına Puanlama Sistemi Eklendi ---
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 # Hafif ceza
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 # Ciddi ceza
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 # Her anlamsız ifade için ceza
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
- # Eğer cevap uzunsa (örneğin 20 kelimeden fazla) ve alakasızsa ceza ver
761
- if len(response.split()) > 20 and not has_montag_relevance: # Buradaki kelime sayısını artırabilirsiniz
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 # Ciddi ceza
769
  filter_reasons.append(f"Agresif/istenmeyen kelime tespit edildi: {aggressive_words_found}.")
770
-
771
- # --- Karar verme eşiği ---
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 # Alternatif ve dokümanları döndür
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: # Maksimum 6 cümle
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 # Cevap ve alınan dokümanları döndür
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ı ===