AAYMA
RU
Войти

AlemProtocol

Система протоколирования совещаний: загрузка аудио, асинхронная обработка, транскрипт с диаризацией, саммари, поручения с исполнителями и сроками…

Рабочий MVP
Команда «Exit 1» 11💬 0 комментариевс 23 сентября 2026 г.

О проекте

Команда: Exit 1
Кейс HackAlem.ai: Инновации — Самрук-Казына
Стадия: Рабочий MVP

Задача кейса: «Хаттама»: протокол и поручения по аудиозаписи совещания (каз./рус./смешанная речь)

Суть

Система протоколирования совещаний: загрузка аудио, асинхронная обработка, транскрипт с диаризацией, саммари, поручения с исполнителями и сроками, ручная правка, подтверждение и экспорт в DOCX.

Как устроено

Frontend на React и Vite загружает WAV, MP3 или M4A. FastAPI-бэкенд сохраняет файл и ставит задачу в очередь в PostgreSQL. Отдельный worker отправляет запись в AI-сервис в Docker, где работает цепочка faster-whisper → pyannote.audio → Qwen через Ollama. Поручения и сроки из естественного языка приводятся к датам. Каждое поручение связано с исходным фрагментом записи. Для разработки без GPU есть mock-режимы.

Ключевые решения

  • faster-whisper ASR
  • pyannote.audio diarization
  • очередь задач в PostgreSQL
  • нормализация дат из текста
  • сопоставление спикеров с участниками
  • mock-режимы

Особенности

Продуманная продакшн-архитектура: API и worker разделены, очередь в PostgreSQL, есть три режима AI (mock, http+mock, real) и инструкция, как разнести компоненты на два ноутбука. Весь код загружен тремя коммитами за 13 минут до конца.

Стек

React 19 · TypeScript · Vite · Python · FastAPI · PostgreSQL · Alembic · SQLAlchemy · Docker Compose · Ollama · Nginx

Модели

Whisper (faster-whisper) · pyannote.audio · Qwen via Ollama


Проект создан за 5 часов на финале хакатона HackAlem.ai (23 сентября 2026, Астана). Код — BAITC-Hacks/hack-bdffe61d-exit-1.

README

README.md

AlemProtocol

Локальная AI-система, которая превращает запись совещания в готовый протокол с транскриптом, кратким содержанием, поручениями, исполнителями и сроками.

React TypeScript FastAPI PostgreSQL Docker

AlemProtocol автоматизирует протоколирование русскоязычных, казахскоязычных и смешанных совещаний. Пользователь загружает аудиозапись, backend ставит её в очередь, AI-сервис локально распознаёт речь и формирует результат, после чего протокол можно проверить, отредактировать, подтвердить и скачать в DOCX.

Возможности

  • загрузка WAV, MP3 и M4A с названием, датой и списком участников;
  • асинхронная обработка записи отдельным worker-процессом;
  • распознавание речи через faster-whisper;
  • разделение реплик по спикерам через pyannote.audio;
  • саммари и извлечение поручений локальной моделью Qwen через Ollama;
  • определение исполнителей и преобразование сроков из естественного языка в даты;
  • переход от поручения к исходному фрагменту записи;
  • сопоставление спикеров с участниками и ручная правка поручений;
  • подтверждение протокола и экспорт в DOCX;
  • mock-режимы для разработки без GPU и ML-моделей;
  • полностью локальная AI-обработка без передачи аудио во внешние API.

Состав проекта

КомпонентКаталогНазначениеПорт по умолчанию
Frontendfrontend/React, TypeScript, Vite5173
Backend APIbackend/FastAPI, загрузка файлов, REST API8080
Backend workerbackend/Очередь и отправка записей в AIотдельный процесс
AI-сервисai-service/ASR, диаризация, LLM, PDF/DOCX8000
База данныхPostgreSQLвстречи, участники, задания и транскрипты5432

Архитектура

Браузер
   │
   ▼
