CLI-скрипт для генерации структурированного протокола совещания из текстового транскрипта по технике Schema-Guided Reasoning (один вызов LLM с заполнением схемы).
Протокол включает:
- Цели встречи
- Установленные факты
- Имеющиеся проблемы
- Ключевые решения (структурированная таблица с контекстом, вариантами, обоснованием и последствиями)
- Поручения (таблица с ответственными и сроками)
- Вопросы и ответы
- Открытые вопросы
🔥 Хорошо работает даже с локальными 4B-моделями!
- Python 3.12 или выше
- Установленный uv (запуск и управление зависимостями в Python-проектах)
Зависимости (устанавливаются автоматически через uv):
openai>=1.101.0— для работы с OpenAI-совместимыми APIpython-dotenv>=1.0.0— для загрузки переменных окружения из.env
Создайте файл .env в корне проекта на основе .env.example и задайте параметры провайдеров LLM, которых планируете использовать.
Достаточно настроить одного из провайдеров (локальный или облачный). Указывайте совместимый с OpenAI API endpoint и ключ, модель — идентификатор модели.
# Локальный провайдер
API_BASE_LOCAL=
API_KEY_LOCAL=
MODEL_LOCAL=
# Облачный провайдер
API_BASE_CLOUD=
API_KEY_CLOUD=
MODEL_CLOUD=Базовый сценарий (по умолчанию - локальный провайдер):
uv run main.py path\to\transcript.txtИспользовать облачного провайдера:
uv run main.py path\to\transcript.txt --onlineПереопределить модель для текущего провайдера (по умолчанию - модель, указанная в .env):
uv run main.py path\to\transcript.txt -m model-id- Для локального распознавания рекомендуется использовать модель
qwen/qwen3-4b-2507(Да, очень маленькая. Да, результаты лучше, чем у больших.) - Для облачного распознавания рекомендуется использовать модель
google/gemini-2.5-pro
Задать температуру семплирования (по умолчанию 0.15):
uv run main.py path\to\transcript.txt -t 0.2Добавить подробности (имя модели и время генерации) в имя выходного файла:
uv run main.py path\to\transcript.txt --detailsИспользовать исходное имя транскрипта вместо даты в качестве префикса:
uv run main.py path\to\transcript.txt --keep_base_nameСистема поддерживает использование глоссария для коррекции некорректных написаний терминов, которые могут возникнуть при распознавании речи (например, "GVT" вместо "JWT", "кавка" вместо "Kafka"). Глоссарий работает в два этапа:
- Промт-инструкции: LLM получает явные правила использования канонических терминов вместо их ошибочных вариантов
- Автоматическая постобработка (по умолчанию включена): удаляет случаи, когда LLM добавляет некорректный вариант в скобках после правильного термина (например,
JWT (GVT)→JWT)
Создайте файл glossary.yaml в корне проекта со следующей структурой (на основе примера glossary.yaml.example):
- canonical: JWT
variants:
- GVT
- гвт
description: JSON Web Token — стандарт токенов для аутентификации
- canonical: Kafka
variants:
- кавка
- кафка
- Кавка
description: Брокер сообщений Apache KafkaКаждая запись содержит:
canonical(обязательно) — правильное написание терминаvariants(обязательно) — список некорректных/альтернативных вариантов написанияdescription(опционально) — краткое описание термина для дополнительного контекста LLM
Базовый глоссарий загружается автоматически, если файл glossary.yaml существует в корне проекта.
Для проектно-специфичных терминов можно указать дополнительный глоссарий через параметр --extra-glossary:
uv run main.py path\to\transcript.txt --extra-glossary client_glossary.yamlПри конфликте (одинаковый вариант указывает на разные канонические термины) приоритет имеет дополнительный глоссарий, конфликт логируется.
По умолчанию глоссарий работает в два этапа:
- Удаление скобочных дублей типа
JWT (GVT)→JWT - Принудительная замена всех отдельных слов, совпадающих с вариантами из глоссария (без учёта регистра), на канонические термины
Примеры замен на втором этапе:
GVT→JWTкавка→KafkaКавка→Kafka
Чтобы отключить принудительную замену и оставить только удаление скобочных дублей:
uv run main.py path\to\transcript.txt --no-force-replaceВнимание: принудительная замена может заменить варианты даже в контекстах, где это нежелательно (например, в прямых цитатах или именах файлов). Если это происходит, используйте флаг --no-force-replace.
Если нужно оставить текст в том виде, как его вернула LLM (без удаления некорректных вариантов в скобках после канонических терминов):
uv run main.py path\to\transcript.txt --no-glossary-cleanupМожно комбинировать флаги:
# Только принудительная замена, без очистки скобок
uv run main.py path\to\transcript.txt --no-glossary-cleanup
# Только очистка скобок, без принудительной замены
uv run main.py path\to\transcript.txt --no-force-replace
# Отключить всю постобработку глоссария
uv run main.py path\to\transcript.txt --no-glossary-cleanup --no-force-replace- Низкая (0.0–0.25): более детерминированный и фактологичный вывод. Рекомендуется для протоколов.
- Средняя (0.25–0.4): немного больше вариативности формулировок.
- Высокая (0.5+): креативнее, но выше риск отклонений от исходного текста — обычно не нужно для протоколов.
По умолчанию используется 0.15.
Итоговый протокол сохраняется рядом с исходным файлом транскрипта. Формат имени зависит от использованных параметров:
- По умолчанию:
<YYYY-MM-DD>-<тема_встречи>.md - С флагом --keep_base_name:
<basename>-<тема_встречи>.md - С флагом --details: к имени файла добавляется
-<model>[<время>s]
Примеры:
2024-11-07-Обсуждение-архитектуры.md(по умолчанию)meeting_transcript-Обсуждение-архитектуры.md(с --keep_base_name)2024-11-07-Обсуждение-архитектуры-qwen3-4b-2507[45s].md(с --details)
Протокол формируется в формате Markdown и включает следующие разделы:
- Цели встречи — нумерованный список целей и задач совещания
- Установленные факты — ключевые факты, подтверждённые на встрече
- Имеющиеся проблемы — выявленные проблемы и вопросы
- Ключевые решения — структурированная таблица с полями:
- Контекст — ситуация, приведшая к вопросу
- Вопрос — суть обсуждаемого вопроса
- Рассмотренные варианты — список вариантов решения
- Решение — финальное решение
- Статус — Предложено / Принято / Отложено / Отклонено
- Последствия — список последствий с префиксами (+) для позитивных и (-) для негативных
- Обоснование — объяснение выбора
- Поручения — таблица поручений с ответственными и сроками выполнения
- Вопросы и ответы — таблица вопросов и ответов из обсуждения
- Открытые вопросы — нерешённые вопросы без конкретных решений
Скрипт автоматически сохраняет логи в директорию logs/meeting_summary.log с ротацией по дням (хранятся последние 30 дней). В логах отображается информация о загрузке глоссариев, конфликтах терминов и применении постобработки.