Реалізація AI-автоматизації протоколювання нарад

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

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

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

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

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

Автоматизація протоколювання зустрічей з AI Система автоматично транскрибує записи зустрічей, визначає учасників, виділяє рішення та завдання, формує структурований протокол. Інтегрується із Zoom, Google Meet, MS Teams, Slack, корпоративними системами управління завданнями. ### Архітектура пайплайна```

Запись встречи (аудио/видео) ↓ VAD + диаризация (pyannote.audio) ↓ Транскрибация (Whisper large-v3) ↓ NLP-обработка (GPT-4o / Claude) ↓ Извлечение: решения / задачи / ответственные / дедлайны ↓ Генерация протокола (Markdown / Notion / Jira) ### Транскрибація з діаризацієюpython import whisper from pyannote.audio import Pipeline import torch

class MeetingTranscriber: def init(self): self.whisper = whisper.load_model("large-v3", device="cuda") self.diarizer = Pipeline.from_pretrained( "pyannote/speaker-diarization-3.1", use_auth_token="HF_TOKEN" )

def transcribe_with_speakers(self, audio_path: str) -> list[dict]:
    # Диаризация
    diarization = self.diarizer(audio_path)
    segments_by_speaker = [
        {"speaker": turn.speaker, "start": turn.start, "end": turn.end}
        for turn, _, _ in diarization.itertracks(yield_label=True)
    ]

    # Транскрипция
    result = self.whisper.transcribe(audio_path, language="ru", word_timestamps=True)

    # Мёржим
    transcript = []
    for seg in result["segments"]:
        speaker = self._find_speaker(seg["start"], segments_by_speaker)
        transcript.append({
            "speaker": speaker,
            "start": seg["start"],
            "end": seg["end"],
            "text": seg["text"].strip()
        })

    return transcript

def _find_speaker(self, timestamp: float, diar_segments: list) -> str:
    for s in diar_segments:
        if s["start"] <= timestamp <= s["end"]:
            return s["speaker"]
    return "UNKNOWN"

### NLP-обробка та вилучення структуриpython from openai import AsyncOpenAI import json

client = AsyncOpenAI()

async def extract_meeting_structure(transcript: list[dict]) -> dict: # Форматируем транскрипт formatted = "\n".join([ f"[{seg['speaker']} | {int(seg['start']//60):02d}:{int(seg['start']%60):02d}] {seg['text']}" for seg in transcript ])

response = await client.chat.completions.create(
    model="gpt-4o",
    messages=[{
        "role": "system",
        "content": """Ты — ассистент для протоколирования встреч.
        Проанализируй транскрипт и верни JSON:
        {
          "summary": "краткое резюме 2-3 предложения",
          "participants": ["SPEAKER_00 = Иван Петров", ...],
          "agenda_items": [{"topic": "...", "discussion": "..."}],
          "decisions": [{"decision": "...", "context": "..."}],
          "action_items": [{"task": "...", "owner": "...", "deadline": "..."}],
          "next_meeting": "дата/условие следующей встречи если обсуждалась"
        }"""
    }, {
        "role": "user",
        "content": f"Транскрипт встречи:\n\n{formatted[:8000]}"
    }],
    response_format={"type": "json_object"}
)

return json.loads(response.choices[0].message.content)

### Генерація протоколуpython def format_meeting_minutes(structure: dict, transcript: list[dict]) -> str: date = datetime.now().strftime("%d.%m.%Y") duration_min = int(transcript[-1]["end"] / 60) if transcript else 0

md = f"""## Протокол встречи от {date}

Продолжительность: {duration_min} минут Участники: {", ".join(structure.get("participants", []))}

Краткое резюме

{structure.get("summary", "")}

Принятые решения

""" for d in structure.get("decisions", []): md += f"- {d['decision']}\n {d.get('context', '')}\n\n"

md += "### Задачи\n\n"
md += "| Задача | Ответственный | Срок |\n|--------|--------------|------|\n"
for item in structure.get("action_items", []):
    md += f"| {item['task']} | {item.get('owner', '—')} | {item.get('deadline', '—')} |\n"

return md

### Інтеграції **Zoom:** через Zoom Recordings API - автоматично отримуємо mp4/m4a після закінчення зустрічі. **Google Meet:** через Google Workspace Events API + Cloud Storage для записів. **MS Teams:** через Microsoft Graph API `/communications/callRecords`.python @app.post("/webhook/zoom/recording") async def zoom_recording_webhook(payload: dict): if payload["event"] == "recording.completed": recording_url = payload["payload"]["object"]["recording_files"][0]["download_url"] meeting_id = payload["payload"]["object"]["uuid"] asyncio.create_task(process_meeting_recording(meeting_id, recording_url)) return {"status": "ok"} ### Експортpython class MinutesExporter: async def to_notion(self, minutes: str, database_id: str): ... async def to_confluence(self, minutes: str, space_key: str): ... async def to_jira_tasks(self, action_items: list, project_key: str): ... async def to_slack(self, summary: str, channel_id: str): ... async def to_email(self, minutes: str, recipients: list[str]): ...