Як я створив Галу-яка-задовбала (AI агент)

💡 Усі статті, обговорення, новини про AI — в одному місці. Приєднуйтесь до AI спільноти!

Мене звуть Андрій, я Forward Deployed Engineer з 25 роками в інфраструктурі та безпеці — той самий тип, якого кличуть, коли «AI у нас вже є, а в проді його чомусь немає». Вбудовуюсь у команду клієнта і доводжу GenAI до робочого результату: agentic workflows, RAG, MLOps.

А ця історія — про те, як один замовник захотів замінити секретарів на AI, а я замість цього випадково зібрав машину часу за $38k.

Якщо ти, мій друже, досі на DOU — то ти айтішник. Такий самий, як усі ми: пишеш код, ненавидиш легасі, вигораєш. І так само, як багатьох із нас, мене звільнили одним днем, але це інша історія, бо там драма.

Поки я шукав нову, то влаштував собі челендж — а що, як стартанути власну контору швидше, ніж отримати оффер? Без бізнес-плану, без інвесторів, без нічого, херак — просто зробив сайт агенції за допомогою AI (ось, https://bablo.biz) і став чекати. Сталося так, що заказник вийшов на мене швидше, ніж оффер. TL;DR — невигідно.

Це не сидіти за ноутом у парку, шукати вакансії та проводити рандеву з рекрутерами онлайн. Треба вкладати гроші в офлайн-візити на різні зустрічі, ще купа витрат на перельоти й готелі, причому робити це системно. Якщо ти екстраверт, носій C1 English із задатками артистизму, вмінням вести дискусії й заводити друзів, то можливо, айтішка вже й не така приваблива.

І ось в агенцію звертається замовник. Ідея — вбити всіх людей, замінити секретарів і секретарок на AI-агента, якому можна доручати різні справи, в ідеалі аж до підписання комерційних угод (з інтеграцією через «Вчасно»). А секретар — це передусім телефон, тож з телефонії й почали.

І тут реальність розставила все по місцях: щойно люди чули типового робота — латенсі, наголоси та інше — одразу кидали трубки. Нуль удач зі ста спроб. Тоді замовник попросив перевірити іншу гіпотезу: а що, як лишати повідомлення на сайтах, щоб продати їм щось-там, не важливо що? Тоді можна просто заздалегідь записати інваріанти голосових файлів живою людиною й посадити human-in-the-loop. Так Клава (ім’я агента секретаря) народила Галу — AI-лідогенератора.

Інженери — це люди, які вирішують проблеми бізнесу, які він створює сам собі

Уяви собі, що ти однаково погано адекватно вмієш DevOps, написання та налагодження коду плюс AI. З чого ж розпочати такий проект?

Правильно, із ризиків. І тут випливла дуже важлива річ. Замовник збирався запускати це все в Німеччині (власне ми там випадково зустрілися), але річ у тому, що за такі приколи покладено ецих із цвяхами штраф і суд. Якби не мій дев’ятирічний досвід із регуляторами та комплайнсами — легко б влетіли. Тому для перевірки гіпотези вибір припав на запуск в Україні. Зараз маємо дірку у законі, через яку можна проводити таку діяльність.

Наступний ризик, власне, той самий людський. Усі чули про те, що AI причина всіх звільнень (насправді ні), тому коли ми шукали менеджера на телефон, то зіткнулися з диким хейтом гейтом(?). Як тільки людина чула, що їй потрібно буде записувати різні фрази — одразу починалося — ааа, ви мене хочете замінити на штучний інтелект! Дякуємо масовим скороченням під приводом AI, якими бізнес роздмухав хайп і тепер усі тільки й думають про те, як захиститися від цієї напасті.

І ось я опинився на тій самій пастці, яку будь-який айтішник ненавидить. Не технічній, там усе чесно: працює або падає. А на тій, де обидві гілки погані, як із загадкою про стільці.

Гілка перша — розвести руками й сказати замовнику, що люди ботів не люблять, дякую за рибу, до побачення. Втратити заказника. Чесно, швидко, боляче.

Гілка друга — визнати, що проблема не в ідеї, а в реалізації — і збудувати щось між живою людиною й роботом. Систему, яка сама синтезує інваріанти голосових записів під кожну репліку розмови, а оператор тицяє: оцю відправити. Одна кнопка. Уся складність — під капотом, де їй і місце.

Я взяв тиждень на подумати, гуляв парками і думав. Поки не прийшов до думки — а що, якщо навпаки? Ну в сенсі — нехай лід сам кнопки тисне? У голосовому меню!

Шукав мідь а знайшов золото

Так, так просто і геніально. Я зробив IVR. Той самий котрий, «натисніть один, щоб..., натисніть два, щоб...». І коли він каже — з’єдную з оператором, то людина готова до того, що в оператора буде інший голос. Стара, нудна технологія телефонії. І вона вистрілила!

Чому? Бо IVR це звичний інтерфейс взаємодії. Він із першої секунди чесно каже: я машина, ось мої кнопки, інші методи не передбачені. Чоловік чує це і спокійно тисне кнопки. Виявляється, люди готові розмовляти із машиною. Просто за однієї умови: щоб машина не вдавала людину.

Якщо з ботом у мене вийшов повний провал, то через IVR ситуація була виграшною! А найголовніше — можна ж надіслати факс! Так, той самий факс, про який ми всі забули. До речі, факси все ще працюють як у Європі, так і в США.

Але найголовніше — я зрізав купу людино-годин та грошей на платформу для підтримки системи голосового інтерфейсу!

Якісний датасет для навчання складається з трьох елементів — кров, піт і сльози

Що ж, час попрацювати з бігдатою. Але без фанатизму — все це коштує денег і часу, тож я зробив найпростіше, що міг: стягнув весь доступний UA, тобто всю зону .ua цілком. І вже на етапі підготовки датасету повилазили такі штуки, що гріх не поділитися. Кому нудно — сміливо гортай до наступного розділу. Усе нижче — не з голови, а зчитане з самого датасету, який лежить у відкритому доступі: huggingface.co/datasets/ARogovsky/uanet-dataset. Відкривай і перевіряй будь-яку цифру прямо в браузері.

Отже, вся зона. Близько 355 тисяч доменів. (Увесь цей зріз я виклав у відкритий доступ — посилання в кінці, можеш перевіряти кожну цифру власноруч, а не вірити мені на слово.) І перше, що така вибірка видає ще до будь-якого навчання, — це портрет українського вебу в профіль. Не парадний. Справжній.

Почнемо з найхолоднішого. Майже половина зони просто не відповіла — 179 765 мовчунів проти 175 182 живих. Кожен другий запис у реєстрі — не сайт, а надгробок: домен куплено, а сайту вже немає. Ось тобі реальний відбиток війни на бізнесі, без презентацій і круглих столів.

domain coverage

Ті ж показники вилазять і в кодах відповіді: 179 765 No Response, далі чесні 166 597 «200 OK», жменя 403 (5462 — хтось таки боїться ботів) і 1903 «404». Решта — статистична похибка.

responce codes

Тепер географія — мій улюблений жарт датасету. com.ua — абсолютний чемпіон, 195 945. А odesa.ua — дванадцять доменів. Не дванадцять тисяч. Дванадцять. На всю Одесу. Для контрасту: kharkiv.ua — 190, lviv.ua — майже три тисячі. І так, перш ніж ти напишеш у коментарях: я сам з Одеси. Тому маю повне право сказати, що в моєму місті, схоже, досі домовляються по телефону. (Решта одеситів, звісно, сидить у com.ua, як усі нормальні люди, — але дозволь мені цей жарт, він вистражданий.)

domain zones

Де це все живе? На своєму. Default-Host (Україна) — 47 тисяч, Prom.ua — 14 тисяч, далі hostsila, MiroHost. Закордон представлений скромно: Hetzner — 5 тисяч, Amazon AWS — аж 1177. Український веб тримається українського заліза.

hosting providers

А ось і археологія. Серед живих сайтів — 23 штуки досі віддають контент у KOI8. Двадцять три. Кодування, якого молодші колеги в очі не бачили. Поруч — близько 2,7 тисячі героїв на Windows-1251. UTF-8, звісно, переміг (153 783), але динозаври ще пасуться.

content types

У тому ж загоні динозаврів — шість (6!) доменів, що відповідають по HTTP/1.0. Олдскул. Жива копалина, яка пережила три епохи й тягне байти, ніби нічого не сталося. HTTP/2 тим часом у 154 тисяч.

http versions

З мобільною версткою все пристойно — для тих, хто живий: 150 627 mobile-friendly проти 24 555, що так і застрягли в десктопних двотисячних. (Решта — Unknown, бо це ті самі, які не відповіли.)

mobile ready

Шифрування в тих, хто таки підняв HTTPS, на диво сучасне: TLSv1.3 — 153 тисячі, TLSv1.2 — 17 тисяч, нічого старішого. Тут укрнет несподівано молодець.

tls versions

АЛЕ. Тут важлива чесна база. Якщо рахувати всю зону — 184 842 домени без жодного SSL. Звучить як «більшість гола», та це лукавство: половина зони — те саме кладовище з початку розділу, а в трупа сертифіката не буває за визначенням. Дивимось лише на живих — і картина перевертається: без сертифіката лишилось аж 5 077 хостів. 2.9%. Серед тих, хто реально працює, HTTPS просто переміг.

А далі — те, заради чого варто було лізти в дані: рядок «self-signed: 1». Один-єдиний адмін на всю країну вирішив, що справжній сертифікат — для слабких. Десь там сидить цей самотній вовк. Поважаю!

Хто ж видає решті сертифікати? Безплатне з’їло ринок: Let’s Encrypt — 116 тисяч, далі Google Trust Services (31 тисяча) і ZeroSSL (15 тисяч). Платні центри — DigiCert, GlobalSign — десь у статистичній зоні гордості.

ssl issues

І контрольний у голову безпечнику. Знову рахуємо по живих — щоб не приписувати мерцям недбалість. Із 175 тисяч робочих хостів повної пошти не має ніхто аж у 40.6% — 71 164 домени без SPF і без DMARC взагалі. Це не дірка — це ворота навстіж: підробити відправника може будь-хто, кому не ліньки. Повний комплект SPF + DMARC налаштували лише 14.7%, 25 743 домени. А якщо дивитись окремо на DMARC — головний замок від спуфінгу, — то його немає у 84.6% живих. Вісім із десяти. По всій зоні цифра ще «страшніша» — без пошти 250 929 доменів, — але туди знову намішано кладовище, тож чесне число саме оце, по живих.

email security

А тепер — навіщо все це. Я не вчив модель на цьому зоопарку цілком. Бо мета — не «портрет зони», а форми: куди агент узагалі зможе щось відправити. І ось тут вибірка схуднула безжально. З ~355 тисяч доменів живих — 175 тисяч. А з тих 175 тисяч реальна контактна форма для відправки знайшлася лише приблизно на 20 тисячах. Двадцять тисяч із трьохсот п’ятдесяти п’яти. Решта — мовчуни, заглушки і пошта навстіж.

Ось ці 20 000 живих форм і стали датасетом, на якому потім вчилася RoBERTa розрізняти simple / CSRF / complex. Не вилизаний бенчмарк із підручника — а реальність, з якою працюєш.

Пилите, Шура, пилите... вони золоті

Щоб перевірити, чи є в цьому взагалі сенс, я зробив симуляцію Saas, за допомогою AI-агента для написання коду та трохи мазків дизайну, зміг зрозуміти одне — потрібно вміти продавати самому замовнику. Далі йде конент, який AI витяг з листування та артефактів.

Так от, пане замовнику. Пам’ятаєш, як ти казав, що нуль зі ста — це вирок, і чи варто взагалі продовжувати? Тримай цифри. Тільки сядь.

За вісім днів пілота передзвонили 160 лідів з 200 холодних контактів, трубку брали практично всі, до кого агент дотягнувся.

calls by days

Але найсмачніше не в обсязі, а в тому, що 22 компанії передзвонили повторно. Одна — чотири рази. Чотири, Карл. Це вже не «лід», це челік, який ганяється за тобою по місту з пачкою бабок. 53 повторні дзвінки на рівному місці — в B2B такий собі коефіцієнт відчаю з боку клієнта, і він на твоєму боці. Коли тобі телефонують тричі, тему можна вважати гарячою.

Тепер про ранок. 103 дзвінки зі 191 припали на вікно 09:00–11:00. Більше половини всього трафіку — поки ти ще каву не допив. А по днях — окремий цирк: пілот відкрився понеділком (1 червня — 43 дзвінки) і закрився понеділком (8 червня — 46), а між ними будні чесно провисали до 17–20. Дві понеділкові свічки по краях тижня. Бо агент розсилає форми на вихідних, а челіки розгрібають пошту в понеділок зранку й одразу набирають. Хочеш більше дзвінків — синхронізуй розсилку під ранок понеділка. Це не магія, це календар.

call by hour

А ось інсайт, який особисто мене поклав. Подивися, скільки часу люди витрачають на машину і скільки — на повідомлення. Навігація по голосовому меню — в середньому 4 секунди. Чотири. Челік чує автомат, розуміє «ага, робот, чесно», тикає кнопку й не нервує. А потім лишає голосове — і ось тут середня 27 секунд, максимум аж 74. Тобто з машиною спілкуються коротко й діловито, а наговорюють — довго й з душею. 106 голосових, наговорених на автовідповідач без жодного роздратування. Пам’ятаєш, я тобі торочив, що людей бісить не робот, а робот, що прикидається людиною? Ось тобі та сама теза в секундах.

ivr

Тепер про симуляцію — ту саму, що я зібрав на коліні з готового дашборду за п’ятнадцять хвилин, бо писати фронт із нуля заради перевірки гіпотези — це спалювати бабки на рівному місці. Симуляція дала 14 реєстрацій. Чотирнадцять клієнтів, які клікнули, подивилися й завели акаунт.

А тепер скоріш звіряй, бо ось де сіль. Сайт, маркетинг, лендінг, реклама — увесь цей класичний фронт намацав 14 реєстрацій. А агент, який тихо працював у полі, пригнав 160 компаній, що дзвонять. Різниця — більш ніж у десять разів. Продукт продав себе сам разів у одинадцять краще, ніж його продавав сайт. Так хто тут, перепрошую, продавець — лендінг чи агент?

happy chart

Після цього замовник побачив чарти. Не торгувався. Оплатив повністю, забрав продукт собі й пішов крутити його далі. Без «давай ще доробимо, без «а знижку?». Бо коли тобі чотири рази телефонує одна й та сама компанія — тему вже не обговорюють. Тему забирають.

Скільки коштувала інфраструктура, збір датасетів, файнтюнінг, дистиляція та навчання своєї llm? Я домовився із замовником про те, що витрачаємо на перевірку гіпотези — до $50k. І ось так я випадково зібрав машину часу.

Час не продається — спитай у будь-кого, хто горів дедлайном. Але є лазівка: можна заздалегідь прорахувати, де витратити більше, щоб вийшло швидше. Це не про економію. Це про фізику делівері.

Вхідні дані: замовник прийшов не зі словами «зроби дешево», а «зроби швидко». Паливо було від нього: $100k на Azure (for startups). За місяць я спалив із них близько $38k.

~$1 000 на власний флот на звичайних Azure-машинах, що відкривав ~175 тисяч живих сайтів зони, шукав форму й пробував заповнити. Та сама робота в готових scraping-сервісів коштувала б $4–13 тисяч.

~$37 000 на резервування моделі для тюнінгу та дистиляції під навчання власної Roberta. Флот браузерів гарують паралельно, кожен питає модель: «цю форму взагалі можна заповнити?». На звичайному тарифі модель на такому натовпі каже «пригальмуй» — і встають не запити, а сотня живих сесій разом.

30% майже безкоштовно за виклик — і так уже назавжди. Та зарезервована модель за час оренди один раз розмітила весь датасет і навчила на ньому маленьку Roberta. Вона працює на звичайному CPU й коштує копійки за виклик — стільки ж завтра, через місяць і через рік, скільки б замовлень не йшло. Дорога модель після цього вимкнена. Вона була потрібна один раз.

Замовник хотів швидко. Замовник отримав швидко. І розрахувався повністю. Продано!

Діра у funnel, куди витікають гроші

А тепер друже, найцінніше, що ми витягли, поки ганяли систему. Не графіки — їх ти вже бачив. А три речі, яких у жодному пітч-деку не напишуть.

Перше. Люди ненавидять брати слухавку. Просто ненавидять. Особливо з незнайомого номера. Особливо в понеділок зранку — а ми вже з’ясували, що саме тоді весь шквал і прилітає. Тобто пік дзвінків припадає рівно на момент, коли людина найменше хоче говорити. Чудовий збіг, дякую, всесвіте.

Друге, і ось воно вже боляче. Люди замовляють на вихідних — це природно, ввечері в суботу всім хочеться щось залишити в формі. А в понеділок не пам’ятають про це нічого. Взагалі. І коли менеджер (байдуже, живий чи синтетичний) бадьоро каже «ви до нас зверталися, чим можемо допомогти?» — типова відповідь звучить приблизно так: «я нічого ні в кого не замовляв, ідіть у дупу». І заносить номер у чорний список. Все. Лід, за якого агент пахав на вихідних, щойно поховав сам себе об понеділковий склероз клієнта.

Третє — і тут починається цікаве. Це не баг агента. Це класична воронка, в якій бізнес втрачає ~80% лідів, і втрачав їх задовго до будь-якого AI. І ось у чому фокус, замовнику: тут абсолютно неважливо, хто дзвонить — бот чи людина. Весь наш холівар «робот vs жива людина», усі ці латенсі й наголоси — мимо каси. Проблема не в голосі.

Проблема вирішується буквально одним рядком який продає краще за конкурентів — не тому, що він хитрий, а тому, що він б’є комфорт лідів. Інтегрується в AI за п’ятнадцять хвилин, дає шквал замовлень замість чорних списків. Тривіально. Дешево. Працює. І майже ніхто цього не робить. Усі натомість палять бабки на дорогущий voice-AI, щоб робот звучав «жвавіше» — лікують симптом, якого немає. Або спалюють гроші на людей, які, як видно за статистикою, — фактично працюють по 4 години 2 рази на тиждень

Можливо, зроблю окремий вебінар про те, як підкрутити AI під продажі так, щоб він приносив прибуток, а не рахунок за токени. Лишилося тільки домовитися із замовником про інтелектуальні права — бо рядок, чесно кажучи, коштує дорожче за все.

👍ПодобаєтьсяСподобалось9
До обраногоВ обраному3
LinkedIn
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

Ну дякую шо капчі слоуп не обходить. Чому б ні. Інтелект ж. Не робот

Деякі капчі дешевше скипати, ніж розгадувати

Я сделал бы так

# Асинхронна взаємодія між агентами
import asyncio

async def agent_task(agent, task):
    result = await agent.execute(task)  # Async
    return result

# Паралельне виконання
tasks = [
    agent_task(base_agent, tasks[0]),
    agent_task(exhaust_agent, tasks[1]),
    agent_task(evaluator_agent, tasks[2])
]
results = await asyncio.gather(*tasks)  # Паралельно → 3× швидше

MAS code до статті:

# MAS для вичерпання контекста
class MultiAgentSystem:
    def __init__(self):
        self.supervisor = SupervisorAgent()
        self.base = BaseSpecialistAgent()
        self.exhaust = ExhaustSpecialistAgent()
        self.evaluator = EvaluatorCriticAgent()
        self.memory = MemoryLayer()
    
    def run(self, goal):
        # Декомпозиція
        tasks = self.supervisor.decompose(goal)
        
        # Розподіл
        self.supervisor.assign(tasks[0], self.base)
        self.supervisor.assign(tasks[1], self.exhaust)
        self.supervisor.assign(tasks[2], self.evaluator)
        
        # Обмін контекстом
        self.memory.share(self.base.output, self.exhaust)
        self.memory.share(self.exhaust.output, self.evaluator)
        
        # Виконання
        return self.evaluator.report()

У мене не стояло типового завдання, щоб боротися з вичерпанням контексту. Мені був важливий RPS до API :)

