AAYMA
RU
Войти

QazMeeting AI

Локальный прототип автопротокола: транскрибирует MP3/WAV на русском, казахском и смешанном языке, извлекает поручения через локальную LLM с…

Прототип
Команда «Flame» 14💬 0 комментариевс 23 сентября 2026 г.

О проекте

Команда: Flame
Кейс HackAlem.ai: Инновации — Самрук-Казына
Стадия: Прототип

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

Суть

Локальный прототип автопротокола: транскрибирует MP3/WAV на русском, казахском и смешанном языке, извлекает поручения через локальную LLM с проверкой по исходным сегментам и экспортирует DOCX через Streamlit.

Как устроено

Аудио транскрибируется локально: faster-whisper на Windows/Linux, MLX Whisper на Apple Silicon, с таймкодами. Опциональная диаризация pyannote при сбое ставит speaker_id=UNKNOWN. MeetingProtocolAgent на Ollama (qwen2.5:3b-instruct) извлекает поручения, ответственных и сроки. Каждое поручение привязано к существующему segment_id, отрицания, отмены и уже выполненные действия отбрасываются, сроки нормализуются, дубли удаляются. Результат оформлен Pydantic-моделью MeetingResult, его можно отредактировать в Streamlit и выгрузить в DOCX.

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

  • faster-whisper
  • MLX Whisper
  • pyannote diarization
  • evidence grounding по segment_id
  • deadline normalization
  • negation/cancellation filtering
  • dedup

Метрики

Совещание №2: 44 сегмента за 44,54 с (Whisper small CPU/int8); строгая проверка агента с qwen3:1.7b: 0/5 ожидаемых поручений

Особенности

Команда честно описывает, что проверено, а что нет: сквозной путь MP3→DOCX не подтверждён, агент набрал 0/5 на совещании №2. Много регрессионных тестов на отрицания, отмены и конфликтующие сроки. Соблюдён строгий принцип «неподтверждённое поручение не выдаётся».

Стек

Python · Streamlit · Pydantic · Ollama · python-docx · pytest · PowerShell

Модели

Whisper small (faster-whisper / MLX) · Ollama qwen2.5:3b-instruct · qwen3:1.7b · pyannote speaker-diarization-community-1


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

README

README.md

QazMeeting AI

Прототип системы автопротоколирования совещаний для HackAlem AI (владелец кейса — Самрук-Қазына).

Статус для жюри. В этой ветке объединены локальный аудио/STT-модуль, общий контракт данных, агент протокола и материалы кейса. Локальное распознавание MP3/WAV с таймкодами проверено на настоящем Совещание №1.mp3. Полный сценарий с UI и экспортом DOCX ещё не проходил сквозную проверку; диаризация и качество поручений требуют ручной проверки.

Какую проблему решает проект

Протоколы совещаний часто составляют вручную. В длинной или смешанной русско-казахской речи можно пропустить поручение, перепутать исполнителя или срок и потерять доказательство того, где решение прозвучало. Для секретаря, руководителя и куратора поручений нужен проверяемый черновик протокола, а не непрозрачный ответ модели.

Целевой сценарий MVP

  1. Пользователь загружает MP3 или WAV.
  2. Локальный multilingual STT строит транскрипт на русском, казахском или в смешанной речи и сохраняет таймкоды.
  3. Диаризация пытается разделить реплики по говорящим.
  4. Локальный Meeting Protocol Agent извлекает поручения, ответственных и сроки, привязывая каждое поручение к исходной реплике.
  5. Пользователь проверяет сомнительные места и получает краткое саммари.
  6. UI команды экспортирует подтверждённый результат в DOCX/PDF.

Обязательные требования кейса: русский, казахский и смешанный язык, распознавание речи, диаризация, поручение с ответственным и сроком, управленческое саммари и экспортный протокол.

Что проверено сейчас

