Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -604,96 +604,64 @@ def generate_answer(question: str, chatbot_history: List[List[str]]) -> Tuple[st
|
|
| 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,
|
| 611 |
-
max_new_tokens=150,
|
| 612 |
do_sample=True,
|
| 613 |
top_p=0.9,
|
| 614 |
temperature=gen_params["temperature"],
|
| 615 |
-
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 |
-
|
| 623 |
-
|
| 624 |
-
|
| 625 |
-
|
| 626 |
-
|
| 627 |
-
|
| 628 |
-
|
| 629 |
-
|
| 630 |
-
|
| 631 |
-
|
| 632 |
-
|
| 633 |
-
|
| 634 |
-
|
| 635 |
-
|
| 636 |
-
|
| 637 |
-
persona_lines = [line.strip() for line in MONTAG_PERSONA.split('\n') if line.strip()]
|
| 638 |
-
for line in persona_lines:
|
| 639 |
-
if response.lower().startswith(line.lower()):
|
| 640 |
-
response = response[len(line):].strip()
|
| 641 |
-
|
| 642 |
-
# 3. Fazladan "Kullanıcı: " veya "Montag: " tekrarlarını ve anlamsız tokenleri temizle
|
| 643 |
-
response = response.replace("<unk>", "").strip()
|
| 644 |
-
response = response.replace(" .", ".").replace(" ,", ",").replace(" ?", "?").replace(" !", "!")
|
| 645 |
-
response = re.sub(r'Kullanıcı:\s*', '', response, flags=re.IGNORECASE)
|
| 646 |
-
response = re.sub(r'Montag:\s*', '', response, flags=re.IGNORECASE)
|
| 647 |
-
if "ETİKETLER:" in response:
|
| 648 |
-
response = response.split("ETİKETLER:", 1)[0].strip()
|
| 649 |
-
response = re.sub(r'\[\s*\.{3,}\s*\]', '', response).strip()
|
| 650 |
-
|
| 651 |
-
# --- Önceki Konuşma ve Tekrar Eden Kalıpları Temizleme ---
|
| 652 |
-
# Bu kısmı kendi irrelevant_dialogue_patterns listenizle birleştirin/değiştirin
|
| 653 |
-
irrelevant_dialogue_patterns = [
|
| 654 |
-
# Modelin sürekli tekrarladığı "Nasılsın, iyi misin" ve devamı kalıbı
|
| 655 |
-
r'Nasılsın,\s*iyi\s*misin\s*"\s*diye\s*sordu\s*Sesin\s*oldukça\s*tizdi,\s*hatta\s*neredeyse\s*boğuluyordu\s*Sesi\s*artık\s*iyice\s*boğuklaşmıştı\s*Gözlerindeki\s*donukluk\s*ve\s*akıl\s*almaz\s*kararlılık,\s*Montag\'ın\s*aklını\s*karıştırıyordu\s*Ne\s*söyleyeceğini\s*bilemiyormuş\s*gibiydi',
|
| 656 |
-
r'Ne\s*düşünüyorsun\s*\,\s*sorusuna,\s*—\s*İyi\s*değil\s*miyim\s*\(Tıslayarak\)\s*Hayır,\s*kötü\s*değil\s*miyim\s*diyerek\s*cevabı\s*yapıştırdı',
|
| 657 |
-
# ... diğer temizlik kalıplarınız ...
|
| 658 |
-
]
|
| 659 |
-
for pattern in irrelevant_dialogue_patterns:
|
| 660 |
-
response = re.sub(pattern, '', response, flags=re.IGNORECASE).strip()
|
| 661 |
-
|
| 662 |
-
response = re.sub(r'\s+', ' ', response).strip() # Fazla boşlukları tek boşluğa indirge
|
| 663 |
|
| 664 |
-
#
|
| 665 |
-
# Örneğin, aggressive_words ve generic_or_nonsense_phrases listelerinizin güncel halini ve puanlama sistemini buraya ekleyin
|
| 666 |
-
|
| 667 |
-
# 2. Persona talimatlarının cevapta tekrarlanmasını engelle (güncel MONTAG_PERSONA'ya göre)
|
| 668 |
persona_lines = [line.strip() for line in MONTAG_PERSONA.split('\n') if line.strip()]
|
| 669 |
for line in persona_lines:
|
| 670 |
-
# Sadece cevabın başında tekrar eden persona talimatlarını temizle
|
| 671 |
if response.lower().startswith(line.lower()):
|
| 672 |
response = response[len(line):].strip()
|
| 673 |
-
|
| 674 |
# 3. Fazladan "Kullanıcı: " veya "Montag: " tekrarlarını ve anlamsız tokenleri temizle
|
| 675 |
response = response.replace("<unk>", "").strip()
|
| 676 |
response = response.replace(" .", ".").replace(" ,", ",").replace(" ?", "?").replace(" !", "!")
|
| 677 |
-
|
| 678 |
-
# Ek olarak, cevabın içinde hala kalmış olabilecek "Kullanıcı:" veya "Montag:" etiketlerini temizle
|
| 679 |
response = re.sub(r'Kullanıcı:\s*', '', response, flags=re.IGNORECASE)
|
| 680 |
response = re.sub(r'Montag:\s*', '', response, flags=re.IGNORECASE)
|
| 681 |
-
|
| 682 |
-
# Cevabın içinde "ETİKETLER:" gibi ifadeler varsa temizle
|
| 683 |
if "ETİKETLER:" in response:
|
| 684 |
response = response.split("ETİKETLER:", 1)[0].strip()
|
| 685 |
-
|
| 686 |
-
# Cevabın sonundaki "[...]" gibi ifadeleri temizle
|
| 687 |
response = re.sub(r'\[\s*\.{3,}\s*\]', '', response).strip()
|
| 688 |
|
| 689 |
-
# ---
|
| 690 |
-
|
| 691 |
-
|
| 692 |
-
|
| 693 |
-
|
| 694 |
-
|
| 695 |
-
|
|
|
|
| 696 |
]
|
|
|
|
|
|
|
|
|
|
| 697 |
for pattern in irrelevant_dialogue_patterns:
|
| 698 |
response = re.sub(pattern, '', response, flags=re.IGNORECASE).strip()
|
| 699 |
|
|
@@ -701,11 +669,10 @@ response = re.sub(r'\s+', ' ', response).strip() # Fazla boşlukları tek boşlu
|
|
| 701 |
response = re.sub(r'\s+', ' ', response).strip()
|
| 702 |
|
| 703 |
# Agresif veya hakaret içeren kelimeleri kontrol et
|
| 704 |
-
|
| 705 |
-
|
| 706 |
|
| 707 |
-
# ---
|
| 708 |
-
# Her bir filtre kuralına bir "ceza puanı" veriyoruz. Toplam puan belirli bir eşiği geçerse reddedeceğiz.
|
| 709 |
rejection_score = 0
|
| 710 |
filter_reasons = []
|
| 711 |
|
|
@@ -713,53 +680,52 @@ response = re.sub(r'\s+', ' ', response).strip() # Fazla boşlukları tek boşlu
|
|
| 713 |
if len(response.split()) < 5:
|
| 714 |
rejection_score += 2 # Hafif ceza
|
| 715 |
filter_reasons.append(f"Çok kısa ({len(response.split())} kelime).")
|
| 716 |
-
|
| 717 |
# 2. Sadece Harf İçermiyor Kontrolü (Bu genellikle iyi bir filtre)
|
| 718 |
if not any(char.isalpha() for char in response):
|
| 719 |
rejection_score += 10 # Ciddi ceza
|
| 720 |
filter_reasons.append("Hiç harf içermiyor (sadece noktalama/sayı).")
|
| 721 |
-
|
| 722 |
# 3. Genel/Anlamsız İfade Kontrolü (Listeyi yukarıda temizlemiştik)
|
| 723 |
generic_or_nonsense_phrases = [
|
| 724 |
"içir unidur", "aligutat fakdam", "tetal inlay", "pessotim elgun", # Modelin ürettiği anlamsız tokenler
|
| 725 |
"nisman tarejoglu", "faksom", "achisteloy vandleradia", "vęudis",
|
| 726 |
"eltareh", "eldlar", "fotjid", "zuhalibalyon",
|
| 727 |
"etiketler:", # Meta bilgi sızıntısı
|
| 728 |
-
# Sadece gerçekten anlamsız olanları bırakın
|
| 729 |
-
]
|
| 730 |
-
|
| 731 |
triggered_generic_phrases = [phrase for phrase in generic_or_nonsense_phrases if phrase in response.lower()]
|
| 732 |
if triggered_generic_phrases:
|
| 733 |
rejection_score += len(triggered_generic_phrases) * 3 # Her anlamsız ifade için ceza
|
| 734 |
filter_reasons.append(f"Anlamsız/istenmeyen ifade tespit edildi: {triggered_generic_phrases}.")
|
| 735 |
|
| 736 |
# 4. Montag Karakteriyle Alaka Kontrolü (Daha esnek)
|
| 737 |
-
|
|
|
|
|
|
|
| 738 |
has_montag_relevance = any(keyword in response.lower() for keyword in montag_keywords)
|
| 739 |
-
|
| 740 |
-
# Eğer cevap uzunsa (
|
| 741 |
-
if len(response.split()) >
|
| 742 |
-
rejection_score +=
|
| 743 |
filter_reasons.append("Montag/bağlamsal anahtar kelime yok ve cevap uzun.")
|
| 744 |
-
|
| 745 |
# 5. Agresif Kelime Kontrolü
|
| 746 |
aggressive_words_found = [word for word in aggressive_words if word in response.lower()]
|
| 747 |
if aggressive_words_found:
|
| 748 |
rejection_score += 5 # Ciddi ceza
|
| 749 |
filter_reasons.append(f"Agresif/istenmeyen kelime tespit edildi: {aggressive_words_found}.")
|
| 750 |
-
|
| 751 |
-
# --- Karar verme eşiği ---
|
| 752 |
-
# Toplam ceza puanı 5'i (veya belirleyeceğiniz başka bir eşiği) geçerse reddet
|
| 753 |
if rejection_score >= 5: # Bu eşik değerini test ederek ayarlamanız gerekebilir.
|
| 754 |
print(f"DEBUG: FİLTRELEME - Cevap YETERSİZ/ANLAMSIZ/ALAKASIZ. Toplam Puan: {rejection_score}")
|
| 755 |
for reason in filter_reasons:
|
| 756 |
print(f" - Sebep: {reason}")
|
| 757 |
print(f"INFO: Üretilen cevap ('{response}') filtreleri geçemedi. Alternatif üretiliyor.")
|
| 758 |
return generate_alternative_response(question), retrieved_docs # Alternatif ve dokümanları döndür
|
| 759 |
-
|
| 760 |
-
# Cümle Bölme ve Limitleme Mantığı
|
| 761 |
sentences = []
|
| 762 |
-
# Noktalama işaretlerine göre böl ve boşlukları temizle
|
| 763 |
split_by_punctuation = re.split(r'[.!?]', response)
|
| 764 |
for s in split_by_punctuation:
|
| 765 |
s_stripped = s.strip()
|
|
@@ -767,22 +733,21 @@ response = re.sub(r'\s+', ' ', response).strip() # Fazla boşlukları tek boşlu
|
|
| 767 |
sentences.append(s_stripped)
|
| 768 |
if len(sentences) >= 6: # Maksimum 6 cümle
|
| 769 |
break
|
| 770 |
-
|
| 771 |
final_response_text = ' '.join(sentences).strip()
|
| 772 |
-
|
| 773 |
# Eğer filtreleri geçerse ve boş değilse
|
| 774 |
-
if not final_response_text:
|
| 775 |
print("INFO: Filtrelerden geçen cevap boş kaldı. Alternatif üretiliyor.")
|
| 776 |
return generate_alternative_response(question), retrieved_docs
|
| 777 |
-
|
| 778 |
final_response = add_emojis(final_response_text)
|
| 779 |
return final_response, retrieved_docs # Cevap ve alınan dokümanları döndür
|
| 780 |
-
|
| 781 |
except Exception as e:
|
| 782 |
print(f"Error generating answer: {e}")
|
| 783 |
-
# Hata durumunda alternatif cevap döndürürken retrieved_docs'ı da döndürmek daha iyi olabilir
|
| 784 |
return generate_alternative_response(question), []
|
| 785 |
|
|
|
|
| 786 |
# === Gradio callback fonksiyonları ===
|
| 787 |
def respond(msg: str, chatbot_history: List[List[str]], progress=gr.Progress()) -> Tuple[str, List[List[str]], str, str]:
|
| 788 |
if not msg.strip():
|
|
|
|
| 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,
|
| 611 |
+
max_new_tokens=150,
|
| 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 |
+
|
| 624 |
+
# --- Cevap Temizleme ve Post-Processing İyileştirmeleri ---
|
| 625 |
+
response = raw_response_with_prompt
|
| 626 |
+
|
| 627 |
+
# 1. Prompt'un kendisini ve "Montag:" kısmını cevaptan ayırma
|
| 628 |
+
match = re.search(r'(?i)Montag:\s*(.*)', response, re.DOTALL)
|
| 629 |
+
if match:
|
| 630 |
+
response = match.group(1).strip()
|
| 631 |
+
else:
|
| 632 |
+
prompt_decoded_for_comparison = tokenizer.decode(inputs[0], skip_special_tokens=True)
|
| 633 |
+
if response.startswith(prompt_decoded_for_comparison):
|
| 634 |
+
response = response[len(prompt_decoded_for_comparison):].strip()
|
| 635 |
+
else:
|
| 636 |
+
response = raw_response_with_prompt.strip()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 637 |
|
| 638 |
+
# 2. Persona talimatlarının cevapta tekrarlanmasını engelle
|
|
|
|
|
|
|
|
|
|
| 639 |
persona_lines = [line.strip() for line in MONTAG_PERSONA.split('\n') if line.strip()]
|
| 640 |
for line in persona_lines:
|
|
|
|
| 641 |
if response.lower().startswith(line.lower()):
|
| 642 |
response = response[len(line):].strip()
|
| 643 |
+
|
| 644 |
# 3. Fazladan "Kullanıcı: " veya "Montag: " tekrarlarını ve anlamsız tokenleri temizle
|
| 645 |
response = response.replace("<unk>", "").strip()
|
| 646 |
response = response.replace(" .", ".").replace(" ,", ",").replace(" ?", "?").replace(" !", "!")
|
|
|
|
|
|
|
| 647 |
response = re.sub(r'Kullanıcı:\s*', '', response, flags=re.IGNORECASE)
|
| 648 |
response = re.sub(r'Montag:\s*', '', response, flags=re.IGNORECASE)
|
|
|
|
|
|
|
| 649 |
if "ETİKETLER:" in response:
|
| 650 |
response = response.split("ETİKETLER:", 1)[0].strip()
|
|
|
|
|
|
|
| 651 |
response = re.sub(r'\[\s*\.{3,}\s*\]', '', response).strip()
|
| 652 |
|
| 653 |
+
# --- Önceki Konuşma ve Tekrar Eden Kalıpları Temizleme ---
|
| 654 |
+
irrelevant_dialogue_patterns = [
|
| 655 |
+
# Modelin sürekli tekrarladığı "Nasılsın, iyi misin" ve devamı kalıbı
|
| 656 |
+
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"),
|
| 657 |
+
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ı"),
|
| 658 |
+
# Modelin ürettiği uzun ve alakasız metinler
|
| 659 |
+
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.',
|
| 660 |
+
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.'
|
| 661 |
]
|
| 662 |
+
# Regex desenlerinde özel karakterleri kaçmak için re.escape() kullandık
|
| 663 |
+
# Aksi takdirde, metin içindeki tırnaklar, parantezler gibi karakterler regex hatasına yol açabilir.
|
| 664 |
+
|
| 665 |
for pattern in irrelevant_dialogue_patterns:
|
| 666 |
response = re.sub(pattern, '', response, flags=re.IGNORECASE).strip()
|
| 667 |
|
|
|
|
| 669 |
response = re.sub(r'\s+', ' ', response).strip()
|
| 670 |
|
| 671 |
# Agresif veya hakaret içeren kelimeleri kontrol et
|
| 672 |
+
# 'aptal' kelimesini listeden çıkardık, çünkü Montag'ın karakterine uygun olabilir.
|
| 673 |
+
aggressive_words = ["salak", "gerizekalı", "saçma", "boş konuşma", "kaba", "agresif"]
|
| 674 |
|
| 675 |
+
# --- Filtreleme Mantığına Puanlama Sistemi Eklendi ---
|
|
|
|
| 676 |
rejection_score = 0
|
| 677 |
filter_reasons = []
|
| 678 |
|
|
|
|
| 680 |
if len(response.split()) < 5:
|
| 681 |
rejection_score += 2 # Hafif ceza
|
| 682 |
filter_reasons.append(f"Çok kısa ({len(response.split())} kelime).")
|
| 683 |
+
|
| 684 |
# 2. Sadece Harf İçermiyor Kontrolü (Bu genellikle iyi bir filtre)
|
| 685 |
if not any(char.isalpha() for char in response):
|
| 686 |
rejection_score += 10 # Ciddi ceza
|
| 687 |
filter_reasons.append("Hiç harf içermiyor (sadece noktalama/sayı).")
|
| 688 |
+
|
| 689 |
# 3. Genel/Anlamsız İfade Kontrolü (Listeyi yukarıda temizlemiştik)
|
| 690 |
generic_or_nonsense_phrases = [
|
| 691 |
"içir unidur", "aligutat fakdam", "tetal inlay", "pessotim elgun", # Modelin ürettiği anlamsız tokenler
|
| 692 |
"nisman tarejoglu", "faksom", "achisteloy vandleradia", "vęudis",
|
| 693 |
"eltareh", "eldlar", "fotjid", "zuhalibalyon",
|
| 694 |
"etiketler:", # Meta bilgi sızıntısı
|
| 695 |
+
# Sadece gerçekten anlamsız olanları bırakın
|
| 696 |
+
]
|
|
|
|
| 697 |
triggered_generic_phrases = [phrase for phrase in generic_or_nonsense_phrases if phrase in response.lower()]
|
| 698 |
if triggered_generic_phrases:
|
| 699 |
rejection_score += len(triggered_generic_phrases) * 3 # Her anlamsız ifade için ceza
|
| 700 |
filter_reasons.append(f"Anlamsız/istenmeyen ifade tespit edildi: {triggered_generic_phrases}.")
|
| 701 |
|
| 702 |
# 4. Montag Karakteriyle Alaka Kontrolü (Daha esnek)
|
| 703 |
+
# Montag'ın iç dünyasına ve genel temalara uygun yeni anahtar kelimeler eklendi
|
| 704 |
+
montag_keywords = ["kitap", "yakmak", "itfaiyeci", "clarisse", "faber", "beatty", "bilgi", "sansür", "düşünce", "gerçek", "televizyon", "alev", "kül", "mildred", "yangın", "fireman",
|
| 705 |
+
"düşünmek", "anlamak", "hissetmek", "arayış", "isyan", "toplum", "cehalet", "yalnızlık", "monotonluk", "gerçeklik"]
|
| 706 |
has_montag_relevance = any(keyword in response.lower() for keyword in montag_keywords)
|
| 707 |
+
|
| 708 |
+
# Eğer cevap uzunsa (örneğin 20 kelimeden fazla) ve alakasızsa ceza ver
|
| 709 |
+
if len(response.split()) > 20 and not has_montag_relevance: # Buradaki kelime sayısını artırabilirsiniz
|
| 710 |
+
rejection_score += 1 # Cezayı düşürdük
|
| 711 |
filter_reasons.append("Montag/bağlamsal anahtar kelime yok ve cevap uzun.")
|
| 712 |
+
|
| 713 |
# 5. Agresif Kelime Kontrolü
|
| 714 |
aggressive_words_found = [word for word in aggressive_words if word in response.lower()]
|
| 715 |
if aggressive_words_found:
|
| 716 |
rejection_score += 5 # Ciddi ceza
|
| 717 |
filter_reasons.append(f"Agresif/istenmeyen kelime tespit edildi: {aggressive_words_found}.")
|
| 718 |
+
|
| 719 |
+
# --- Karar verme eşiği ---
|
|
|
|
| 720 |
if rejection_score >= 5: # Bu eşik değerini test ederek ayarlamanız gerekebilir.
|
| 721 |
print(f"DEBUG: FİLTRELEME - Cevap YETERSİZ/ANLAMSIZ/ALAKASIZ. Toplam Puan: {rejection_score}")
|
| 722 |
for reason in filter_reasons:
|
| 723 |
print(f" - Sebep: {reason}")
|
| 724 |
print(f"INFO: Üretilen cevap ('{response}') filtreleri geçemedi. Alternatif üretiliyor.")
|
| 725 |
return generate_alternative_response(question), retrieved_docs # Alternatif ve dokümanları döndür
|
| 726 |
+
|
| 727 |
+
# Cümle Bölme ve Limitleme Mantığı
|
| 728 |
sentences = []
|
|
|
|
| 729 |
split_by_punctuation = re.split(r'[.!?]', response)
|
| 730 |
for s in split_by_punctuation:
|
| 731 |
s_stripped = s.strip()
|
|
|
|
| 733 |
sentences.append(s_stripped)
|
| 734 |
if len(sentences) >= 6: # Maksimum 6 cümle
|
| 735 |
break
|
|
|
|
| 736 |
final_response_text = ' '.join(sentences).strip()
|
| 737 |
+
|
| 738 |
# Eğer filtreleri geçerse ve boş değilse
|
| 739 |
+
if not final_response_text:
|
| 740 |
print("INFO: Filtrelerden geçen cevap boş kaldı. Alternatif üretiliyor.")
|
| 741 |
return generate_alternative_response(question), retrieved_docs
|
| 742 |
+
|
| 743 |
final_response = add_emojis(final_response_text)
|
| 744 |
return final_response, retrieved_docs # Cevap ve alınan dokümanları döndür
|
| 745 |
+
|
| 746 |
except Exception as e:
|
| 747 |
print(f"Error generating answer: {e}")
|
|
|
|
| 748 |
return generate_alternative_response(question), []
|
| 749 |
|
| 750 |
+
|
| 751 |
# === Gradio callback fonksiyonları ===
|
| 752 |
def respond(msg: str, chatbot_history: List[List[str]], progress=gr.Progress()) -> Tuple[str, List[List[str]], str, str]:
|
| 753 |
if not msg.strip():
|