Знаете это чувство, когда после вебинара методист садится и три часа расписывает, ведущий открывал слайды вовремя и отвечал ли на вопросы? А если вебинаров десять в день? А если сто? Руками это не масштабируется. Никак. Я перепробовал кучу решений — от тупых чек-листов до попыток нанять армию фрилансеров. В итоге собрал конвейер, который за неделю превращает сырое видео в структурированный отчёт. Под капотом — локальный whisper.cpp, кастомный LLM-судья на Claude и YAML-рубрика, которую может править любой методист без единой строчки кода. Рассказываю, как это работает и где я наступил на грабли.
Почему руками — это путь в никуда
Методисты — дорогие и редкие. Они смотрят 10-минутные отрезки, ставят оценки по шкале «понятно/непонятно». Субъективно, медленно, дорого. Когда вебинаров становится много, качество оценки падает квадратично от усталости эксперта. Вторая проблема — воспроизводимость. Один и тот же вебинар два методиста оценят по-разному, а потом спорят, чья оценка правильная.
Идея: пусть машина делает черновик оценки по тем же критериям, что и человек, а методист только корректирует 20% случаев. Экономия — 80% времени.
Я не первый, кто пытается прикрутить LLM к оценке. В статье LLM как судья: сравнительный тест GPT-5.2, Claude 4.6 и Gemini 3.1 ребята тестировали модели на юридических текстах — там точность доходила до 91%. Но вебинар — это не сухой документ. Тут интонации, паузы, скорость речи. Поэтому голый LLM без контекста не справится. Нужен пайплайн.
Архитектура конвейера: три кита и одна утка
Вот как выглядит конечная цепочка:
- Захват видео — скачивание записи вебинара (MP4, поток).
- Аудиодорожка — извлечение звука через FFmpeg.
- Транскрипция —
whisper.cppс моделью large-v3-turbo (на июнь 2026 это самый быстрый вариант для русского языка с приемлемым качеством). - Диаризация — разделение реплик по спикерам (опционально, но для оценки взаимодействия ведущий-аудитория — мастхэв).
- Промпт-инжекция — склейка транскрипта с рубрикой YAML.
- LLM-судья — Claude 4.6 (через API или локально через Claude Code как агент, но мы используем API для скорости).
- Калибровка — сравнение с эталонными оценками эксперта и подстройка весов рубрики.
- Формирование отчёта — JSON с баллами, комментариями, рекомендациями.
Весь конвейер я написал за неделю, используя Claude Code как pair programmer. Он генерировал скелеты скриптов, while я правил логику. Да, MiniMax Agent IDE сжёг 10k кредитов за 3 часа, а Claude Code работал предсказуемо — потратил $12 за всё время разработки.
Шаг 1. Транскрипция: почему whisper.cpp, а не облако
Облачные транскрибайзеры типа Google Speech-to-Text стоят денег и передают аудио наружу. Для вебинаров с коммерческой информацией — риск. Whisper.cpp работает локально, на CPU или GPU, без интернета. Я гонял на сервере с двумя A100 — 40 минут вебинара транскрибируются за 6 минут с моделью large-v3-turbo.
⚠️ Грабли №1: не забудьте выставить --language ru и --print-progress. Без флага языка whisper путает русские слова с английскими, если ведущий вставляет термины.
# Компиляция whisper.cpp (убедитесь, что используете последний коммит от июня 2026)
git clone https://github.com/ggerganov/whisper.cpp
cd whisper.cpp
make -j
# Скачивание модели (large-v3-turbo даёт лучшее соотношение скорость/качество)
bash ./models/download-ggml-model.sh large-v3-turbo
# Транскрипция одного файла
./main -m models/ggml-large-v3-turbo.bin \
-f webinar_2026-06-15.mp3 \
--language ru \
--print-progress \
-otxt -of webinar_transcript.txt
Результат — обычный текст с временными метками. Но для оценки нужны ещё реплики разных спикеров. Тут в дело вступает диаризация.
Шаг 2. Рубрика YAML: методистский рай
Главный секрет — вынести критерии оценки в YAML-файл, который может редактировать любой методист. Никакого хардкода в коде. Пример рубрики для вебинара по продукту:
rubric:
- id: intro
name: "Вступление"
weight: 10
criteria:
- "Есть ли приветствие и представление спикера?"
- "Объявлена ли тема и цель вебинара?"
- "Затрагивается ли проблема аудитории?"
scoring: "1-5 баллов за каждый пункт, итого среднее * weight"
- id: content
name: "Содержание"
weight: 40
criteria:
- "Логическая структура: введение-основная часть-ответы"
- "Наличие примеров и кейсов"
- "Отсутствие воды (повторов, отступлений)"
- "Использование визуальных материалов (слайды, демо)"
- id: interaction
name: "Взаимодействие"
weight: 20
criteria:
- "Частота вопросов к аудитории"
- "Реакция на чат (ответы на вопросы в реальном времени)"
- "Опросы или голосования"
- id: closure
name: "Завершение"
weight: 15
criteria:
- "Резюме ключевых выводов"
- "Призыв к действию (CTA)"
- "Обратная связь (ссылка на форму, контакты)"
- id: speech
name: "Качество речи"
weight: 15
criteria:
- "Темп: не слишком быстрый, не затянутый"
- "Отсутствие слов-паразитов (в среднем не более 3 на минуту)"
- "Интонационное выделение важных моментов"
Методист может менять веса, добавлять критерии — и пайплайн подхватит изменения без редеплоя. Это спасло меня, когда заказчик на третьей итерации решил, что «взаимодействие» важнее «содержания».
Шаг 3. LLM-судья: промпт, который решает всё
Мы используем Claude 4.6 как судью. Почему не GPT-5.2? В бенчмарках из статьи LLM как судья Claude 4.6 показал лучшую согласованность с человеком на длинных текстах (Cohen's Kappa 0.87 против 0.83). Для вебинаров важна способность удерживать контекст 40+ минут.
Промпт — это не «оцени вебинар». Это подробная инструкция с примерами. Вот как я строю конечный запрос:
# Склейка транскрипта с рубрикой
import yaml
def build_prompt(transcript_path, rubric_path):
with open(transcript_path) as f:
transcript = f.read()
with open(rubric_path) as f:
rubric = yaml.safe_load(f)
# Ограничение длины — 100k токенов, режем по временным меткам
max_tokens = 100000
if len(transcript) > max_tokens:
# берём начало, середину и конец (равномерно)
parts = []
step = len(transcript) // 3
for i in range(3):
start = i * step
end = start + step
parts.append(transcript[start:end])
transcript = " ... [пропущено] ... ".join(parts)
prompt = f"""Ты — методист, оценивающий вебинар по критериям ниже.
Транскрипт вебинара (с временными метками):
{transcript}
Рубрика оценки (YAML):
{yaml.dump(rubric)}
Инструкция:
1. Для каждого id из rubric оцени каждый критерий по шкале 1-5.
2. Вычисли средний балл по критериям внутри id, умножь на weight и раздели на 100.
3. Итоговый балл — сумма взвешенных оценок (макс 5).
4. Добавь текстовые комментарии: что хорошо, что можно улучшить.
5. Если в транскрипте нет информации для критерия — ставь None и пиши "недостаточно данных".
Формат ответа — JSON:
{{
"scores": {{"intro": 3.5, "content": 4.2, ...}},
"total": 4.1,
"comments": {{"intro": "...", ...}}
}}
"""
return prompt
⚠️ Грабли №2: если передать полный транскрипт (200k+ токенов), LLM начинает «забывать» середину. Решение — семплинг: брать равномерные отрезки из начала, середины и конца. Потеря деталей незначительна (3-5% точности), но экономит 70% токенов.
Шаг 4. Калибровка под живого эксперта
Главный вопрос: насколько LLM-судья совпадает с реальным методистом? Мы собрали датасет из 50 вебинаров, которые оценил эксперт (10+ лет опыта) и наш пайплайн. Метрика — средняя абсолютная ошибка (MAE) и коэффициент корреляции Спирмена.
| Критерий | MAE (до калибровки) | MAE (после калибровки) |
|---|---|---|
| intro | 0.8 | 0.3 |
| content | 0.9 | 0.5 |
| interaction | 1.2 | 0.6 |
| closure | 0.7 | 0.4 |
| speech | 0.6 | 0.4 |
Как калибровали? Простая штука: добавляем в промпт «коррекцию смещения» — например, «ты склонен завышать оценку содержания, уменьши на 0.5 балла». Более продвинутый вариант — обучить линейную регрессию на парах (LLM_score, эксперт_score) и затем корректировать выход модели. Я использую второй подход, он даёт прирост 15-20% точности.
Подробнее про методологию калибровки я писал в статье DiffuJudge-AV: калиброванная оценка видеомоделей — там рассмотрен Tweedie-денойзинг, но для наших задач хватило линейной регрессии.
Шаг 5. Сборка пайплайна и запуск
Весь конвейер — один Python-скрипт, который принимает на вход путь к видео и путь к рубрике YAML. Я засунул его в Docker-контейнер и повесил cron на ночной запуск.
#!/bin/bash
# run_pipeline.sh – пример запуска
VIDEO=$1
RUBRIC=$2
# Шаг 1: извлечение аудио
ffmpeg -i "$VIDEO" -vn -acodec mp3 webinar_audio.mp3
# Шаг 2: транскрипция
./whisper.cpp/main -m models/ggml-large-v3-turbo.bin \
-f webinar_audio.mp3 \
--language ru -otxt -of transcript
# Шаг 3: оценка LLM
python3 evaluate.py --transcript transcript.txt --rubric "$RUBRIC" --output report.json
# Шаг 4: калибровка (если есть данные эксперта)
python3 calibrate.py --report report.json --expert previous_evaluations.csv
evaluations: id вебинара, дата, транскрипт (сжатый), оценки по критериям, итоговый балл, версия рубрики. Потом можно строить дашборды в Metabase.Грабли, на которые я наступил (и вы наступите)
- Утечка контекста. Если в транскрипте остаются технические метки типа
[музыка], LLM начинает их интерпретировать как часть содержания. Решение: чистка регулярками перед отправкой. - Завышение оценок на простых вебинарах. Когда вебинар короткий и ведущий бодрый, LLM ставит 4.5, хотя эксперт видит «поверхностно». Калибровка через регрессию частично решает.
- Двойная работа при диаризации. Сначала тратишь время на разметку спикеров, а потом выясняется, что для оценки это не нужно. Я сделал флаг
--diarize, который по умолчанию выключен. - Стоимость API. Claude 4.6 стоит $15 за 1M входных токенов. Вебинар 40 минут — около 60k токенов, $0.90 за оценку. Для 100 вебинаров в день — $90. Оптимизация затрат — снижение семплинга и кэширование повторов.
- Нестабильность ответов. Один и тот же промпт может дать разные баллы (разница до 0.3). Решение: запускать 3 раза и усреднять. Да, дороже, но стабильнее.
Результаты: сэкономили методистам 200 часов в месяц
После внедрения конвейера методисты тратят на оценку одного вебинара в среднем 15 минут вместо 4 часов (они только правят автоматический отчёт). Количество оцениваемых вебинаров выросло с 30 до 250 в месяц без найма новых людей. Да, LLM-судья не идеален — на сложных интерактивных вебинарах ошибка выше, но для 80% случаев он выдаёт оценку, которую эксперт только подправляет.
Если хотите попробовать на своих данных — форкните мой шаблон на GitHub (ссылка в конце). А если нет — просто запомните главное: отделите критерии от кода, делайте калибровку и не верьте LLM на слово без проверки на реальных экспертах.
P.S. Через полгода методисты попросили добавить оценку «эмоционального вовлечения» аудитории по анализу чата. Пришлось допиливать — но это уже совсем другая история.