ci / build-test (push) Canceled after 0s
SaaS-мониторинг Telegram: ядро (модули Cards/Kanban/Pipeline/Tenants/Settings/ Discovery, Api, Infrastructure), сервисы telegram/ai/ml/storage, фронт Vue, контракты и grpc-hosting, деплой-конфиги (dev/prod/observability/CI-раннер), Gitea Actions CI, документация (ТЗ, техдок, api-map, код-стайл, планы, бэклог). Текущее состояние: все этапы роадмапа 0–12 закрыты, сборка 5 sln 0/0, тесты 1340/130/52/38/9 зелёные.
2.7 KiB
2.7 KiB
Task 5: Оценка контента (язык, темы, fit по профилю задачи)
Files:
- Create:
backend/app/services/discovery_eval.py
Interfaces:
-
Consumes:
store,ml_client,ai_service(chat_json),pipeline.clean_short. -
Produces:
def detect_lang_ru(texts: list[str]) -> bool | None— доля кириллических букв от всех букв в сумме:>=0.15 → True;<=0.03 → False; между порогами →None(неопределённо).def group_by_topic(messages: list[dict]) -> list[dict]— группировка поtopic_id(None → "main"); возвращает[{"topic_id", "title", "messages": [...]}], title = сниппет первого текста темы (≤60 симв.), сортировка по количеству сообщений (убыв.).async def evaluate_message(task: dict, text: str) -> dict—{"fit": bool, "reason": str, "source": "heuristic"|"ml"|"ai"}:- текст пустой/длина <10 → fit False «слишком короткое»;
- ML: если
ml_client.is_enabled()и прогнозtakeиlabel=='spam'→ fit False «ML: спам»; - ИИ: если
aiEnabled→ один JSON-вызовai_service.chat_json(промпт, user=text)с промптом из описания задачи и ключей ({fit, reason}); ошибка → шаг 4; - эвристика: fit = любой ключ входит в
clean_short(text)casefold; reason «совпал ключ "…"» / «нет совпадений с ключами».
async def evaluate_sample(task: dict, messages: list[dict]) -> dict— последовательно по каждому сообщению; вернуть{"fit_count": int, "total": int, "fit_ratio": float, "per_message": [{"text": …, "fit", "reason", "topic_id"}]}.def passed(ev: dict, task: dict) -> bool—ev["total"] >= 3 and ev["fit_ratio"]*100 >= task["threshold"].
-
Step 1: Реализовать модуль. Промпт ИИ (внутри модуля, константа):
Оцени, относится ли сообщение к сфере/задаче. Описание: {description}. Ключи: {keywords}. Верни JSON {"fit": 0|1, "reason": "краткая причина"}. -
Step 2: Проверить на временной БД (без сети):
detect_lang_ru(["Ищем python разработчика"]) is True;detect_lang_ru(["we need a python developer"]) is False;group_by_topicобъединяет по topic_id и сортирует;evaluate_messageна задаче без ИИ/ML возвращает эвристический fit по ключу.