AudioToText: управление требованиями через записи встреч. asr.. asr. audiototext.. asr. audiototext. diarization.. asr. audiototext. diarization. ner.. asr. audiototext. diarization. ner. nlp.. asr. audiototext. diarization. ner. nlp. nlp обработка текста.. asr. audiototext. diarization. ner. nlp. nlp обработка текста. speech recognition.

Ссылка на GitHub с кодом проекта в конце статьи

Транскрибация встреч и краткое summary сегодня уже не редкость: это умеют и корпоративные сервисы, и связка «транскрипт + LLM». Не хватает другого — материала, по которому можно сопоставлять позиции разных людей по одним и тем же сущностям и не терять историю принятых решений. Из этой задачи и вырос AudioToText: pet‑проект, который пытается превратить записи встреч в основу для управления требованиями на проекте, а не просто в ещё один текстовый артефакт.

В этой статье я хочу показать AudioToText не как набор ML‑экспериментов, а как продукт в его текущем состоянии: что он уже умеет, как выглядит пользовательский сценарий и в каких ситуациях такой инструмент действительно помогает. Техническую кухню, архитектурные компромиссы и путь к текущим решениям логичнее вынести в отдельную публикацию — здесь фокус именно на том, как проект работает «снаружи».

Зачем вообще нужен такой инструмент

Идея AudioToText родилась из практики внедрения проектов, преимущественно в сфере BI. На крупных внедрениях аналитики параллельно аудируют пользователей заказчика: разговаривают с разными должностными лицами, фиксируют требования, пытаются собрать целостную картину. На этом этапе часто всплывает одна и та же проблема — разные люди со стороны заказчика высказывают разнородные, а иногда и прямо противоречивые требования к одной и той же сущности. При большой команде такие расхождения не всегда удаётся своевременно отловить: они успевают превратиться в противоречивые ТЗ, составленные разными аналитиками и отданные на реализацию разным разработчикам.

Вторая сторона той же боли — потеря истории обсуждения. На встречах обсуждаются бизнес‑процессы, функциональные требования, архитектурные решения и другие важные аспекты. Запись формально всё сохраняет, но без удобного доступа команда снова и снова опирается на память и разрозненные заметки: кто‑то помнит одно, кто‑то — другое, а общая картина постепенно расползается.

Особенно сильно это проявляется уже после внедрения, когда проект переходит в поддержку силами интегратора, а на стороне заказчика так и не появляется человек, полностью погружённый в проект и его сопровождение. Через год или больше неизбежно всплывают вопросы вроде «а почему на проекте принято то или иное решение по обработке данных?» Ответ почти всегда лежит в ранних этапах — в сборе функциональных и бизнес‑требований. Наличие формальной документации от этого мало спасает: после закрытия чек‑листа приёмки к ней, как правило, уже никто не возвращается.

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

Что такое AudioToText

Страница со списком встреч

Страница со списком встреч

AudioToText — это pet‑проект для работы с записями встреч, в котором несколько технических слоёв собраны в один продукт: распознавание речи на базе MLX Whisper, диаризация спикеров, последующая NLP‑обработка, аннотация, сценарии проверки (review workflow), экспорт результатов и простой Django‑интерфейс для работы с материалом через веб.

Если смотреть на проект как на поток, логика такая: аудиозапись проходит через ML‑пайплайн и превращается в канонический JSON‑транскрипт, после чего попадает в веб‑интерфейс. Там материал можно просматривать, проверять, связывать спикеров с пользователями приложения и при необходимости выгружать. Поверх этого автоматически выделяются именованные сущности, а затем строится summary в разрезе meeting × speaker × entity — не общее «о чём был созвон», а компактная фиксация того, кто именно и что сказал по конкретной сущности. Если нужно, тот же материал можно использовать для ручной разметки и оценки качества NER.

Как выглядит сценарий работы

Детальная страница встречи

Детальная страница встречи

