Інтеграція ChatGPT API у мобільний додаток
Інтеграція ChatGPT API у мобільний додаток — це не просто URLSession.dataTask з JSON-тілом. Це керування потоковим виводом, контекстом діалогу, безпекою ключів та витратами. Кожен з цих аспектів має свої нюанси на мобілі.
API-ключ: ніколи не в клієнтському коді
Перше й головне: OpenAI API-ключ не повинен потрапити в пакет додатку, вихідний код або навіть у зашифровані налаштування на пристрої. Якщо ключ у клієнті — він скомпрометований.
Правильна архітектура: мобільний додаток → ваш backend-proxy → OpenAI API. Backend авторизує користувачів, застосовує обмеження швидкості, логує витрати, надає ключ. Крім того: backend може кешувати типові відповіді, зменшуючи витрати.
На backend: якщо ви не хочете писати proxy з нуля, використовуйте openai-node або openai-python SDK за nginx. Або serverless через Cloudflare Workers — холодний старт ~5 мс, дешевше, ніж EC2 при низькому трафіку.
Потоковий вивід (streaming)
Без streaming користувачі чекають повної відповіді — 3–8 секунд для довгих текстів. З streaming — перший токен з'являється за 200–400 мс, текст зростає по мірі генерації.
OpenAI Chat Completions API з stream: true повертає Server-Sent Events (SSE). На мобілі парсити SSE потрібно вручну — URLSession не підтримує SSE з коробки.
На iOS — URLSessionDataDelegate з urlSession(_:dataTask:didReceive:):
func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data) {
let lines = String(data: data, encoding: .utf8)?.components(separatedBy: "\n") ?? []
for line in lines where line.hasPrefix("data: ") {
let jsonString = String(line.dropFirst(6))
guard jsonString != "[DONE]" else { return }
// парсимо delta.content з JSON
}
}
На Android — OkHttp з EventSourceListener із okhttp-sse:
val eventSource = EventSources.createFactory(client)
.newEventSource(request, object : EventSourceListener() {
override fun onEvent(source: EventSource, id: String?, type: String?, data: String) {
if (data == "[DONE]") return
// парсимо delta.content
}
})
Оновлюйте UI на кожному токені: @Published var streamingText: String (iOS) або StateFlow<String> (Android). Не викликайте recompose / setState надто часто — буферизуйте токени та оновлюйте UI кожні 50–100 мс.
Керування контекстом діалогу
ChatGPT API без стану — кожен запит незалежний. Ви будуєте контекст діалогу: передаєте масив messages з історією.
Обмеження: gpt-4o-mini має контекст із 128k токенів. На практиці довгий контекст означає високі витрати. Стратегії:
- Ковзне вікно — останніх N повідомлень, решту відкидаємо.
-
Резюме — при перевищенні порога (наприклад, 8000 токенів) стискаємо стару історію через окремий запит з
"Summarize this conversation in 3 sentences". - Вибіркова пам'ять — зберігаємо лише повідомлення з високою важливістю (користувач явно вказав факт про себе).
Відстеження витрат
Кожен запит коштує грошей. На мобілі важливо:
- Не надсилати запит при кожному натисненні клавіші (debounce 500 мс)
- Обмежувати
max_tokensу відповіді для завдання — не 4096, де достатньо 256 - Логувати
usage.total_tokensз кожної відповіді в аналітику (Firebase або власний backend) - Встановити обмеження через OpenAI Usage Limits dashboard (жорсткий ліміт на місяць)
Приклад: додаток для вивчення мов з AI-репетитором. gpt-4o-mini, streaming. Контекст — останніх 10 повідомлень + системний промпт з правилами уроку (~300 токенів). Середній запит: 450 input + 180 output токенів. При 500 DAU та 15 повідомленнях на сесію — ~3.4M токенів щодня. При цінах 2025 року — прийнятно. Кешування системного промпту через OpenAI Prompt Caching зменшило вартість input на 35%.
Обробка помилок
429 Too Many Requests — експоненціальний backoff: 1s, 2s, 4s, 8s. Максимум 3 повторення. 503 Service Unavailable — аналогічно. 400 Bad Request — зазвичай проблема із форматом messages (порожній content, неправильна роль). Усі помилки йдуть у Crashlytics / Sentry з повним контекстом запиту (без ключа).
Терміни
Інтеграція з потоковим виводом, керуванням контекстом та backend-proxy — 3–5 робочих днів. Вартість розраховується індивідуально.







