Патерни агентних інтерфейсів, які реально конвертують
У жовтні 2024 року я підключив ШІ-помічника запису до сайту мережі з чотирьох стоматологічних клінік біля Порту. Власник хотів розвантажити ресепшн від дзвінків. Пацієнти дзвонили щодо страховки, вікон на п'ятницю та цін на чистку. Я випустив чат, який закривав усі три питання. Він читав API розкладу, називав ціни з таблиці тарифів і записував на прийом через ендпоінт адміністраторів. Демо виглядало чудово. За два тижні цифри розповіли холоднішу історію. Щотижня чат відкривали близько чотирьохсот відвідувачів. Записувалася тридцять одна людина. Решта закривала вікно посеред розмови. Я розібрав двадцять записів сесій і побачив: люди йдуть у ті самі три моменти. Чат вистрілював п'ятьма запитаннями одразу. Він мовчав дев'ять секунд, поки опитував календар. Він здавався з плоскою помилкою, коли пацієнт друкував назву страхової з одруком. Ці три точки виходу дали мені три патерни, які я перевикористовую в кожній збірці агента відтоді.
Чому більшість чат-ботів втрачає користувачів
Більшість чат-ботів губить людей у проміжку між читанням повідомлення та дією. Звичайний чат приховує все. Відвідувач друкує запит і дивиться на три стрибучі крапки. Інтерфейс мовчить про наступний крок і про час очікування. За чотири секунди відвідувач вирішує, що сторінка зависла. Я заміряв це на стоматологічній збірці до будь-яких змін. Медіана часу від запитання до підтвердження запису склала одинадцять секунд. Чат увесь час показував крапки. Сімдесят відсотків відвідувачів, які чекали довше шести секунд, закривали вікно. Відповідь їх влаштовувала. Вони її не побачили.
Витік має форму. По-перше, бот одразу просить забагато, і відвідувач почувається як на допиті. По-друге, бот працює мовчки, і відвідувач почувається покинутим. По-третє, бот ламається плоско, і відвідувач звинувачує дрібний одрук у глухому куті. На кожне відчуття є ліки. Я показую одне запитання за раз. Я показую кожен виклик інструмента в момент роботи. Кожну помилку я перетворюю на меншу пропозицію. Далі розберу кожні ліки.
Патерн 1: прогресивне розкриття
Моя перша збірка ставила п'ять запитань в одній бульбашці: ім'я, телефон, страхова, бажаний лікар, зручний день. На телефоні це читалося як податкова декларація. Дванадцять із двадцяти моїх записів закінчилися рівно там. Люди відповідали на одне поле й ішли.
Я замінив стіну ланцюжком. Чат ставить одне запитання, чекає, потім ставить наступне. Кожна відповідь звужує продовження. Пацієнт обирає чистку: бот повністю пропускає питання про лікаря і пропонує найближче вікно гігієніста. Пацієнт обирає лікування каналу: бот питає прізвище лікаря. Правило, якого я тримаюся: просити в людини лише те, чого система ще тримає, плюс ставити друге запитання лише після відповіді на перше, раз відповідь його змінює.
Код лишається простим. Я тримаю об'єкт слотів із п'ятьма ключами та функцію next, яка повертає рівно одне запитання за заповненими слотами. React малює один рядок введення та ряд швидких чипів. Чипи забирають більшість натискань: вибір чипа займає один тап, набір тексту займає дев'ять. Після переходу завершення кроків із запитаннями зросло з тридцяти восьми відсотків до сімдесяти дев'яти. Старти записів подвоїлися за тиждень. Кожен агентний сценарій тепер питає по одному й добирає решту з контексту.
Патерн 2: видимі виклики інструментів
Дев'ять секунд тиші вбили другу групу. Бот перевіряв правила страхової, потім опитував календарі трьох лікарів, потім утримував слот. Вся робота йшла по ділу. Вся робота лишалася невидимою. Відвідувачі бачили крапки й думали, що нічого відбувається. Шість записів показали, як відвідувач друкує «hello?» у порожнечу, потім закриває вкладку.
Я зробив роботу видимою. Коли бот перевіряє покриття, чат друкує маленьку картку: «Перевіряю вашу страховку в ClinicPlus». Коли стартує опитування календаря, з'являється друга картка: «Дивлюся вікна на п'ятницю в доктора Соузи». Коли утримання проходить, картка перевертається в галочку з часом слоту. Кожна картка припливає поверх чату, відвідувач спостерігає, як прогрес прибуває крок за кроком.
Збірка використовує server-sent events із роуту Next.js. Кожен виклик інструмента шле статус-подію з підписом, який я написав вручну. Сирі імена функцій я ховаю. Внутрішнє ім'я check_calendar перетворюється на «Дивлюся вікна на п'ятницю». Видимих кроків тримаю максимум чотири на хід, усе глибше згортається в одну картку. Відвал на викликах інструментів упав із сорока одного відсотка до дев'яти. Показуй роботу, і люди чекають.
Патерн 3: м'яка деградація
Плоска помилка вбила третю групу. Пацієнт надрукував «ClinikPlus» з літерою K. Бот знайшов нуль провайдерів і відповів «I don't understand. Please rephrase». Пацієнт спробував іще раз, уперся в ту саму стіну й подзвонив у клініку. Журнал дзвінків показав: адміністратор записала його за дві хвилини. Слот у бота був із самого початку. Його підвів правопис.
Я замінив стіну драбиною. Крок перший: нечітке порівняння. «ClinikPlus» збігається з ClinicPlus на одну літеру, тому бот питає «Ви мали на увазі ClinicPlus?» з двома чипами. Крок другий: звуження області. Коли бот не може розібрати запит цілком, він пропонує три найчастіші дії чипами: перевірити страховку, знайти вікно, дізнатися ціну чистки. Крок третій: людина з ім'ям і строком. Коли обидва кроки мимо, бот каже: «Марта з ресепшну записує такі випадки вручну. Залиште номер, вона передзвонить протягом однієї робочої години». Кожен глухий кут закінчується чипом або зворотним дзвінком, глухих кутів без виходу більше нема.
Кожен глухий кут я пишу в Postgres із номером кроку. Промахи першого рівня закриваються всередині чату у вісімдесяти відсотках випадків. Зворотні дзвінки третього рівня конвертуються в п'ятдесят п'ять відсотків того самого дня. Бот продовжує помилятися. Помилка тепер вручає відвідувачу меншу робочу пропозицію.
Метрики, які я відстежую: завершення задач, частота глухих кутів, час до цінності
Три числа показують, чи заслуговує агентний інтерфейс на своє місце. Завершення задач: частка відкритих чатів, що закінчилися записом. Стоматологічний чат стартував із восьми відсотків і сьогодні тримається на двадцяти чотирьох. Я рахую метрику щотижня за таблицею записів, з'єднаною із сесіями чату. Все нижче п'ятнадцяти відсотків значить: сценарій просить забагато або ховає забагато.
Частота глухих кутів: частка ходів, що вперлися в драбину. Кожен рівень рахую окремо. Перший рівень вище тридцяти відсотків значить: порівнянню потрібні синоніми. Третій рівень вище десяти відсотків значить: сценарій пропускає живий намір, йому потрібна нова гілка. Після правки одруків глухі кути першого рівня впали з двадцяти двох відсотків до шести.
Час до цінності: секунди від першого повідомлення до підтвердження запису. Медіана стартувала з одинадцяти хвилин живого часу разом із паузами, тепер тримається близько трьох. Сімдесят п'ятий перцентиль я теж дивлюся: середні ховають повільний хвіст, де пацієнти друкують одним пальцем в автобусі.
Три числа ми розбираємо щопонеділка з керівницею клініки. Обираємо одну правку, випускаємо її до п'ятниці, потім знову читаємо числа. Цей ритм дав конверсії більше, ніж будь-який редизайн із запропонованих мною. Патерни на слайді виглядають дрібно. На живому сайті вони вирішують, чи перетворяться чотириста щотижневих відвідувачів на тридцять записів або на дев'яносто.