Между разговором и задачей оставалось слишком много ручной работы
Мой рабочий день во многом состоит из разговоров: с самим собой, ИИ-агентом и клиентом на созвоне. Почти всё сказанное потом превращается в текст и задачи. Наговорить мысль получается в разы быстрее, чем набрать её на клавиатуре. А после часового созвона ещё нужно переслушать запись и вытащить из неё договорённости.
Готовые сервисы это вроде бы решают, но каждый живёт в своём облаке: задачи в одном, расшифровка речи в другом, учёт времени в третьем, и твои данные лежат на чужих серверах, а не рядом с кодом. Мне хотелось наоборот: чтобы инструмент был встроен в редактор, где я и так весь день, а данные оставались моими. Так появилась Sonara.
Запись митинга проходит путь до канбан-доски
Sonara собрана вокруг одного рабочего цикла. Наговорил задачу или добавил запись митинга - расширение расшифровывает её локально. Текст отдаёшь ИИ-агенту: он сжимает двухчасовой разговор в три абзаца договорённостей и предлагает список задач. После сверки с клиентом задачи переходят в канбан-доску, где по ним уже ведётся работа.
Ключевой выигрыш - в самом верхнем звене: больше не нужно переслушивать длинную запись. Митинг укладывается в несколько абзацев решения, клиент ставит палец вверх, и можно идти делать.
Данные остаются обычными файлами рядом с кодом
Sonara не требует аккаунта, не отправляет данные в облако и не собирает телеметрию. Всё, что она хранит, лежит внутри проекта в папке .vscode/sonara/ и перемещается вместе с кодом. Что добавить в общий репозиторий, а что оставить только у себя, решает сам пользователь.
| Что | Где лежит | Формат |
|---|---|---|
| Задачи | tasks/ |
markdown, по файлу на задачу |
| История диктовок | voice-log/ |
построчный JSON |
| Расшифровки записей | voice-transcripts/ |
markdown |
| Учёт времени | time-tracker/ |
JSON по дням |
| Словарь терминов | vocabulary.md |
markdown |
Ничего проприетарного: задачу можно открыть и отредактировать обычным текстовым редактором, расшифровку - прочитать без всякого приложения. И всё это работает офлайн: интернет нужен ровно один раз - при первом запуске, чтобы скачать локальную модель распознавания речи.
Четыре рабочих поверхности помещаются в одном редакторе
Внутри одного расширения - четыре рабочие поверхности, и каждая заточена под свою часть цикла.
Тяжёлая модель просыпается только по запросу
Локальная модель распознавания речи занимает несколько гигабайт памяти. Если держать её включённой постоянно, она забирает ресурсы у редактора и остальных инструментов. Поэтому Sonara управляет её жизненным циклом сама, не перекладывая контроль памяти на пользователя.
- Ленивый старт. Движок распознавания не запущен, пока ты не начнёшь первую диктовку. Не диктуешь - память свободна.
- Переключатель в статус-баре. Одним кликом можно выключить движок, и модель тут же выгружается из памяти; при следующей записи Sonara спросит, включить ли обратно.
- Само-выгрузка по простою. Пока движок включён, но им не пользуются несколько минут, он сам выключается и освобождает память, а на следующей диктовке поднимается заново.
- Восстановление после нехватки памяти. Если посреди расшифровки на видеокарте кончается память, Sonara не падает молча, а предлагает повторить на процессоре или на модели поменьше - и потом возвращает твою обычную.
Эта логика появилась из реальных сбоев, на которые я натыкался сам. Инструмент должен переживать нехватку памяти на видеокарте и освобождать ресурсы, когда голос сейчас не используется.
Одно ограничение от платформы, другое от технологии
Часть возможностей пришлось ограничить, и причины у них разные.
Запись голоса пока работает только на Linux - звук берётся через системный звуковой слой (PulseAudio/PipeWire). Задачи и учёт времени работают везде, а на macOS и Windows голосовые команды прямо сообщают, что запись недоступна, вместо тихого сбоя.
Была и ветка, которая не поддалась. Я пробовал синхронный перевод: говоришь на своём языке, слышишь английский, в реальном времени. И упёрся в естественное ограничение. Настоящий синхрон требует предугадывать, что ты собираешься сказать через секунду, а распознавание речи так не умеет: оно работает по уже произнесённому.
Поэтому перевод получался не синхронным, а "договори до конца, потом всё разом". Перебить его на полуслове было нельзя, он договаривал переведённый кусок и только потом слушал дальше. Вывод для меня оказался ценнее самой фичи: живой перевод строится не на одном распознавании речи, а на модели, которая держит контекст и предвосхищает продолжение. Эту ветку я отложил.
Открытый проект показывает решения целиком
Sonara я сделал для себя из интереса собрать весь цикл своими руками. Другие мои внутренние инструменты связаны с вещами, которые я не хочу открывать, а этот получился отдельным и самодостаточным. Поэтому код опубликован под свободной лицензией: кому подходит такой процесс, может собрать расширение у себя и пользоваться.
Кода тут немного, и половина ценности не в нём, а в решениях: держать данные у пользователя, а не в чужом облаке; не дать тяжёлой модели молча съесть память; спроектировать инструмент вокруг того, как реально идёт работа, а не вокруг списка возможностей. Ровно это суждение я приношу и в клиентские проекты - просто там оно спрятано за NDA, а здесь его видно целиком, вплоть до кода.
Sonara открыта под лицензией MIT и лежит на GitHub: github.com/ArtisanWebLab/sonara. Это пока сборка для себя, но база под ней крепкая - есть на чём развивать дальше.
Хороший инструмент знает меру: делает своё дело и тихо уходит с дороги, не прося ни аккаунта, ни лишней памяти, ни твоего внимания.
Это наш проект, поэтому показываем его внутреннее устройство без оговорок - вплоть до архитектуры и кода.

