Создание простого чат-бота для сайта на Python и Flask

Создание простого чат-бота для сайта на Python и Flask

Чат-бот на Flask способен заменить операторов в рутинных операциях. Рассказываем, как создать простого pattern-based бота для сайта и рассматриваем сценарии его использования.

Введение

Flask — микрофреймворк Python, идеально подходящий для создания лёгких веб-сервисов, таких как чат-боты. Его преимущества:

  • не навязывает структуру проекта, позволяя начинать с одного файла app.py;
  • легко интегрируется с любыми библиотеками обработки естественного языка (NLP);
  • способен обрабатывать сотни запросов в секунду при правильной настройке;
  • WebSocket-поддержка через расширения (Flask-SocketIO) для реального времени.

В этой статье мы рассмотрим создание простого чат-бота на основе шаблонов (Pattern-Based), работающего по принципу сопоставления ключевых слов. Развернуть такого бота можно всего за день. При грамотной настройке с использованием регулярных выражений и конечных автоматов он справится с большинством типовых задач — от ответов на частые вопросы до навигации по сайту и сбора контактной информации. Для более «умного» поведения уже понадобится NLP.

Аренда VPS/VDS от 219 руб/месяц

Преимущества VPS в AdminVPS:

✓ Бесплатное администрирование

✓ Только быстрые NVMe-диски

✓ Защита от DDoS-атак

✓ Быстрая техподдержка

Аренда VPS/VDS виртуального сервера от AdminVPS — это прозрачная и честная услуга с доступной ценой

Подготовка среды

Установка Python и инструментов (на Debian/Ubuntu):

sudo apt update
sudo apt install python3.11-venv python3-pip

Создаём виртуальное окружение:

mkdir chatbot && cd chatbot
python3 -m venv venv
source venv/bin/activate

Установка Flask и зависимостей:

pip install flask flask-httpauth
Примерная структура проекта
Примерная структура проекта

Пишем простой бот на правилах (Pattern-Based)

Пример файла app.py:

# app.py
from flask import Flask, request, jsonify
app = Flask(__name__)
responses = {
    "привет": "Здравствуйте! Чем могу помочь?",
    "как дела": "Всё отлично, спасибо!",
    "погода": "Погоду можно узнать <a href='https://pogoda.ru'>здесь</a>",
    "default": "Извините, не понимаю ваш вопрос. Попробуйте перефразировать."
}
@app.route('/chat', methods=['POST'])
def chat_handler():
    user_message = request.json.get('message', '').lower()   
    # Поиск совпадения с ключевыми фразами
    for pattern, response in responses.items():
        if pattern in user_message:
            return jsonify({"reply": response})
    return jsonify({"reply": responses["default"]})

Ключевые элементы:

  • @app.route('/chat', methods=['POST']) — создаёт обработчик (endpoint), принимающий POST-запросы по адресу /chat;
  • request.json.get('message', '') — извлекает текст сообщения из JSON-тела запроса;
  • lower() — приводит текст к нижнему регистру для унификации сравнения;
  • цикл for pattern, response in responses.items() — итерирует по словарю с шаблонами.

Протестируем бот локально. Запуск встроенного сервера разработки Flask (приложение будет искать экземпляр Flask с именем app в файле app.py):

flask --app app run --port 5000

Отправка тестового запроса через curl:

curl -X POST http://localhost:5000/chat \
  -H "Content-Type: application/json" \
  -d '{"message":"Привет! Как дела?"}'

curl должен вывести:

  "reply": "Здравствуйте! Чем могу помочь?"
}

Сценарии использования

Pattern-Based бот подходит для:

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

Рассмотрим конкретные сценарии использования, которые встречаются чаще всего.

Первая линия службы поддержки

Обращаясь в поддержку, большинство пользователей задают однотипные вопросы, например:

  • Как сбросить пароль?
  • Где посмотреть тарифы?
  • Как связаться с отделом продаж?

На них может отвечать чат-бот, если загрузить в него ответы на FAQ — что снизит нагрузку на живых операторов.

Примеры шаблонов ответов:

  responses = {
      "пароль": "Перейдите на страницу восстановления пароля: https://site.com/recover",
      "тариф": "Тарифы: https://site.com/pricing",
      "отдел продаж": "Звоните +7-XXX-XXX-XX-XX или email sales@site.com",
  }

Навигация по сайту/сервису

Бот может помогать в поиске разделов:

  • Где найти документацию?
  • Как пополнить баланс?

Пример:

  {
      "документация": "Документация: https://site.com/docs",
      "пополнить баланс": "Инструкция: https://site.com/payment",
  }

