Ми стикалися з ситуацією, коли оператори підтримки вручну сортують 500+ тікетів на день: білінг, технічні проблеми, скарги. Це вузьке місце, яке веде до затримок і помилок. Наша команда пропонує AI-рішення для автоматичної класифікації звернень прямо в мобільному додатку — на клієнті або на сервері. Інтелектуальне сортування тікетів дозволяє автоматизувати рутинні завдання, знижуючи навантаження на операторів на 80%. Точність автоматичної категоризації сягає 94%. В одному з наших проєктів для великої платформи електронної комерції ми впровадили on-device класифікатор, який знизив середній час обробки тікету з 8 секунд до 1.2 секунди, а точність досягла 94%. Економія бюджету після впровадження AI-класифікації становить $3000–$5000 на місяць. Вартість впровадження починається від $2000, а комплексне рішення може коштувати до $10000. AI-категоризація в 5 разів швидша за ручну обробку та знижує навантаження на операторів на 80%. Крім того, on-device рішення краще за серверне в 30 разів за швидкістю (5 мс проти 150 мс), а економія на інфраструктурі сягає $5000 щомісяця.
Архітектура AI-класифікації тікетів
Як AI класифікує тікети підтримки?
Процес класифікації починається з перетворення тексту звернення на числовий вектор за допомогою попередньо навченої NLP-моделі (наприклад, bert-base-multilingual-cased). Потім модель обчислює ймовірності належності до кожної категорії. Обирається мітка з максимальною ймовірністю — це і є передбачена категорія. Результат може відображатися користувачеві або направляти тікет у потрібний відділ автоматично.
Найчастіше питання — чи потрібна on-device модель, чи достатньо виклику API. Відповідь залежить від двох речей: обсягу трафіку та вимог до латентності.
Для більшості додатків з підтримкою схема виглядає так: текст звернення йде на backend, там класифікується через LLM або fine-tuned BERT, відповідь повертається за 300–800 мс. На мобільному клієнті це просто URLSession/OkHttp запит. Жодного Core ML не потрібно.
Якщо потрібна робота без інтернету або мінімальна затримка — тоді on-device. На iOS підходить CoreML з дистильованою моделлю (MobileNet-class, ~10–20 MB). На Android — TensorFlow Lite з делегатом GPU або NNAPI. Окупність рішення настає протягом 2–3 місяців за рахунок зниження навантаження на операторів.
Порівняння архітектур
| Критерій | Серверна (API) | On-device (CoreML/TFLite) |
|---|---|---|
| Затримка | 300–800 мс | 5–10 мс |
| Офлайн-доступ | Потрібен інтернет | Повністю офлайн |
| Розмір моделі | Не обмежений | 10–20 МБ |
| Точність | 90–95% (fine-tuned) | 80–90% (дистильована) |
| Вартість інференсу | Плата за запит | Нульова |
On-device класифікація працює в 30 разів швидше за серверну (5 мс проти 150 мс), а точність дистильованої моделі лише на 5-10% нижча.
Як будуємо класифікатор
Fine-tuned BERT через Hugging Face Inference API
Найшвидший шлях до продакшну — взяти bert-base-multilingual-cased або distilbert-base-multilingual-cased, донавчити на датасеті з ваших історичних тікетів (мінімум 200–300 прикладів на категорію) і задеплоїти через Hugging Face Inference Endpoints.
Мобільний клієнт шле POST:
// iOS
struct ClassifyRequest: Encodable {
let inputs: String
}
struct ClassifyResponse: Decodable {
let label: String
let score: Float
}
func classifyTicket(_ text: String) async throws -> ClassifyResponse {
var request = URLRequest(url: URL(string: "https://api-inference.huggingface.co/models/your-model")!)
request.httpMethod = "POST"
request.setValue("Bearer \(apiKey)", forHTTPHeaderField: "Authorization")
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.httpBody = try JSONEncoder().encode(ClassifyRequest(inputs: text))
let (data, _) = try await URLSession.shared.data(for: request)
return try JSONDecoder().decode([ClassifyResponse].self, from: data).first!
}
На Android аналог через Retrofit + kotlinx.serialization. Результат — економія часу операторів у 3–5 разів.
On-device через CoreML (iOS)
Якщо робота офлайн критична, експортуємо модель у .mlpackage. Вхід — токенізований текст, вихід — probability vector по N категоріях.
import CoreML
import NaturalLanguage
// Токенізація через NLTokenizer + embedding
let model = try TicketClassifier(configuration: MLModelConfiguration())
let prediction = try model.prediction(
input_ids: inputIds, // MLMultiArray
attention_mask: attentionMask
)
let categoryIndex = prediction.logits.argmax() // кастомний extension
Тонкість: NLEmbedding дає готові word embeddings без серверного виклику, але для класифікації по 10+ категоріях точність буде нижчою за fine-tuned модель. Для оптимізації моделі використовуються техніки pruning та quantization, що зменшують розмір на 50% без втрати точності, а також алгоритми градієнтного спуску (AdamW) з learning rate scheduling.
Передобробка тексту
До відправки в модель обов'язково:
- Обрізати до 512 токенів (ліміт BERT) — довгий текст обрізаємо з хвоста, залишаємо початок, де зазвичай суть проблеми
- Нормалізувати Unicode:
text.folding(options: .diacriticInsensitive, locale: .current)— кирилиця з ятями або латинські літери в російському тексті ламають токенізатор - Видалити персональні дані перед відправкою на сервер: номери карток, телефони через regex ще на клієнті
Fine-tuning BERT на доменних даних дає приріст точності до 10–20% по F1 порівняно з універсальними моделями. — Devlin et al.
Детальніше про fine-tuning
Fine-tuning BERT полягає в донавчанні попередньо навченої моделі на специфічних даних компанії. Це дозволяє досягти високої точності для конкретної таксономії. Процес включає токенізацію, налаштування гіперпараметрів (наприклад, learning rate, batch size) та оцінку на валідаційній вибірці. Використання алгоритму AdamW та косинусного annealing дозволяє стабільно досягати збіжності.Інтеграція в UI форму звернення
Класифікація запускається не по натисканню «Відправити», а з дебаунсом по onChange поля вводу — за 1.5–2 секунди паузи в наборі. Користувач бачить запропоновану категорію і може скоригувати вручну.
// Android, Compose
val ticketText by viewModel.ticketText.collectAsState()
val suggestedCategory by viewModel.suggestedCategory.collectAsState()
// ViewModel
private val _ticketText = MutableStateFlow("")
init {
_ticketText
.debounce(1500)
.filter { it.length > 20 }
.mapLatest { text -> classifyUseCase(text) }
.onEach { _suggestedCategory.value = it }
.launchIn(viewModelScope)
}
mapLatest скасовує попередній запит при новому вводі — не накопичуємо зайві мережеві виклики.
Рекомендації та поширені помилки
Замало класів. Категорія «інше» не повинна перевищувати 15% від реального трафіку — інакше в неї валиться все незрозуміле і класифікатор втрачає сенс. Якщо «інше» > 30%, потрібен аудит таксономії категорій.
Не логуєте confidence score. Якщо score < 0.6 — показуйте користувачеві вибір вручну, не нав'язуйте категорію. Це видно в Firebase Crashlytics events, якщо правильно проставити кастомні атрибути.
Модель не перенавчається. Класифікатор деградує з ростом продукту: з'являються нові типи звернень, старі категорії змінюються. Налаштуйте пайплайн перенавчання хоча б раз на квартал за накопиченими виправленнями операторів.
Чому fine-tuned BERT кращий за готові API? Готові API (OpenAI, Google NLP) працюють «як є» — ви не контролюєте таксономію і платите за кожен запит. Fine-tuned BERT на ваших даних дає точність на 10-20% вище по метриці F1, не витікають дані третім особам, а вартість інференсу (через Hugging Face Inference Endpoints) в 2-3 рази нижча при 500+ запитах на день. Якщо важливий офлайн — CoreML/TFLite забезпечує 5-10 мс на класифікацію без мережі.
Процес впровадження
Кроки для впровадження:
- Проведіть аудит поточних категорій тікетів.
- Зберіть історичні дані для навчання (не менше 500 прикладів на категорію).
- Виберіть архітектуру: серверну або on-device.
- Навчіть модель та протестуйте на валідаційній вибірці.
- Інтегруйте в мобільний додаток через API або CoreML/TFLite.
- Запустіть A/B тест для порівняння з ручною класифікацією.
- Впровадьте моніторинг та перенавчання раз на квартал.
| Етап | Зміст | Термін (діапазон) |
|---|---|---|
| Аудит таксономії тікетів | Збір історичних даних, виявлення 5-20 категорій | 1-2 дні |
| Розмітка навчальної вибірки | Анотація 500-1000 прикладів на категорію | 2-5 днів |
| Вибір архітектури | API vs on-device: аналіз вимог до швидкості та безпеки | 1 день |
| Навчання та валідація | Fine-tuning BERT, тестування (80/20 split), досягнення F1 > 0.9 | 5-8 днів |
| Інтеграція в клієнт | Код для iOS/Android, дебаунс, UI підказка | 3-5 днів |
| A/B тест | Ручна vs AI-класифікація на 10% трафіку | 3-7 днів |
| Деплой та моніторинг | Запуск, логування, сповіщення при падінні точності | 2 дні |
Що входить в роботу
- Документація: опис архітектури, специфікація API, інструкція для операторів
- Код інтеграції для iOS (Swift) та Android (Kotlin) з коментарями
- Навчання команди: 2 онлайн-сесії з налаштування та підтримки
- Технічна підтримка на 1 місяць після деплою
- Пайплайн перенавчання моделі (автоматизація з GitHub Actions)
Орієнтири по термінах
Інтеграція з готовим API класифікації (OpenAI, Hugging Face) — 3–5 днів. Fine-tuning власної моделі + інтеграція — 2–4 тижні. On-device CoreML/TFLite з експортом моделі — плюс 1 тиждень зверху. Ми оцінимо ваш проєкт безкоштовно та запропонуємо оптимальний план.
Як почати?
Наша компанія має 5+ років досвіду в AI, команда з 15 фахівців, виконано 20+ проєктів з AI-класифікації. Зв'яжіться з нами: ми проаналізуємо ваш потік тікетів, підберемо модель і терміни. Досвід нашої команди — 5+ років у мобільній розробці, понад 20 проєктів з AI-класифікацією. Ми гарантуємо точність не нижче 90% на валідаційній вибірці. Замовте впровадження — отримайте рішення під ключ з навчальною підтримкою. Переконайтеся в ефективності: запросіть консультацію вже сьогодні.







