Реалізація AI-чат-бота в мобільному додатку
Інтегрувати GPT-4o або Claude в мобільний чат — це не «підключити SDK і готово». Справжня складність починається після першого робочого запиту: управління контекстом діалогу, відображення потокової генерації без смикання UI, обробка мережі при поганому сигналі та зберігання історії чатів між сесіями без витоку персональних даних. Ми — команда з 8-річним досвідом у мобільній розробці, яка реалізувала 40+ проєктів з AI-функціями (понад 5 років на ринку). Пропонуємо інтеграцію AI-чат-бота під ключ: від вибору моделі до публікації в сторах. Оцінимо ваш проєкт за 1–2 дні.
Як управляти контекстом діалогу без втрати якості?
Усі LLM — stateless. Кожен запит до OpenAI, Anthropic, GigaChat або YandexGPT відправляє повну історію діалогу. Це означає: зберігання та урізання контексту — ваше завдання. При наївній реалізації після 20 повідомлень вартість токенів зростає в 3–4 рази, а при контексті 128k — можна отримати відповідь через 30+ секунд.
Практичне рішення — ковзне вікно з summarisation:
class ConversationManager {
private var messages: [ChatMessage] = []
private let maxMessages = 20
private let summaryThreshold = 15
func addMessage(_ message: ChatMessage) {
messages.append(message)
if messages.count > summaryThreshold {
Task { await compressSummary() }
}
}
private func compressSummary() async {
// Беремо повідомлення до порогу, сумаризуємо окремим запитом до LLM
let toCompress = Array(messages.prefix(10))
let summary = try? await llmClient.summarize(messages: toCompress)
if let summary {
messages = [ChatMessage(role: .system, content: "Контекст: \(summary)")] +
Array(messages.suffix(10))
}
}
}
Системний промпт — окрема історія. Він має залишатися першим повідомленням завжди. При стисненні контексту не чіпайте його.
Як забезпечити потокову генерацію без затримок?
Користувач не повинен чекати повної відповіді. Стрімінг через SSE — стандарт для всіх сучасних LLM API. На iOS:
// Оновлення SwiftUI View через @Published
class ChatViewModel: ObservableObject {
@Published var streamingText = ""
func streamResponse(for prompt: String) {
streamingText = ""
Task {
for try await chunk in llmClient.stream(prompt: prompt) {
await MainActor.run {
streamingText += chunk
}
}
}
}
}
На Android з Compose — StateFlow<String>, що оновлюється з collectAsState(). Типова помилка: виклик notifyDataSetChanged() або перестворення RecyclerView Adapter на кожен чанк — це дає видиме миготіння. Оновлюйте лише текст останнього повідомлення, не весь список.
Поради щодо оптимізації стрімінгу
- Використовуйте incremental відображення: додавайте нові чанки до існуючого тексту, а не замінюйте весь текст. - Для дуже довгих відповідей (понад 30 секунд) додайте прогресс-індикатор або анімацію набору тексту. - Встановіть `timeoutIntervalForResource: 120` для URLSession, щоб уникнути передчасних таймаутів.Offline-режим: on-device vs cloud
| Критерій | On-device модель | Cloud LLM (GPT-4o) |
|---|---|---|
| Затримка (перший чанк) | ~50 мс (без мережі) | 200–800 мс |
| Швидкість генерації | ~15 токенів/сек (iPhone 15 Pro) | 50–150 токенів/сек |
| Конфіденційність | Дані на пристрої | Передача провайдеру |
| Складність | Потрібна оптимізація під чип | Готовий API |
| Сценарій | FAQ, автодоповнення | Творчі відповіді, сумаризація |
Для базових сценаріїв — Apple Intelligence API (iOS 18+) або SmartReply від ML Kit. Для складнішого — llama.cpp через Metal/CoreML. On-device модель дає відповідь у 3 рази швидше для простих запитів завдяки відсутності мережевої затримки. Гарантуємо коректну роботу з будь-яким стеком.
Зберігання історії діалогів
Історія чатів — персональні дані. SQLite/Core Data з шифруванням через SQLCipher або iOS Data Protection. Не зберігайте історію в UserDefaults — вона синхронізується в iCloud без шифрування. На Android — Room з EncryptedSharedPreferences для ключів шифрування.
Стратегія очищення: автовидалення діалогів старших за N днів (рекомендуємо 30 днів), або явне видалення за запитом користувача — вимога GDPR та 152-ФЗ.
Що входить у роботу
- Архітектура: вибір LLM-провайдера, on-device vs cloud, схема авторизації.
- Бекенд-проксі з rate limiting, кешуванням, логуванням.
- ConversationManager: ковзне вікно, summarization, системний промпт.
- Чат-UI: bubble-layout, стрімінг, typing indicator, react-кнопки.
- Сховище історії: шифрування, автоочищення, експорт.
- Moderation API: фільтрація вводу та виводу.
- Тестування edge-cases: втрата мережі, довгі відповіді, паралельні запити.
- Документація: README, схема потоків, інструкція з розгортання.
- Підтримка: 2 тижні після здачі (консультації, багфікси).
Типові проблеми в продакшені
Повторювані відповіді. GPT іноді зациклюється на паттерні. Параметр presence_penalty: 0.6 та frequency_penalty: 0.3 знижують ймовірність на 60%. Якщо зациклилося — detect-логіка на клієнті: якщо останні 3 повідомлення бота містять > 60% однакових н-грам, скинути контекст.
Timeout при поганій мережі. LLM може генерувати довго. URLSession таймаут за замовчуванням — 60 секунд, це мало для довгих відповідей у режимі стрімінга. Ставте timeoutIntervalForResource: 120 і додатковий прогресс-індикатор «знаю...» після 5 секунд очікування першого чанку.
Moderation. OpenAI Moderation API перед відправкою користувацького вводу — обов'язково для користувацьких додатків. Один POST /v1/moderations дешевший ($0.01 за 1K токенів), ніж відпрацювання скарги в App Store Review.
За даними OpenAI, вартість одного запиту до Moderation API становить $0.01 за 1K токенів.
Процес роботи
- Консультація та оцінка проєкту (1–2 дні).
- Проєктування архітектури: вибір LLM-провайдера, on-device vs cloud, схема авторизації.
- Розробка бекенд-проксі з rate limiting.
- Реалізація ConversationManager з управлінням контекстом (ковзне вікно, summarization).
- Чат-UI зі стрімінгом, bubble-layout, typing indicator.
- Історія діалогів з шифруванням (SQLite/Core Data + SQLCipher).
- Інтеграція Moderation API (OpenAI або власна).
- Тестування edge-cases: втрата мережі під час генерації, дуже довгі відповіді, паралельні запити.
- Здача документації та інструкцій.
Орієнтири за термінами
Простий чат з одним LLM-провайдером без історії — 5–7 днів. Повноцінний чат-бот з історією, стисненням контексту, офлайн-режимом та moderations — 3–5 тижнів. Вартість розраховується індивідуально. Зв'яжіться — отримайте консультацію та оцінку проєкту за 1–2 дні.