КомпонентФактический статус
MP3/WAV → текст с таймкодамиApple Silicon: MLX Whisper. Windows/Linux: faster-whisper. На Windows «Совещание №2.mp3» распознано моделью small на CPU/int8: 44 сегмента за 44,54 с (без времени загрузки модели).
Speaker diarizationЕсть локальный адаптер и безопасный fallback. В проверенном прогоне модель была недоступна, поэтому все сегменты получили speaker_id="UNKNOWN"; имена говорящих не угадываются.
Meeting Protocol AgentЛокальная реализация Ollama, evidence-проверка, нормализация сроков, отмены и дедупликация добавлены вместе с материалами кейса. Качество зависит от модели и требует ручной проверки.
Материалы кейсаВ case_materials/ добавлены описание кейса, эталонные протоколы, манифест и ожидаемые поручения. MP3 и полные транскрипты не коммитятся.
UI и DOCXОбъединены в main: Streamlit, ручное редактирование и экспорт DOCX. Полный путь MP3 → DOCX с настоящими моделями пока не подтверждён.

Отдельная строгая проверка агента на материалах совещания №2 с qwen3:1.7b дала 0/5 обязательных ожиданий: единственный кандидат был отброшен, потому что не подтвердился выбранным evidence. Это ограничение зафиксировано намеренно: неподтверждённое поручение не выдаётся за факт.

Приватность и API-ключи

Финальный путь обработки проектируется для закрытого контура: аудио и текст совещания обрабатываются локально и не отправляются во внешние AI API. Ключи OpenAI и NVIDIA не нужны для локального MVP и не должны попадать в Git.

Ссылка NVIDIA Brev предоставляет биллинг/GPU-кредиты, а не ключ inference. Для NVIDIA API Catalog нужен отдельный NVIDIA_API_KEY; в этой ветке нет непроверенного NVIDIA-STT backend.

В репозитории есть отдельный opt-in smoke test OpenAI. Он отправляет выбранный файл наружу только при явном флаге --allow-cloud-upload и предназначен для отдельной проверки, а не для закрытого контура. Ранее тестовый запрос получил HTTP 429, поэтому успешный облачный результат не заявляется.

Никогда не коммитьте:

  • OPENAI_API_KEY, NVIDIA_API_KEY, HF_TOKEN и любые другие токены;
  • реальные чувствительные аудиозаписи;
  • скачанные модели и полные транскрипты.

Если ключ уже публиковался в чате или логе, его следует немедленно отозвать и создать новый.

Архитектура

Audio MP3/WAV
      |
      v
Local Audio / STT (faster-whisper on Windows/Linux, MLX on Apple Silicon)
  - preprocessing
  - multilingual transcription
  - timestamps
      |
      v
Local diarization (pyannote, optional)
  - speaker segments
  - merge with transcript
      |
      v
MeetingProtocolAgent (Ollama, local)
  - speaker resolution
  - task extraction
  - deadline normalization
  - evidence validation
  - summary
      |
      v
MeetingResult (Pydantic)
      |
      +--> Streamlit UI
      +--> DOCX export

Если диаризация недоступна, транскрипция сохраняется, выдаётся предупреждение и используется speaker_id="UNKNOWN". UNKNOWN не означает установленную личность.

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

app/
├── agents/meeting_agent.py
├── models/schemas.py
├── services/audio.py
├── services/audio_cloud.py
└── config.py
case_materials/
├── expected/              # ожидаемые поручения без аудио
├── source/                # описание кейса и reference DOCX
└── manifest.json
scripts/
├── smoke_audio.py
├── smoke_audio_cloud.py
└── evaluate_agent.py
tests/
requirements.txt
requirements-audio.txt
requirements-agent.txt
README.md

Единый контракт данных

Все ветки используют модели из app/models/schemas.py; дубликаты схем не создаются и публичные поля не меняются.

# feature/audio
from app.services.audio import process_audio
segments = process_audio("/path/to/meeting.mp3")
# process_audio(audio_path: str) -> list[TranscriptSegment]

# feature/agent
from app.agents import MeetingProtocolAgent
result = MeetingProtocolAgent().run(transcript, meeting_date, title)

# feature/ui
build_docx(result: MeetingResult) -> bytes

