13 KiB
Meeting Protocol Service — Design Spec
Сервис транскрибации аудио/видео записей встреч и автоматической генерации протоколов с использованием локальной модели Whisper и внешних LLM.
1. Цели и контекст
- Автоматизация создания протоколов по записям встреч (внутренних и с клиентами)
- Протоколы клиентских встреч — основа для результирующей документации по обследованию процессов
- Бесплатная локальная транскрибация (Whisper на GPU)
- Генерация протоколов через бесплатные/платные LLM API
- Веб-интерфейс + полнофункциональные боты в Telegram и Lensa
- Хранение кода и версионирование в Gitea на http://78.153.7.224:3000
2. Архитектура
Подход: модульный монолит
Единый деплой с изолированными модулями, общение между которыми — через очереди задач (Celery/Redis). Каждый модуль можно выделить в отдельный сервис при необходимости.
Модули
| Модуль | Ответственность |
|---|---|
| API | REST endpoints, авторизация (JWT), загрузка файлов, раздача SPA |
| Транскрибация | Извлечение аудио (FFmpeg), транскрибация (faster-whisper на GPU) |
| Протоколирование | Вызов LLM, применение шаблонов промптов, экспорт DOCX/PDF/MD |
| Мессенджеры | Telegram бот (aiogram 3.x), Lensa бот (SDK/webhook), общий MessengerService |
Поток обработки записи
- Загрузка файла (web / telegram / lensa)
- Извлечение аудио из видео (FFmpeg) — Celery task
- Транскрибация (faster-whisper large-v3, GPU) — Celery task
- Генерация протокола (LLM через LiteLLM) — Celery task
- Сохранение результата, уведомление пользователя
- Экспорт по запросу (DOCX/PDF/MD)
Асинхронная обработка
Все тяжёлые операции (шаги 2-4) выполняются в Celery workers и не блокируют API. Пользователь получает обновления о прогрессе через polling (web) и push-уведомления (мессенджеры).
3. Модель данных
User
idUUID PKusernamestr uniqueemailstr uniquepassword_hashstrroleenum: admin, user (расширяемо)is_activeboolcreated_attimestamp
Recording
idUUID PKuser_idFK → Usertitlestrfile_pathstrfile_sizebigintdurationintervalformatstr (mp4, webm, mp3, wav, ogg)sourceenum: web, telegram, lensastatusenum: uploaded, processing, done, errorcreated_attimestamp
Transcription
idUUID PKrecording_idFK → Recording (1:1)texttextsegmentsJSONB (массив сегментов с таймкодами)languagestrwhisper_modelstrprocessing_timeintervalcreated_attimestamp
Protocol
idUUID PKtranscription_idFK → Transcriptiontemplate_idFK → PromptTemplatecontentJSONB (структурированный по разделам)raw_texttextllm_modelstrstatusenum: generating, done, errorcreated_attimestampupdated_attimestamp
PromptTemplate
idUUID PKnamestrdescriptionstrtypeenum: client_survey, client_intro, internal, customsystem_prompttextuser_prompttextoutput_schemaJSONB (описание ожидаемых разделов)is_defaultboolcreated_attimestamp
ExportFile
idUUID PKprotocol_idFK → Protocolformatenum: docx, pdf, mdfile_pathstrfile_sizebigintcreated_attimestamp
Связи
User 1→N Recording 1→1 Transcription 1→N Protocol 1→N ExportFile
PromptTemplate 1→N Protocol
4. Предустановленные шаблоны протоколов
4.1 Обследование процессов клиента
Разделы:
- Дата, участники, тема встречи
- Описание обследуемого процесса (задачи бизнеса, подпроцесс)
- Текущее состояние (as-is)
- Выявленные проблемы / узкие места
- Договорённости и решения
- Открытые вопросы (о которых не договорились)
- Задачи с ответственными и сроками
- Следующие шаги
4.2 Вводная встреча-знакомство с клиентом
Разделы:
- Дата, участники, тема встречи
- Верхнеуровневые цели клиента
- Параметры будущего проекта
- Бюджетные ограничения
- Ограничения по срокам
- Лица, принимающие решения (ЛПР)
- Бенефициары
- Лица, влияющие на принятие решения
- Договорённости и решения
- Открытые вопросы
- Следующие шаги
4.3 Внутренняя рабочая встреча
Разделы:
- Дата, участники, тема
- Обсуждённые вопросы
- Выявленные проблемы
- Принятые решения
- Открытые вопросы
- Задачи с ответственными и сроками
- Следующие шаги
4.4 Кастомный шаблон
Пользователь может создать свой шаблон с произвольными разделами и промптом через веб-интерфейс или бот.
5. Веб-интерфейс
Страницы
| Страница | Функционал |
|---|---|
| Записи | Список записей с фильтрами по источнику/дате, загрузка файлов, статус обработки |
| Протоколы | Просмотр, редактирование, экспорт (DOCX/PDF/MD), перегенерация с другим шаблоном |
| Шаблоны | Управление промптами, создание кастомных шаблонов, предпросмотр |
| Настройки | LLM провайдер/модель, API-ключи, retention period, очистка данных, профиль |
Навигация
Шапка: логотип, разделы (Записи, Протоколы, Шаблоны, Настройки), индикатор занятого дискового пространства ("Занято: N ГБ"), профиль пользователя.
Стек фронтенда
- React + TypeScript
- Vite (сборка)
- Tailwind CSS
- React Query (работа с API)
- React Router
6. Интеграция с мессенджерами
Сценарий работы
- Пользователь отправляет файл в бот
- Бот предлагает выбрать тип протокола (inline-кнопки)
- Бот показывает прогресс обработки
- Бот отправляет готовый протокол + кнопки: экспорт (DOCX/PDF/MD), перегенерация, открыть в вебе
Команды бота
Основные: /start (авторизация), /upload (или просто отправить файл), /list (записи), /protocols (протоколы)
Работа с протоколами: /view [id], /export [id] [формат], /regenerate [id], /templates
Настройки: /settings (шаблон по умолчанию), /help, /logout
Технические детали
- Telegram — aiogram 3.x, webhook mode через FastAPI, inline-кнопки
- Lensa — SDK/webhook интеграция с аналогичным интерфейсом
- MessengerService — общий слой абстракции, единая логика для обоих мессенджеров
- Лимит файлов — Telegram Bot API ограничивает 50 МБ; для больших файлов — ссылка на веб-загрузку
- Авторизация — привязка аккаунта мессенджера к учётной записи через
/start(логин/пароль)
7. Авторизация
- Базовая: логин/пароль, JWT-токены
- Роли: admin, user (расширяемо в будущем)
- Все авторизованные пользователи видят все протоколы
- Привязка аккаунтов мессенджеров к учётной записи
- Подготовлена структура для расширения ролевой модели (поле role — enum, легко расширить)
8. Управление хранилищем
- Retention policies — настраиваемый срок хранения для записей, транскрипций и экспортов (по умолчанию: 90 дней)
- Ручная очистка — админ может удалить старые данные из настроек (записи + связанные файлы)
- Автоочистка — Celery beat задача по расписанию удаляет данные старше retention period
- Индикатор — в шапке навигации отображается занятое место ("Занято: N ГБ")
- Стратегия хранения — SSD для активных данных (ОС, Docker, БД), HDD для архива (старые записи)
9. Деплой
Сервер
- Адрес: 78.153.7.224
- ОС: Windows (Docker Desktop установлен, PostgreSQL и другие сервисы уже развёрнуты)
- CPU: Intel i9-10900 (10 ядер, 2.8 GHz)
- RAM: 32 GB
- GPU: NVIDIA RTX 3070 Ti (8 GB VRAM)
- Хранилище: 1 TB SSD + 1 TB HDD
Docker Compose — контейнеры
| Контейнер | Назначение |
|---|---|
app |
FastAPI + Uvicorn, API + раздача SPA, port 8000 |
worker |
Celery worker с GPU доступом (Whisper + LLM вызовы) |
beat |
Celery beat — планировщик (автоочистка, scheduled tasks) |
redis |
Redis 7 — брокер задач + кэш |
db |
PostgreSQL 16 |
nginx |
Reverse proxy, static files, port 80/443 |
Распределение ресурсов
- GPU (8 GB VRAM) — faster-whisper large-v3 (~3 GB модель, остальное — буфер)
- RAM — ~4 GB PostgreSQL, ~2 GB Redis, ~4 GB FastAPI + workers, ~8 GB Whisper worker, остальное — ОС
- CPU — 10 ядер достаточно для параллельной работы API + воркеров
Портативность
Архитектура на Docker Compose полностью переносима: docker-compose.yml + .env → docker compose up -d на любом сервере. При отсутствии GPU на целевом сервере — переключение faster-whisper на CPU-режим через переменную окружения.
CI/CD
- Код — Gitea на http://78.153.7.224:3000
- Деплой —
docker compose up -d --build(ручной или через Gitea webhook) - Миграции —
alembic upgrade headпри старте контейнераapp
10. Технологический стек — сводка
| Слой | Технологии |
|---|---|
| Backend | Python 3.11+, FastAPI, Uvicorn, Celery, Redis, SQLAlchemy, Alembic, Pydantic v2 |
| AI/ML | faster-whisper large-v3, CUDA 12 + cuDNN, FFmpeg, LiteLLM |
| Frontend | React, TypeScript, Vite, Tailwind CSS, React Query, React Router |
| Мессенджеры | aiogram 3.x (Telegram), Lensa SDK/webhook |
| Экспорт | python-docx (DOCX), WeasyPrint (PDF), Jinja2 (шаблоны) |
| Инфра | Docker, Docker Compose, NVIDIA Container Toolkit, Nginx, Gitea, Alembic |