AI-система управління віртуальними заходами

Проектуємо та впроваджуємо системи штучного інтелекту: від прототипу до production-ready рішення. Наша команда поєднує експертизу в машинному навчанні, дата-інжинірингу та MLOps, щоб AI працював не в лабораторії, а в реальному бізнесі.
Показано 1 з 1Усі 1566 послуг
AI-система управління віртуальними заходами
Середній
~2-4 тижні
Часті запитання

Напрямки AI-розробки

Етапи розробки AI-рішення

Останні роботи

  • image_website-b2b-advance_0.webp
    Розробка сайту компанії B2B ADVANCE
    1284
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1196
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    901
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1119
  • image_logo-advance_0.webp
    Розробка логотипу компанії B2B Advance
    586
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    853

AI-система управления виртуальными мероприятиями

Организация онлайн-конференции на 500+ участников — это не только платформа для трансляции. Это регистрация с персонализацией, рассылки по сегментам, модерация Q&A в реальном времени, автоматические follow-up письма после секций, аналитика вовлечённости. AI-система закрывает операционную рутину: организатор занимается контентом, а не ответами на «а когда будут записи?».

Архитектура системы управления мероприятием

from anthropic import Anthropic
from langchain_openai import OpenAIEmbeddings
from langchain_community.vectorstores import Chroma
from datetime import datetime, timedelta
import json
import asyncio

client = Anthropic()
embeddings = OpenAIEmbeddings(model="text-embedding-3-small")


class EventKnowledgeBase:
    """База знаний о мероприятии для AI-ассистента"""

    def __init__(self, event_id: str):
        self.vectorstore = Chroma(
            collection_name=f"event_{event_id}",
            embedding_function=embeddings,
        )

    def index_event_data(self, event_data: dict):
        """Индексирует данные о мероприятии"""
        texts = []
        metadatas = []

        # Программа
        for session in event_data.get("sessions", []):
            text = f"""Секция: {session['title']}
Спикер: {session['speaker']} ({session['speaker_bio']})
Время: {session['start_time']} — {session['end_time']}
Описание: {session['description']}
Зал/трек: {session.get('track', 'общий')}"""
            texts.append(text)
            metadatas.append({"type": "session", "session_id": session["id"]})

        # FAQ
        for item in event_data.get("faq", []):
            texts.append(f"Вопрос: {item['q']}\nОтвет: {item['a']}")
            metadatas.append({"type": "faq"})

        # Спикеры
        for speaker in event_data.get("speakers", []):
            text = f"""Спикер: {speaker['name']}
Должность: {speaker['title']} в {speaker['company']}
Биография: {speaker['bio']}
Темы: {', '.join(speaker.get('topics', []))}"""
            texts.append(text)
            metadatas.append({"type": "speaker", "speaker_name": speaker["name"]})

        self.vectorstore.add_texts(texts=texts, metadatas=metadatas)


class EventAssistant:
    """AI-ассистент для участников мероприятия"""

    def __init__(self, event_id: str, event_name: str):
        self.event_name = event_name
        self.kb = EventKnowledgeBase(event_id)
        self.sessions: dict[str, list] = {}  # история диалогов

    def answer(self, participant_id: str, question: str, current_time: datetime = None) -> str:
        results = self.kb.vectorstore.similarity_search_with_score(question, k=5)
        context = "\n\n".join([doc.page_content for doc, score in results if (1 - score) > 0.5])

        time_context = f"Текущее время: {current_time.strftime('%H:%M')}" if current_time else ""

        history = self.sessions.get(participant_id, [])
        messages = history + [{
            "role": "user",
            "content": f"{time_context}\n\nВопрос участника: {question}\n\nИнформация о мероприятии:\n{context}"
        }]

        response = client.messages.create(
            model="claude-haiku-4-5",
            max_tokens=512,
            system=f"""Ты — ассистент участников мероприятия «{self.event_name}».
Отвечай кратко и конкретно. Если информации нет — скажи честно.""",
            messages=messages,
        )

        answer = response.content[0].text
        history.append({"role": "user", "content": question})
        history.append({"role": "assistant", "content": answer})
        self.sessions[participant_id] = history[-10:]

        return answer


class QAModerator:
    """AI-модерация вопросов Q&A сессии"""

    def __init__(self):
        self.question_queue: list[dict] = []
        self.answered: list[dict] = []

    def moderate_question(self, question: str, participant: dict) -> dict:
        """Модерирует вопрос: релевантность, дубликаты, качество"""
        # Проверяем на дубликат
        if self.question_queue or self.answered:
            existing = [q["question"] for q in self.question_queue + self.answered[-20:]]
            existing_text = "\n".join(f"- {q}" for q in existing[-15:])
        else:
            existing_text = "нет"

        response = client.messages.create(
            model="claude-haiku-4-5",
            max_tokens=256,
            messages=[{
                "role": "user",
                "content": f"""Оцени вопрос для Q&A сессии:

Вопрос: "{question}"
Уже есть вопросы: {existing_text}

Верни JSON:
{{
  "approve": true/false,
  "is_duplicate": true/false,
  "duplicate_of": "похожий вопрос или null",
  "quality_score": 1-5,
  "category": "technical|business|personal|off_topic",
  "cleaned_question": "отредактированная версия (убрать грубость, опечатки)",
  "reject_reason": "причина отклонения или null"
}}

Одобряй вопросы по теме, не спам и не грубость. Только JSON."""
            }],
        )

        text = response.content[0].text
        result = json.loads(text[text.find("{"):text.rfind("}") + 1])

        if result.get("approve"):
            self.question_queue.append({
                "question": result.get("cleaned_question", question),
                "original": question,
                "participant": participant,
                "quality": result.get("quality_score", 3),
                "category": result.get("category"),
                "submitted_at": datetime.now().isoformat(),
            })

        return result

    def get_top_questions(self, n: int = 5) -> list[dict]:
        """Возвращает топ вопросов по оценке качества"""
        sorted_queue = sorted(
            self.question_queue,
            key=lambda q: q.get("quality", 3),
            reverse=True
        )
        return sorted_queue[:n]

    def get_summary_for_speaker(self, session_topic: str) -> str:
        """Готовит спикеру сводку вопросов перед Q&A"""
        if not self.question_queue:
            return "Вопросов пока нет."

        questions_text = "\n".join([
            f"{i+1}. [{q['category']}] {q['question']}"
            for i, q in enumerate(self.get_top_questions(10))
        ])

        response = client.messages.create(
            model="claude-haiku-4-5",
            max_tokens=512,
            messages=[{
                "role": "user",
                "content": f"""Тема сессии: {session_topic}

Вопросы от аудитории:
{questions_text}

Сгруппируй по темам, выдели наиболее частые — помоги спикеру подготовиться к Q&A.
Кратко, по делу."""
            }],
        )

        return response.content[0].text