Точная точка импорта аудио для UI и агента: app.services.audio.process_audio. Результат использует именно TranscriptSegment из app/models/schemas.py и содержит id, start, end, speaker_id и text. speaker_name и language заполняются только при достоверном источнике.

Установка

Нужен Python 3.11 (допускается 3.12).

git clone https://github.com/BAITC-Hacks/hack-4649b58f-flame.git
cd hack-4649b58f-flame
python3.11 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
pip install -r requirements-audio.txt

Первый запуск загрузит multilingual Whisper в локальный кэш: small для Windows/Linux, MLX small для Apple Silicon. Модель можно заменить через AUDIO_STT_MODEL. Без заранее известного языка не задавайте AUDIO_LANGUAGE: Whisper сам определит режим multilingual-распознавания.

Для локальной диаризации установите pip install -r requirements-diarization.txt. Нужна модель pyannote/speaker-diarization-community-1. Её условия принимаются в Hugging Face один раз; токен задаётся только через окружение HF_TOKEN или локальный путь AUDIO_DIARIZATION_MODEL. Если модель недоступна, срабатывает fallback UNKNOWN, а текст не теряется.

Streamlit UI и DOCX

Для запуска интерфейса под Windows:

python -m venv .venv
.venv\Scripts\python.exe -m pip install -r requirements-ui.txt -r requirements-audio.txt
.venv\Scripts\python.exe -m streamlit run streamlit_app.py

Для анализа транскрипта установите Ollama с официального сайта и в отдельном терминале запустите:

ollama pull qwen2.5:3b-instruct-q4_K_M
ollama serve

Если Ollama уже запущена приложением, второй serve не нужен. Рекомендуемые параметры для 16 GB RAM / RTX 3050 6 GB (задайте в терминале запуска UI):

$env:AUDIO_STT_BACKEND = "auto"
$env:AUDIO_STT_DEVICE = "cpu"
$env:AUDIO_STT_COMPUTE_TYPE = "int8"
$env:OLLAMA_NUM_CTX = "8192"
$env:OLLAMA_TIMEOUT_SECONDS = "180"
.venv\Scripts\python.exe -m streamlit run streamlit_app.py

После установки зависимостей можно запускать всё одной командой:

.\scripts\start_windows.ps1
# Для portable Ollama:
.\scripts\start_windows.ps1 -OllamaPath "C:\path\to\ollama.exe"

Скрипт проверяет локальную Ollama, при необходимости запускает её в фоне, скачивает выбранную модель и открывает Streamlit. Служебная папка .ollama создаётся Ollama в профиле пользователя; если доступ запрещён, запуск нужно выполнить из обычного пользовательского терминала. Никакие секреты скрипт не записывает в репозиторий.

Demo-режим использует явно помеченные синтетические данные. В локальном режиме UI вызывает app.services.audio.process_audio, затем MeetingProtocolAgent.run. Перед экспортом DOCX можно исправить имена говорящих, исполнителей и сроки.

На Windows выбран CPU/int8, чтобы не требовать ручной установки CUDA/cuDNN; NVIDIA остаётся доступна Ollama. При установленных CUDA-библиотеках можно явно выбрать AUDIO_STT_DEVICE=cuda и AUDIO_STT_COMPUTE_TYPE=float16. Запуск demo не является проверкой настоящих моделей. При недоступной диаризации сохраняется текст с UNKNOWN; при недоступной Ollama — транскрипт и предупреждение. .env.example — образец: параметры задаются через окружение, .env автоматически не загружается. Исходное аудио не отправляется во внешние AI API.

Smoke test аудио

Аудио должно находиться вне Git (например, в ~/Downloads).

python scripts/smoke_audio.py "/path/to/Совещание №1.mp3" \
  --limit 8 --output output/meeting_1_transcript.json

Скрипт печатает время обработки, количество сегментов, speaker id и несколько реплик с таймкодами. Каталог output/ игнорируется Git.

Локальный агент и материалы кейса

Агент обращается только к 127.0.0.1/localhost через Ollama и проверяет каждое поручение по существующему segment_id. Evidence и таймкоды берутся из исходных сегментов, а не придумываются моделью. Невалидные ответы, несуществующие сегменты и неподтверждённые задачи отбрасываются.

