support-bot-saas/README.md
2026-06-20 16:07:21 +03:00

8 KiB
Raw Blame History

RAG-ассистент техподдержки

Система поиска решений по истории обращений в техподдержку. Основана на RAG (Retrieval-Augmented Generation) — находит похожие решённые тикеты и формирует ответ на их основе.


Архитектура

tickets.json (792 тикета)
      │
      ▼
prepare_data.py         ← фильтрация, очистка, нарезка чанков
      │
      ▼
sentence-transformers    ← векторизация (intfloat/multilingual-e5-small, GPU CUDA)
      │
      ▼
chroma_db/              ← векторная база данных (416 чанков)
      │
      ▼
app.py                  ← Streamlit-интерфейс
      │
      ├── вопрос специалиста → embedding → поиск топ-5
      │                                   │
      │                                   ▼
      └── контекст → LM Studio (qwen2.5-7b) → ответ

Как это работает

1. Подготовка данных (prepare_data.py)

Что делает скрипт:

  • Читает все файлы tickets*.json в папке проекта (сейчас 6 файлов, ~3300 тикетов)
  • Чистит текст: удаляет цитаты [q]...[/q], ссылки, лишние пробелы
  • Фильтрует: оставляет только тикеты с реальным решением. Отбрасываются:
    • тикеты, где последнее сообщение support — просьба уточнить / прислать скрин
    • тикеты без ответа / с закрытием "нет обратной связи"
    • слишком короткие сообщения (< 100 символов)
  • Формирует чанки: каждый тикет = один чанк вида:
    Категория: ...
    Проблема: <описание>
    Решение: <все сообщения support>
    
  • Векторизует: превращает текст в вектор (384 числа) через intfloat/multilingual-e5-small на GPU
  • Сохраняет в ChromaDB (папка chroma_db/)

Результат: 416 чанков с реальными решениями (376 тикетов отфильтровано как бесполезные).

2. Поиск и генерация (app.py)

Специалист вводит проблему клиента. Приложение:

  1. Векторизует вопрос той же моделью эмбеддингов
  2. Ищет 5 похожих чанков в ChromaDB по косинусной близости
  3. Формирует контекст из найденных тикетов
  4. Отправляет в LM Studio (чат-модель Qwen2.5-7B) с промптом:

    "Ответь на основе ТОЛЬКО переданного контекста. Не придумывай, не отсылай в другую поддержку"

  5. Показывает ответ и исходные тикеты для проверки

Установка и запуск

Требования

  • Python 3.11+
  • NVIDIA GPU с 8+ GB VRAM (для эмбеддингов и LLM)
  • LM Studio (для чат-модели)

Установка

pip install -r requirements.txt

Установить PyTorch с CUDA (если ещё не):

pip install torch torchvision --index-url https://download.pytorch.org/whl/cu124

Подготовка базы знаний

python prepare_data.py

Скрипт создаст папку chroma_db/ с векторной базой.

Запуск

streamlit run app.py --server.headless true

Открыть в браузере: http://localhost:8501

Запуск чат-модели

Для генерации ответов нужна чат-модель в LM Studio:

  1. Открыть LM Studio
  2. Вкладка Developer → загрузить модель (например, Qwen2.5-7B-Instruct)
  3. Нажать Start Server
  4. API будет доступен на http://localhost:1234/v1

Без чат-модели приложение работает в режиме поиска — показывает похожие тикеты без генерации ответа.

Структура проекта

support-bot/
├── tickets*.json         # исходные данные (несколько файлов)
├── prepare_data.py       # подготовка и векторизация
├── app.py                # Streamlit-интерфейс + RAG
├── requirements.txt      # зависимости
├── chroma_db/            # векторная БД (создаётся prepare_data.py)
└── .gitignore

Системные промпты

Главный системный промпт — в файле app.py:15, переменная SYSTEM_PROMPT:

SYSTEM_PROMPT = """Ты — специалист техподдержки. Отвечай клиенту, используя ТОЛЬКО информацию из переданных тикетов (контекст).

Правила:
- Если контекст содержит подходящее решение — напиши ответ своими словами, адаптируя под вопрос
- Если контекст не относится к вопросу — напиши: «Недостаточно информации в истории обращений»
- НЕ придумывай ответы, НЕ используй общие знания
- НЕ говори «обратитесь в службу поддержки» — ты сам и есть поддержка
- Укажи в конце: «Основано на тикете №...»"""

Именно этот промпт управляет тем, как LLM отвечает на вопрос специалиста. Если нужно изменить стиль ответа, тон, правила или требования к формату — редактировать здесь.

Промпт отправляется в LM Studio как system-сообщение при каждом запросе генерации ответа (строка app.py:120-127).

Фильтрация тикетов без решения

Паттерны для отбраковки пустых тикетов — в prepare_data.py:19-22, переменная NON_SOLUTION:

NON_SOLUTION = re.compile(
    r"(уточнит|приложите скрин|какая ошибка|с какой проблемой"
    r"|нет обратной связи|запрос завершу|открыть его снова"
    r"|откройте новый|обратиться в службу поддержки"
    r"|свяжитесь с технической"
    r"|напишите нам|позвоните нам)", re.I
)

Если в последнем сообщении support встречается одно из этих слов — тикет считается бесполезным и не попадает в базу знаний. Можно расширять или уточнять список.


Технологии

Компонент Технология
Эмбеддинги intfloat/multilingual-e5-small (384d, GPU) через sentence-transformers
Векторная БД ChromaDB
Чат-модель Qwen2.5-7B-Instruct через LM Studio (OpenAI-совместимый API)
Фреймворк LangChain + Streamlit
Язык Python 3.11
GPU CUDA 12.4+

Git

git remote add origin https://git.itoservice.ru/dosnav/support-bot.git
git push -u origin master