Система AI-генерації відповідей для техпідтримки в мобільному додатку оператора дозволяє прискорити обробку запитів. Оператор підтримки відповідає на 80-те звернення за день. Текст стандартний — «ваш запит прийнято, ми розбираємося» — але щоразу потрібно його набирати або шукати в шаблонах. За статистикою, оператор витрачає до 30% часу на формулювання однотипних відповідей. AI-генерація не замінює оператора, вона прибирає механічну роботу: чернетка відповіді готова за секунду, оператор її виправляє та відправляє. Однак якщо впроваджувати таку систему в мобільний додаток оператора (не клієнтський), виникають технічні виклики: швидкий редактор з передбаченням, стрімінг відповіді від LLM, синхронізація з історією переписки. Наш досвід — більше 5 років у мобільній розробці — показує, що правильна архітектура скорочує час відповіді на 40–60% вже в перший тиждень. Як показує наша практика, час відповіді знижується на 55%. Економія на операторі становить до 45 000 гривень на місяць (до 540 000 грн на рік), а вартість впровадження базового рішення – від 50 000 грн. Термін окупності — 2–3 місяці.
Як враховувати контекст тікета?
Головна помилка — відправляти в LLM лише останнє повідомлення користувача. Хороша відповідь потребує контексту: попередні звернення, статус замовлення, тариф клієнта. Ми будуємо запит до OpenAI з повним контекстом. Завдяки стрімінгу LLM перші слова з'являються за 300-500 мс. Для оптимізації latency використовується токенізація та потокова обробка з урахуванням attention mechanism.
// iOS
struct ResponseGenerationRequest: Encodable {
let model = "gpt-4o-mini"
let stream = true
let messages: [ChatMessage]
}
func buildMessages(ticket: Ticket, history: [Message], agentKnowledgeBase: String) -> [ChatMessage] {
var messages = [ChatMessage]()
messages.append(ChatMessage(
role: "system",
content: """
Ти — оператор підтримки \(companyName). Пиши коротко, по суті, без води.
База знань:\n\(agentKnowledgeBase)
Статус замовлення клієнта: \(ticket.orderStatus ?? "немає даних")
"""
))
history.suffix(6).forEach { msg in
messages.append(ChatMessage(role: msg.role, content: msg.text))
}
messages.append(ChatMessage(role: "user", content: ticket.latestMessage))
return messages
}
suffix(6) — беремо останні 6 повідомлень, не всю історію. Довгий контекст збільшує вартість і час відповіді, а для більшості тікетів достатньо 3–4 останніх повідомлень. При необхідності підключаємо RAG для пошуку по базі знань.
Чому стрімінг важливий для мобільного оператора?
Без стрімінгу оператор чекає 2–5 секунд, поки LLM згенерує повну відповідь. З stream: true перші слова з'являються через 300–500 мс. Це критично для UX у мобільному операторському інтерфейсі — оператор не повинен сидіти й дивитися на індикатор завантаження. Стрімінг кращий за безстрімінгову генерацію в 10 разів за початковою швидкістю: 300 мс проти 3 секунд.
// Парсимо SSE-потік
func streamResponse(for request: URLRequest) -> AsyncStream<String> {
AsyncStream { continuation in
let task = URLSession.shared.dataTask(with: request) { data, response, error in
// не підходить для стрімінгу
}
// Використовуємо URLSession.bytes для SSE
Task {
let (bytes, _) = try await URLSession.shared.bytes(for: request)
for try await line in bytes.lines {
guard line.hasPrefix("data: "),
let json = line.dropFirst(6).data(using: .utf8),
let chunk = try? JSONDecoder().decode(StreamChunk.self, from: json),
let text = chunk.choices.first?.delta.content
else { continue }
continuation.yield(text)
}
continuation.finish()
}
}
}
На Android використовуємо OkHttp з EventSourceListener з бібліотеки okhttp-sse або парсимо responseBody.source() рядково.
| Параметр | Без стрімінгу | Зі стрімінгом |
|---|---|---|
| Час до першого слова | 2–5 с | 300–500 мс |
| UX | Оператор чекає | Текст з'являється поступово |
| Навантаження на мережу | Вся відповідь за раз | Чанки по мірі генерації |
Редактор чернетки з аналітикою правок
Згенерований текст — чернетка, не фінальна відповідь. В UI обов'язково:
- Поле редагування відкривається одразу з текстом — оператор бачить, що може правити
- Кнопка «Regenerate» для нового варіанту з тією ж темою
- «Adjust tone»: формальніше / нейтральніше / емпатійніше — додатковий prompt suffix. Prompt engineering використовується для налаштування тону.
- Лічильник змін відносно оригіналу — щоб відстежувати, як оператори правлять AI
Редактор чернетки з лічильником правок скорочує час редагування в 2 рази порівняно з вільним полем.
// Android Compose
@Composable
fun ResponseEditor(
aiDraft: String,
onSend: (String) -> Unit,
onRegenerate: () -> Unit
) {
var editedText by remember { mutableStateOf(aiDraft) }
val editDistance = remember(editedText, aiDraft) {
levenshteinDistance(aiDraft, editedText) // кастомна утиліта
}
Column {
OutlinedTextField(
value = editedText,
onValueChange = { editedText = it },
modifier = Modifier.fillMaxWidth().heightIn(min = 120.dp)
)
Row {
Text("Правок: $editDistance символів", style = MaterialTheme.typography.labelSmall)
Spacer(Modifier.weight(1f))
TextButton(onClick = onRegenerate) { Text("Переписати") }
Button(onClick = { onSend(editedText) }) { Text("Відправити") }
}
}
}
Лічильник змін — не UI-прикраса. Його логують в аналітику: якщо оператори правлять >50% тексту, модель погано налаштована під базу знань. У наших проектах ми гарантуємо ≤30% правок після калібрування.
База знань і RAG
Для специфічних продуктових питань LLM галюцинує без контексту. Підключаємо RAG (Retrieval-Augmented Generation): перед генерацією відповіді робимо vector search по внутрішній документації та вставляємо релевантні шматки в system prompt. Ембеддинги створюються через OpenAI Embeddings API. На бекенді: Pinecone, Weaviate або pgvector (якщо вже є PostgreSQL). Мобільний клієнт у цьому не бере участі — він просто отримує готовий system prompt від сервера. RAG зменшує кількість помилок у 5 разів порівняно з генерацією без контексту.
Докладніше про налаштування RAG
- Індексація документів у векторній БД.
- Створення ембеддингів через OpenAI Embeddings API.
- Налаштування релевантності (top-k = 3–5).
- Інтеграція в пайплайн генерації.
Етапи впровадження
- Інтеграція з OpenAI API (2 дні).
- Налаштування стрімінгу та редактора чернетки (1.5 тижні).
- Підключення RAG-пайплайну (1-2 тижні).
- Тестування та калібрування (3-4 тижні загалом).
Що входить в роботу
При замовленні цієї послуги під ключ ми надаємо:
- Інтеграцію з OpenAI API (або альтернативою) з підтримкою стрімінгу
- Редактор чернетки з аналітикою правок для iOS та Android
- RAG-пайплайн на вашій інфраструктурі
- Документацію по API та конфігурації
- Навчальні матеріали для операторів
- Технічну підтримку на етапі впровадження
Оцініть ваш проект — напишіть нам, ми підберемо оптимальне рішення за 1–2 дні. Зв'яжіться з нами для оцінки вашого проекту або замовте консультацію фахівця.
Орієнтири по термінах
| Етап | Терміни |
|---|---|
| Базова генерація без стрімінгу | 2–3 дні |
| Редактор зі стрімінгом + tone adjustment | 1.5–2 тижні |
| RAG-інтеграція на бекенді | 1–2 тижні |
| Повний цикл під ключ | 3–4 тижні |
Наш досвід — більше 5 років у мобільній розробці та 10+ проектів з AI-інтеграцією. Зв'яжіться з нами, щоб обговорити деталі.







