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

172 lines
8 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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](https://lmstudio.ai/) (для чат-модели)
### Установка
```bash
pip install -r requirements.txt
```
Установить PyTorch с CUDA (если ещё не):
```bash
pip install torch torchvision --index-url https://download.pytorch.org/whl/cu124
```
### Подготовка базы знаний
```bash
python prepare_data.py
```
Скрипт создаст папку `chroma_db/` с векторной базой.
### Запуск
```bash
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`:
```python
SYSTEM_PROMPT = """Ты — специалист техподдержки. Отвечай клиенту, используя ТОЛЬКО информацию из переданных тикетов (контекст).
Правила:
- Если контекст содержит подходящее решение — напиши ответ своими словами, адаптируя под вопрос
- Если контекст не относится к вопросу — напиши: «Недостаточно информации в истории обращений»
- НЕ придумывай ответы, НЕ используй общие знания
- НЕ говори «обратитесь в службу поддержки» — ты сам и есть поддержка
- Укажи в конце: «Основано на тикете №...»"""
```
Именно этот промпт управляет тем, **как LLM отвечает** на вопрос специалиста. Если нужно изменить стиль ответа, тон, правила или требования к формату — редактировать здесь.
Промпт отправляется в LM Studio как `system`-сообщение при каждом запросе генерации ответа (строка `app.py:120-127`).
### Фильтрация тикетов без решения
Паттерны для отбраковки пустых тикетов — в **`prepare_data.py:19-22`**, переменная `NON_SOLUTION`:
```python
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
```bash
git remote add origin https://git.itoservice.ru/dosnav/support-bot.git
git push -u origin master
```