pip install -r requirements-agent.txt
ollama pull qwen2.5:3b-instruct-q4_K_M
ollama serve
export OLLAMA_MODEL=qwen2.5:3b-instruct-q4_K_M

python scripts/evaluate_agent.py \
  /path/to/meeting_2_transcript.json \
  case_materials/expected/meeting_2.json \
  --meeting-date 2026-09-23 \
  --title "Совещание №2" \
  --timeout 300

В case_materials/source/ находятся предоставленные описание кейса и эталонные DOCX. MP3 остаются во внешнем хранилище; JSON-транскрипты для локальной оценки создаются отдельно и не добавляются в Git.

Отдельный облачный smoke test (не часть MVP)

Команда ниже допустима только для аудио, передачу которого явно разрешили:

export OPENAI_API_KEY="<ключ из окружения, не из Git>"
python scripts/smoke_audio_cloud.py "/path/to/meeting.mp3" \
  --allow-cloud-upload --limit 8 --output output/cloud_transcript.json

Без --allow-cloud-upload аудио не отправляется. Публичный process_audio(...) и обычный локальный smoke test облачных вызовов не делают.

Проверка

python -m pytest -q

Тесты проверяют общий Pydantic-контракт, конфигурацию, аудио-обработку, облачный opt-in транспорт, evidence-валидацию агента, fallback и совместимость ответов Ollama/MLX. Unit-тесты не заменяют оценку качества STT, диаризации, агента или экспорта.

Ветки команды и ограничения

  • feature/audio — локальный STT, таймкоды и fallback диаризации;
  • feature/agent — локальный агент, извлечение и проверка поручений;
  • feature/ui — Streamlit и DOCX-интеграция;
  • main — общий контракт и интеграционная база.

Пока не реализованы production-интеграции с Teams/Zoom/Google Meet и СЭД, голосовая биометрическая идентификация и развёрнутая версия сервиса. До демонстрации полного MVP нужно отдельно прогнать русский, казахский и смешанный аудиоматериал по пути MP3 → транскрипт → говорящие → поручения → саммари → DOCX и провести ручную проверку результата.

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

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

Алимжан 45Interface 14Shaikh21bb 13Bekzhan Shaikhanzar Galymzhan 12

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

  • 2026-09-23 17:58Select mlx mock backend explicitly in audio testsBekzhan Shaikhanzar Galymzhan
  • 2026-09-23 17:56fix(agent): reassemble fragmented speech and reject noun-only assignmentsАлимжан
  • 2026-09-23 17:56Make audio backend tests platform-independentBekzhan Shaikhanzar Galymzhan
  • 2026-09-23 17:47fix(agent): stabilize local extraction and preserve speaker uncertaintyАлимжан
  • 2026-09-23 17:45Align Brev model setup with local agent defaultBekzhan Shaikhanzar Galymzhan
  • 2026-09-23 17:41Keep Brev audio dependencies lightweightBekzhan Shaikhanzar Galymzhan
  • 2026-09-23 16:37style(ui): adopt white and blue paletteInterface
  • 2026-09-23 17:34feat: prepare self-hosted Brev audio and meeting storageBekzhan Shaikhanzar Galymzhan
