Речевая аналитика звонков через Deepgram + OpenAI

 Публичный пост
26 ноября 2024  404

Я продолжаю исследовать невероятные возможности AI. Делюсь очередным кейсом из B2B. Недавно обратился заказчик с задачей: проанализировать звонки сейлзов клиентам. Общая длительность аудиозаписей - около 30 часов. Цель - "выкопать косяки", чтобы провести тренинг для сейлзов. Важный момент - при анализе нужно учитывать специфику продаж в бизнесе заказчика. Нюансы он описал в отдельной методичке.

Почему не "Готовые решения"?

На старте мы рассмотрели несколько готовых систем, в которых сразу "под капотом" есть транскрибация звонка в текст и его последующий анализ. Но столкнулись с ограничениями:

  1. Привязка к IP-телефонии сервиса:

Большинство решений привязаны к своей платформе, включая собственную IP-телефонию. То есть мы не можем туда просто отправить свой mp3 файл с записью разговора и получить отчет. Для генерации репорта необходимо сам звонок осуществить через телефонию сервиса. Как вы догадываетесь, наш заказчик не горел желанием менять свою текущую телефонию.

2. Не "признает" нашу методичку:

В нашем случае для заказчика была критична привязка анализа к его бизнес процессам. Оказалось сложно найти сервис, который позволяет подать на вход собственную методичку.

По итогу, решили отложить готовые решения и собрать "from scratch".

Собираем "из подручных"

Наша задача состоит из 2-х частей: транскрибировать звонок и произвести анализ транскрипта (с целью выявления ошибок в коммуникации).

1. Транскрибация (Speech-To-Text)

Первоначально мы рассматривали Whisper, но он не поддерживает разделение на спикеров, что критично для анализа звонков, где важно понимать, кто говорит. После исследования мы остановились на Deepgram, который обеспечивает:

  • Высокое качество распознавания (в том числе для славянских языков).
  • Разделение на спикеров (Diarization "по умному").

Ниже пример распознанного диалога:

Sales Manager (SM): - Алло, добрый день! Это Василий из компании "ТехМарт". Мы занимаемся поставками офисной техники. Вам удобно говорить?
Client (C): - Да, слушаю.
SM: - Отлично! У нас сейчас выгодное предложение по принтерам. Мы предлагаем самые низкие цены на рынке. Вы же закупаете технику для офиса?
C: - Иногда закупаем, а что именно предлагаете?
SM: - Ну, я точно не знаю, что вам нужно, но у нас есть большой выбор. Могу сразу сказать, что наши цены намного ниже, чем у конкурентов.
C: - Хорошо, но у нас сейчас всё вроде в порядке с принтерами.
SM: - А может быть, вы просто не знаете, что они скоро устареют? У нас есть отличные новые модели, которые вам точно понравятся.
C: - Нет, пока всё устраивает.
SM: - Подождите, а что насчёт расходных материалов? Может быть, вам нужны картриджи или бумага?
C: - Мы обычно работаем с нашими поставщиками, они нас устраивают.
SM: - А вы сравнивали цены? Наверняка мы можем предложить что-то лучше. Давайте я вышлю прайс-лист, и вы посмотрите.
C: - Не уверен, что мне это нужно.
SM: - Ну, вдруг пригодится. Я вам просто отправлю информацию, а потом перезвоню завтра, чтобы уточнить, что вы выбрали.
C: - Нет, спасибо.
SM: - Вы уверены? А то такие предложения редко бывают.
C: - Да, всё в порядке.
SM: - Ладно, ну, тогда я вам всё равно на почту вышлю, хорошо?
C: - Нет, не нужно. Спасибо.
SM: - Хорошо... До свидания.

2. Анализ коммуникации

Здесь не стали изобретать велосипед и использованил OpenAI. Обычный Chat Completions API. Методичку подкидываем как system message. В документе по ссылке ниже результаты анализа:

https://docs.google.com/document/d/1aX5pV3c5qYiaa0HDONX_5V58YVamcTYK2OMglAsPu8Q/edit?usp=sharing

Что по итогу

Решение позволяет сократить общее время на анализ звонков с нескольких дней до 2-3 часов. Кроме того, есть еще пара неочевидных плюшек:

a. На практике, наш заказчик чаще всего прокрастинировал анализ звонков (несмотря на то, что ставил себе в план). То есть - задача актуальна, но постоянно теряется в множестве более приоритетных.

b. По факту анализа заказчик хочет не только провести тренинг с сейлзами, но и внедрить AI анализ звонков на постоянной основе. По его мнению, когда сотрудники будут "ощущать постоянный контроль", они не будут скатываться к старым косякам через несколько дней после тренинга.

Если захотите сами "поиграться"

Ниже привел исходный код, если захотите развернуть демку и протестить на собственном диалоге. Также, сейчас готовим веб демо, куда вы сможете подкинуть свой Deepgram и OpenAI апи-ключи, а также свою методичку и проанализировать нужный вам mp3 файл.

import fs from 'fs';
import fetch from 'node-fetch'; // Ensure 'node-fetch' is installed

// Replace the following keys with your own API keys, or use environment variables for security
const OPENAI_API_KEY = process.env.OPENAI_API_KEY || "YOUR_OPENAI_API_KEY_HERE";
const DEEPGRAM_API_KEY = process.env.DEEPGRAM_API_KEY || "YOUR_DEEPGRAM_API_KEY_HERE";

// Initialize Deepgram client
const deepgram = createClient(DEEPGRAM_API_KEY);

// Path to the audio file for transcription
const audioFilePath = "path/to/your/audio/file.mp3";

// Options for the Deepgram transcription model
const options = {
  model: "nova-2",
  language: 'uk', // Specify the language for transcription
  diarize: true,  // Enable speaker diarization
};

