add fixes for service validator and serializator

This commit is contained in:
harold 2025-04-20 14:26:10 +05:00
parent ebbe667c9d
commit 600fdaee0c
2 changed files with 63 additions and 133 deletions

View File

@ -1,129 +1,61 @@
ROLE = """
Вы являетесь опытным маркетологом в компании,
которая разрабатывает программное обеспечение любой сложности на основе аутсорсинга.
Компания специализируется на:
Backend: Python, ...
Frontend: React, JS, CSS
Мобильная разработка: Flutter, iOS/Android (Kotlin/Swift)
Data Science & AI: машинное обучение, компьютерное зрение
Кибербезопасность
Ваша задача анализировать переписку и находить потенциальных клиентов, которым нужна разработка ПО.
"""
ANALYTIC_PROMT = """
Ты получаешь json с такими полями
ANALYTIC_PROMPT = """
Ты получаешь json с такими полями:
{
chats: [
"slice_id": UUID4
"chats": [
{
"slice_id": "UUID4",
"messages": [
{
"user_id: integer,
"user_id": integer,
"message_id": integer,
"text": string,
"date": datetime
"date": "datetime"
}
]
]
}
chats - это список чатов.
messages - Это представляет собой беседу в чате.
ВАЖНО. Каждый slice_id это отдельный чат и они не связаны между собой.
user_id никак не учитывается в обработке смысла диалога.
Анализируйте только текст сообщений, игнорируя рекламные хэштеги и подписи. Реагируйте исключительно на технико-коммерческие предложения с четкими параметрами.
Критерии отбора. Обязательные условия:
1. Четкое описание проекта/проблемы
2. Упоминание технологий или типа разработки
3. Наличие хотя бы одного из:
Бюджета/сроков
Технического задания
Бизнес-цели проекта
3. Ключевые фразы (только с конкретикой):
"Нужна разработка [тип системы] для [цель]"
"Ищем разработчиков для [конкретный проект]"
"Требуется автоматизация [процесс] с использованием [технология]"
"Готовы инвестировать в разработку [чего именно]"
Примеры валидных запросов:
"Нужна команда для разработки ERP-системы на Python, бюджет 1.5 млн руб"
"Ищем подрядчика для интеграции API нашего CRM с телефонией"
"Хотим автоматизировать учет товаров на складе. Сейчас всё в Excel, нужна система с API для подключения"
"Ищем подрядчика для создания мобильного приложения под iOS/Android"
"Проблемы с нагрузкой на текущий BI-инструмент. Ищем решение для обработки 1 млн+ строк данных в день"
"Нужна команда для создания MVP: бэкенд (Node.js), фронтенд (React), мобильное приложение."
"Текущий разработчик пропал. Нужен срочный аудит кода и исправление багов в модуле оплат"
Фильтры исключения:
Любые упоминания:
Заработка/дохода/инвестиционных схем
Подработки/удаленной работы без технических деталей
Партнерских программ
Вакансий не связанных с разработкой
Сообщения содержащие:
"пишите в ЛС/личку"
"напишите '+'/комментарий"
"интересует? писать..."
"быстрый старт"
"без вложений"
Более 3 эмодзи/восклицательных знаков
Гиперболы ("золотая возможность", "гарантированный доход")
Финансовые маркеры:
Любые упоминания: "доход/заработок/прибыль" + временной период
"инвестиции" без технического контекста
"пассивный доход", "подработка", "выгодные условия"
"удаленная работа", "гибкий график"
"оплата ежедневно/еженедельно"
Бот-активность:
Сообщения от ботов (содержащие "нажмите кнопку", "верификация")
Автоматические уведомления
Повторяющиеся идентичные сообщения
Контекстные исключения:
Обсуждения вакансий/услуг (менеджеры, выгул собак и т.д.)
Сообщения короче 5 слов без технических деталей
Примеры автоматического отклонения:
"Нужны 2 человека для работы с телефоном"
"Доход $500 в неделю, пишите '+'"
Любые сообщения ботов о верификации
"Ищем партнеров для заработка"
Дополнительные правила:
Игнорируйте диалоги, где более 50% сообщений попадают под фильтры исключения
Отклоняйте сообщения с упоминанием "менеджер", если нет технических требований
Не анализируйте повторяющиеся сообщения (дубли)
Условно в нескольких чатах может быть несколько потенциальных клиентов, тогда вот так выведи
{
success: [
{
"user_id": integer,
"slice_id": integer,
"reason": string
}
]
}
поле reason: Кратко(до 100 симоволов) почему ты решил, что это потенциальный клиент.
Анализируй каждый чат отдельно. Ответ должен быть ТОЛЬКО в JSON формате, без каких-либо пояснений или форматирования.
Если ты хотя бы чуть чуть не уверен, то верни вот такую строку
Пример правильного ответа:
{
success: null
"success": [
{
"user_id": 123,
"slice_id": "550e8400-e29b-41d4-a716-446655440000",
"reason": "Упоминание разработки мобильного приложения с указанием технологий"
}
]
}
Если нет четких признаков или есть сомнения, верни:
{"success": null}
ВАЖНО: Ты должен вернуть ТОЛЬКО JSON и не словом больше. Иначе я разорюсь.
без ```json ``` просто так без каких либо спецсимволов
Правила анализа:
1. Игнорируй сообщения с рекламой, вакансиями или заработком
2. Обращай внимание на технические требования и конкретные цели
3. Проверяй наличие бюджета/сроков/технического задания
4. Отклоняй сообщения с чрезмерными эмодзи или восклицаниями
Критерии положительного решения:
- Четкое описание проекта
- Указание технологий/платформы
- Наличие сроков/бюджета/техзадания
- Конкретные бизнес-цели
"""
@ -132,7 +64,7 @@ GEMINI_BASE_MESSAGE = [
"role": "user",
"parts": [
{"text": ROLE},
{"text": ANALYTIC_PROMT},
{"text": ANALYTIC_PROMPT},
]
}
]

View File

@ -1,9 +1,12 @@
import json
from json import JSONDecodeError
from typing import List
import google.generativeai as genai
from pydantic import ValidationError
from src.gemini_sdk.promt import GEMINI_BASE_MESSAGE
from src.gemini_sdk.schemas import FullRequestForGeminiSchema, ResponseFromGeminiSchema
from src.gemini_sdk.schemas import ResponseFromGeminiSchema
from src.schemas import MessagesForSendToWorkersSchema
from src.settings.base import settings
@ -16,53 +19,48 @@ class GoogleHelper:
) -> None:
self.api_key = api_key
self.model = model_name
genai.configure(api_key=api_key)
self._model = genai.GenerativeModel(model_name=model_name)
@staticmethod
def _serialize_messages_to_promt(
def _serialize_messages_to_prompt(
chats: MessagesForSendToWorkersSchema,
) -> list[dict]:
) -> List[dict]:
messages_for_request = GEMINI_BASE_MESSAGE.copy()
text_for_request = json.dumps(chats.model_dump_json())
# Исправлена двойная сериализация
text_for_request = json.dumps(chats.model_dump(mode='json'))
extend_message = {
"role": "user",
"parts": [
{
"text": text_for_request,
}
],
"parts": [{"text": text_for_request}],
}
messages_for_request.append(extend_message)
return messages_for_request
@staticmethod
def _serialize_response_to_json(
response_text: str,
) -> ResponseFromGeminiSchema:
response = response_text.replace('\n', '')
response_as_dict = json.loads(response_text)
try:
# Удаляем возможные обертки и форматирование
cleaned_response = response_text.strip().replace('```json\n', '').replace('\n```', '')
response_as_dict = json.loads(cleaned_response)
return ResponseFromGeminiSchema(**response_as_dict)
except (JSONDecodeError, ValidationError) as e:
# Логирование ошибки можно добавить здесь
return ResponseFromGeminiSchema(success=None)
def create_request_ai(
self,
messages: MessagesForSendToWorkersSchema,
) -> ResponseFromGeminiSchema:
contents = self._serialize_messages_to_promt(messages)
response = self._model.generate_content(
contents=contents
)
contents = self._serialize_messages_to_prompt(messages)
response = self._model.generate_content(contents=contents)
return self._serialize_response_to_json(response.text)
gemini_helper = GoogleHelper(
api_key=settings.GEMINI.API_KEY,
model_name=settings.GEMINI.MODEL_NAME,