Все коммиты (84)
  • 2026-09-23 17:30fix: enable Windows transcription and improve protocol review UIАлимжан
  • 2026-09-23 16:30chore: remove second temporary push checkInterface
  • 2026-09-23 16:29chore: add second temporary push checkInterface
  • 2026-09-23 16:22chore: remove temporary push checkInterface
  • 2026-09-23 16:21chore: add temporary push checkInterface
  • 2026-09-23 16:19style(ui): switch to balanced monochrome paletteInterface
  • 2026-09-23 17:10Merge feature/ui into main and reconcile integration documentationАлимжан
  • 2026-09-23 16:08feat(ui): adopt warm dark Apple themeInterface
  • 2026-09-23 16:02feat(ui): add polished motion designInterface
  • 2026-09-23 17:02Merge feature/audio into mainАлимжан
  • 2026-09-23 16:52merge: integrate case materials and update project READMEBekzhan Shaikhanzar Galymzhan
  • 2026-09-23 16:45Merge pull request #2 from BAITC-Hacks/feature/agentShaikh21bb
  • 2026-09-23 16:42docs(audio): explain jury value and verified MVP limitsBekzhan Shaikhanzar Galymzhan
  • 2026-09-23 15:42feat(ui): polish Streamlit experienceInterface
  • 2026-09-23 16:36fix(agent): preserve valid tasks on malformed candidates and deadlinesАлимжан
  • 2026-09-23 16:34fix(audio): report cloud limits safely and export local transcriptBekzhan Shaikhanzar Galymzhan
  • 2026-09-23 16:24feat(audio): add opt-in OpenAI cloud smoke testBekzhan Shaikhanzar Galymzhan
  • 2026-09-23 16:20feat(agent): chunk long transcripts with evidence isolationAlimzhan
  • 2026-09-23 16:20fix(agent): bound Ollama output and generation sizeAlimzhan
  • 2026-09-23 16:20fix(agent): reject cloud model aliases and bound local payloadsAlimzhan
  • 2026-09-23 15:19fix(ui): preserve review state and surface pipeline warningsInterface
  • 2026-09-23 16:19fix(agent): retain assignee named in evidenceBekzhan Shaikhanzar Galymzhan
  • 2026-09-23 16:18feat(agent): add HackAlem case materials and local evaluationBekzhan Shaikhanzar Galymzhan
  • 2026-09-23 16:17fix(agent): scope cancellation and neighbor assignee evidenceAlimzhan
  • 2026-09-23 16:15fix(agent): validate inflected names and Kazakh clause scopeAlimzhan
  • 2026-09-23 16:15fix(agent): require exact source deadline expressionsAlimzhan
  • 2026-09-23 16:14fix(agent): handle Kazakh inflections and next-week ambiguityAlimzhan
  • 2026-09-23 16:13fix(agent): validate deadlines and enforce local Ollama transportАлимжан
  • 2026-09-23 16:07test(agent): reject bare Kazakh date mentionsAlimzhan
  • 2026-09-23 16:07fix(agent): avoid bare Kazakh duration false deadlinesAlimzhan
  • 2026-09-23 16:06test(agent): cover Kazakh assignment and deadline handlingAlimzhan
  • 2026-09-23 16:06feat(agent): validate Kazakh and mixed-language assignmentsAlimzhan
  • 2026-09-23 16:03fix(agent): cover retrospective verb inflectionsAlimzhan
  • 2026-09-23 16:03test(agent): reject discussion-only action mentionsAlimzhan
  • 2026-09-23 16:02fix(agent): require positive assignment evidenceAlimzhan
  • 2026-09-23 16:00test(agent): cover completed actions and negated fieldsAlimzhan
  • 2026-09-23 16:00fix(agent): reject negated identities, deadlines and completed actionsAlimzhan
  • 2026-09-23 14:58feat(ui): integrate audio and agent branchesInterface
  • 2026-09-23 15:57test(agent): cover mixed STT segments and repeated action semanticsAlimzhan
  • 2026-09-23 15:57fix(agent): scope negation and completion to the target taskAlimzhan
  • 2026-09-23 15:56test(agent): cover conflicting deadline revisionsAlimzhan
  • 2026-09-23 15:55fix(agent): avoid normalizing competing deadline revisionsAlimzhan
  • 2026-09-23 14:55Merge remote-tracking branch 'origin/feature/agent' into feature/uiInterface
  • 2026-09-23 14:55Merge remote-tracking branch 'origin/feature/audio' into feature/uiInterface
  • 2026-09-23 14:54feat(ui): add Streamlit review and DOCX exportInterface
  • 2026-09-23 15:53test(agent): add regression coverage for remaining validation bugsAlimzhan
  • 2026-09-23 15:52fix(agent): scope cancellation and self-assignment checksAlimzhan
  • 2026-09-23 15:51fix(agent): harden grounding, names, deadlines and cancellationAlimzhan
  • 2026-09-23 15:40chore: remove temporary agent workflowAlimzhan
  • 2026-09-23 15:27ci(agent): probe GitHub Actions runnerAlimzhan
  • 2026-09-23 15:26ci(agent): temporary Python 3.11 verificationAlimzhan
  • 2026-09-23 15:26test(agent): cover proxy isolation and nuanced action semanticsAlimzhan
  • 2026-09-23 15:25fix(agent): enforce proxy-free local transport and precise completion checksAlimzhan
  • 2026-09-23 15:23test(agent): cover completed facts cancellation and evidence-safe dedupAlimzhan
  • 2026-09-23 15:23fix(agent): handle completed facts cancellations and evidence-safe dedupAlimzhan
  • 2026-09-23 15:19test(agent): cover negation qualifiers and strict JSONAlimzhan
  • 2026-09-23 15:19fix(agent): reject negations and tighten dedup validationAlimzhan
  • 2026-09-23 15:14test(agent): cover hallucinations conflicts and safe fallbackAlimzhan
  • 2026-09-23 15:13fix(agent): harden grounding validation and deadline handlingAlimzhan
  • 2026-09-23 14:54docs(agent): record exact local model install commandsAlimzhan
  • 2026-09-23 14:52test(agent): cover extraction validation and fallbackAlimzhan
  • 2026-09-23 14:52chore(agent): document local-only dependency boundaryAlimzhan
  • 2026-09-23 14:52feat(agent): implement local meeting protocol extractionAlimzhan
  • 2026-09-23 14:45feat(audio): add local transcription and diarization fallbackBekzhan Shaikhanzar Galymzhan
  • 2026-09-23 14:22docs: align README with shared foundation and integration gatesShaikh21bb
  • 2026-09-23 14:21chore: add shared foundation tests/test_schemas.pyShaikh21bb
  • 2026-09-23 14:21chore: add shared foundation app/config.pyShaikh21bb
  • 2026-09-23 14:21chore: add shared foundation app/agents/meeting_agent.pyShaikh21bb
  • 2026-09-23 14:21chore: add shared foundation app/agents/__init__.pyShaikh21bb
  • 2026-09-23 14:21chore: add shared foundation app/models/schemas.pyShaikh21bb
  • 2026-09-23 14:21chore: add shared foundation app/models/__init__.pyShaikh21bb
  • 2026-09-23 14:21chore: add shared foundation app/__init__.pyShaikh21bb
  • 2026-09-23 14:21chore: add shared foundation requirements.txtShaikh21bb
  • 2026-09-23 14:21chore: add shared foundation .env.exampleShaikh21bb
  • 2026-09-23 14:21chore: establish shared meeting agent foundationShaikh21bb
  • 2026-09-23 14:19docs: define QazMeeting AI MVP and architectureShaikh21bb
