Upload app.py
Browse files
app.py
CHANGED
@@ -341,180 +341,8 @@ def normalize_text(text):
|
|
341 |
|
342 |
return text
|
343 |
|
344 |
-
def generate_turkish_text(prompt, max_length=300):
|
345 |
-
"""Türkçe metin üretme fonksiyonu - daha kararlı ve optimize edilmiş versiyon"""
|
346 |
-
try:
|
347 |
-
print(f"Prompt: {prompt[:100]}...")
|
348 |
-
inputs = tokenizer(prompt, return_tensors="pt")
|
349 |
-
|
350 |
-
# Daha basit ve kararlı parametreler kullan
|
351 |
-
try:
|
352 |
-
output = text_model.generate(
|
353 |
-
inputs["input_ids"],
|
354 |
-
max_length=max_length,
|
355 |
-
num_return_sequences=1, # Performans için tek yanıt üret
|
356 |
-
do_sample=True,
|
357 |
-
temperature=0.7,
|
358 |
-
top_p=0.92,
|
359 |
-
top_k=50,
|
360 |
-
repetition_penalty=1.2,
|
361 |
-
no_repeat_ngram_size=2,
|
362 |
-
pad_token_id=tokenizer.eos_token_id
|
363 |
-
)
|
364 |
-
except RuntimeError as e:
|
365 |
-
print(f"Model üretme hatası: {str(e)}")
|
366 |
-
# Daha basit parametrelerle tekrar dene
|
367 |
-
output = text_model.generate(
|
368 |
-
inputs["input_ids"],
|
369 |
-
max_length=max_length,
|
370 |
-
do_sample=True,
|
371 |
-
temperature=0.7,
|
372 |
-
pad_token_id=tokenizer.eos_token_id
|
373 |
-
)
|
374 |
-
|
375 |
-
# Yanıt metni oluştur
|
376 |
-
try:
|
377 |
-
response = tokenizer.decode(output[0], skip_special_tokens=True)
|
378 |
-
|
379 |
-
# Prompt'tan sonraki kısmı al
|
380 |
-
if prompt in response:
|
381 |
-
response = response[len(prompt):].strip()
|
382 |
-
|
383 |
-
print(f"Ham yanıt: {response[:50]}...")
|
384 |
-
|
385 |
-
# Temizlik işlemleri
|
386 |
-
response = clean_response(response)
|
387 |
-
|
388 |
-
# Yanıt boşsa veya çok kısaysa
|
389 |
-
if not response or len(response) < 10:
|
390 |
-
# Yedek bir yanıt oluştur
|
391 |
-
backup_response = "Bu konuda seninle konuşmak güzel. Daha fazla detay paylaşır mısın?"
|
392 |
-
print("Yanıt çok kısa, yedek yanıt kullanılıyor")
|
393 |
-
return backup_response
|
394 |
-
|
395 |
-
return response
|
396 |
-
|
397 |
-
except Exception as e:
|
398 |
-
print(f"Yanıt işleme hatası: {str(e)}")
|
399 |
-
return "Nasıl hissettiğini anlıyorum. Bu durumda nasıl yardımcı olabilirim?"
|
400 |
-
|
401 |
-
except Exception as e:
|
402 |
-
print(f"Metin üretme genel hatası: {str(e)}")
|
403 |
-
import traceback
|
404 |
-
print(f"Hata detayı: {traceback.format_exc()}")
|
405 |
-
return "Şu an düşüncelerimi toparlıyorum. Biraz daha anlatır mısın?"
|
406 |
-
|
407 |
-
def clean_response(text):
|
408 |
-
"""Yanıtı temizle ve kalitesini artır"""
|
409 |
-
# HTML/CSS etiketlerini temizle
|
410 |
-
text = re.sub(r'\[/?vc_\w+\]', '', text)
|
411 |
-
|
412 |
-
# Diğer potansiyel bozuk formatları temizle
|
413 |
-
text = re.sub(r'<.*?>', '', text)
|
414 |
-
|
415 |
-
# Çoklu boşlukları temizle
|
416 |
-
text = re.sub(r'\s+', ' ', text).strip()
|
417 |
-
|
418 |
-
# Sistem talimatlarını temizle - genişletilmiş ve daha kapsamlı liste
|
419 |
-
patterns_to_clean = [
|
420 |
-
r'arkadaşça destek mesajı:', r'dostça destek mesajı:',
|
421 |
-
r'motive edici arkadaş mesajı:', r'coşkulu ve arkadaşça yanıt:',
|
422 |
-
r'yanıt:', r'cevap:', r'cevabında şunları yap:', r'cevabımda:',
|
423 |
-
r'[0-9]\. .*?:', r'yanıtı:', r'kişinin mesajı:', r'yapmalısın:',
|
424 |
-
r'Şunları yapmalısın:', r'Şöyle cevap ver:', r'Böyle cevap ver:',
|
425 |
-
r'Adımlar:', r'Şunları yap:', r'Bu kişiye .*? olarak:',
|
426 |
-
r'Ona bir .*? olarak:', r'Bir .*? olarak yanıt veriyorum:',
|
427 |
-
r'Sana .*? olarak yanıt veriyorum:'
|
428 |
-
]
|
429 |
-
|
430 |
-
for pattern in patterns_to_clean:
|
431 |
-
text = re.sub(pattern, '', text, flags=re.IGNORECASE)
|
432 |
-
|
433 |
-
# Maddeli liste yapıları kaldır
|
434 |
-
text = re.sub(r'^\s*[\*\-\•]\s*', '', text, flags=re.MULTILINE)
|
435 |
-
|
436 |
-
# Başlangıç klişelerini kaldır
|
437 |
-
cliche_starts = [
|
438 |
-
"Anlıyorum", "Anladım", "Seni anlıyorum", "Seni çok iyi anlıyorum",
|
439 |
-
"Üzgünüm", "Üzüldüm", "Haklısın", "Kesinlikle haklısın",
|
440 |
-
"Merhaba", "Selam", "Öncelikle", "İşte", "Tabii"
|
441 |
-
]
|
442 |
-
|
443 |
-
for start in cliche_starts:
|
444 |
-
if text.startswith(start):
|
445 |
-
text = text[len(start):].strip()
|
446 |
-
# Noktalama kaldır
|
447 |
-
if text and text[0] in [',', '.', ':', ';', '!']:
|
448 |
-
text = text[1:].strip()
|
449 |
-
|
450 |
-
# Son temizleme
|
451 |
-
text = re.sub(r'\s+', ' ', text).strip()
|
452 |
-
|
453 |
-
# İlk harfi büyük, son noktalama işareti kontrolü
|
454 |
-
if text:
|
455 |
-
# İlk harf büyük
|
456 |
-
text = text[0].upper() + text[1:]
|
457 |
-
|
458 |
-
# Son karakter noktalama işareti değilse, nokta ekle
|
459 |
-
if not text[-1] in ['.', '!', '?']:
|
460 |
-
text += '.'
|
461 |
-
|
462 |
-
return text
|
463 |
-
|
464 |
-
def score_response_quality(text):
|
465 |
-
"""Yanıt kalitesini değerlendir"""
|
466 |
-
score = 0.5 # Başlangıç skoru
|
467 |
-
|
468 |
-
# Uzunluk - çok kısa veya çok uzun olmamalı
|
469 |
-
length = len(text)
|
470 |
-
if 20 <= length <= 300:
|
471 |
-
score += 0.2
|
472 |
-
elif length < 20:
|
473 |
-
score -= 0.3
|
474 |
-
|
475 |
-
# Tekrar eden kelime veya ifadeler
|
476 |
-
words = text.lower().split()
|
477 |
-
unique_words = set(words)
|
478 |
-
word_variety = len(unique_words) / len(words) if words else 0
|
479 |
-
|
480 |
-
if word_variety > 0.7: # Yüksek çeşitlilik
|
481 |
-
score += 0.15
|
482 |
-
elif word_variety < 0.5: # Düşük çeşitlilik
|
483 |
-
score -= 0.2
|
484 |
-
|
485 |
-
# Kopya-yapıştır yapılar
|
486 |
-
if any(text.count(phrase) > 1 for phrase in [word for word in words if len(word) > 5]):
|
487 |
-
score -= 0.15
|
488 |
-
|
489 |
-
# Konu bütünlüğü - noktalama işaretleri ile cümle yapısını kontrol et
|
490 |
-
sentences = re.split(r'[.!?]', text)
|
491 |
-
if 2 <= len(sentences) <= 5:
|
492 |
-
score += 0.1
|
493 |
-
|
494 |
-
# Klişe veya genel ifadeler - samimiyeti azaltır
|
495 |
-
cliches = [
|
496 |
-
"her şey güzel olacak", "sorunlar geçici", "mutlu olmaya bak",
|
497 |
-
"hayat kısa", "kendine iyi bak", "herkesin sorunları var",
|
498 |
-
"zaman her şeyin ilacı", "yarın başka bir gün"
|
499 |
-
]
|
500 |
-
|
501 |
-
if any(cliche in text.lower() for cliche in cliches):
|
502 |
-
score -= 0.1
|
503 |
-
|
504 |
-
# Daha semantik ve spesifik ifadeler kullanma
|
505 |
-
specific_phrases = [
|
506 |
-
"hissettiğin", "yaşadığın", "deneyimin", "düşüncelerin",
|
507 |
-
"gelecek", "geçmiş", "bugün", "yarın", "adım", "strateji",
|
508 |
-
"önerim", "deneyebilirsin", "hatırla", "unutma", "farket"
|
509 |
-
]
|
510 |
-
|
511 |
-
if any(phrase in text.lower() for phrase in specific_phrases):
|
512 |
-
score += 0.2
|
513 |
-
|
514 |
-
return min(1.0, max(0.0, score)) # 0 ile 1 arasında sınırla
|
515 |
-
|
516 |
def create_better_prompts(text, label, score):
|
517 |
-
"""
|
518 |
|
519 |
# Metni normalize et
|
520 |
text = normalize_text(text)
|
@@ -523,247 +351,401 @@ def create_better_prompts(text, label, score):
|
|
523 |
emotion, _ = detect_emotion_from_text(text, label, score)
|
524 |
personality = get_personality_profile(text, emotion)
|
525 |
|
526 |
-
#
|
527 |
-
|
528 |
-
|
529 |
-
|
530 |
-
|
531 |
-
|
532 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
533 |
"""
|
534 |
|
535 |
# Soru veya komut kontrol et
|
536 |
if is_question_or_command(text):
|
537 |
return f"""{personality['prompt_prefix']}
|
538 |
{common_guide}
|
539 |
-
Bu kişi sana bir soru sormuş veya bir istekte bulunmuş.
|
540 |
-
|
541 |
-
Kişinin mesajı: '{text}'
|
542 |
|
543 |
Yanıt:"""
|
544 |
|
545 |
-
# Duygu durumuna göre prompt oluştur - daha
|
546 |
if label == "NEGATIVE":
|
547 |
if score > 0.85: # Çok olumsuz
|
548 |
prompt = f"""{personality['prompt_prefix']}
|
549 |
{common_guide}
|
550 |
-
|
|
|
|
|
551 |
|
552 |
-
|
553 |
-
|
554 |
|
555 |
Yanıt:"""
|
556 |
else: # Orta derecede olumsuz
|
557 |
prompt = f"""{personality['prompt_prefix']}
|
558 |
{common_guide}
|
559 |
-
|
|
|
560 |
|
561 |
-
|
562 |
-
|
563 |
|
564 |
Yanıt:"""
|
565 |
-
elif label == "POSITIVE"
|
566 |
prompt = f"""{personality['prompt_prefix']}
|
567 |
{common_guide}
|
568 |
-
|
|
|
569 |
|
570 |
-
|
571 |
-
|
572 |
|
573 |
Yanıt:"""
|
574 |
-
else: #
|
575 |
prompt = f"""{personality['prompt_prefix']}
|
576 |
{common_guide}
|
577 |
-
|
|
|
578 |
|
579 |
-
|
580 |
-
|
581 |
|
582 |
Yanıt:"""
|
583 |
|
584 |
return prompt
|
585 |
|
586 |
def process_input(text, personality_choice=None):
|
587 |
-
"""Kullanıcı girdisini işle -
|
|
|
|
|
588 |
start_time = time.time()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
589 |
|
590 |
try:
|
591 |
-
#
|
592 |
-
if not text
|
593 |
-
|
|
|
594 |
|
595 |
-
#
|
596 |
-
|
|
|
|
|
597 |
|
598 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
599 |
|
600 |
# Uygunsuz içerik kontrolü
|
601 |
-
|
602 |
-
|
603 |
-
|
|
|
|
|
|
|
|
|
|
|
604 |
|
605 |
-
#
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
606 |
try:
|
|
|
|
|
607 |
sentiment_result = sentiment_model(text)[0]
|
|
|
|
|
608 |
label = sentiment_result['label']
|
609 |
score = sentiment_result['score']
|
610 |
-
|
|
|
611 |
except Exception as e:
|
612 |
-
|
613 |
-
#
|
614 |
-
label = "NEUTRAL"
|
615 |
score = 0.5
|
616 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
617 |
|
618 |
-
#
|
619 |
try:
|
|
|
620 |
emotion, emoji_count = detect_emotion_from_text(text, label, score)
|
|
|
621 |
|
|
|
622 |
if personality_choice:
|
623 |
-
# Doğrudan kimlik
|
624 |
if personality_choice in PERSONALITY_PROFILES:
|
625 |
personality = PERSONALITY_PROFILES[personality_choice]
|
|
|
626 |
else:
|
627 |
-
# İsim ile
|
628 |
found = False
|
629 |
for pid, p in PERSONALITY_PROFILES.items():
|
630 |
-
if p["name"] == personality_choice:
|
631 |
personality = p
|
632 |
personality_choice = pid
|
633 |
found = True
|
|
|
634 |
break
|
|
|
635 |
if not found:
|
636 |
-
#
|
637 |
-
|
638 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
639 |
else:
|
|
|
640 |
personality = get_personality_profile(text, emotion)
|
|
|
641 |
|
642 |
-
#
|
643 |
VOICE = personality.get("voice", "tr-TR-EmelNeural")
|
644 |
-
|
645 |
|
646 |
except Exception as e:
|
647 |
-
|
648 |
-
|
|
|
|
|
|
|
649 |
personality = PERSONALITY_PROFILES[DEFAULT_PERSONALITY]
|
650 |
emotion = "destek"
|
651 |
emoji_count = 0
|
652 |
VOICE = "tr-TR-EmelNeural"
|
653 |
-
|
654 |
|
655 |
-
#
|
656 |
try:
|
|
|
657 |
prompt = create_better_prompts(text, label, score)
|
658 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
659 |
except Exception as e:
|
660 |
-
|
661 |
-
# Basit prompt
|
662 |
prompt = f"Bu kişinin mesajına sıcak ve destekleyici bir şekilde yanıt ver: '{text}'"
|
663 |
-
|
664 |
|
665 |
-
#
|
666 |
try:
|
667 |
-
|
|
|
|
|
|
|
|
|
|
|
668 |
response = generate_turkish_text(prompt, max_length=350)
|
669 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
670 |
except Exception as e:
|
671 |
-
|
672 |
-
|
673 |
-
|
674 |
-
print("Yedek yanıt kullanılıyor")
|
675 |
-
|
676 |
-
# Eğer yanıt üretilemediyse veya çok kısaysa
|
677 |
-
if not response or len(response) < 10:
|
678 |
-
print("Yanıt çok kısa, tekrar deneniyor...")
|
679 |
-
# Daha basit bir prompt ile tekrar dene
|
680 |
-
try:
|
681 |
-
simple_prompt = f"Şu konuda yardımcı ve dost cevap ver: '{text}'"
|
682 |
-
response = generate_turkish_text(simple_prompt, max_length=200)
|
683 |
-
except Exception as e:
|
684 |
-
print(f"İkinci deneme hatası: {str(e)}")
|
685 |
-
response = "Merhaba! Mesajını aldım. Nasıl yardımcı olabilirim?"
|
686 |
|
687 |
-
|
688 |
-
|
|
|
689 |
|
690 |
-
#
|
691 |
try:
|
692 |
response = clean_response(response)
|
693 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
694 |
except Exception as e:
|
695 |
-
|
696 |
-
# Basit
|
697 |
response = re.sub(r'\s+', ' ', response).strip()
|
698 |
if response:
|
699 |
response = response[0].upper() + response[1:]
|
700 |
if not response[-1] in ['.', '!', '?']:
|
701 |
response += '.'
|
|
|
702 |
|
703 |
-
#
|
704 |
try:
|
705 |
-
|
706 |
-
|
707 |
-
if quality_score < 0.4:
|
708 |
-
fallback_responses = [
|
709 |
-
f"Mesajını aldım. Bu konuda düşüncelerini paylaşmak ister misin?",
|
710 |
-
f"Bu konuda nasıl hissettiğini anlıyorum. Daha fazla konuşmak ister misin?",
|
711 |
-
f"Paylaştığın için teşekkür ederim. Seni dinlemek güzel.",
|
712 |
-
f"Düşüncelerini paylaştığın için teşekkürler. Nasıl hissettiğini anlamak istiyorum."
|
713 |
-
]
|
714 |
-
response = random.choice(fallback_responses)
|
715 |
-
print("Yedek yanıt kullanıldı")
|
716 |
-
except Exception as e:
|
717 |
-
print(f"Kalite skoru hatası: {str(e)}")
|
718 |
-
# Kalite skoru kontrolü atlama
|
719 |
-
|
720 |
-
# Uzman önerileri ekle - belirli şartlara göre ve kalite kontrolü ile
|
721 |
-
try:
|
722 |
-
if label == "NEGATIVE" and score > 0.7 and random.random() < 0.6: # %60 ihtimalle olumsuz durumlarda öneri ekle
|
723 |
recommendations = get_appropriate_expert_recommendations(text, emotion, score)
|
|
|
724 |
if recommendations:
|
|
|
725 |
formatted_recs = format_recommendations(recommendations)
|
726 |
-
|
|
|
|
|
727 |
response += formatted_recs
|
728 |
-
|
|
|
|
|
729 |
except Exception as e:
|
730 |
-
|
731 |
# Önerileri ekleme
|
732 |
|
733 |
-
# Emoji
|
734 |
try:
|
735 |
-
|
736 |
-
|
737 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
738 |
except Exception as e:
|
739 |
-
|
740 |
# Emoji eklememe
|
741 |
|
742 |
-
#
|
743 |
try:
|
744 |
-
|
|
|
|
|
|
|
745 |
audio_path = create_speech(response)
|
746 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
747 |
except Exception as e:
|
748 |
-
|
749 |
audio_path = None
|
750 |
-
# Ses dosyası oluşturulamadı
|
751 |
|
|
|
752 |
process_time = time.time() - start_time
|
753 |
-
|
754 |
|
755 |
-
#
|
756 |
if not response or len(response.strip()) < 5:
|
|
|
757 |
response = "Merhaba! Seninle sohbet etmek güzel. Nasıl yardımcı olabilirim?"
|
758 |
|
759 |
return response, audio_path
|
760 |
|
761 |
except Exception as e:
|
762 |
-
|
763 |
-
|
|
|
|
|
764 |
import traceback
|
765 |
-
|
766 |
-
|
|
|
|
|
767 |
|
768 |
# Demo başlığı ve açıklaması
|
769 |
title = "MoodF - Duygusal Destek Asistanı"
|
@@ -994,4 +976,193 @@ def get_personality_profile(text=None, emotion=None):
|
|
994 |
return random.choice([PERSONALITY_PROFILES["bilge_danisman"], PERSONALITY_PROFILES["motive_edici_koc"]])
|
995 |
|
996 |
# Varsayılan olarak anlayışlı dost modelini kullan
|
997 |
-
return PERSONALITY_PROFILES[DEFAULT_PERSONALITY]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
341 |
|
342 |
return text
|
343 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
344 |
def create_better_prompts(text, label, score):
|
345 |
+
"""Kullanıcı girdisiyle daha alakalı yanıtlar üretmek için prompt yapısını iyileştir"""
|
346 |
|
347 |
# Metni normalize et
|
348 |
text = normalize_text(text)
|
|
|
351 |
emotion, _ = detect_emotion_from_text(text, label, score)
|
352 |
personality = get_personality_profile(text, emotion)
|
353 |
|
354 |
+
# Ana konuyu çıkart
|
355 |
+
keywords = re.sub(r'[^\w\s]', '', text.lower()).split()
|
356 |
+
keywords = [w for w in keywords if len(w) > 3 and w not in ["nasıl", "neden", "ama", "fakat", "çünkü", "gibi", "kadar", "için"]]
|
357 |
+
|
358 |
+
# Ortak kılavuz ilkeler - alakalı ve tutarlı yanıtlar için
|
359 |
+
common_guide = f"""Önemli: Bu kişinin mesajına DOĞRUDAN ilgili bir yanıt ver. Konu dışına çıkma.
|
360 |
+
Kullanıcının asıl sorunu: '{text}'
|
361 |
+
Mesajın ana konusu: {' '.join(keywords[:5]) if keywords else text}
|
362 |
+
Mesajın duygu tonu: {emotion}
|
363 |
+
|
364 |
+
Şu kurallara mutlaka uy:
|
365 |
+
1. Kullanıcının mesajına doğrudan cevap ver, alakasız konulara girme
|
366 |
+
2. Gerçek ve ilgili içerik üret, hayal ürünü veya alakasız hiçbir şey ekleme
|
367 |
+
3. Sadece kullanıcının belirttiği durum/problem üzerine konuş
|
368 |
+
4. Başka kullanıcılar veya senaryolardan bahsetme, sadece şu anki kullanıcının durumuna odaklan
|
369 |
"""
|
370 |
|
371 |
# Soru veya komut kontrol et
|
372 |
if is_question_or_command(text):
|
373 |
return f"""{personality['prompt_prefix']}
|
374 |
{common_guide}
|
375 |
+
Bu kişi sana bir soru sormuş veya bir istekte bulunmuş.
|
376 |
+
Kullanıcının sorusuna veya isteğine doğrudan cevap ver: '{text}'
|
|
|
377 |
|
378 |
Yanıt:"""
|
379 |
|
380 |
+
# Duygu durumuna göre prompt oluştur - daha alakalı ve daha az şablon yaklaşım
|
381 |
if label == "NEGATIVE":
|
382 |
if score > 0.85: # Çok olumsuz
|
383 |
prompt = f"""{personality['prompt_prefix']}
|
384 |
{common_guide}
|
385 |
+
Kişinin ifade ettiği problem: '{text}'
|
386 |
+
Bu probleme yönelik, kişiselleştirilmiş ve spesifik bir yanıt ver.
|
387 |
+
Standart tavsiyeler veya genel teselli cümleleri kullanmaktan kaçın.
|
388 |
|
389 |
+
Şu formatta cevap verme: "Anlıyorum, bu zor bir durum..." veya "Üzüldüm, senin için..."
|
390 |
+
Bunun yerine, doğrudan duruma yönelik içgörü ve destek sağla.
|
391 |
|
392 |
Yanıt:"""
|
393 |
else: # Orta derecede olumsuz
|
394 |
prompt = f"""{personality['prompt_prefix']}
|
395 |
{common_guide}
|
396 |
+
Kişinin ifade ettiği durum: '{text}'
|
397 |
+
Bu duruma özel ve alakalı bir yanıt ver.
|
398 |
|
399 |
+
Genel ifadelerden ve klişelerden kaçın. Bunun yerine, kişinin spesifik durumunu ele al.
|
400 |
+
Kullanıcının tam olarak neye endişelendiği veya üzüldüğü konusuna odaklan.
|
401 |
|
402 |
Yanıt:"""
|
403 |
+
elif label == "POSITIVE":
|
404 |
prompt = f"""{personality['prompt_prefix']}
|
405 |
{common_guide}
|
406 |
+
Kişinin ifade ettiği olumlu durum: '{text}'
|
407 |
+
Bu olumlu duruma özel ve alakalı bir yanıt ver.
|
408 |
|
409 |
+
Genel tebrik ifadeleri yerine, kişinin spesifik başarısına veya mutlu olduğu konuya odaklan.
|
410 |
+
Kullanıcının tam olarak neden mutlu olduğunu veya neyi başardığını ele al.
|
411 |
|
412 |
Yanıt:"""
|
413 |
+
else: # Nötr
|
414 |
prompt = f"""{personality['prompt_prefix']}
|
415 |
{common_guide}
|
416 |
+
Kişinin ifade ettiği durum: '{text}'
|
417 |
+
Bu duruma özel ve alakalı bir yanıt ver.
|
418 |
|
419 |
+
Kullanıcının ifade ettiği durumu veya konuyu dikkatle ele al. Konudan sapmadan yanıt ver.
|
420 |
+
Kişinin ne söylediğini dikkate alarak cevabını oluştur.
|
421 |
|
422 |
Yanıt:"""
|
423 |
|
424 |
return prompt
|
425 |
|
426 |
def process_input(text, personality_choice=None):
|
427 |
+
"""Kullanıcı girdisini işle - Tamamen iyileştirilmiş, hataya dayanıklı ve performans odaklı versiyon"""
|
428 |
+
|
429 |
+
# İşlem izleme için zaman ölçümü ve benzersiz istek ID'si
|
430 |
start_time = time.time()
|
431 |
+
request_id = f"req_{int(time.time())}_{random.randint(1000, 9999)}"
|
432 |
+
|
433 |
+
# Log sistemi
|
434 |
+
def log(message, level="INFO"):
|
435 |
+
timestamp = time.strftime("%Y-%m-%d %H:%M:%S")
|
436 |
+
print(f"[{timestamp}] [{level}] [ID:{request_id}] {message}")
|
437 |
+
|
438 |
+
log(f"Yeni istek başladı: '{text[:50]}...' (Personality: {personality_choice})")
|
439 |
|
440 |
try:
|
441 |
+
# Giriş doğrulama ve ön işleme
|
442 |
+
if not text:
|
443 |
+
log("Boş giriş alındı", "WARNING")
|
444 |
+
return "Lütfen düşüncelerinizi veya duygularınızı paylaşın.", None
|
445 |
|
446 |
+
# Çok uzun girişleri sınırla
|
447 |
+
if len(text) > 1000:
|
448 |
+
text = text[:1000]
|
449 |
+
log("Çok uzun giriş kısaltıldı", "WARNING")
|
450 |
|
451 |
+
# Metni normalize et - hataya dayanıklı
|
452 |
+
try:
|
453 |
+
text = normalize_text(text)
|
454 |
+
except Exception as e:
|
455 |
+
log(f"Metin normalizasyon hatası: {str(e)}", "ERROR")
|
456 |
+
# Basit alternatif temizleme
|
457 |
+
text = re.sub(r'\s+', ' ', text).strip()
|
458 |
+
|
459 |
+
log(f"İstek normalizasyon sonrası: {text[:50]}...")
|
460 |
|
461 |
# Uygunsuz içerik kontrolü
|
462 |
+
try:
|
463 |
+
is_bad, error_msg = is_inappropriate(text)
|
464 |
+
if is_bad:
|
465 |
+
log(f"Uygunsuz içerik tespit edildi: {error_msg}", "WARNING")
|
466 |
+
return error_msg, None
|
467 |
+
except Exception as e:
|
468 |
+
log(f"İçerik kontrolü hatası: {str(e)}", "ERROR")
|
469 |
+
# Hata durumunda kontrole devam et, ancak içeriği kabul et
|
470 |
|
471 |
+
# Bellek yönetimi - uzun süreli oturumlar için
|
472 |
+
if hasattr(torch, "cuda") and torch.cuda.is_available():
|
473 |
+
try:
|
474 |
+
# GPU belleğini temizle
|
475 |
+
torch.cuda.empty_cache()
|
476 |
+
log("GPU belleği temizlendi", "DEBUG")
|
477 |
+
except Exception as e:
|
478 |
+
log(f"GPU bellek temizleme hatası: {str(e)}", "WARNING")
|
479 |
+
|
480 |
+
# Duygu analizi yap - performans optimize edilmiş
|
481 |
try:
|
482 |
+
# Hafif model kullanım kontrolü
|
483 |
+
start_sentiment = time.time()
|
484 |
sentiment_result = sentiment_model(text)[0]
|
485 |
+
sentiment_time = time.time() - start_sentiment
|
486 |
+
|
487 |
label = sentiment_result['label']
|
488 |
score = sentiment_result['score']
|
489 |
+
log(f"Duygu analizi sonucu: {label} ({score:.2f}) - {sentiment_time:.2f}sn", "INFO")
|
490 |
+
|
491 |
except Exception as e:
|
492 |
+
log(f"Duygu analizi hatası: {str(e)}", "ERROR")
|
493 |
+
# Basit yedek analiz
|
494 |
+
label = "NEUTRAL"
|
495 |
score = 0.5
|
496 |
+
|
497 |
+
# Basit duygu analizi
|
498 |
+
negative_words = ["üzgün", "kötü", "mutsuz", "endişe", "korku", "sinir", "kaygı"]
|
499 |
+
positive_words = ["mutlu", "iyi", "güzel", "harika", "sevgi", "başarı", "memnun"]
|
500 |
+
|
501 |
+
text_lower = text.lower()
|
502 |
+
neg_count = sum(1 for word in negative_words if word in text_lower)
|
503 |
+
pos_count = sum(1 for word in positive_words if word in text_lower)
|
504 |
+
|
505 |
+
if neg_count > pos_count:
|
506 |
+
label = "NEGATIVE"
|
507 |
+
score = 0.7 + (0.2 * min(1, neg_count/3))
|
508 |
+
elif pos_count > neg_count:
|
509 |
+
label = "POSITIVE"
|
510 |
+
score = 0.7 + (0.2 * min(1, pos_count/3))
|
511 |
+
|
512 |
+
log("Yedek duygu analizi kullanıldı", "WARNING")
|
513 |
|
514 |
+
# Kişilik ve profil belirleme - hata toleranslı
|
515 |
try:
|
516 |
+
# Duygu durumu tespiti
|
517 |
emotion, emoji_count = detect_emotion_from_text(text, label, score)
|
518 |
+
log(f"Duygu durumu: {emotion}, emoji sayısı: {emoji_count}", "INFO")
|
519 |
|
520 |
+
# Kişilik seçimi
|
521 |
if personality_choice:
|
522 |
+
# Doğrudan kimlik kontrolü
|
523 |
if personality_choice in PERSONALITY_PROFILES:
|
524 |
personality = PERSONALITY_PROFILES[personality_choice]
|
525 |
+
log(f"Seçili kişilik kullanıldı: {personality_choice}", "INFO")
|
526 |
else:
|
527 |
+
# İsim ile arama
|
528 |
found = False
|
529 |
for pid, p in PERSONALITY_PROFILES.items():
|
530 |
+
if p["name"].lower() == personality_choice.lower():
|
531 |
personality = p
|
532 |
personality_choice = pid
|
533 |
found = True
|
534 |
+
log(f"İsimle eşleşen kişilik bulundu: {pid}", "INFO")
|
535 |
break
|
536 |
+
|
537 |
if not found:
|
538 |
+
# Bulunamazsa benzerlik kontrolü
|
539 |
+
best_match = None
|
540 |
+
best_score = 0
|
541 |
+
for pid, p in PERSONALITY_PROFILES.items():
|
542 |
+
# Basit benzerlik skoru
|
543 |
+
name = p["name"].lower()
|
544 |
+
choice = personality_choice.lower()
|
545 |
+
words1 = set(name.split())
|
546 |
+
words2 = set(choice.split())
|
547 |
+
common_words = words1.intersection(words2)
|
548 |
+
|
549 |
+
if common_words:
|
550 |
+
score = len(common_words) / max(len(words1), len(words2))
|
551 |
+
if score > best_score and score > 0.3:
|
552 |
+
best_score = score
|
553 |
+
best_match = pid
|
554 |
+
|
555 |
+
if best_match:
|
556 |
+
personality = PERSONALITY_PROFILES[best_match]
|
557 |
+
log(f"Benzer kişilik bulundu: {best_match} (benzerlik: {best_score:.2f})", "INFO")
|
558 |
+
else:
|
559 |
+
# Varsayılan kişilik
|
560 |
+
personality = PERSONALITY_PROFILES[DEFAULT_PERSONALITY]
|
561 |
+
log(f"Kişilik bulunamad��, varsayılan kullanılıyor", "WARNING")
|
562 |
else:
|
563 |
+
# Otomatik kişilik seçimi
|
564 |
personality = get_personality_profile(text, emotion)
|
565 |
+
log(f"Otomatik kişilik seçildi: {personality['name']}", "INFO")
|
566 |
|
567 |
+
# Kişiliğe uygun ses
|
568 |
VOICE = personality.get("voice", "tr-TR-EmelNeural")
|
569 |
+
log(f"Ses seçildi: {VOICE}", "DEBUG")
|
570 |
|
571 |
except Exception as e:
|
572 |
+
log(f"Kişilik belirleme hatası: {str(e)}", "ERROR")
|
573 |
+
import traceback
|
574 |
+
log(traceback.format_exc(), "DEBUG")
|
575 |
+
|
576 |
+
# Varsayılan kişilik ve duygu durumu
|
577 |
personality = PERSONALITY_PROFILES[DEFAULT_PERSONALITY]
|
578 |
emotion = "destek"
|
579 |
emoji_count = 0
|
580 |
VOICE = "tr-TR-EmelNeural"
|
581 |
+
log("Varsayılan kişilik ve duygu durumu kullanılıyor", "WARNING")
|
582 |
|
583 |
+
# Prompt oluşturma - daha güvenli ve etkin
|
584 |
try:
|
585 |
+
log("Prompt oluşturuluyor...", "DEBUG")
|
586 |
prompt = create_better_prompts(text, label, score)
|
587 |
+
|
588 |
+
# Prompt'un çok uzun olup olmadığını kontrol et
|
589 |
+
if len(prompt) > 1000:
|
590 |
+
log("Prompt çok uzun, kısaltılıyor", "WARNING")
|
591 |
+
prompt = prompt[:1000]
|
592 |
+
|
593 |
+
log(f"Prompt hazır: {prompt[:100]}...", "INFO")
|
594 |
+
|
595 |
except Exception as e:
|
596 |
+
log(f"Prompt oluşturma hatası: {str(e)}", "ERROR")
|
597 |
+
# Basit yedek prompt
|
598 |
prompt = f"Bu kişinin mesajına sıcak ve destekleyici bir şekilde yanıt ver: '{text}'"
|
599 |
+
log("Basit yedek prompt kullanılıyor", "WARNING")
|
600 |
|
601 |
+
# Metin üretimi - optimize edilmiş ve hata korumalı
|
602 |
try:
|
603 |
+
log("Metin üretiliyor...", "INFO")
|
604 |
+
|
605 |
+
# Metin üretimi için zaman ölçümü
|
606 |
+
start_generation = time.time()
|
607 |
+
|
608 |
+
# Maximum 3 defa üretim denemesi yap
|
609 |
response = generate_turkish_text(prompt, max_length=350)
|
610 |
+
|
611 |
+
generation_time = time.time() - start_generation
|
612 |
+
log(f"Metin üretildi ({generation_time:.2f}sn): {response[:50]}...", "INFO")
|
613 |
+
|
614 |
+
# Hızlı doğrulama kontrolü
|
615 |
+
if not response or len(response.strip()) < 10:
|
616 |
+
log("Üretilen yanıt çok kısa - yedek yanıt", "WARNING")
|
617 |
+
# Duygu durumuna göre yedek yanıt
|
618 |
+
if emotion == "üzüntü":
|
619 |
+
response = "Bu durumun senin için ne kadar zor olduğunu anlıyorum. Biraz daha anlatmak ister misin?"
|
620 |
+
elif emotion == "mutluluk":
|
621 |
+
response = "Bu harika bir durum! Kendini nasıl hissettiğini biraz daha anlatır mısın?"
|
622 |
+
elif emotion == "endişe":
|
623 |
+
response = "Endişelerini anlıyorum. Bu durum hakkında ne düşünüyorsun?"
|
624 |
+
else:
|
625 |
+
response = "Anlattıkların için teşekkür ederim. Bu konuda daha fazla konuşmak ister misin?"
|
626 |
+
|
627 |
except Exception as e:
|
628 |
+
log(f"Metin üretme hatası: {str(e)}", "ERROR")
|
629 |
+
import traceback
|
630 |
+
log(traceback.format_exc(), "DEBUG")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
631 |
|
632 |
+
# Genel yedek yanıt
|
633 |
+
response = "Seninle bu konu hakkında konuşmak isterim. Biraz daha anlatır mısın?"
|
634 |
+
log("Genel yedek yanıt kullanıldı", "WARNING")
|
635 |
|
636 |
+
# Yanıt temizliği ve kalite kontrolü
|
637 |
try:
|
638 |
response = clean_response(response)
|
639 |
+
log(f"Temizlenmiş yanıt: {response[:50]}...", "DEBUG")
|
640 |
+
|
641 |
+
# Kalite değerlendirmesi
|
642 |
+
try:
|
643 |
+
quality_score = score_response_quality(response)
|
644 |
+
log(f"Yanıt kalite skoru: {quality_score:.2f}", "INFO")
|
645 |
+
|
646 |
+
if quality_score < 0.4:
|
647 |
+
log("Düşük kaliteli yanıt tespit edildi", "WARNING")
|
648 |
+
# Daha iyi alternatif yanıtlar
|
649 |
+
alternatives = [
|
650 |
+
f"Anlattıkların benim için önemli. Bu konuda neler hissediyorsun?",
|
651 |
+
f"Bu durumda kendini nasıl hissettiğini merak ediyorum. Biraz daha açıklar mısın?",
|
652 |
+
f"Söylediklerini dinliyorum. Bu konuda başka neler eklemek istersin?",
|
653 |
+
f"Bu konudaki düşüncelerin benim için değerli. Devam etmek ister misin?"
|
654 |
+
]
|
655 |
+
response = random.choice(alternatives)
|
656 |
+
log("Alternatif yüksek kalite yanıt kullanıldı", "INFO")
|
657 |
+
except Exception as e:
|
658 |
+
log(f"Kalite değerlendirme hatası: {str(e)}", "ERROR")
|
659 |
+
# Kalite kontrolü atlama
|
660 |
+
|
661 |
except Exception as e:
|
662 |
+
log(f"Yanıt temizleme hatası: {str(e)}", "ERROR")
|
663 |
+
# Basit bir temizleme işlemi
|
664 |
response = re.sub(r'\s+', ' ', response).strip()
|
665 |
if response:
|
666 |
response = response[0].upper() + response[1:]
|
667 |
if not response[-1] in ['.', '!', '?']:
|
668 |
response += '.'
|
669 |
+
log("Basit yanıt temizliği uygulandı", "WARNING")
|
670 |
|
671 |
+
# Uzman önerileri - doğru durumlarda ve kaliteli içerik
|
672 |
try:
|
673 |
+
if label == "NEGATIVE" and score > 0.7 and random.random() < 0.5:
|
674 |
+
log("Uzman önerileri değerlendiriliyor", "DEBUG")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
675 |
recommendations = get_appropriate_expert_recommendations(text, emotion, score)
|
676 |
+
|
677 |
if recommendations:
|
678 |
+
log(f"{len(recommendations)} öneri bulundu", "INFO")
|
679 |
formatted_recs = format_recommendations(recommendations)
|
680 |
+
|
681 |
+
# Yanıtı çok uzatmadan ekle
|
682 |
+
if len(response) + len(formatted_recs) <= 800:
|
683 |
response += formatted_recs
|
684 |
+
log("Uzman önerileri eklendi", "INFO")
|
685 |
+
else:
|
686 |
+
log("Öneriler çok uzun, eklenmedi", "WARNING")
|
687 |
except Exception as e:
|
688 |
+
log(f"Uzman önerileri hatası: {str(e)}", "ERROR")
|
689 |
# Önerileri ekleme
|
690 |
|
691 |
+
# Emoji ekleme - doğal ve uygun sayıda
|
692 |
try:
|
693 |
+
# Kişilik emoji kullanım eğilimi
|
694 |
+
emoji_prob = 0.4 # Varsayılan olasılık
|
695 |
+
if personality_choice == "pozitif_arkadas":
|
696 |
+
emoji_prob = 0.7 # Pozitif arkadaş daha fazla emoji kullanır
|
697 |
+
elif personality_choice == "bilge_danisman":
|
698 |
+
emoji_prob = 0.2 # Bilge danışman daha az emoji kullanır
|
699 |
+
|
700 |
+
if random.random() < emoji_prob:
|
701 |
+
response = add_emojis(response, emotion, min(2, emoji_count)) # Maksimum 2 emoji
|
702 |
+
log("Emoji eklendi", "DEBUG")
|
703 |
except Exception as e:
|
704 |
+
log(f"Emoji ekleme hatası: {str(e)}", "ERROR")
|
705 |
# Emoji eklememe
|
706 |
|
707 |
+
# Sesli yanıt oluşturma - optimize edilmiş
|
708 |
try:
|
709 |
+
log("Sesli yanıt üretiliyor...", "INFO")
|
710 |
+
start_speech = time.time()
|
711 |
+
|
712 |
+
# Her durumda ses üretmeyi dene
|
713 |
audio_path = create_speech(response)
|
714 |
+
|
715 |
+
speech_time = time.time() - start_speech
|
716 |
+
log(f"Sesli yanıt oluşturuldu ({speech_time:.2f}sn): {audio_path}", "INFO")
|
717 |
+
|
718 |
+
# Ses dosyası kontrolü
|
719 |
+
if audio_path and os.path.exists(audio_path) and os.path.getsize(audio_path) > 100:
|
720 |
+
log("Ses dosyası doğrulandı", "DEBUG")
|
721 |
+
else:
|
722 |
+
log("Ses dosyası oluşturulamadı veya geçersiz", "WARNING")
|
723 |
+
audio_path = None
|
724 |
except Exception as e:
|
725 |
+
log(f"Ses üretme hatası: {str(e)}", "ERROR")
|
726 |
audio_path = None
|
|
|
727 |
|
728 |
+
# İşlem özeti
|
729 |
process_time = time.time() - start_time
|
730 |
+
log(f"İşlem tamamlandı ({process_time:.2f} saniye)", "INFO")
|
731 |
|
732 |
+
# Final kalite kontrolü - kritik son adım
|
733 |
if not response or len(response.strip()) < 5:
|
734 |
+
log("Kritik: Final yanıt boş veya çok kısa", "ERROR")
|
735 |
response = "Merhaba! Seninle sohbet etmek güzel. Nasıl yardımcı olabilirim?"
|
736 |
|
737 |
return response, audio_path
|
738 |
|
739 |
except Exception as e:
|
740 |
+
# En üst seviye hata yakalama - kritik
|
741 |
+
error_msg = f"Kritik işlem hatası: {str(e)}"
|
742 |
+
log(error_msg, "CRITICAL")
|
743 |
+
|
744 |
import traceback
|
745 |
+
log(f"Hata detayı: {traceback.format_exc()}", "DEBUG")
|
746 |
+
|
747 |
+
# Her durumda tutarlı bir yanıt dönün
|
748 |
+
return "Seninle konuşmak istiyorum. Lütfen düşüncelerini benimle paylaşmaya devam et.", None
|
749 |
|
750 |
# Demo başlığı ve açıklaması
|
751 |
title = "MoodF - Duygusal Destek Asistanı"
|
|
|
976 |
return random.choice([PERSONALITY_PROFILES["bilge_danisman"], PERSONALITY_PROFILES["motive_edici_koc"]])
|
977 |
|
978 |
# Varsayılan olarak anlayışlı dost modelini kullan
|
979 |
+
return PERSONALITY_PROFILES[DEFAULT_PERSONALITY]
|
980 |
+
|
981 |
+
def clean_response(text):
|
982 |
+
"""Yanıtı temizle ve kalitesini artır"""
|
983 |
+
# HTML/CSS etiketlerini temizle
|
984 |
+
text = re.sub(r'\[/?vc_\w+\]', '', text)
|
985 |
+
|
986 |
+
# Diğer potansiyel bozuk formatları temizle
|
987 |
+
text = re.sub(r'<.*?>', '', text)
|
988 |
+
|
989 |
+
# Çoklu boşlukları temizle
|
990 |
+
text = re.sub(r'\s+', ' ', text).strip()
|
991 |
+
|
992 |
+
# Sistem talimatlarını temizle - genişletilmiş ve daha kapsamlı liste
|
993 |
+
patterns_to_clean = [
|
994 |
+
r'arkadaşça destek mesajı:', r'dostça destek mesajı:',
|
995 |
+
r'motive edici arkadaş mesajı:', r'coşkulu ve arkadaşça yanıt:',
|
996 |
+
r'yanıt:', r'cevap:', r'cevabında şunları yap:', r'cevabımda:',
|
997 |
+
r'[0-9]\. .*?:', r'yanıtı:', r'kişinin mesajı:', r'yapmalısın:',
|
998 |
+
r'Şunları yapmalısın:', r'Şöyle cevap ver:', r'Böyle cevap ver:',
|
999 |
+
r'Adımlar:', r'Şunları yap:', r'Bu kişiye .*? olarak:',
|
1000 |
+
r'Ona bir .*? olarak:', r'Bir .*? olarak yanıt veriyorum:',
|
1001 |
+
r'Sana .*? olarak yanıt veriyorum:'
|
1002 |
+
]
|
1003 |
+
|
1004 |
+
for pattern in patterns_to_clean:
|
1005 |
+
text = re.sub(pattern, '', text, flags=re.IGNORECASE)
|
1006 |
+
|
1007 |
+
# Maddeli liste yapıları kaldır
|
1008 |
+
text = re.sub(r'^\s*[\*\-\•]\s*', '', text, flags=re.MULTILINE)
|
1009 |
+
|
1010 |
+
# Başlangıç klişelerini kaldır
|
1011 |
+
cliche_starts = [
|
1012 |
+
"Anlıyorum", "Anladım", "Seni anlıyorum", "Seni çok iyi anlıyorum",
|
1013 |
+
"Üzgünüm", "Üzüldüm", "Haklısın", "Kesinlikle haklısın",
|
1014 |
+
"Merhaba", "Selam", "Öncelikle", "İşte", "Tabii"
|
1015 |
+
]
|
1016 |
+
|
1017 |
+
for start in cliche_starts:
|
1018 |
+
if text.startswith(start):
|
1019 |
+
text = text[len(start):].strip()
|
1020 |
+
# Noktalama kaldır
|
1021 |
+
if text and text[0] in [',', '.', ':', ';', '!']:
|
1022 |
+
text = text[1:].strip()
|
1023 |
+
|
1024 |
+
# Son temizleme
|
1025 |
+
text = re.sub(r'\s+', ' ', text).strip()
|
1026 |
+
|
1027 |
+
# İlk harfi büyük, son noktalama işareti kontrolü
|
1028 |
+
if text:
|
1029 |
+
# İlk harf büyük
|
1030 |
+
text = text[0].upper() + text[1:]
|
1031 |
+
|
1032 |
+
# Son karakter noktalama işareti değilse, nokta ekle
|
1033 |
+
if not text[-1] in ['.', '!', '?']:
|
1034 |
+
text += '.'
|
1035 |
+
|
1036 |
+
return text
|
1037 |
+
|
1038 |
+
def score_response_quality(text):
|
1039 |
+
"""Yanıt kalitesini değerlendir"""
|
1040 |
+
score = 0.5 # Başlangıç skoru
|
1041 |
+
|
1042 |
+
# Uzunluk - çok kısa veya çok uzun olmamalı
|
1043 |
+
length = len(text)
|
1044 |
+
if 20 <= length <= 300:
|
1045 |
+
score += 0.2
|
1046 |
+
elif length < 20:
|
1047 |
+
score -= 0.3
|
1048 |
+
|
1049 |
+
# Tekrar eden kelime veya ifadeler
|
1050 |
+
words = text.lower().split()
|
1051 |
+
unique_words = set(words)
|
1052 |
+
word_variety = len(unique_words) / len(words) if words else 0
|
1053 |
+
|
1054 |
+
if word_variety > 0.7: # Yüksek çeşitlilik
|
1055 |
+
score += 0.15
|
1056 |
+
elif word_variety < 0.5: # Düşük çeşitlilik
|
1057 |
+
score -= 0.2
|
1058 |
+
|
1059 |
+
# Kopya-yapıştır yapılar
|
1060 |
+
if any(text.count(phrase) > 1 for phrase in [word for word in words if len(word) > 5]):
|
1061 |
+
score -= 0.15
|
1062 |
+
|
1063 |
+
# Konu bütünlüğü - noktalama işaretleri ile cümle yapısını kontrol et
|
1064 |
+
sentences = re.split(r'[.!?]', text)
|
1065 |
+
if 2 <= len(sentences) <= 5:
|
1066 |
+
score += 0.1
|
1067 |
+
|
1068 |
+
# Klişe veya genel ifadeler - samimiyeti azaltır
|
1069 |
+
cliches = [
|
1070 |
+
"her şey güzel olacak", "sorunlar geçici", "mutlu olmaya bak",
|
1071 |
+
"hayat kısa", "kendine iyi bak", "herkesin sorunları var",
|
1072 |
+
"zaman her şeyin ilacı", "yarın başka bir gün"
|
1073 |
+
]
|
1074 |
+
|
1075 |
+
if any(cliche in text.lower() for cliche in cliches):
|
1076 |
+
score -= 0.1
|
1077 |
+
|
1078 |
+
# Daha semantik ve spesifik ifadeler kullanma
|
1079 |
+
specific_phrases = [
|
1080 |
+
"hissettiğin", "yaşadığın", "deneyimin", "düşüncelerin",
|
1081 |
+
"gelecek", "geçmiş", "bugün", "yarın", "adım", "strateji",
|
1082 |
+
"önerim", "deneyebilirsin", "hatırla", "unutma", "farket"
|
1083 |
+
]
|
1084 |
+
|
1085 |
+
if any(phrase in text.lower() for phrase in specific_phrases):
|
1086 |
+
score += 0.2
|
1087 |
+
|
1088 |
+
return min(1.0, max(0.0, score)) # 0 ile 1 arasında sınırla
|
1089 |
+
|
1090 |
+
def generate_turkish_text(prompt, max_length=300):
|
1091 |
+
"""Türkçe metin üretme fonksiyonu - tutarlılık ve alaka düzeyi iyileştirildi"""
|
1092 |
+
try:
|
1093 |
+
print(f"Prompt: {prompt[:100]}...")
|
1094 |
+
inputs = tokenizer(prompt, return_tensors="pt")
|
1095 |
+
|
1096 |
+
# Tutarlı ve alakalı yanıtlar için optimize edilmiş parametreler
|
1097 |
+
try:
|
1098 |
+
output = text_model.generate(
|
1099 |
+
inputs["input_ids"],
|
1100 |
+
max_length=max_length,
|
1101 |
+
num_return_sequences=1,
|
1102 |
+
do_sample=True,
|
1103 |
+
temperature=0.6, # Daha düşük sıcaklıkla daha tutarlı yanıtlar
|
1104 |
+
top_p=0.85, # Daha tutarlı kelime seçimleri
|
1105 |
+
top_k=40, # Sınırlı kelime havuzu
|
1106 |
+
repetition_penalty=1.3, # Tekrarları daha fazla cezalandır
|
1107 |
+
no_repeat_ngram_size=3, # 3 kelimelik tekrarları engelle
|
1108 |
+
pad_token_id=tokenizer.eos_token_id
|
1109 |
+
)
|
1110 |
+
except RuntimeError as e:
|
1111 |
+
print(f"Model üretme hatası: {str(e)}")
|
1112 |
+
# Daha basit parametrelerle tekrar dene
|
1113 |
+
output = text_model.generate(
|
1114 |
+
inputs["input_ids"],
|
1115 |
+
max_length=max_length,
|
1116 |
+
do_sample=True,
|
1117 |
+
temperature=0.6,
|
1118 |
+
pad_token_id=tokenizer.eos_token_id
|
1119 |
+
)
|
1120 |
+
|
1121 |
+
# Yanıt metni oluştur ve işle
|
1122 |
+
try:
|
1123 |
+
response = tokenizer.decode(output[0], skip_special_tokens=True)
|
1124 |
+
|
1125 |
+
# Prompt'tan sonraki kısmı al
|
1126 |
+
if prompt in response:
|
1127 |
+
response = response[len(prompt):].strip()
|
1128 |
+
|
1129 |
+
print(f"Ham yanıt: {response[:50]}...")
|
1130 |
+
|
1131 |
+
# Kullanıcının girdisini tekrar etmeyi engelle
|
1132 |
+
user_input = re.search(r"'(.*?)'", prompt).group(1) if re.search(r"'(.*?)'", prompt) else ""
|
1133 |
+
if user_input and response.startswith(user_input):
|
1134 |
+
response = response[len(user_input):].strip()
|
1135 |
+
|
1136 |
+
# Temizlik işlemleri
|
1137 |
+
response = clean_response(response)
|
1138 |
+
|
1139 |
+
# Yanıt kalitesi kontrolü
|
1140 |
+
if not response or len(response) < 15:
|
1141 |
+
# Tutarlı yedek yanıt oluştur
|
1142 |
+
# Kullanıcı girdisinden anahtar kelimeler çıkar
|
1143 |
+
words = re.sub(r'[^\w\s]', '', user_input.lower()).split()
|
1144 |
+
keywords = [w for w in words if len(w) > 3 and w not in ["nasıl", "neden", "ama", "fakat", "çünkü", "gibi", "kadar", "için"]]
|
1145 |
+
|
1146 |
+
if "endişe" in user_input.lower() or "korku" in user_input.lower():
|
1147 |
+
backup_response = f"Endişelerini anlıyorum. Bu durum karşısında kendini nasıl hissettiğini biraz daha anlatır mısın?"
|
1148 |
+
elif "üzgün" in user_input.lower() or "mutsuz" in user_input.lower():
|
1149 |
+
backup_response = f"Bu durum gerçekten zor olmalı. Senin için yapabileceğim bir şey var mı?"
|
1150 |
+
elif "gelecek" in user_input.lower():
|
1151 |
+
backup_response = f"Gelecek hakkındaki düşüncelerin önemli. Hangi konuda en çok endişeleniyorsun?"
|
1152 |
+
else:
|
1153 |
+
backup_response = f"Söylediklerini dikkate alıyorum. Bu konuda daha fazla nasıl yardımcı olabilirim?"
|
1154 |
+
|
1155 |
+
print("Yanıt çok kısa veya boş, alakalı yedek yanıt kullanılıyor")
|
1156 |
+
return backup_response
|
1157 |
+
|
1158 |
+
return response
|
1159 |
+
|
1160 |
+
except Exception as e:
|
1161 |
+
print(f"Yanıt işleme hatası: {str(e)}")
|
1162 |
+
return "Söylediklerini dikkate alıyorum. Bu durumla nasıl başa çıkabileceğin hakkında konuşabilir miyiz?"
|
1163 |
+
|
1164 |
+
except Exception as e:
|
1165 |
+
print(f"Metin üretme genel hatası: {str(e)}")
|
1166 |
+
import traceback
|
1167 |
+
print(f"Hata detayı: {traceback.format_exc()}")
|
1168 |
+
return "Bu konudaki düşüncelerini anlıyorum. Biraz daha detaylı anlatır mısın?"
|