Тоді BATS/ACON/compaction/large requests = exactly навпаки, більш ніж потрібне.

Навіть якщо ми зробимо супер-асинхронний MAS з asyncio.gather і літатимемо в 10 потоках — ми все одно впораємося в квоти по RPM/TPM. Тому правильне рішення — резервування. Інакше твій код спамитиме 429 (rate limit).

Резервування = для 503/502, а для 429 = exponential backoff + rate limiting + кешування.

503/502 — це проблеми/капасіті, а ось 429 — тротлінг

Я би додав код: snippet для генерації large requests, вимірювання recall, активації BATS/ACON/compaction.

# generate "large worthless requests"
def generate_large_request(size_mb=10):
    # великі блоки JSON/коду/текстів
    return large_json / large_code / large_text

# parallel recall tests
def recall_test(facts_in_middle):
    # факти в середній частині вікна
    recall = model.query(facts_in_middle)
    return recall

# BATS CRITICAL
if token_usage > 0.85:
    bats_mode = "CRITICAL"
    limit_new_tokens()
    prioritize_critical_tools()

# ACON
failure_cases = analyze_failures()
update_guidelines(failure_cases)
compare_full_vs_compressed()

# Compaction
if token_usage > 0.70:
    compact_history()
    new_window_with_summary() 
 

Мені вдалося успішно уникнути такого оверинжинірингу

Неясна технічна архітектура агента.
Не досліджено обмеження моделі (немає метрик).
Немає вичерпання контекстного вікна.

Шануй з початку і до кінця. Гала — це не модель. Це банальний автовідповідач, на який люди реагують краще ніж на голосового бота.
Модель — це Roberta, яка розуміє по хидерам сервера — чи можна йому надсилати форму через реквести/хеадед браузер/краще взагалі не надсилати

Звучить круто!
Не до кінця зрозумів з чим телефонувала Гала, коли проходилась по доменах і що пропонувала. Таке враження, що абзац пропущений.

А зайшовши на сайт ще більше заплутався. Бо тут наче про дзвінки, а там про заповнення форм.

Гала сама нікому не дзвонила, бо не вміє :)

Для тестового прогону та перевірки гіпотези, Гала заходила на сайти та заповнювала контактну форму, куди вносила те, що вона може робити.
Після цього менеджер бачив повідомлення, де було вказано телефонний номер — і дзвонив до Галі.
Ну а далі класичний IVR+Voicemail.

Підписатись на коментарі