class EventEmailAutomation:
    """Автоматические рассылки для мероприятия"""

    EMAIL_TYPES = {
        "reminder_24h": "Напоминание за 24 часа",
        "reminder_1h": "Напоминание за 1 час",
        "welcome": "Приветствие при подключении",
        "session_followup": "Follow-up после секции",
        "post_event": "Итоговое письмо",
        "recording_ready": "Запись доступна",
    }

    def __init__(self, event_data: dict):
        self.event = event_data

    def generate_email(
        self,
        email_type: str,
        participant: dict,
        session: dict = None,
        extra_data: dict = {},
    ) -> dict:
        """Генерирует персонализированное письмо"""
        context = f"""
Мероприятие: {self.event['name']}
Дата: {self.event['date']}
Участник: {participant['name']}, {participant.get('company', '')} ({participant.get('job_title', '')})
Интересы: {', '.join(participant.get('interests', []))}
"""
        if session:
            context += f"\nСекция: {session['title']}\nСпикер: {session['speaker']}"

        context += f"\nДоп. данные: {json.dumps(extra_data, ensure_ascii=False)}"

        response = client.messages.create(
            model="claude-haiku-4-5",
            max_tokens=1024,
            messages=[{
                "role": "user",
                "content": f"""Напиши {self.EMAIL_TYPES[email_type]} для участника конференции.
Контекст: {context}

Формат: {{"subject": "тема письма", "body_html": "HTML текст письма", "body_text": "plain text"}}
Тон: профессиональный, персонализированный.
Только JSON."""
            }],
        )

        text = response.content[0].text
        return json.loads(text[text.find("{"):text.rfind("}") + 1])

Аналитика вовлечённости в реальном времени

class EngagementAnalytics:
    """Аналитика вовлечённости участников"""

    def __init__(self):
        self.events_log: list[dict] = []

    def log_event(self, event_type: str, participant_id: str, data: dict = {}):
        self.events_log.append({
            "type": event_type,  # view, question, reaction, leave, join
            "participant_id": participant_id,
            "timestamp": datetime.now().isoformat(),
            **data
        })

    def get_session_insights(self, session_id: str) -> str:
        """AI-анализ вовлечённости по сессии"""
        session_events = [e for e in self.events_log if e.get("session_id") == session_id]

        stats = {
            "total_views": len([e for e in session_events if e["type"] == "view"]),
            "questions_asked": len([e for e in session_events if e["type"] == "question"]),
            "reactions": len([e for e in session_events if e["type"] == "reaction"]),
            "avg_watch_time_min": sum(e.get("watch_time", 0) for e in session_events) / max(len(session_events), 1) / 60,
            "drop_off_points": sorted(
                [e.get("timestamp", "") for e in session_events if e["type"] == "leave"]
            )[:5],
        }

        response = client.messages.create(
            model="claude-haiku-4-5",
            max_tokens=512,
            messages=[{
                "role": "user",
                "content": f"Проанализируй вовлечённость аудитории по данным: {json.dumps(stats, ensure_ascii=False)}\nДай краткие выводы и рекомендации для следующего мероприятия."
            }],
        )

        return response.content[0].text

Практический кейс: IT-конференция, 800 участников

Масштаб: 2-дневная онлайн-конференция, 22 секции, 800 зарегистрированных участников, 3 параллельных трека.

Что автоматизировали:

  • Q&A чат-бот отвечал на вопросы о программе, спикерах и технических вопросах подключения (78% вопросов)
  • Модерация Q&A: 340 вопросов за 2 дня, спикеры получали топ-5 самых качественных каждые 20 минут
  • Персонализированные follow-up письма по 3 трекам (технический, бизнес, менеджмент)
  • Напоминания за 24ч и 1ч: +18% к attendance rate vs предыдущей конференции без напоминаний

Результаты:

  • Оргкоманда (3 человека): сэкономили ~40 часов операционной работы за 2 дня
  • Время ответа на вопрос участника: 30 мин → 90 сек
  • Отчёт по вовлечённости каждой секции: готов через 5 мин после окончания

Сроки

  • AI-ассистент для участников + Q&A модерация: 1–2 недели
  • Email-автоматизация (персонализированные рассылки): 1 неделя
  • Аналитика вовлечённости: 3–5 дней
  • Полная система для крупной конференции: 4–6 недель