Frontend (React/Vite или static hosting)
   │  /api/*
   ▼
Reverse proxy ───────────────► Backend API :8080
                                  │          │
                                  │          ├──► PostgreSQL
                                  │          └──► persistent audio storage
                                  ▼
                           очередь в PostgreSQL
                                  │
                                  ▼
                         Backend worker
                                  │  HTTP + audio
                                  ▼
                         AI service :8000
                                  │
                faster-whisper → pyannote → Qwen/Ollama

API быстро сохраняет файл и создаёт задачу. Worker независимо забирает задачи из PostgreSQL, отправляет записи в AI-сервис и сохраняет результат. Поэтому для полной обработки должны работать оба backend-процесса: API и worker.

Быстрый локальный запуск

Для запуска всей системы без ML-моделей используйте встроенный mock backend. Понадобятся:

  • Node.js 20.19+ или 22.12+ и npm;
  • Python 3.11 или 3.12;
  • PostgreSQL;
  • Git.

1. Клонирование

git clone https://github.com/BAITC-Hacks/hack-bdffe61d-exit-1.git
cd hack-bdffe61d-exit-1

2. PostgreSQL и backend

Создайте базу и пользователя PostgreSQL, затем подготовьте окружение:

cd backend
python -m venv .venv

# Linux/macOS
source .venv/bin/activate

# Windows PowerShell
.venv\Scripts\Activate.ps1

python -m pip install -r requirements.txt
cp .env.example .env  # Windows: Copy-Item .env.example .env

Для локальной проверки без отдельного AI-сервиса укажите в backend/.env:

DATABASE_URL=postgresql+psycopg://hackalem:[email protected]:5432/hackalem
STORAGE_DIR=C:/hackalem-data
MAX_UPLOAD_MB=200
AI_BASE_URL=http://127.0.0.1:8000
AI_MODE=mock
AI_INTERNAL_TOKEN=
AI_TIMEOUT_SECONDS=3600
FRONTEND_ORIGIN=http://localhost:5173

Создайте каталог из STORAGE_DIR, примените миграции и запустите API:

python -m alembic upgrade head
python -m uvicorn app.main:app --host 0.0.0.0 --port 8080

Во втором терминале, с тем же виртуальным окружением и из каталога backend, запустите worker:

python -m app.worker

Проверка backend:

3. Frontend

В третьем терминале:

cd frontend
npm ci
cp .env.example .env  # Windows: Copy-Item .env.example .env
npm run dev

Откройте http://localhost:5173. Frontend обращается к /api, а Vite перенаправляет запросы на BACKEND_URL=http://127.0.0.1:8080 и удаляет префикс /api.

Проверить прокси можно по адресу http://localhost:5173/api/ready.

Подключение реального AI

Сначала запустите AI-сервис в mock-режиме, чтобы проверить транспорт между компонентами, затем подготовьте модели и переключите его в real.

cd ai-service
cp .env.example .env  # Windows: Copy-Item .env.example .env
docker compose up --build -d

Проверка: http://localhost:8000/health.

В backend/.env задайте:

AI_MODE=http
AI_BASE_URL=http://127.0.0.1:8000
AI_INTERNAL_TOKEN=replace-with-a-long-random-token

В ai-service/.env должен быть тот же токен:

AI_MODE=real
INTERNAL_TOKEN=replace-with-a-long-random-token

После изменения .env перезапустите AI-сервис, backend API и worker. Подготовка Whisper, pyannote и Ollama, offline-режим и GPU-запуск описаны в ai-service/README.md.

Для запуска компонентов на разных компьютерах используйте CONNECT_TWO_LAPTOPS.md.

Режимы AI

Backend AI_MODEAI-сервис AI_MODEЧто происходит
mockлюбойBackend возвращает встроенный тестовый результат, HTTP-запроса нет
httpmockПолный HTTP-путь с тестовым ответом AI-сервиса
httprealНастоящее распознавание и анализ локальными моделями

Переменные окружения

Frontend

ПеременнаяПримерНазначение
VITE_USE_MOCKfalseИспользовать реальный backend или UI-заглушку
VITE_API_BASE_URL/apiПубличный путь к backend API
VITE_MAX_UPLOAD_MB200Ограничение файла в интерфейсе
BACKEND_URLhttp://127.0.0.1:8080Цель Vite proxy в dev/preview

VITE_* встраиваются во frontend во время сборки. BACKEND_URL нужен только Vite dev/preview и не используется статическими файлами после production build.

Backend

ПеременнаяПримерНазначение
DATABASE_URLpostgresql+psycopg://...Подключение к PostgreSQL
STORAGE_DIR/var/lib/alemprotocol/audioПостоянное хранилище аудио
MAX_UPLOAD_MB200Максимальный размер записи
AI_BASE_URLhttp://ai-host:8000Базовый URL AI-сервиса
AI_MODEhttpmock, http или совместимый alias real
AI_INTERNAL_TOKENсекретТокен для AI-сервиса
AI_TIMEOUT_SECONDS3600Таймаут долгой AI-обработки
FRONTEND_ORIGINhttps://alem.exampleРазрешённый browser origin для CORS

Полные шаблоны находятся в frontend/.env.example, backend/.env.example и ai-service/.env.example.

Production deployment

Рекомендуемая схема

  • Frontend: статическая сборка на Nginx, CDN, S3-compatible hosting, Netlify или Vercel;
  • Backend API + worker: Linux VM или PaaS с постоянными процессами;
  • PostgreSQL: managed database или отдельный сервер с резервным копированием;
  • Audio storage: persistent volume, доступный одновременно API и worker;
  • AI-сервис: отдельная GPU/CPU VM с Docker, локальными моделями и постоянными volumes;
  • Сеть: backend и AI соединяются по private network или VPN, а не через публичный порт.

Serverless-функции без фоновых процессов и постоянного диска для backend не подходят: worker должен непрерывно опрашивать очередь, а API и worker должны видеть одни и те же аудиофайлы.

1. Сборка frontend

Создайте frontend/.env.production:

VITE_USE_MOCK=false
VITE_API_BASE_URL=/api
VITE_MAX_UPLOAD_MB=200

Соберите приложение:

cd frontend
npm ci
npm run build

Публиковать нужно содержимое frontend/dist. Веб-сервер должен:

  1. отдавать index.html для неизвестных frontend-маршрутов, включая /meetings/:id;
  2. проксировать /api/* в backend с удалением префикса /api;
  3. разрешать запросы размером не меньше MAX_UPLOAD_MB;
  4. работать по HTTPS.

Пример Nginx:

server {
    listen 80;
    server_name alem.example;

    root /var/www/alemprotocol;
    index index.html;
    client_max_body_size 200m;

    location /api/ {
        proxy_pass http://127.0.0.1:8080/;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_read_timeout 3600s;
    }

    location / {
        try_files $uri $uri/ /index.html;
    }
}

TLS можно завершать на Nginx, load balancer или CDN. Если frontend и API размещены на разных доменах, задайте полный VITE_API_BASE_URL=https://api.example.com до сборки и укажите точный URL frontend в FRONTEND_ORIGIN backend.

2. Развёртывание backend

На сервере создайте виртуальное окружение, установите зависимости и сохраните production .env в backend/.env:

cd /opt/alemprotocol/backend
python3.12 -m venv .venv
.venv/bin/python -m pip install -r requirements.txt
.venv/bin/python -m alembic upgrade head

Запускайте два независимых долгоживущих процесса через systemd, Supervisor или возможности PaaS:

# Web process
.venv/bin/python -m uvicorn app.main:app --host 127.0.0.1 --port 8080

# Worker process
.venv/bin/python -m app.worker

Миграции выполняются один раз перед запуском новой версии. STORAGE_DIR должен находиться на постоянном диске; при разнесении API и worker по разным узлам потребуется shared storage.

3. Развёртывание AI-сервиса

AI лучше размещать на отдельном узле. Подготовьте модели по инструкции AI-сервиса, задайте AI_MODE=real, включите offline-флаги и запустите Compose:

cd /opt/alemprotocol/ai-service
docker compose -f docker-compose.yml -f docker-compose.gpu.yml up --build -d
curl http://127.0.0.1:8000/health

Для CPU уберите docker-compose.gpu.yml. Каталоги моделей и volume Ollama должны сохраняться между релизами. Порт 8000 разрешайте только backend-хосту. Порт Ollama 11434 не должен быть доступен из интернета.

4. Порядок релиза и healthchecks

  1. проверить доступность PostgreSQL и persistent storage;
  2. применить Alembic-миграции;
  3. запустить AI-сервис и проверить GET /health;
  4. запустить backend API и worker;
  5. проверить backend GET /health и GET /ready;
  6. опубликовать frontend и проверить GET /api/ready через reverse proxy;
  7. выполнить сквозной тест с тестовой записью.

Проверка проекта

Frontend

cd frontend
npm ci
npm run lint
npm run build
npm run smoke

npm run test:connected проверяет реальный путь frontend → backend → worker → AI mock, включая аудио после перезагрузки, редактирование, подтверждение и DOCX. Для него все сервисы должны быть запущены, backend должен использовать AI_MODE=http, а AI-сервис — AI_MODE=mock.

Backend

cd backend
python -m pip install -r requirements-dev.txt
python -m pytest -q tests
python scripts/smoke_e2e.py --audio "/path/to/meeting.wav"

AI-сервис

cd ai-service
python -m pip install -r requirements-dev.txt
pytest
ruff check app tests scripts

Структура репозитория

.
├── frontend/                  # React UI и browser-тесты
├── backend/
│   ├── app/api/               # REST endpoints
│   ├── app/models/            # SQLAlchemy models
│   ├── app/services/          # AI-клиент и DOCX export
│   ├── migrations/            # Alembic migrations
│   ├── scripts/               # backend E2E smoke-test
│   └── tests/                 # integration tests
├── ai-service/
│   ├── app/pipeline/          # ASR, diarization, LLM и сроки
│   ├── scripts/               # модели и test audio
│   └── tests/                 # unit и API-тесты
└── CONNECT_TWO_LAPTOPS.md     # запуск компонентов на разных устройствах

Безопасность и данные

  • не добавляйте .env, реальные записи, модели, базы и generated documents в Git;
  • используйте разные длинные случайные значения INTERNAL_TOKEN/AI_INTERNAL_TOKEN для каждого окружения;
  • не публикуйте AI-сервис и Ollama напрямую в интернете;
  • ограничьте доступ к PostgreSQL и storage на уровне сети и прав файловой системы;
  • включите HTTPS на публичной точке входа и регулярно создавайте backup PostgreSQL и audio storage;
  • для закрытого контура заранее скачайте модели и оставьте Hugging Face в offline-режиме.

Проект разработан командой Exit 1 для BAITC Hacks.

Звёзды
⭐ 0
Форки
0
Язык
Python
Последний push
в прошлом месяце
Коммиты
3
Авторы
1
Файлы
110
Ветки
1

Авторы коммитов

zalewko-droid 3

История коммитов

  • 2026-09-23 17:56feat: connect frontend and backendzalewko-droid
  • 2026-09-23 17:46docs: add comprehensive project READMEzalewko-droid
  • 2026-09-23 17:43Add frontend and AI servicezalewko-droid
Структура репозитория (110 файлов)
.gitignore
CONNECT_TWO_LAPTOPS.md
README.md
ai-service/.dockerignore
ai-service/.env.example
ai-service/.gitignore
ai-service/Dockerfile
ai-service/README.md
ai-service/app/__init__.py
ai-service/app/audio.py
ai-service/app/config.py
ai-service/app/errors.py
ai-service/app/exporters.py
ai-service/app/main.py
ai-service/app/pipeline/__init__.py
ai-service/app/pipeline/asr.py
ai-service/app/pipeline/dates.py
ai-service/app/pipeline/diarization.py
ai-service/app/pipeline/llm.py
ai-service/app/pipeline/memory.py
ai-service/app/pipeline/merge.py
ai-service/app/pipeline/mock.py
ai-service/app/pipeline/service.py
ai-service/app/pipeline/speakers.py
ai-service/app/schemas.py
ai-service/app/timing.py
ai-service/docker-compose.gpu.yml
ai-service/docker-compose.yml
ai-service/pyproject.toml
ai-service/requirements-dev.txt
ai-service/requirements-ml.txt
ai-service/requirements.txt
ai-service/samples/README.md
ai-service/scripts/download_models.py
ai-service/scripts/generate_e2e_sample.ps1
ai-service/scripts/generate_e2e_sample_espeak.sh
ai-service/scripts/generate_sample.py
ai-service/tests/test_api.py
ai-service/tests/test_dates.py
ai-service/tests/test_merge.py
ai-service/tests/test_pipeline.py
backend/.env.example
backend/alembic.ini
backend/app/__init__.py
backend/app/api/__init__.py
backend/app/api/meetings.py
backend/app/check_ai.py
backend/app/config.py
backend/app/db.py
backend/app/main.py
backend/app/models/__init__.py
backend/app/models/action_item.py
backend/app/models/base.py
backend/app/models/job.py
backend/app/models/meeting.py
backend/app/models/participant.py
backend/app/models/segment.py
backend/app/models/speaker.py
backend/app/schemas/__init__.py
backend/app/schemas/meeting.py
backend/app/schemas/meeting_actions.py
backend/app/services/__init__.py
backend/app/services/ai_processor.py
backend/app/services/docx_export.py
backend/app/services/remote_ai.py
backend/app/worker.py
backend/migrations/env.py
backend/migrations/script.py.mako
backend/migrations/versions/.gitkeep
backend/migrations/versions/343522380fa7_initial_domain_schema.py
backend/requirements-dev.txt
backend/requirements.txt
backend/scripts/smoke_e2e.py
backend/tests/conftest.py
backend/tests/test_ai_integration.py
env
frontend/.env.example
frontend/.gitignore
frontend/.oxlintrc.json
frontend/README.md
frontend/index.html
frontend/package-lock.json
frontend/package.json
frontend/public/favicon.svg
frontend/public/icons.svg
frontend/src/App.css
frontend/src/App.tsx
frontend/src/api/meetings.ts
frontend/src/assets/hero.png
frontend/src/assets/react.svg
frontend/src/assets/vite.svg
frontend/src/components/AudioPlayer.tsx
frontend/src/components/ProcessingStatus.tsx
frontend/src/components/Summary.tsx
frontend/src/components/TasksTable.tsx
frontend/src/components/Transcript.tsx
frontend/src/components/UploadForm.tsx
frontend/src/index.css
frontend/src/main.tsx
frontend/src/mocks/meeting.json
frontend/src/pages/HomePage.tsx
frontend/src/pages/MeetingPage.tsx
frontend/src/types/meeting.ts
frontend/src/utils/format.ts
frontend/tests/connected.mjs
frontend/tests/smoke.mjs
frontend/tsconfig.app.json
frontend/tsconfig.json
frontend/tsconfig.node.json
frontend/vite.config.ts

Обсуждение 0 комментариев

Войдите, чтобы комментировать

Пока нет комментариев — будьте первым.