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

@@ -210,6 +210,23 @@ class AsyncBotDB:
return await self.factory.posts.update_status_for_media_group_by_helper_id(
helper_message_id, status
)
# Методы для ML Scoring
async def get_post_text_by_message_id(self, message_id: int) -> Optional[str]:
"""Получает текст поста по message_id."""
return await self.factory.posts.get_post_text_by_message_id(message_id)
async def update_ml_scores(self, message_id: int, ml_scores_json: str) -> bool:
"""Обновляет ML-скоры для поста."""
return await self.factory.posts.update_ml_scores(message_id, ml_scores_json)
async def get_approved_posts_texts(self, limit: int = 1000) -> List[str]:
"""Получает тексты одобренных постов для обучения RAG."""
return await self.factory.posts.get_approved_posts_texts(limit)
async def get_declined_posts_texts(self, limit: int = 1000) -> List[str]:
"""Получает тексты отклоненных постов для обучения RAG."""
return await self.factory.posts.get_declined_posts_texts(limit)
# Методы для работы с черным списком
async def set_user_blacklist(

View File

@@ -357,3 +357,126 @@ class PostRepository(DatabaseConnection):
post_content = await self._execute_query_with_result(query, (published_message_id,))
self.logger.info(f"Получен контент опубликованного поста: {len(post_content)} элементов для published_message_id={published_message_id}")
return post_content
# ============================================
# Методы для работы с ML-скорингом
# ============================================
async def update_ml_scores(self, message_id: int, ml_scores_json: str) -> bool:
"""
Обновляет ML-скоры для поста.
Args:
message_id: ID сообщения в группе модерации
ml_scores_json: JSON строка со скорами
Returns:
True если обновлено успешно
"""
try:
query = "UPDATE post_from_telegram_suggest SET ml_scores = ? WHERE message_id = ?"
await self._execute_query(query, (ml_scores_json, message_id))
self.logger.info(f"ML-скоры обновлены для message_id={message_id}")
return True
except Exception as e:
self.logger.error(f"Ошибка обновления ML-скоров для message_id={message_id}: {e}")
return False
async def get_ml_scores_by_message_id(self, message_id: int) -> Optional[str]:
"""
Получает ML-скоры для поста.
Args:
message_id: ID сообщения
Returns:
JSON строка со скорами или None
"""
query = "SELECT ml_scores FROM post_from_telegram_suggest WHERE message_id = ?"
rows = await self._execute_query_with_result(query, (message_id,))
if rows and rows[0][0]:
return rows[0][0]
return None
async def get_post_text_by_message_id(self, message_id: int) -> Optional[str]:
"""
Получает текст поста по message_id.
Args:
message_id: ID сообщения
Returns:
Текст поста или None
"""
query = "SELECT text FROM post_from_telegram_suggest WHERE message_id = ?"
rows = await self._execute_query_with_result(query, (message_id,))
if rows and rows[0][0]:
return rows[0][0]
return None
async def get_approved_posts_texts(self, limit: int = 1000) -> List[str]:
"""
Получает тексты опубликованных постов для обучения RAG.
Args:
limit: Максимальное количество постов
Returns:
Список текстов
"""
query = """
SELECT text FROM post_from_telegram_suggest
WHERE status = 'approved'
AND text IS NOT NULL
AND text != ''
AND text != '^'
ORDER BY created_at DESC
LIMIT ?
"""
rows = await self._execute_query_with_result(query, (limit,))
texts = [row[0] for row in rows if row[0]]
self.logger.info(f"Получено {len(texts)} опубликованных постов для обучения")
return texts
async def get_declined_posts_texts(self, limit: int = 1000) -> List[str]:
"""
Получает тексты отклоненных постов для обучения RAG.
Args:
limit: Максимальное количество постов
Returns:
Список текстов
"""
query = """
SELECT text FROM post_from_telegram_suggest
WHERE status = 'declined'
AND text IS NOT NULL
AND text != ''
AND text != '^'
ORDER BY created_at DESC
LIMIT ?
"""
rows = await self._execute_query_with_result(query, (limit,))
texts = [row[0] for row in rows if row[0]]
self.logger.info(f"Получено {len(texts)} отклоненных постов для обучения")
return texts
async def update_vector_hash(self, message_id: int, vector_hash: str) -> bool:
"""
Обновляет хеш вектора для поста (для кеширования).
Args:
message_id: ID сообщения
vector_hash: Хеш вектора
Returns:
True если обновлено успешно
"""
try:
query = "UPDATE post_from_telegram_suggest SET vector_hash = ? WHERE message_id = ?"
await self._execute_query(query, (vector_hash, message_id))
return True
except Exception as e:
self.logger.error(f"Ошибка обновления vector_hash для message_id={message_id}: {e}")
return False