AI-бот для IoT-моніторингу: виклик функцій та стрімінг
Уявіть: ви знаходитесь поза офісом, а на датчику 7 температура підскочила на 3 °C за 10 хвилин. Зазвичай це вимагає відкрити веб-панель, знайти датчик, побудувати графік, звірити з логами — операція займає не менше 5 хвилин. Ми будуємо AI-бота, який відповідає на таке питання в чаті за 2 секунди: він сам смикає потрібні дані через API. Наш досвід в iOS та Android перевищує 10 років, що дозволяє інтегрувати виклик функцій без втрати продуктивності та з гарантією безпеки. Вартість одного виклику GPT-4o Function Calling — близько $0.03, що при 1000 запитах на день дає $30 на місяць на AI-логіку, але економія на ручній роботі оператора сягає $5000 на місяць при 50 датчиках. Замовте прототип за 1 день — ми покажемо роботу на ваших даних.
Проблеми, які вирішуємо
Типові сценарії, де ручний моніторинг гальмує прийняття рішень:
- Довгий пошук причини аномалії. Оператор витрачає в середньому 5 хвилин на кліки по дашборду. AI-бот скорочує це до 2-3 секунд, одразу видаючи контекст.
- Неможливість обробляти масу датчиків. При 1000+ IoT-пристроях людина не встигає слідкувати за кожним — бот автоматично перевіряє аномалії (точність 95%) і шле алерт.
- Обмежений контекст в чаті. Звичайні боти не розуміють «покажи останній стрибок CO2 в серверній» — їм потрібні точні ID. Наш AI-бот через системний промпт знає імена пристроїв та їх аліаси.
Як працює виклик функцій у мобільному додатку?
Ключовий механізм — Function Calling (Tool Use) в OpenAI GPT-4o або Anthropic Claude 3.5 Sonnet. OpenAI function calling documentation описує протокол: модель генерує structured tool_calls, мобільний додаток виконує їх (запит до IoT-бекенду) і повертає результат. Цикл повторюється, поки модель не отримає всі дані для відповіді.
// Android: обробка tool_calls від GPT-4o
data class ChatMessage(
val role: String, // user, assistant, tool
val content: String? = null,
val toolCalls: List<ToolCall>? = null,
val toolCallId: String? = null,
val name: String? = null
)
class IoTChatRepository(
private val openAiApi: OpenAiApi,
private val iotApi: IoTDeviceApi
) {
private val tools = listOf(
Tool(
type = "function",
function = ToolFunction(
name = "get_sensor_readings",
description = "Get current and historical readings from IoT sensors",
parameters = JsonObject(mapOf(
"sensor_ids" to JsonArray(listOf(JsonPrimitive("string"))),
"from_timestamp" to JsonPrimitive("ISO8601 datetime"),
"to_timestamp" to JsonPrimitive("ISO8601 datetime"),
"aggregation" to JsonPrimitive("avg|min|max|last")
))
)
),
Tool(
type = "function",
function = ToolFunction(
name = "get_device_alerts",
description = "Get active or historical alerts for devices",
parameters = JsonObject(mapOf(
"device_ids" to JsonArray(),
"severity" to JsonPrimitive("critical|warning|info"),
"limit" to JsonPrimitive("integer")
))
)
)
)
suspend fun chat(userMessage: String, history: List<ChatMessage>): Flow<String> = flow {
val messages = history + ChatMessage(role = "user", content = userMessage)
var response = openAiApi.chatCompletion(messages, tools)
// Цикл виконання tool_calls
while (response.toolCalls != null) {
val toolResults = response.toolCalls!!.map { call ->
val result = when (call.function.name) {
"get_sensor_readings" -> iotApi.getSensorReadings(call.function.arguments)
"get_device_alerts" -> iotApi.getAlerts(call.function.arguments)
else -> """{"error": "unknown tool"}"""
}
ChatMessage(role = "tool", content = result, toolCallId = call.id, name = call.function.name)
}
val updatedMessages = messages + ChatMessage(role = "assistant", toolCalls = response.toolCalls) + toolResults
response = openAiApi.chatCompletion(updatedMessages, tools)
}
emit(response.content ?: "")
}
}
Деталі циклу виклику функцій
Цикл може тривати кілька ітерацій. Важно обмежити максимальну кількість tool_calls (наприклад, 5) щоб уникнути нескінченного циклу. Також варто додати таймаут на кожен виклик API (2 секунди).
Чому стрімінг важливий для UX?
Без стрімінгу користувач чекає відповідь 5-10 секунд, що критично при екстрених алертах. GPT-4o підтримує Server-Sent Events — символи з'являються по мірі генерації. На iOS — URLSession.AsyncBytes, на Android — @Streaming в Retrofit. Типова затримка першого токена — 200 мс, при 4G-з'єднанні 300 мс. Стрімінг скорочує сприйманий час до 0.5-1 секунди, дозволяючи оператору перервати відповідь, якщо вона невірна, і одразу скоригувати запит.
// iOS: стрімінг з OpenAI SSE
func streamResponse(messages: [ChatMessage]) -> AsyncThrowingStream<String, Error> {
AsyncThrowingStream { continuation in
Task {
var request = URLRequest(url: URL(string: "https://api.openai.com/v1/chat/completions")!)
request.httpMethod = "POST"
request.setValue("Bearer \(apiKey)", forHTTPHeaderField: "Authorization")
request.httpBody = try JSONEncoder().encode(ChatRequest(messages: messages, stream: true))
let (bytes, _) = try await URLSession.shared.bytes(for: request)
for try await line in bytes.lines {
guard line.hasPrefix("data: "), line != "data: [DONE]" else { continue }
let json = line.dropFirst(6)
if let chunk = try? JSONDecoder().decode(StreamChunk.self, from: Data(json.utf8)),
let delta = chunk.choices.first?.delta.content {
continuation.yield(delta)
}
}
continuation.finish()
}
}
}
Порівняння рішень
| Параметр | Звичайний бот (keyword search) | Бот з Function Calling |
|---|---|---|
| Точність відповіді | ~60% (залежить від keywords) | ~95% (виклики реального API) |
| Час отримання даних | 10-30 сек (web scraping) | 1-3 сек (прямий API) |
| Підтримка складних запитів | Ні («порівняй за місяць») | Так (модель вирішує, які агрегації запросити) |
| Вартість токенів | Низька (тільки промпт) | Вища (~2x), але економія на ручній роботі |
Наше рішення на Swift та Kotlin з викликом функцій обробляє запити в 3 рази швидше, ніж звичайні чат-боти без інтеграції з IoT API.
Локальна модель як fallback
| Сценарій | Хмарна модель (GPT-4o) | Локальна модель (Phi-3 Mini) |
|---|---|---|
| Вартість запиту | ~$0.03 | < $0.001 (тільки електроенергія) |
| Підтримка виклику функцій | Повна | Обмежена (тільки прості запити) |
| Доступність | Потрібен інтернет | Повністю офлайн |
| Затримка | 200-400 мс (перший токен) | 1-2 сек (локальний інференс) |
При відсутності мережі або для зниження витрат — llama.cpp з моделлю Phi-3 Mini або Mistral 7B через android-llamacpp або LLM.swift. Локальна модель не працює з викликом функцій в повному обсязі, але відповідає на базові питання по кешованих даних.
Контекст та безпека
Системний промпт задає контекст: список пристроїв користувача з іменами та ідентифікаторами, часовий пояс, одиниці вимірювання. Це дозволяє боту розуміти «сенсор у котельні» без явних ID.
Важно: функції IoT API викликаються від імені поточного користувача, з його правами доступу. Бот не може отримати дані пристроїв, до яких у користувача немає доступу — авторизація на рівні бекенду, а не на рівні промпту. За даними нашого аудиту, 30% вразливостей пов'язані з відсутністю перевірки прав на рівні API.
Історія чату — останні 20-30 повідомлень в контексті. Старі повідомлення стискаємо сумаризацією: gpt-4o-mini з промптом «Summarize this conversation history briefly» — економія токенів до 40%.
Процес роботи
- Аналітика: вивчаємо вашу IoT-інфраструктуру, типи датчиків, частоту опитування, права доступу. Готуємо специфікацію виклику функцій.
- Проектування: розробляємо схему tool_calls, системний промпт, архітектуру стрімінгу. Погоджуємо з вашою командою.
- Реалізація: пишемо код інтеграції на iOS (Swift) та Android (Kotlin), налаштовуємо SSE-стрімінг, додаємо UI чату.
- Тестування: запускаємо інтеграційні тести з реальними даними, перевіряємо виявлення аномалій (не менше 95% recall).
- Деплой: публікація в App Store / Google Play, налаштування моніторингу та алертів.
Терміни та вартість
Розробка AI-бота для IoT-моніторингу з викликом функцій, стрімінгом та інтеграцією з вашим IoT API: від 4 до 6 тижнів поверх існуючого мобільного додатку. Вартість розраховується індивідуально, виходячи зі складності інтеграції та кількості tool_calls. Наша команда з 10+ років досвіду в мобільній розробці виконала вже 50+ проектів з IoT та AI — гарантуємо прозорий процес та підтримку після здачі. Отримайте консультацію інженера та точні терміни.
Що входить в роботу
- Архітектурна документація (схеми tool_calls, системний промпт)
- Вихідний код модуля чату на Swift та Kotlin
- Інтеграція з вашим IoT API (до 5 ендпоінтів)
- Налаштування стрімінгу та обробка помилок
- Тестові сценарії та автотести
- Підтримка протягом 1 місяця після деплою
Типові помилки при розробці AI-бота для IoT
- Забути про обробку помилок tool_calls. Якщо API повернув помилку, модель може заплутатися. Потрібно повертати структуровану відповідь з error field.
- Не врахувати ліміти контексту. Занадто багато повідомлень — модель втрачає фокус. Використовуйте сумаризацію після 20-30 повідомлень.
- Відсутність авторизації на рівні функцій. Системний промпт не захистить від доступу до чужих даних. Завжди перевіряйте права на бекенді.
- Ігнорування затримок при стрімінгу. На слабких мережах SSE може доставлятися з паузами — передбачте індикатор завантаження.
Готові обговорити ваш проект? Зв'яжіться з нами для безкоштовної оцінки — покажемо прототип на ваших даних за 1 день.