Причём он может возвращать не только текст, но и JSON с глубокими ссылками (deeplinks).

Триггеры для автоматизации

Инициирование процессов:

  • зарегистрируй меня → запуск регистрации;
  • хочу тестовый период → создаёт trial-аккаунт;
  • отмени подписку → отправляет запрос в биллинг.

Реализация:

  if "тестовый период" in user_message:
      create_trial_account(request.json['user_id'])
      return jsonify({"reply": "Аккаунт создан! Данные отправлены на email."})

Сбор информации

Анкетирование:

import redis
r = redis.Redis(
    host='localhost',
    port=6379,
    decode_responses=True
)
@app.route('/chat', methods=['POST'])
def chat_handler():
    user_id = request.json.get('user_id')
    user_message = request.json.get('message', '').lower()
    user_state = r.get(f"user_state:{user_id}")
    if user_state == "waiting_email":
        if validate_email(user_message):
            save_email(user_id, user_message)
            r.delete(f"user_state:{user_id}")
            return jsonify({"reply": "Спасибо! Данные сохранены."})
        else:
            return jsonify({"reply": "Некорректный email. Повторите:"})   
    if "подписаться" in user_message:
        r.setex(f"user_state:{user_id}", 1800, "waiting_email")
        return jsonify({"reply": "Введите email:"})

Интеграция с внешними API

Бот может выполнять простые запросы:

  • курс доллара → запрос к ЦБ РФ;
  • погода в Москве → вызов WeatherAPI;
  • акции Apple → Financial Modeling Prep API.

Пример:

  if "курс доллара" in user_message:
      rate = get_cbr_currency_rate("USD")
      return jsonify({"reply": f"Курс доллара: {rate} руб."})

Веб-интерфейс для бота

Чтобы пользователь мог взаимодействовать с ботом в браузере, ему нужен веб-интерфейс. Пример простого HTML-шаблона (файл templates/index.html):

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Чат-бот</title>
    <link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
</head>
<body>
    <div class="chat-container">
        <div id="chat-history"></div>
        <input type="text" id="user-input" placeholder="Введите сообщение...">
        <button onclick="sendMessage()">Отправить</button>
    </div>
    <script>
        async function sendMessage() {
            const input = document.getElementById('user-input');
            const message = input.value.trim();
            if (!message) return;
            // Добавляем сообщение пользователя в историю
            addToChat(message, 'user');
            const response = await fetch('/chat', {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({ message })
            });
            const data = await response.json();
            addToChat(data.reply, 'bot');
            input.value = '';  // Очищаем поле ввода
        }
        function addToChat(text, sender) {
            const history = document.getElementById('chat-history');
            const messageDiv = document.createElement('div');
            messageDiv.className = `message ${sender}`;
            messageDiv.textContent = text;
            history.appendChild(messageDiv);
        }
    </script>
</body>
</html> 

Ограничения Pattern-Based подхода

Боты на основе шаблонов имеют жёсткие правила: они не понимают синонимы, например, на каждый вариант приветствия («Привет», «Здравствуйте», «Добрый день» и т. д.) нужны отдельные шаблоны. Также такой бот не понимает контекст диалога, не обрабатывает сленг, опечатки, то есть в случае ошибки пользователя шаблон не сработает (например, «превет» не будет распознано без соответствующего шаблона).

Распознавание ошибок пользователей можно улучшить, если использовать регулярные выражения:

  import re
  patterns = {
      r"(привет|здравствуй|добр(ый|ое))": "Привет!",
      r"(погод[аы])\s*(в)?\s*([а-я]+)": handle_weather_request,
  }
  def handle_weather_request(match):
      city = match.group(3)
      return f"Погода в {city}: ..."

Ещё один способ — синонимы через ИИ:

  from synonyms import get_synonyms
  expanded_responses = {}
  for phrase, reply in responses.items():
      for synonym in get_synonyms(phrase):  # ваша функция расширения
          expanded_responses[synonym] = reply

Когда переходить на NLP-бота:

  • Нужно настроить большое количество интентов: когда количество шаблонов превышает 100 или появляются синонимичные запросы, есть смысл перейти на NLP-бота.
  • Пользователи предпочитают естественные формулировки: «Хочу купить билет на завтра в СПб», а не «Купить авиабилет».
  • Нужно реализовать контекстные диалоги: «Ищу ноутбук» → «Какой бюджет?» → «До 100 тысяч».

Читайте в блоге:

Loading spinner
0 Комментарий
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии

VPN на VPS-сервере

Узнайте, как создать собственный VPN на VPS-сервере для защиты ваших конфиденциальных данных!

Что будем искать? Например,VPS-сервер

Мы в социальных сетях