Skip to content

Meeting summary from meeting transcript using LLM via OpenAI-like completion API

Notifications You must be signed in to change notification settings

dimonier/meeting_summary

Repository files navigation

Протокол встречи из транскрипта встречи (SGR)

CLI-скрипт для генерации структурированного протокола совещания из текстового транскрипта по технике Schema-Guided Reasoning (один вызов LLM с заполнением схемы).

Протокол включает:

  • Цели встречи
  • Установленные факты
  • Имеющиеся проблемы
  • Ключевые решения (структурированная таблица с контекстом, вариантами, обоснованием и последствиями)
  • Поручения (таблица с ответственными и сроками)
  • Вопросы и ответы
  • Открытые вопросы

🔥 Хорошо работает даже с локальными 4B-моделями!

Требования

  • Python 3.12 или выше
  • Установленный uv (запуск и управление зависимостями в Python-проектах)

Зависимости (устанавливаются автоматически через uv):

  • openai>=1.101.0 — для работы с OpenAI-совместимыми API
  • python-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"). Глоссарий работает в два этапа:

  1. Промт-инструкции: LLM получает явные правила использования канонических терминов вместо их ошибочных вариантов
  2. Автоматическая постобработка (по умолчанию включена): удаляет случаи, когда 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

При конфликте (одинаковый вариант указывает на разные канонические термины) приоритет имеет дополнительный глоссарий, конфликт логируется.

Принудительная замена всех вхождений некорректных вариантов

По умолчанию глоссарий работает в два этапа:

  1. Удаление скобочных дублей типа JWT (GVT)JWT
  2. Принудительная замена всех отдельных слов, совпадающих с вариантами из глоссария (без учёта регистра), на канонические термины

Примеры замен на втором этапе:

  • GVTJWT
  • кавка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 и включает следующие разделы:

  1. Цели встречи — нумерованный список целей и задач совещания
  2. Установленные факты — ключевые факты, подтверждённые на встрече
  3. Имеющиеся проблемы — выявленные проблемы и вопросы
  4. Ключевые решения — структурированная таблица с полями:
    • Контекст — ситуация, приведшая к вопросу
    • Вопрос — суть обсуждаемого вопроса
    • Рассмотренные варианты — список вариантов решения
    • Решение — финальное решение
    • Статус — Предложено / Принято / Отложено / Отклонено
    • Последствия — список последствий с префиксами (+) для позитивных и (-) для негативных
    • Обоснование — объяснение выбора
  5. Поручения — таблица поручений с ответственными и сроками выполнения
  6. Вопросы и ответы — таблица вопросов и ответов из обсуждения
  7. Открытые вопросы — нерешённые вопросы без конкретных решений

Логирование

Скрипт автоматически сохраняет логи в директорию logs/meeting_summary.log с ротацией по дням (хранятся последние 30 дней). В логах отображается информация о загрузке глоссариев, конфликтах терминов и применении постобработки.

About

Meeting summary from meeting transcript using LLM via OpenAI-like completion API

Topics

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages