Автоматизация поддержки клиентов на основе контекстной близости вопросов. embeddings.. embeddings. Natural Language Processing.. embeddings. Natural Language Processing. python.. embeddings. Natural Language Processing. python. векторные представления.. embeddings. Natural Language Processing. python. векторные представления. искусственные нейронные сети.. embeddings. Natural Language Processing. python. векторные представления. искусственные нейронные сети. искусственный интеллект.. embeddings. Natural Language Processing. python. векторные представления. искусственные нейронные сети. искусственный интеллект. обработка естественного языка.. embeddings. Natural Language Processing. python. векторные представления. искусственные нейронные сети. искусственный интеллект. обработка естественного языка. поддержка клиентов.. embeddings. Natural Language Processing. python. векторные представления. искусственные нейронные сети. искусственный интеллект. обработка естественного языка. поддержка клиентов. поддержка пользователей.. embeddings. Natural Language Processing. python. векторные представления. искусственные нейронные сети. искусственный интеллект. обработка естественного языка. поддержка клиентов. поддержка пользователей. Программирование.. embeddings. Natural Language Processing. python. векторные представления. искусственные нейронные сети. искусственный интеллект. обработка естественного языка. поддержка клиентов. поддержка пользователей. Программирование. Управление продажами.. embeddings. Natural Language Processing. python. векторные представления. искусственные нейронные сети. искусственный интеллект. обработка естественного языка. поддержка клиентов. поддержка пользователей. Программирование. Управление продажами. эмбеддинги.


Меня зовут Анатолий, занимаюсь диалоговыми системами и применением Искусственного Интеллекта в бизнесе.

Кейсовая задача – предоставить клиентам возможность составлять вопрос на естественном языке, а не искать вопрос в списке FAQ-раздела сайта. При этом система должна выдавать ответ из существующей базы знаний “Вопрос-Ответ” существующего FAQ-раздела.

Задача реализована с помощью определения контекстной близости вопросов.


Техническая реализация:

  • Все вопросы из базы знаний переводятся в векторные представления (embeddings) с помощью искусственной нейронной сети.

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

  • Серверная часть реализована на Python в виде flask-приложения.

  • Для взаимодействия с сервером необходимо отправить на сервер POST-запрос в формате JSON. Сам вопрос необходимо присвоить переменной question.

  • Сервер выдает ответ в формате JSON. Ответ содержит три переменные: most_similar_question – ближайший по смыслу вопрос из базы знаний, answer – непосредственно текст ответа, similarity – показатель контекстной близости

Версия кода для серверной части:
import pandas as pd
from flask import Flask, request, jsonify
from flask_cors import CORS
from sentence_transformers import SentenceTransformer
import numpy as np

question_url = "..." # Адрес, с которого отправляются запросы
file = "..."         # Файл базы знаний

# Функция для вычисления косинусной близости
def cosine_similarity(vec1, vec2):
    return np.dot(vec1, vec2) / (np.linalg.norm(vec1) * np.linalg.norm(vec2))

# Создание датафрейма
df = pd.read_excel(file)
questions, answers = list(df.questions), list(df.answers)

# Загрузка модели
model = SentenceTransformer('cointegrated/rubert-tiny2')

# Перевод вопросов базы знаний в векторные представления
questions_embeddings = model.encode(questions)  

app = Flask(__name__)

# Настройки CORS
CORS(app, resources={r"/*": {"origins": question_url}})

@app.route('/')
def hello_world():
    return 'Hello, World!'

@app.route('/', methods=['POST'])
def find_similar():
    data = request.get_json()
    user_question = data.get('question', '')
    if not user_question:
        return jsonify({'error': 'Вопрос не найден в запросе'}), 400

    user_emb = model.encode(user_question)
    similarities = [cosine_similarity(user_emb, q_emb) for q_emb in questions_embeddings]
    max_sim = max(similarities)
    max_idx = similarities.index(max_sim)
    return jsonify({
        'most_similar_question': questions[max_idx],
        'answer': answers[max_idx],
        'similarity': float(max_sim)
    })

    
if __name__ == '__main__':
    app.run(debug=True)

Прямой запуск запускает приложение локально на порту 5000.
Для доступности с внешних интернет-ресурсов арендую облачный сервер ubuntu, устанавливаю все обновления, необходимые пакеты python плюс nginx и gunicorn и запускаю командой gunicorn -w 2 -b 0.0.0.0:8000 faqbot:app.
Приложение становится доступно для внешних POST-запросов на порту 8000.
При простом заходе браузером на порт 8000 в качестве проверки появится ‘Hello, World!’

Версия кода для отправки POST-запроса со страницы сайта

Особенности и пояснения

  • Ближайший по смыслу вопрос определяется именно по смыслу, а не по ключевым словам, частям или подстрокам.

  • Система использует векторные представления текста, но не использует Генеративный Искусственный Интеллект. Ответы берутся из заранее составленной базы знаний, на один и тот же вопрос каждый раз будет один и тот же ответ.

  • Система не обращается к внешним ресурсам, то есть может работать в закрытом контуре, с чувствительными данными, не требует получения API ключей и оплаты за токены.

  • Система не учитывает контекст и историю предыдущих вопросов и ответов, каждый вопрос будет рассматривается как “с чистого листа”.

  • Векторные представления вопросов из базы знаний создаются один раз, при загрузке и обновлении базы знаний, поэтому дорогие серверы с GPU не требуются – достаточно обычной производительности.

  • Систему можно использовать в качестве помощника оператора и предлагать оператору на выбор несколько вариантов ответа (например, три) по рейтингу контекстной близости вопросов. Это не совсем автоматизация, но может существенно ускорить выдачу ответа оператором.

  • Систему можно применять не только с сайтом, но и с мессенджерами, виджетами, электронной почтой, сборщиками сообщений и так далее. Необходимо и достаточно отправить на сервер POST-запрос с принятым вопросом, а затем вывести или переправить дальше полученный ответ.

С какими трудностями столкнулся

  • Теоретически, минимальное значение показателя контекстной близости должно быть примерно в интервала 0.7-0.8, чтобы вопрос из базы знаний принимать за релевантный, но как именно определить его точно – пока не понятно. Представляется, что только подбором при наборе определенной статистики, причем для каждой базы знаний минимальное значение может быть своим.

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

Перспективы развития

  • При больших объемах базы знаний следует разделить формирование векторных представлений и непосредственно выдачу ответа. Формировать векторные представления следует запуском отдельного файла и хранить векторные представления в соответствующий векторной базе данных.

  • Кажется, что для выбора ответа можно применять контекстную близость самих ответов, а не вопросов С другой стороны, вопрос может быть весьма коротким, а ответ весьма длинным и подробным, в этом случае показатели контекстной близости могут давать совершенно неприемлемые для данной задачи результаты. Для анализа ответов лучше применять другие нейронные сети и несколько иные подходы. Возможно, следует реализовать это отдельно и запустить “соревнование” между различающимися подходами.

  • Генеративный Искусственный Интеллект становится все мощнее, точнее и популярнее. Подход RAG (генерация с учетом добавленных данных) дает очень хорошие результаты для ответов по базе знаний. Однако для обращения к внешним LLM нужно отправлять свои данные на внешний ресурс, а это не всегда возможно по причинам информационной безопасности, плюс общая плата за токены при большом объеме отправлений может быть весьма существенна. А на своих серверах в общем случае разворачивают квантированные модели, и даже в этом случае понадобятся GPU, что резко влияет на экономику проекта. Поэтому RAG, Langchain, Генеративный Искусственный Интеллект и Агенты – все это также для отдельного проекта.

  • Представляется, что данную систему можно улучшить ведением журнала вопросов и ответов. Это позволит более точно определить, какие из часто встречающихся вопросов встречаются наиболее часто, даже с учетом вариативности формулировок клиентов.

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

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

Выводы

Автоматизация поддержки клиентов на основе контекстной близости вопросов – это подход, при котором система принимает вопрос, определяет ближайший по смыслу вопрос в заранее составленной базе знаний, состоящей из пар “Вопрос-Ответ”, и выдает ответ из соответствующей пары.

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

Благодарности

Спасибо за прочтение статьи.
Буду признателен за любые комментарии, особенно за сообщения о том, с какими реальными трудностями сталкивались при автоматизации поддержки клиентов.

Автор: AnatolyBelov

Источник

Rambler's Top100