Сценарий работы в AudioToText изначально задумывался как максимально прямой. Пользователь запускает обработку записи встречи через веб‑интерфейс, система выполняет транскрибацию и диаризацию и формирует структурированный результат. Этот материал затем появляется в интерфейсе: его можно посмотреть на уровне списка встреч и детальной страницы, при необходимости связать спикеров с пользователями приложения (об этом подробнее будет ниже) и выгрузить результат наружу.

Но мне было важно, чтобы всё не заканчивалось на уровне «вот вам транскрипт». Поэтому следующим шагом поверх проверенного материала автоматически выполняется выделение именованных сущностей, а затем строится summary в разрезе meeting × speaker × entity — не общее резюме созвона, а компактная фиксация того, кто именно и что сказал по конкретной теме. При необходимости тот же материал можно использовать и для ручной разметки, чтобы дальше оценивать качество NER.

Summary по сущностям внутри встречи в разрезе спикеров

Summary по сущностям внутри встречи в разрезе спикеров

Иными словами, идея проекта здесь не в самом факте распознавания речи, а в том, чтобы превратить запись встречи в рабочий артефакт: вещь, пригодную для проверки, уточнения, сопоставления позиций разных участников и последующего анализа требований.

Схема workflow AudioToText

Схема workflow AudioToText

Что уже есть в проекте

Редактирование сущностей

Редактирование сущностей

Сейчас проект находится в фазе Django MVP review workflow. В качестве текущих опорных элементов в README перечислены: канонический JSON‑контракт для транскрипта, structured‑output схемы для NER, минимальная наблюдаемость через tracing, layout датасетов и веб‑MVP с ключевыми экранами для ревью встреч.

Если разложить это по понятным продуктовым функциям, уже сейчас есть:

  • транскрибация аудио и сохранение результата в структурированном формате;

  • поддержка speaker diarization как части пайплайна;

  • подготовка канонического представления транскрипта для повторно используемой обработки;

  • интерфейс для списка встреч и просмотра деталей встречи в Django;

  • сценарии speaker identification;

  • построение summary позиций в разрезе meeting × speaker × entity;

  • экспорт данных для следующих шагов пайплайна и для оценки NER;

  • заготовленная инфраструктура для NER‑экспериментов и gold‑аннотаций.

Отдельно отмечу, что в проекте уже есть и слой наблюдаемости. Даже в pet‑проекте это оказалось полезным: если в системе появляются несколько этапов преобразования данных и LLM/NER‑компоненты, без trace‑механики быстро становится трудно понимать, где именно сломался результат и почему.

Какие возможности выглядят особенно полезными

Идентификация спикера

Идентификация спикера

Для практического использования у проекта уже сейчас есть несколько сильных сторон.

Первая — связка транскрипции и диаризации. Для встреч мало получить просто текст; важно понимать, кто именно что сказал. Без этого запись быстро превращается в обезличенный массив реплик, который сложно использовать и для анализа, и для последующих действий.

Вторая — каноническая структура результата. А значит, над проектом проще надстраивать новые режимы обработки.

Третья — review workflow. Между «модель что‑то распознала» и «этим можно пользоваться» здесь сознательно существует отдельный слой ревью, правки и подтверждения. Для рабочих встреч это критично: даже хороший ASR‑результат почти всегда требует человеческого взгляда, особенно если дальше из него должны рождаться заметки и сущности.

Четвёртая — локальный запуск без опоры на облачные GPU и внешние SaaS для базового контура. Проект изначально собирался так, чтобы его можно было крутить на машине разработчика с относительно скромными по меркам ML‑стека ресурсами. Весь основной контур — MLX Whisper, базовый пайплайн и эксперименты — рассчитан на Apple Silicon, что позволяет держать чувствительные записи встреч локально, а не отдавать их во внешние сервисы.

Что относится к дополнительным возможностям

Управление очередью именованных сущностей на редактирование/подтверждение

Управление очередью именованных сущностей на редактирование/подтверждение

Помимо основного сценария, в проекте уже есть дополнительные направления, которые не обязательны для каждого пользователя, но заметно повышают ценность системы для исследовательского и инженерного использования.

