Всем привет! Меня зовут Александр Мешков, я автор бесплатной платформы TestGrow для тестировщиков. В последнее время я достаточно большое количество времени стал уделять генеративному искусственному интеллекту и возможностям его применения в различных аспектах обучения.
С появлением больших лингвистических моделей (LLM) сфера ИТ начала стремительно меняться. Уже сейчас многие ИТ специалисты и компании используют различные инструменты на базе ИИ для выполнения рутинных задач. Кроме того, постоянное развитие и обучение новых моделей большими игроками (Google-Gemini, Microsoft– OpenAI и Meta - Llama) приводит к тому, что генерация ответов на базе нейронных сетей становится все более и более качественной, поэтому, как бы это грубо ни звучало, в долгосрочной перспективе я ожидаю значительные изменения и интеграцию ИИ во многие рабочие аспекты.
В целом на тему ИИ можно много холеварить, но в этой статье я хотел бы поделиться с вами моим новым проектом в сфере ИИ для проведения собеседований и немного погрузить вас в технические аспекты реализации голосового интервьюера.
Сейчас мой проект уже запущен, он будет бесплатным (пока запросы не начнут выливаться мне в существенные деньги) и вы можете самостоятельно попробовать пройти учебное интервью. Бот доступен по ссылке.
Ну а дальше я хочу рассказать вам про технические особенности его реализации.
Итак, я думаю многие из вас, кто регулярно пользует LLM моделями, как в повседневной жизни, так и в своей работе, знают, что тот же самый ChatGPT при должных инструкциях способен не только выдавать вам различный контент, но и выступать в роли учителя или оценщика. Принимая определённые ваши критерии оценки на вход LLM способна, используя данные критерии, давать оценку тому инпуту, который модель должна обработать. Для того, чтобы организовать учебное интервью с ИИ, нужно было разделить работу с LLM на две части:
Получить список вопросов, который был бы полный и соответствовал той позиции, на которую человек хочет пройти интервью
Дать обратную связь по каждому ответу на вопрос, получив ответ от человека.
В целом задача выглядит достаточно просто. Поэтому первым этапом необходимо было понять, какую модель лучше всего использовать для взаимодействия с ИИ на каждом этапе. Почему это важно? При работе с генеративным искусственным интеллектом стоит принимать во внимание 3 составляющих: скорость ответа, стоимость использования модели (в токенах) и качество ответа. Вам всегда необходимо найти некий баланс, который с минимальными затратами позволял бы получать достаточно быстро ответ, который был бы при этом еще и достаточно качественным. Наиболее популярные модели вы всегда можете посмотреть на HuggingFace. На момент написания статьи в категории качества ответов на русском языке (мы же живём в РФ все-таки) были следующие модели (честно, я пока не пробовал и не изучал модели от Яндекс YandexGPT и от Сбера Gigachat от Сбера, поэтому если у кого-то есть опыт использования, делитесь в комментариях):
Из трех наиболее развитых LLM моделей я остановил свой выбор в пользу моделей OpenAI, потому, что:
Llama в целом как аналитическая модель пока слабовата и ее развертывание на внутренних мощностях при большом количестве запросов может выйти в копеечку.
Gemini – вполне хороший конкурент OpenAI по качеству генерации ответов, но платные google сервисы voice-to-text и text-to-voice, которые берут по 0.024 доллара за минуту обработки выглядит дороговато для бесплатного приложения, когда OpenAI предлагает стоимость в 4 раза ниже, 0.006 доллара за минуту обработки.
OpenAI - в целом уже достаточно давно работаю с данной моделью и мне нравиться как качество генерации ответов их моделей, а также доступность документации для разработчика, плюс удобный API и библиотеки для voice-to-text и text-to-voice. Не нужно изобретать велосипед заново, OpenAI уже обо всем за нас позаботился, что несомненно очень удобно.
Итак, если подходить к выбору моделей, то при создании приложения, если у вас нет большого бюджета за плечами, стоит задумать о рациональности использования последних и самых дорогих моделей для решения всех задач, поэтому пришлось делать изначально небольшие тесты, для того, чтобы определить на каких этапах интервью какую модель лучше применять, с точки зрения все тех же критериев, качество ответа, стоимость токенов и скорость.
С точки зрения стоимости и скорости ответа сразу отпала новая модель o1-preview, потому что используемая в ней технология chain of thoughts достаточно долго обрабатывает полученные запросы и время на получения ответа может доходить до 30-60 секунд. Плюс стоимость использования модели в 10 раз выше, чем модели 4o - $15.00 / 1M input tokens и $60.00 / 1M output tokens.
Далее выбор встал между моделью gpt-4o и gpt-4o mini. Плюсы gpt-4o mini в том, что она в два раза дешевле обычной 4о модели, то есть $0.150 / 1M input tokens и $0.600 / 1M output tokens в gpt-4o mini против $2.50 / 1M input tokens и $10.00 / 1M output tokens в gpt-4o.
Скрытый текстНебольшой оффтоп.
Кстати из последних фишек от OpenAI буквально на прошлой неделе они объявили о том, что они внедряют возможности кэширования промптов, что позволяет еще в половину сократить стоимость использования их моделей. Подробности о кэшировании промптов можно посмотреть тут. https://platform.openai.com/docs/guides/prompt-caching
В общем я решил немного потестировать эти две модели и поделиться с вами результатами. Ниже примеры двух запросов, которые показывают качество ответов от этих двух моделей на генерацию вопросов и предоставление обратной связи по ответу пользователя (п.с. для тестирования я использовал более простые промпты).
Какие можно сделать выводы. GPT-4o генерирует более последовательные вопросы, которые в том числе встраиваются по уровню сложности, а также включают в себя практические задачи, в отличии от gpt-4o mini, которая подготовила вопросы в основном только в части теории, но в целом при изменении промпта и добавления определенных условий, данная модель также способна вполне хорошо справляться с данной задачей.
Далее тест на разбор ответа от человека:
Тут уже разница появляется значительная разница в ответе. В своем запросе я специально не указал принцип ООП – Наследование, и как вы можете видеть из ответов моделей, gpt-4o сразу указала на это в своем разборе, а вот модель gpt-4o mini пропустила этот недочет. Также ответ gpt-4o явно указывает мне на то, что мне стоит подучить и как лучше ответить на вопрос именно для моей позиции JAVA junior разработчик, и эти подсказки фигурирует во всем ответе, тогда как gpt-4o mini ссылается на это только в конце своего сообщения. Ну и в целом, ответ gpt-4o выглядит более естественным для нас с вами.
Поэтому, когда планируете разработку решений на базе существующих генеративных ИИ моделей, всегда делайте такой первоначальный анализ, чтобы понять, насколько качественно модели будут обрабатывать ваши запросы. Что касается меня, то для генерации вопросов я пока отдал предпочтение gpt-4o mini, немного подкорректировав промпт и расширив его инструкциями, а вот анализ ответов отдал на откуп gpt-4o.
Теперь давайте перейдем к технической реализации приложения.
Как я писал уже ранее, чтобы не изобретать велосипед, я принял решение воспользоваться стандартными решениями от OpenAI, которые доступны в их API документации.
Во-первых, они изначально используют модели, которые обучены OpenAI и явно будут значительно лучше обрабатывать или создавать аудио, а во-вторых, не нужно писать никакой логики, буквально 3-4 строчки кода на Python полностью решат все ваши проблемы.
Пример speech-to-text c использованием модели whisper (ссылка на документацию):
from openai import OpenAI
def speech_to_text(audio_file_path):
with open(audio_file_path, "rb") as audio_file:
# Используем OpenAI API для транскрипции речи
transcription = client.audio.transcriptions.create(
model="whisper-1",
file=audio_file
)
recognized_text = transcription.text
return recognized_text
Пример text-to-speech c использованием модели TTS (ссылка на документацию):
from openai import OpenAI
def text_to_speech(text_input, output_file_name="speech.mp3", voice="nova"):
# Отправляем текст в OpenAI TTS API
response = client.audio.speech.create(
model="tts-1",
voice=voice,
input=text_input
)
# Сохраняем синтезированную речь в MP3 файл
response.stream_to_file(speech_file_path)
return str(speech_file_path)
Из плюсов использования моделей Whisper еще заключается в том, что у нее достаточно хороший уровень поддержки русского языка. Измерение качества модели по показателям WERs (word error rates) or CER (character error rates) показывает достаточно низкий уровень количества ошибок.
Для сравнения я также пробовал использовать бесплатные библиотеки как для распознавания голосового ответа, так и в обратную сторону, но, к сожалению, качество бесплатных библиотек SpeechRecognition и pyttsx3 пока оставляет желать лучшего.
Наверное, если брать во внимание весь проект целиком, то данная часть была, наверное, максимально сложной. Почему? Ну во первых я выбрал JS, для реализации фронт-енд части приложения (к сожалению современных vue, node.js и прочего я не знаю) и оказывается, что в технологии записи голоса на js в браузер есть уйма нюансов, связанных с кроссбраузерностью и поддержкой тех или иных технологий записи голоса. Причем речь идет не только о Web браузерах, но и о мобильных также.
Немного о том, как в общем происходит обработка голоса в браузере. Работа с записью голоса в браузере делится на 3 части:
Получение доступа к микрофону
Запись и обработка голосового сообщения
Сохранение его в медиафайл
Для работы с микрофонами в JS чаще всего используется API MediaDevices.
Данный API используется для получения доступа к микрофонам с помощью информационного объекта navigatorв Browser Object Model (BOM).
Navigator – это объект, который используется для получения разной информации о браузере, сетевом соединении, операционной системе и так далее. Так как часто вы можете столкнуться с тем, что у пользователя могут быть подключены несколько микрофонов, то желательно в JS реализовывать отдельно возможность выбора микрофона.
async function getMicrophones() {
const devices = await navigator.mediaDevices.enumerateDevices();
const audioDevices = devices.filter(device => device.kind === 'audioinput');
const microphoneSelect = document.getElementById('microphoneSelect');
// Очищаем список перед его заполнением
microphoneSelect.innerHTML = '';
audioDevices.forEach(device => {
const option = document.createElement('option');
option.value = device.deviceId;
option.text = device.label || `Микрофон ${audioDevices.length + 1}`;
microphoneSelect.appendChild(option);
});
microphoneSelect.addEventListener('change', (event) => {
selectedMicrophoneId = event.target.value;
});
if (audioDevices.length > 0) {
selectedMicrophoneId = audioDevices[0].deviceId; // Устанавливаем микрофон по умолчанию
}
}
Далее переходим в самой сложной части всего этого процесса – эта непосредственно запись и обработка голосового ответа. Изначально в проекте я пробовал использовать просто MediaRecorder API.
navigator.mediaDevices.getUserMedia({ audio: true})
.then(stream => {
const mediaRecorder = new MediaRecorder(stream);
let voice = [];
document.querySelector('#start').addEventListener('click', function(){
mediaRecorder.start();
});
mediaRecorder.addEventListener("dataavailable",function(event) {
voice.push(event.data);
});
document.querySelector('#stop').addEventListener('click', function(){
mediaRecorder.stop();
});
});
Но на первых же кроссбраузерных тестах оказалось, что есть проблемы, связанные с доступом к микрофону, например, Яндекс браузер доступ давать не хотел, а в Web Safary по умолчанию не выбирался микрофон. Плюс на мобильных браузерах результаты тестирования микрофона были очень нестабильными, несмотря на заявленные достаточно широкие возможности в части кроссбраузерности. В итоге пришлось искать другие, более стабильные варианты для записи голоса, и как выяснилось, на просторах интернета не там много практических кейсов работы с записью голоса в JS. Что меня спасло? Вот это видео, записанное уже почти 5 лет назад.
Достаточно хорошим решением оказалось использование RecorderJS, который поддерживает в том числе и мобильные браузеры. Я не эксперт в JS, но мои результаты тестов показали в целом лучшую обработку записи на разных браузерах.
Реализация всех рекордеров очень похожа, везде есть блок инициализации рекордера, начала и завершения записи.
navigator.mediaDevices.getUserMedia(constraints)
.then(function (stream) {
gumStream = stream;
// Создаем источник для аудио потока
const input = audioContext.createMediaStreamSource(stream);
// Создаем объект Recorder.js с поддержкой одного канала
recorder = new Recorder(input, { numChannels: 1 });
// Начинаем запись
recorder.record();
// Останавливаем запись
recorder.stop();
// Останавливаем поток микрофона
gumStream.getAudioTracks()[0].stop();
// Экспортируем записанные данные в формате WAV и отправляем на сервер
recorder.exportWAV(function (blob) {
console.log("Запись завершена");
// Используем FileReader для отправки аудиофайла на сервер
let reader = new FileReader();
reader.readAsArrayBuffer(blob);
reader.onloadend = function () {
// Отправить аудио через API
sendAudioAnswer(reader.result);
};
})
На текущий момент приложение запущено и доступно бесплатно каждому, кто хочет попробовать пройти интервью с AI и самое главное получить обратную связь. Это был мой первый опыт написания подобного рода приложения, поэтому я надеюсь, что бесплатная версия voice интервьюера может оказаться полезной, особенно для начинающий свою карьеру в ИТ специалистов.
Какие есть возможности?
Вы может генерировать до 50 вопросов по различным направлениям, например, аналитика, разработка или тестирование. Ответы на вопросы предполагает использование как голосовых ответов, так и есть возможность ответа в формате текста, что очень удобно для решения практических задач. Кроме того, по завершению интервью вы можете скачать результаты собеседования, где будут сохранены вопросы, ваши ответы и комментарии AI для дальнейшего анализа.
Что важно знать. Не пытайтесь думать, что AI это человек, который будет вам отвечать очень естественно. Рассматривайте AI в контексте собеседований как помощника, который подскажет вам, как лучше ответить на тот или иной вопрос. И да, в моей промпте AI всегда даст вам замечания или предложения к ответу:)
Возможно сейчас собеседование с ИИ пока еще кажется чем-то необычным или противоречивым, но мне кажется, уже в ближайшем будущем большую часть технического интервью уже станет проводить AI, оставив нам оценку soft skills.
Также если у вас есть желания поконтрибьютить в данный проект, пиши мне в телеграм, я буду рад любой помощи.
Посмотрим, что нас будет ждать дальше!