Структура репозитория (44 файлов)
.env.example
.gitignore
.streamlit/config.toml
README.md
app/__init__.py
app/agents/__init__.py
app/agents/meeting_agent.py
app/config.py
app/demo.py
app/models/__init__.py
app/models/schemas.py
app/services/__init__.py
app/services/audio.py
app/services/audio_cloud.py
app/services/docx_builder.py
app/services/pipeline.py
app/ui_state.py
case_materials/README.md
case_materials/expected/meeting_1.json
case_materials/expected/meeting_2.json
case_materials/manifest.json
case_materials/source/HackAlem_AI_case.docx
case_materials/source/meeting_1_reference_protocol.docx
case_materials/source/meeting_2_reference_protocol.docx
pytest.ini
requirements-agent.txt
requirements-audio.txt
requirements-diarization.txt
requirements-ui.txt
requirements.txt
scripts/evaluate_agent.py
scripts/smoke_audio.py
scripts/smoke_audio_cloud.py
scripts/start_windows.ps1
streamlit_app.py
tests/test_agent_regressions.py
tests/test_audio.py
tests/test_audio_cloud.py
tests/test_docx_builder.py
tests/test_meeting_agent.py
tests/test_pipeline.py
tests/test_schemas.py
tests/test_streamlit_app.py
ui-open.txt
Ветки (5)

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

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

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