Одно из таких направлений — «золотые» аннотации для NER. В AudioToText предусмотрена ручная разметка сущностей, и сама разметка строится не по отдельным фрагментам, а по смысловым блокам: несколько последовательных реплик одного спикера объединяются в единый отрезок, с которым удобно работать человеку. Это пример того, как продуктовый UX и подготовка данных для ML начинают работать вместе: материал одновременно остаётся удобным для чтения и даёт основу для последующей оценки качества извлечения сущностей.

Что сознательно отложено

Важно не только то, что в проекте уже есть, но и то, чего в нём пока нет. Отдельно зафиксирован набор вещей, которые сейчас сознательно остаются за рамками: REST API, Celery или другие async‑workers, pgvector и внешние интеграции.

Такой список помогает держать рамку: не пытаться построить сразу всё, а сначала довести до осмысленного состояния базовый сценарий работы с транскриптом и ревью. PostgreSQL и векторный слой — это уже следующая фаза развития проекта. В этой фазе pgvector планируется использовать для хранения эмбеддингов по summary и семантического сравнения таких резюме между собой.

Идея проста: summary в разрезе meeting × speaker × entity превращаются в вектора, которые отражают их смысловое содержание. Дальше можно оценивать косинусное расстояние между такими векторами и программно находить случаи, где разные люди говорят про одну и ту же сущность, но их позиции плохо совпадают. Именно вокруг такого сценария — поиска противоречий по summary внутри одной категории и по одной и той же сущности — и будет строиться следующая ступень развития AudioToText: от фиксации позиций в текстовом виде к полуавтоматическому обнаружению конфликтов требований.

В этой статье я сфокусировался на том, как AudioToText выглядит снаружи — как продукт и как рабочий сценарий. В отдельной публикации уже хочу разобрать инженерную сторону: эволюцию пайплайна, канонический JSON‑контракт, trace‑слой, NER‑эксперименты и следующий этап с PostgreSQL и векторным поиском. Отдельный важный кусок этой инженерной части — модель пользователей и ролей, о ней тоже стоит сказать пару слов уже сейчас.

Пользователи, участники проекта и спикеры

Ещё один слой, который почти не виден в простом сценарии «загрузил запись → получил summary», но без которого проект теряет смысл именно как инструмент для работы с требованиями, — это разделение двух пользовательских сущностей: user и project‑member.

User — это аккаунт в приложении: человек, который может войти в систему, открыть встречи, пройтись по ревью, связать спикеров или выгрузить результат. Project‑member (участник проекта) — это человек в контексте конкретного проекта: аналитик, менеджер, стейкхолдер со стороны заказчика и т.д. У участника проекта может быть связанный аккаунт, а может и не быть: на встрече часто звучат люди, которым не нужен полный доступ в систему, но чьи позиции всё равно важно фиксировать.

К этой паре добавляется третий слой — спикеры. После диаризации в записи появляются локальные кластеры вроде Speaker_1 / Speaker_2. Сами по себе они ещё не люди: это просто «кто‑то говорил в этой встрече». Имеет смысл связать такой кластер с участником проекта, а через него — с пользователем приложения, если аккаунт есть. Тогда реплика перестаёт быть анонимным фрагментом транскрипта и становится позицией конкретного человека в конкретном проекте. Если говорящий внешний и без учётки, остаётся голосовой профиль спикера без обязательной привязки к user — и это тоже штатный сценарий, а не «дырка» в модели.

Поверх этого у AudioToText сразу закладывалась ролевая модель с несколькими типами доступа:

  • viewer — внешний участник со стороны заказчика; видит только те встречи, в которых сам участвует, без права правки.

  • viewer_full — широкий read‑only доступ ко всем встречам проекта, но без возможности менять результат.

  • project_manager — ведёт проект целиком: видит всё и управляет основными процессами.

  • analyst — работает с материалом встреч в рамках своих прав на просмотр и правку.

На уровне этой статьи я сознательно не углубляюсь в детали реализации — связи вида meeting_speaker → project_membership → user, инварианты идентификации и разрезание прав на уровне queryset — это уже материал следующей, технической публикации, где будет разбор архитектуры и внутренних решений проекта.

AudioToText GitHub

Автор: ivaneremenko

Источник