// Main function
const run = async () => {
  try {
    // Transcribe the audio file using Deepgram
    const { result, error } = await deepgram.listen.prerecorded.transcribeFile(
      fs.createReadStream(audioFilePath),
      options
    );

    if (error) {
      console.error("Transcription Error:", error);
      return;
    }

    // Extract words and organize transcript by speaker
    const words = result.results.channels[0].alternatives[0].words;
    let currentSpeaker = null;
    let line = "";
    let transcript = "";

    words.forEach((word) => {
      if (word.speaker !== currentSpeaker) {
        if (line) {
          transcript += `Speaker${currentSpeaker}: ${line.trim()}\n\n`;
        }
        currentSpeaker = word.speaker;
        line = "";
      }
      line += ` ${word.word}`;
    });

    // Add the last line to the transcript
    if (line) {
      transcript += `Speaker${currentSpeaker}: ${line.trim()}\n\n`;
    }

    console.log("Transcript:\n", transcript);

    // Analyze the transcript with ChatGPT
    const analysis = await analyzeWithChatGPT(transcript);
    console.log("ChatGPT Analysis:\n", analysis);

  } catch (err) {
    console.error("Error during processing:", err);
  }
};

// Function to send the transcript to ChatGPT for analysis
const analyzeWithChatGPT = async (transcript) => {
  try {
    const response = await fetch("https://api.openai.com/v1/chat/completions", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        Authorization: `Bearer ${OPENAI_API_KEY}`,
      },
      body: JSON.stringify({
        model: "gpt-4o", // Use the model as per your subscription
        messages: [
          {
            role: "system",
            content: `
You are a helpful assistant with expertise in sales conversation analysis. 
Your task is to evaluate the following transcript of a conversation between a sales manager and a client. 
Provide actionable recommendations to the sales manager on specific moments in the conversation 
that can be improved to increase the conversion rate. 
- Keep the language of your recommendations the same as the transcript language
- Return the result structured in markdown format.
`,
          },
          { role: "user", content: transcript },
        ],
        max_tokens: 1000,
      }),
    });

    const data = await response.json();

    if (response.ok) {
      return data.choices[0].message.content;
    } else {
      console.error("Error with OpenAI API:", data);
      return "An error occurred while processing the request.";
    }
  } catch (err) {
    console.error("Error during ChatGPT analysis:", err);
    return "An unexpected error occurred.";
  }
};

// Run the script
run();

Дальнейшие планы

В процессе работы мы увидели потенциал для дальнейшего развития инструмента:

  1. Создать симулятор звонков:

Хочется на основе выявленных ошибок создавать тренажеры, где AI имитирует реального клиента. Что-то вроде кастомизированного ChatGTP Voice Mode. Такой инструмент позволит менеджерам тренироваться в сложных сценариях общения с клиентами, получать рекомендации в реальном времени и улучшать свои навыки без риска потери реальных сделок.

  1. Система непрерывной аналитики звонков:

Как упоминал выше, чтобы добиться стойкого эффекта, планируем реализовать систему непрерывной аналитики. Заказчик сможет каждую неделю видеть автоматический отчет по качеству работы его сейлзов, а сейлзы - ощущать постоянный контроль.

  1. Анализ "сентиментов":

Внедрить транскрибацию, которая распознает не только текст, но и эмоциональную составляющую разговора, интонации и паузы. Эти факторы выведут аналитику на новый уровень.

  1. Адаптация для задач контакт центров:

В одном из недавних интервью я выяснил, что у руководителей контакт центров (например, в банках) возникают альтернативные задачи при анализе звонков. А именно - выделить типичные темы, по которым идут обращения пользователей. Цель - снизить нагрузку на контакт центры посредством редизайна продукта или userflow в целом. Планируем адаптировать наши решения и под этот кейс.

Что нам нужно

  • Ваши идеи, как можно дополнить или улучшить инструмент.
  • Если у вас есть знакомые руководители отделов продаж или поддержки, которые занимаются анализом звонков - буду благодарен за знакомство. Хотел бы задать пару вопросов.
12 комментариев 👇
Petr Gavrilov html программист 26 ноября 2024

Можно ли все это проделывать в реалтайме?
Speech-To-Text + перевод + gpt подсказки

мне бы пригодился помощник для разговоров по телефону на незнакомом языке.

  Развернуть 1 комментарий

@petter, приветствую! Сейчас как раз активно копаю в данный вопрос. Предварительно скажу так: это возможно, однако надо принять наличие задержки (примерно в 3-5-7 секунд в зависимости от объема текста). Любопытно в контексте каких разговоров это используете?

p.s. если удобнее обсуждать это в ЛС, могу написать туда

  Развернуть 1 комментарий

@apris, я живу в стране где не очень знаю местный язык, а местные не знают русского или английского. В большинстве ситуаций мне помогают приложения с переводом, но вот со звонками тяжело. Даже если я успеваю перевести речь собеседника, то в обратную сторону уже нет.

  Развернуть 1 комментарий

@petter, приемлемо ли наличие задержки? Другими словами, сможете ли потянуть время до ответа?

  Развернуть 1 комментарий

@apris, я думаю что 3-5 секунд задержка допустима, если это не только речи, а сразу перевод и подсказки.

  Развернуть 1 комментарий

Звонок про принтер - это же не настоящий диалог?

  Развернуть 1 комментарий

@rkn, да, есть такое дело. Из крайних реальных диалог не нашел такого, чтобы был максимально репрезентативен

  Развернуть 1 комментарий
🕵️ Юзер скрыл свои комментарии от публичного просмотра...

😎

Автор поста открыл его для большого интернета, но комментирование и движухи доступны только участникам Клуба

Что вообще здесь происходит?


Войти  или  Вступить в Клуб