Реалізація AI-агента з виконанням дій у мобільному додатку (бронювання, заказ)
Агент, який не тільки ответить, а й робить—це інший рівень відповідальності. Забронювати столик, оформити заказ, перевести гроші. Помилка в такому агенті—це не «неправильний текст», це реальна дія з реальними наслідками. Саме тому архітектура агентів з виконанням дій принципово відрізняється від інформаційних.
Human-in-the-Loop: чому це обов'язково
Ніякий агент у продакшені не повинен виконувати незворотні дії без явного підтвердження користувача. Це не перестраховка—це правило. GPT-4o іноді інтерпретує «я б хотів заказати піцу» як прямую команду до дії, а не як вираження бажання.
Правильний UX: агент збирає всі параметри → показує сводку → чекає confirm від користувача → виконує. На мобільному реалізується через спеціальний інструмент request_confirmation:
// Інструмент підтвердження—не виконує дію, а запитує дозвіл
data class ConfirmationRequest(
val action: String, // "book_restaurant"
val summary: String, // "Столик на 2 у Кафе Мінськ, 26 березня 19:00"
val details: Map<String, Any> // всі параметри для відображення
)
// Агент викликає цей інструмент останнім перед дією
// Клієнт показує Bottom Sheet з деталями та кнопкою "Підтвердити"
Модель не повинна мати можливість «пропустити» підтвердження. У системному промпті явно: «Перед будь-яким бронюванням або заказом ОБОВ'ЯЗКОВО виклич інструмент request_confirmation та дочекайся ответу користувача».
Ідемпотентність та захист від дублювання
Користувач натиснув «Підтвердити», з'єднання оборвалось, додаток не знає—виконаний заказ чи ні. Без ідемпотентності—подвійний заказ. Рішення: генеруємо idempotency_key (UUID) до першої відправки та передаємо з кожним повтором:
// iOS—створюємо ключ один раз, зберігаємо до підтвердження виконання
let idempotencyKey = UUID().uuidString
UserDefaults.standard.set(idempotencyKey, forKey: "pending_order_key")
// Передаємо у заголовку або тілі запиту на бекенд
request.setValue(idempotencyKey, forHTTPHeaderField: "Idempotency-Key")
Більшість платіжних систем (Stripe, YooKassa) підтримують Idempotency-Key нативно. Для власного бекенду потрібно зберігати ключи у Redis з TTL 24 години та повертати кешований результат для повторних запитів.
Откат та обробка частичних збоїв
Сценарій: агент забронював рейс, але готель не ответив. Потрібно либо відмінити рейс, либо повідомити користувача про частичний успіх. Паттерн Saga: кожно дія має компенсуючу дію (відміну). Агент повинен знати про ці компенсуючі дії та уметь їх викликати.
{
"name": "cancel_flight_booking",
"description": "Відміняє раніше виконане бронювання рейсу. Використовуй ТІЛЬКИ при явній просьбі користувача або при збої у наступних кроках бронювання.",
"parameters": {
"booking_id": {"type": "string", "description": "ID бронювання з результату search_flights"}
}
}
Стан заказу та офлайн-черга
Дія може займати час—ответ від зовнішньої системи бронювання іноді приходить через 3–10 секунд. На мобільному означає індикатор прогресу з описом поточного кроку («Перевіряємо наявність місць...»), а не просто спіннер.
Якщо додаток був свернутий під час виконання—використовуйте WorkManager на Android для фонової задачі з статусом, або BGTaskScheduler на iOS. Користувач отримує push з результатом.
Локально зберігайте стан агента у Room/Core Data: поточний крок, параметри, ідентифікатори бронювань. При перезапуску додатку—відновлення стану та можливість продовжити або скасувати.
Що тестувати обов'язково
- Подвійне натискання «Підтвердити» (race condition)
- Таймаут зовнішнього API на кроці оплати
- Відмова одного сервісу при успіху іншого (часткова транзакція)
- Зміна ціни або доступності між пошуком та бронюванням
- Спроба агента виконати дію без підтвердження (adversarial prompts)
Етапи роботи
Аналіз бізнес-процесів та визначення «небезпечних» дій → проектування human-in-the-loop для кожної → реалізація ідемпотентності та компенсуючих дій → агентний цикл з управлінням станом → UI підтвердження та прогресу → інтеграційне тестування edge-cases → нагрузкові тести.
Сроки: агент для одного типу дії (наприклад, тільки бронювання столика)—3–4 тижні. Мультидоменний агент (рейс + готель + трансфер)—6–10 тижнів.







