О проекте
Команда: 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.mdQazMeeting AI
Прототип системы автопротоколирования совещаний для HackAlem AI (владелец кейса — Самрук-Қазына).
Статус для жюри. В этой ветке объединены локальный аудио/STT-модуль, общий контракт данных, агент протокола и материалы кейса. Локальное распознавание MP3/WAV с таймкодами проверено на настоящем
Совещание №1.mp3. Полный сценарий с UI и экспортом DOCX ещё не проходил сквозную проверку; диаризация и качество поручений требуют ручной проверки.
Какую проблему решает проект
Протоколы совещаний часто составляют вручную. В длинной или смешанной русско-казахской речи можно пропустить поручение, перепутать исполнителя или срок и потерять доказательство того, где решение прозвучало. Для секретаря, руководителя и куратора поручений нужен проверяемый черновик протокола, а не непрозрачный ответ модели.
Целевой сценарий MVP
- Пользователь загружает MP3 или WAV.
- Локальный multilingual STT строит транскрипт на русском, казахском или в смешанной речи и сохраняет таймкоды.
- Диаризация пытается разделить реплики по говорящим.
- Локальный Meeting Protocol Agent извлекает поручения, ответственных и сроки, привязывая каждое поручение к исходной реплике.
- Пользователь проверяет сомнительные места и получает краткое саммари.
- 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 и провести ручную проверку результата.
Авторы коммитов
История коммитов
- 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
Обсуждение 0 комментариев
Войдите, чтобы комментироватьПока нет комментариев — будьте первым.