Нативная работа с аудио: Обработка речи и тональности
Введение: Почему транскрибация — это прошлый век
Добро пожаловать на урок, который изменит ваше представление о работе со звуком. В первом модуле мы говорили о текстовых моделях, но здесь, в Модуле 2, мы начинаем раскрывать истинную мощь мультимодальности Gemini 3.
Давайте начнем с честного признания: долгое время стандартом индустрии была цепочка Speech-to-Text (STT) -> LLM. То есть, мы сначала превращали аудио в текст (Whisper, Google STT), а затем скармливали этот текст модели. Это работало, но это был «костыль».
В чем проблема этого подхода?
Когда вы превращаете речь в текст, вы теряете 50% информации. Вы теряете:
- Интонацию: Сарказм («Ну конечно, отличная идея») превращается в одобрение.
- Эмоции: Дрожь в голосе, вздохи, паузы неуверенности.
- Идентификацию спикеров: Кто кого перебил? Кто повысил голос?
- Фоновые звуки: Звук сирены, стук клавиатуры, музыка на фоне.
Gemini 3 работает иначе. Это нативная мультимодальная модель. Она не транскрибирует аудио в текст «под капотом» перед анализом. Она «слышит» аудио напрямую, воспринимая звуковые волны как токены, так же, как она воспринимает слова. Это позволяет нам анализировать не только то, что было сказано, но и как это было сказано.
Техническая реализация: File API и Токенизация звука
Прежде чем мы перейдем к анализу эмоций, давайте разберем, как технически передать аудио в модель. В отличие от коротких текстовых промптов, аудиофайлы могут быть большими. Передавать их в base64-кодировке внутри JSON-запроса — плохая практика для файлов длинее нескольких секунд.
Для работы с аудио в Gemini мы используем File API. Это временное хранилище, куда мы загружаем медиафайлы. Файл хранится там 48 часов, после чего автоматически удаляется. Это безопасно и эффективно.
Важный момент про токены:
Как аудио конвертируется в контекстное окно? Для Gemini 3 (на базе архитектуры 1.5) одна секунда аудио — это не фиксированное количество байт, а определенное количество токенов.
Эвристика: 1 минута аудио занимает примерно 1 000 – 1 200 токенов (зависит от плотности речи и версии модели). С контекстным окном в 1-2 миллиона токенов вы можете загружать целые подкасты, лекции или многочасовые записи совещаний за один раз.
import google.generativeai as genai
import time
import os
# Настройка API ключа
genai.configure(api_key=os.environ["GEMINI_API_KEY"])
def upload_and_wait_for_processing(file_path, display_name="Audio Sample"):
"""
Загружает файл в File API и ожидает завершения его обработки.
Аудиофайлы требуют времени на процессинг на стороне Google.
"""
print(f"Загрузка файла: {file_path}...")
audio_file = genai.upload_file(path=file_path, display_name=display_name)
print(f"Файл загружен: {audio_file.name}. Ожидание обработки...")
# Цикл проверки статуса
while audio_file.state.name == "PROCESSING":
print(".", end="", flush=True)
time.sleep(2) # Пауза перед следующей проверкой
audio_file = genai.get_file(audio_file.name)
if audio_file.state.name == "FAILED":
raise ValueError("Не удалось обработать аудиофайл.")
print(f"\nГотово! Файл активен. URI: {audio_file.uri}")
return audio_file
# Пример использования (предполагается наличие файла meeting_recording.mp3)
# uploaded_audio = upload_and_wait_for_processing("meeting_recording.mp3")
Сценарий 1: Семантический поиск и суммаризация
Самый базовый уровень использования — это работа с содержимым. Но даже здесь нативность дает преимущество. Представьте запись плохого качества: шум улицы, эхо. Классический транскрибатор может выдать «кашу», где ключевые слова будут искажены. Gemini, обладая широким контекстом, способна восстанавливать смысл, опираясь на окружающие звуки и общую логику разговора, подобно тому, как это делает человек.
При работе с длинными аудио (например, записью часового звонка с клиентом) важно не просто просить «сделай саммари», а задавать структуру.
Совет архитектора: Всегда запрашивайте временные метки (timestamps). Модель умеет соотносить сказанное с таймлайном.
# Инициализация модели (используем последнюю версию Flash или Pro для мультимодальности)
model = genai.GenerativeModel(model_name="gemini-1.5-pro-latest")
# Промпт для извлечения структурированных данных
prompt = """
Прослушай эту запись встречи команды разработчиков.
Составь протокол встречи в формате JSON со следующими полями:
1. "summary": Краткое резюме (2-3 предложения).
2. "action_items": Список задач, кто ответственный и дедлайн (если назван).
3. "key_decisions": Принятые архитектурные решения.
4. "timeline": Ключевые моменты с таймкодами [MM:SS].
Игнорируй светскую беседу в начале (small talk).
"""
# Отправка запроса: Текст промпта + Объект файла
# response = model.generate_content([prompt, uploaded_audio])
# print(response.text)
Сценарий 2: Анализ тональности и скрытых смыслов
Вот здесь начинается магия, недоступная текстовым моделям. Тональность голоса часто несет больше смысла, чем слова.
Представьте ситуацию в службе поддержки:
Клиент говорит: «Ну, спасибо вам большое за помощь».
Текст видит: Благодарность.
Аудио слышит: Агрессивный сарказм, повышенный тон, резкое окончание фразы.
Если вы строите систему контроля качества для колл-центра на базе Gemini 3, вы можете (и должны) просить модель оценивать эмоциональное состояние.
Ключевые аспекты для анализа:
- Pitch (Высота голоса): Повышение часто свидетельствует о стрессе или волнении.
- Speed (Скорость речи): Ускорение может означать срочность или тревогу.
- Pauses (Паузы): Длинные паузы перед ответом могут указывать на ложь или неуверенность.
analyst_prompt = """
Ты - эксперт по поведенческой психологии и анализу голоса.
Проанализируй аудиозапись звонка клиента.
Мне не нужна просто транскрипция.
Ответь на следующие вопросы, аргументируя ответ ссылками на звучание голоса:
1. Эмоциональное состояние клиента в начале и в конце звонка. Изменилось ли оно?
2. Есть ли моменты, где оператор проявлял неуверенность (эканье, долгие паузы, дрожащий голос)? Укажи таймкоды.
3. Был ли момент сарказма? Если да, процитируй фразу и опиши интонацию.
4. Общая оценка напряженности разговора по шкале от 1 до 10.
"""
# response = model.generate_content([analyst_prompt, uploaded_audio])
Работа с несколькими спикерами (Диаризация)
Gemini 3 не имеет встроенной функции жесткой «диаризации» (разметки Спикер 1 / Спикер 2), как специализированные узкие модели, возвращающие массив сегментов. Однако, благодаря огромному контексту и пониманию семантики, она отлично справляется с ролью логической диаризации.
Вместо того чтобы просить «Раздели аудио на спикеров», попросите: «Идентифицируй участников разговора по ролям (например, Менеджер и Клиент) и напиши диалог, указывая, кто говорит».
Практический кейс:
В юридической практике или HR важно не просто что сказали, а кто это сказал. Gemini может различить мужской и женский тембр, а также характерные речевые паттерны (например, один человек использует много терминологии, другой задает простые вопросы), чтобы правильно атрибутировать реплики.
Задание: Детектор лжи (Анализ неуверенности)<br><br>Представьте, что вы разрабатываете ассистента для рекрутеров. У вас есть аудиозапись ответа кандидата на вопрос: «Почему вы ушли с прошлого места работы?».<br><br>Напишите промпт для Gemini, который:<br>1. Выделит фактическую причину, названную кандидатом.<br>2. Проанализирует невербальные сигналы (вздохи, изменения темпа, заминки), которые могут указывать на то, что кандидат что-то недоговаривает или приукрашивает.<br>3. Вернет результат в формате JSON с полем `truthfulness_score` (0-100%) и обоснованием.
В чем главное преимущество нативной обработки аудио в Gemini 3 по сравнению с пайплайном 'Whisper (STT) -> LLM'?