Автооценка вебинаров с LLM-судьей: конвейер на whisper.cpp и Claude Code | AiManual
AiManual Logo Ai / Manual.
22 Июн 2026 Гайд

Автооценка вебинаров с LLM-судьей: конвейер на whisper.cpp и Claude Code за неделю

Пошаговый гайд по созданию пайплайна автооценки вебинаров: транскрипция whisper.cpp, рубрики YAML, калибровка LLM-судьи под эксперта. Код, метрики, грабли.

Реклама
cliv1

Знаете это чувство, когда после вебинара методист садится и три часа расписывает, ведущий открывал слайды вовремя и отвечал ли на вопросы? А если вебинаров десять в день? А если сто? Руками это не масштабируется. Никак. Я перепробовал кучу решений — от тупых чек-листов до попыток нанять армию фрилансеров. В итоге собрал конвейер, который за неделю превращает сырое видео в структурированный отчёт. Под капотом — локальный whisper.cpp, кастомный LLM-судья на Claude и YAML-рубрика, которую может править любой методист без единой строчки кода. Рассказываю, как это работает и где я наступил на грабли.

Почему руками — это путь в никуда

Методисты — дорогие и редкие. Они смотрят 10-минутные отрезки, ставят оценки по шкале «понятно/непонятно». Субъективно, медленно, дорого. Когда вебинаров становится много, качество оценки падает квадратично от усталости эксперта. Вторая проблема — воспроизводимость. Один и тот же вебинар два методиста оценят по-разному, а потом спорят, чья оценка правильная.

Идея: пусть машина делает черновик оценки по тем же критериям, что и человек, а методист только корректирует 20% случаев. Экономия — 80% времени.

Я не первый, кто пытается прикрутить LLM к оценке. В статье LLM как судья: сравнительный тест GPT-5.2, Claude 4.6 и Gemini 3.1 ребята тестировали модели на юридических текстах — там точность доходила до 91%. Но вебинар — это не сухой документ. Тут интонации, паузы, скорость речи. Поэтому голый LLM без контекста не справится. Нужен пайплайн.

Архитектура конвейера: три кита и одна утка

Вот как выглядит конечная цепочка:

  1. Захват видео — скачивание записи вебинара (MP4, поток).
  2. Аудиодорожка — извлечение звука через FFmpeg.
  3. Транскрипцияwhisper.cpp с моделью large-v3-turbo (на июнь 2026 это самый быстрый вариант для русского языка с приемлемым качеством).
  4. Диаризация — разделение реплик по спикерам (опционально, но для оценки взаимодействия ведущий-аудитория — мастхэв).
  5. Промпт-инжекция — склейка транскрипта с рубрикой YAML.
  6. LLM-судья — Claude 4.6 (через API или локально через Claude Code как агент, но мы используем API для скорости).
  7. Калибровка — сравнение с эталонными оценками эксперта и подстройка весов рубрики.
  8. Формирование отчёта — 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

Результат — обычный текст с временными метками. Но для оценки нужны ещё реплики разных спикеров. Тут в дело вступает диаризация.

💡
Если аудио чистое (нет overlapping речи), можно обойтись без диаризации — Claude сам поймёт смену говорящего по контексту. Для перегруженных вебинаров лучше использовать pyannote-audio или просто размечать реплики по паузам.

Шаг 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
💡
Для хранения результатов использую SQLite — лёгкий, не требует отдельного сервера. Одна таблица 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. Через полгода методисты попросили добавить оценку «эмоционального вовлечения» аудитории по анализу чата. Пришлось допиливать — но это уже совсем другая история.

Подписаться на канал