feat: интеграция ML-скоринга с использованием RAG и DeepSeek

- Обновлен Dockerfile для установки необходимых зависимостей.
- Добавлены новые переменные окружения для настройки ML-скоринга в env.example.
- Реализованы методы для получения и обновления ML-скоров в AsyncBotDB и PostRepository.
- Обновлены обработчики публикации постов для интеграции ML-скоринга.
- Добавлен новый обработчик для получения статистики ML-скоринга в админ-панели.
- Обновлены функции для форматирования сообщений с учетом ML-скоров.
This commit is contained in:
2026-01-26 18:40:38 +03:00
parent e2b1353408
commit 7f6f0f028c
25 changed files with 2833 additions and 52 deletions

View File

@@ -111,7 +111,16 @@ def determine_anonymity(post_text: str) -> bool:
return False
def get_text_message(post_text: str, first_name: str, username: str = None, is_anonymous: Optional[bool] = None):
def get_text_message(
post_text: str,
first_name: str,
username: str = None,
is_anonymous: Optional[bool] = None,
deepseek_score: Optional[float] = None,
rag_score: Optional[float] = None,
rag_confidence: Optional[float] = None,
rag_score_pos_only: Optional[float] = None,
):
"""
Форматирует текст сообщения для публикации в зависимости от наличия ключевых слов "анон" и "неанон"
или переданного параметра is_anonymous.
@@ -121,6 +130,10 @@ def get_text_message(post_text: str, first_name: str, username: str = None, is_a
first_name: Имя автора поста
username: Юзернейм автора поста (может быть None)
is_anonymous: Флаг анонимности (True - анонимно, False - не анонимно, None - legacy, определяется по тексту)
deepseek_score: Скор от DeepSeek API (0.0-1.0, опционально)
rag_score: Скор от RAG/ruBERT neg/pos (0.0-1.0, опционально)
rag_confidence: Уверенность RAG модели (0.0-1.0, зависит от количества примеров)
rag_score_pos_only: Скор RAG только по положительным примерам (0.0-1.0, опционально)
Returns:
str: - Сформированный текст сообщения.
@@ -137,21 +150,37 @@ def get_text_message(post_text: str, first_name: str, username: str = None, is_a
else:
author_info = f"{first_name} (Ник не указан)"
# Формируем базовый текст
# Если передан is_anonymous, используем его, иначе определяем по тексту (legacy)
# TODO: Уверен можно укоротить
if is_anonymous is not None:
if is_anonymous:
return f'{safe_post_text}\n\nПост опубликован анонимно'
final_text = f'{safe_post_text}\n\nПост опубликован анонимно'
else:
return f'{safe_post_text}\n\nАвтор поста: {author_info}'
final_text = f'{safe_post_text}\n\nАвтор поста: {author_info}'
else:
# Legacy: определяем по тексту
if "неанон" in post_text or "не анон" in post_text:
return f'{safe_post_text}\n\nАвтор поста: {author_info}'
final_text = f'{safe_post_text}\n\nАвтор поста: {author_info}'
elif "анон" in post_text:
return f'{safe_post_text}\n\nПост опубликован анонимно'
final_text = f'{safe_post_text}\n\nПост опубликован анонимно'
else:
return f'{safe_post_text}\n\nАвтор поста: {author_info}'
final_text = f'{safe_post_text}\n\nАвтор поста: {author_info}'
# Добавляем блок со скорами если есть
if deepseek_score is not None or rag_score is not None or rag_score_pos_only is not None:
scores_lines = ["\n📊 Уверенность в одобрении:"]
if deepseek_score is not None:
scores_lines.append(f"DeepSeek: {deepseek_score:.2f}")
if rag_score is not None:
rag_line = f"RAG neg/pos: {rag_score:.2f}"
if rag_confidence is not None:
rag_line += f" (уверенность: {rag_confidence:.0%})"
scores_lines.append(rag_line)
if rag_score_pos_only is not None:
scores_lines.append(f"RAG pos only: {rag_score_pos_only:.2f}")
final_text += "\n" + "\n".join(scores_lines)
return final_text
@track_time("download_file", "helper_func")
@track_errors("helper_func", "download_file")