Як ми створили Slack-бота й пришвидшили процес найму нових фахівців
Досвід Grid Dynamics з автоматизації узгодження технічних інтерв’ю за допомогою Slack-бота. Автор порівнює попередні підходи, описує архітектуру, інтерфейс і результати впровадження.
Translated by ChatGPT GPT-6.1 Sol
Відомості про першоджерело
Как мы создали Slack-бот и ускорили процесс найма новых специалистов
Архівна публікація. Посади, показники й технічні інструкції наведено станом на дату першої публікації.
Усім привіт! Мене звати Дмитро Гой. Я працюю Python Software Engineer у компанії Grid Dynamics. У цій статті я розповім про те, як ми автоматизували процес найму нових фахівців за допомогою Slack-бота. Цей матеріал буде цікавий розробникам, менеджерам із найму, рекрутерам, а також усім тим, хто безпосередньо залучений до процесу співбесіди з кандидатами. Отже, почнімо.
Скільки часу знадобиться, щоб зрозуміти, коли можуть усі? або Виявлення проблеми
Найм нових людей у компанію — доволі трудомісткий процес, що потребує багато часу. У ньому беруть участь рекрутер, кандидат і технічні фахівці компанії, які оцінюють рівень знань претендента.
У загальному сенсі найм можна розділити на окремі етапи, які проходить кандидат від моменту надсилання резюме до ухвалення остаточного рішення. Перед проведенням технічного інтерв’ю необхідно узгодити час між трьома сторонами, як було зазначено вище. Рекрутер виступає медіатором на цьому етапі й безпосередньо на самому інтерв’ю.
Щоб наочніше показати масштаб ситуації, подивімося на цифри. У локальних офісах у нас працює понад 40 людей у команді рекрутингу й близько 700 інженерів, які бажають брати участь у проведенні технічних інтерв’ю. Головним завданням Slack-бота було оптимізувати комунікацію рекрутерів з інтерв’юерами для визначення часових інтервалів, оптимальних як для інтерв’юерів, так і для кандидата.
Складність узгодження пов’язана з тим, що технічні фахівці мають свій набір завдань і обмежену кількість вільного часу. Часові проміжки не завжди очевидні й рідко обходяться без особистого узгодження двох сторін. Зрештою рекрутеру доводиться виконати безліч дій: вибрати відповідних фахівців для проведення технічного інтерв’ю, скласти їхній список і надіслати письмовий запит кожному потенційному інтерв’юеру, щоб підібрати зручний час, який збігається з побажаннями кандидата. Само собою зрозуміло, що всі ці дії відбуваються в робочий час, коли відповідь від інтерв’юера може зайняти від кількох хвилин до кількох годин. Отже, швидкість підбору часу зустрічі сильно залежить як від можливостей інтерв’юера в момент отримання запиту, так і від можливостей кандидата.
З огляду на сказане вище виділимо кілька завдань, які необхідно було розв’язати:
-
Простий і швидкий пошук відповідних інтерв’юерів.
-
Легке визначення вільних фахівців, готових до проведення інтерв’ю.
-
Сповіщення інтерв’юера про майбутню зустріч із найменшими витратами часу рекрутера.
-
Оптимізація комунікації з фахівцями для звільнення часу на поточні завдання.
Що, як зібрати всіх охочих разом? або Зосередження запитів у чаті
Першим рішенням на шляху оптимізації цього етапу в нашому випадку стала концентрація пулу інтерв’юерів і запитів в одному каналі комунікації. Простий збір інформації про необхідні параметри інтерв’ю від рекрутера в каналах комунікації, наприклад у Slack-чаті, дав змогу скасувати дублювання запитів в особистому листуванні, дозволив фахівцям гнучкіше визначати час відповіді на такі запити, а також оцінювати відповідність запитів можливостям. На щастя, у корпоративному месенджері доступна функція організації певних Workflows, які дають змогу бачити актуальність окремих запитів і трохи автоматизувати відповідь на них. Однак це не розв’язує завдання повною мірою, адже визначити, чи вільний фахівець у потрібний проміжок часу, без його участі й відволікання від поточних завдань усе ще неможливо, оскільки кожен запит у чаті має прочитати кожен інтерв’юер, щоб зрозуміти, може він узяти участь чи ні.
Це призводить до того, що не всі читають чат, і повертає нас до початкового завдання. Для розподілу за релевантністю також не забуваємо про створення не одного, а цілої групи чатів, які щонайменше охоплять різні дисципліни, зменшуючи при цьому інформаційне навантаження на кожного з фахівців.
Засоби реалізації:
-
Slack-чат
-
Slack Workflows
Переваги рішення:
-
Відповідальність за визначення відповідного інтерв’юера передано самим фахівцям. Кожен сам реагує на запит і розуміє свою можливу роль на зустрічі.
-
Зменшення часу на комунікацію й очікування відповідей між ними.
-
Автоматично передбачається сповіщення про майбутню зустріч для фахівця, який самостійно прийняв запит.
-
Легка організація завдяки наявним інструментам.
Недоліки:
-
Повільна відповідь на запити через меншу відповідальність із боку фахівців порівняно з особистим зверненням.
-
Навантаження їхнього інформаційного поля під час виконання поточних завдань не завжди релевантними запитами.
-
Не дає змоги дізнатися загальну кількість претендентів на роль інтерв’юерів під кожен запит.
Резервування часу через форми опитування й побудова бази можливостей
Другим варіантом для реалізації поставлених цілей можна назвати збір інформації про можливості інтерв’юерів на певний період часу наперед і формування бази даних, яка містила б цю інформацію. Розв’язуючи завдання таким чином, окрім необхідності написати інструкцію щодо правильного заповнення цієї інформації з боку інтерв’юера, також необхідно було навчити команду рекрутингу користуватися цими даними. Побудувавши таку схему, коли фахівець указує часові проміжки своєї можливої участі в зустрічі, а рекрутер бронює його час для якогось конкретного заходу, ми все ще не розв’язуємо проблему цілком. Крім того, додається навантаження на всі сторони як щодо часу на роботу з таким підходом (наприклад, таблицею), так і щодо додаткового узгодження й механіки (позначка про бронювання, зайнятість, зміни в розкладі тощо).
Засоби реалізації:
- Онлайн-таблиці
Переваги рішення:
-
Оперативніша комунікація про час зустрічі.
-
Декларування можливостей інтерв’юера щодо можливих проміжків часу.
Недоліки рішення:
-
Додаткові дії для фахівців у межах щотижневих завдань.
-
Складність визначення відповідних фахівців через додаткові зіставлення даних у таблицях.
-
Неможливість сповістити інтерв’юера про майбутню зайнятість без безпосереднього звернення.
-
Значна складність фільтрації та актуалізації інформації під час роботи з таблицями.
-
Можливі перетини запитів і комунікації різних рекрутерів з інтерв’юерами.
Автоматизований помічник з узгодження часу інтерв’ю
Цей варіант увібрав у себе всі переваги попередніх опцій завдяки можливості його реалізації на базі Slack-застосунку. Насамперед, використовуючи автоматизованого помічника або, простіше кажучи, бота, ми можемо побудувати для себе ланцюжок дій для всіх учасників таким чином, щоб уникнути різночитань у підходах до попередніх варіантів реалізації або інструкцій. Нормалізуючи й визначаючи потрібну нам вкладеність даних і розподіл у базі даних, ми також спрощуємо роботу з безпосередніми даними, надаючи кожному користувачеві певний інтерфейс взаємодії.
Засоби реалізації:
-
Slack-застосунок
-
Сервер із ботом
-
База даних
Переваги рішення:
-
Самостійне керування відповідним часом із боку інтерв’юера.
-
Автоматизоване нагадування про вказаний час.
-
Зручний пошук відповідного фахівця із зазначенням необхідних параметрів і дати.
-
Кероване розв’язання конфліктів під час бронювання часових проміжків.
-
Автоматичне сповіщення про бронювання часу.
-
Контроль над даними на кожному кроці взаємодії.
-
Зведення комунікації між учасниками процесу до необхідного мінімуму.
Недоліки рішення:
-
Самостійне керування ботом і підтримка його працездатності.
-
Пошук універсально придатних для більшості користувачів рішень у реалізації інтерфейсу.
-
Єдиний процес, який може бути недостатньо універсальним для всіх технічних фахівців.
Реалізація бота
У процесі пошуку рішення цього завдання було впроваджено й випробувано кожен із запропонованих варіантів. Далі в цій статті буде описано реалізацію бота як найбільш відповідного нашим запитам варіанта розв’язання завдання.
Для реалізації такого бота вибрали такий набір технологій:
-
Python 3.10 — актуальна версія мови програмування, якою, своєю чергою, швидко писати код, яка дуже поширена, а також має велику спільноту розробників і безліч бібліотек для реалізації задуманого.
-
Бібліотека Slack Bolt — офіційна бібліотека для роботи зі Slack-застосунками, доступна мовою Python.
-
Бібліотека Boto3 — офіційна бібліотека для роботи з AWS, у нашому випадку необхідна для взаємодії з базою даних DynamoDB, доступна мовою Python.
-
Бібліотека Google API client — офіційна бібліотека для роботи з Google API, використовується для роботи з Google Calendar і надає можливість взаємодії з календарями фахівців у Google Workspace, доступна мовою Python.
-
Бібліотека APScheduler — бібліотека з відкритим вихідним кодом, що надає можливість планування автоматичного виконання певного коду в заданий час (проміжок часу) із заданими параметрами.
Крім того, для реалізації ми написали додаткові базові функції, які використовуються для поліпшення якості коду та стабільності його роботи. На мій погляд, це те, чого бракує для більш «pythonic» роботи зі Slack API.
Наприклад, під час отримання інформації про користувача на виході ми маємо словник, звернення до якого можливе лише через рядковий ключ. Для такого випадку написано функції, які розбирають дані з отриманої інформації та видають саме запитувану.
Інфраструктура самого бота має такий вигляд:

Також написали невелику ОRМ (модель відношення об’єктів), яка дає змогу гнучкіше й якісніше працювати з даними, що зберігаються в базі даних. У цьому випадку ми також позбуваємося роботи з асоціативними масивами на користь роботи з об’єктами. На жаль, відповідних готових рішень для роботи з DynamoDB не було знайдено.
Проєкт складається з кількох частин:
-
handlers — містять класи, які використовуються для перехоплення подій взаємодії з ботом;
-
services — класи, що відповідають за взаємодію зі сторонніми сервісами;
-
database — класи для роботи з базою даних;
-
middlewares — дають змогу обробляти запити до надсилання обробнику безпосередньо через контекст;
-
blocks — універсальні блоки й кнопки, які повторно використовуються в handlers;
-
utils — сюди увійшли необхідні допоміжні класи (helpers) для роботи з часовими поясами, розсилками повідомлень і часовими проміжками.
Щодо налаштування самого застосунку в Slack, у нашому випадку необхідні були лише права на надсилання повідомлень користувачам, дозвіл на відображення Домашньої сторінки (Home tab), а також пошук інформації у Workspace для зручнішого зіставлення користувачів бота та їхньої інформації, яка зберігається самим Slack.
У новому інтерфейсі налаштувань застосунків Slack дає змогу працювати безпосередньо з manifest.json для налаштування ваших застосунків. Це дуже допомогло для подальшого розширення прав. Наприклад, щоб дозволити боту в реальному часі ділитися логами помилок/багів у продакшені у вигляді файлів зі звітами.
Найзручнішим варіантом взаємодії з ботом виявилося використання відображення модальних вікон, які дають змогу розмістити до 100 блоків інформації. Дуже приємно те, що такі вікна можуть мати можливість надсилання (submit) і містити блоки введення інформації (це і селектори, і введення тексту). Також зручно використовувати кнопки, які безпосередньо допомагають працювати з даними, асоційованими з інформацією, вказаною в блоці.
Наприклад, нижче ми бачимо відображення вибраних часових інтервалів, коли інтерв’юер має можливість провести інтерв’ю з кандидатом:

Відповідно, ми можемо відмовитися від цього часу, використовуючи асоційовану з ним кнопку. Крім того, доступна кнопка видалення всіх вибраних часових проміжків.
Головною точкою взаємодії є форма пошуку інтерв’юерів. У цьому вікні ми вибираємо потрібні нам параметри для проведення інтерв’ю й завдяки введеним даним отримуємо інформацію про можливості наших фахівців для участі в зустрічі.
Виглядає це так:

Для початку ми вибираємо дисципліну, для якої нам потрібно знайти інтерв’юера.

Після цього ми вибираємо потрібні нам параметри фахівця. Важливими пунктами є технологія, за якою ми визначаємо, хто може провести інтерв’ю з кандидатом, а також дата, зручна як для фахівця, так і для кандидата.
Поділ на два окремі вікна, які послідовно відкриваються, необхідний для того, щоб брати релевантні технології та платформи щодо потрібної нам дисципліни. Ці два селектори беруться з константи, у якій описано відношення дисциплін до цих пунктів завдяки використанню функції отримання зовнішніх даних за запитом значень для селектора (selector with external data). Для первинної реалізації не було необхідності додатково зберігати ці відношення в базі даних. У майбутньому, у зв’язку з використанням цього елемента, є можливість брати ці дані з таких таблиць. Самі вікна знають про вибрані раніше значення завдяки використанню параметра metadata, який зберігає їх у вигляді текстового рядка.
Slack-бот має таку функціональність:
-
Збір статистичних даних та їхня обробка для отримання менеджментом корисної інформації й аналітики.
-
Створення інформації про інтерв’юерів і керування нею з боку адміністраторів бота та надання прав для роботи з нею представникам менеджменту компанії (наприклад, відповідальним за дисципліни).
-
Виведення інформації з бази даних користувачам, які там описані, і налаштування деяких параметрів із боку користувачів.
-
Розсилка повідомлень і сповіщень усім групам користувачів (як автоматизована, так і за запитом адміністраторів).
-
Обробка й виведення інформації про помилки.
-
Інтеграція з Google Календарем для визначення часу, який може бути використаний інтерв’юерами для участі в зустрічах, а також збереження заповнювача (placeholder) безпосередньо в календарі інтерв’юера.
-
Маркування часових проміжків, у яких уже є підтвердження від схожих за параметрами інтерв’юерів.
Також виділимо важливі аспекти роботи зі Slack Application:
-
Відкриття модального вікна має відбуватися протягом 3 секунд. Для обходу цього обмеження було вибрано підхід, що передбачає відкриття «вікна очікування», яке містить відповідний текст, а після оновлення цього вікна — уже дані, які, наприклад, беруться з бази даних.
-
Застосунок має протягом 15 секунд відповісти Slack, що запит було оброблено. Для такої відповіді використовується функція Acknowledge з бібліотеки Slack Bolt, і підхід, описаний у попередньому пункті, також допоміг нам обійти це обмеження в місцях довгих запитів до бази даних або множинних запитів. Наприклад, під час валідації надісланих даних, коли виведення помилки безпосередньо біля поля з помилкою займає більше передбаченого часу.
-
Для збереження даних користувачеві необхідно надсилати повідомлення з результатами деяких операцій. Також це допомогло нам мати додаткову історію дій користувача для подальшого отримання корисної інформації в процесі налагодження.
-
Блоки, які використовуються для формування інтерфейсу, можна використовувати в модальних вікнах, у повідомленнях, а також на Домашній сторінці. Це допомагає побудувати гнучкі інтерфейси. У нашій реалізації ця можливість також використовується для відображення повідомлення, яке передбачається розіслати користувачам. Таким чином адміністратори бота бачать, який вигляд матиме повідомлення для користувачів.
-
Можливість нативного підтвердження дій користувачів (confirm object). Вбудований елемент інтерфейсу, який може бути прикріплений практично до будь-якої користувацької взаємодії, дає змогу вивести додаткову інформацію, що пояснює наслідки дії, і надає додатковий рівень підтвердження. Наприклад, що відбудеться і як буде зрозуміла ботом зміна поля або натискання кнопки.
Щодо самої бібліотеки Slack Bolt, то одним із важливих аспектів є можливість створення інтерфейсів із використанням об’єктів класів різних блоків. Бібліотека також дає змогу використовувати словники (dict) для визначення інформації блоків, але цей підхід не дуже ефективний як у процесі розробки, так і для налагодження. Крім того, використання вбудованих у бібліотеку класів допомогло позбутися проблем із валідацією на стороні Slack. Головною особливістю також є можливість використовувати різні вбудовані варіанти отримання подій і взаємодії із серверами Slack. Само собою, для реалізації нашого бота було вибрано взаємодію через sockets.
Куди рухатися далі? або Висновок
У результаті за 4 місяці всіх наших інтерв’юерів додано до бази для роботи з ботом. За цей час використано кілька варіантів часових проміжків, які безпосередньо розроблено на основі пропозицій користувачів.
І рекрутери, й інтерв’юери відзначили практичну користь від використання бота. Ми можемо також побачити це з цифр за останній місяць:
-
2600 часових проміжків підтверджено;
-
550 — заброньовано рекрутерами;
-
понад 1000 пошукових запитів виконано через бота.
І за весь час роботи:
-
понад 750 часових проміжків згенеровано для продакшену;
-
7 ботів у stage-середовищі створено для роботи над кінцевим результатом;
-
12 релізів із функціональністю розгорнуто;
-
4 часові пояси враховано в роботі з ботом, ще 5 на підході (США).
Як далі розвиватиметься Slack-бот? Із цього приводу є багато ідей, але одне з перших завдань — використання бота на рівні всієї компанії, тобто додавання всіх інтерв’юерів і всіх дисциплін, які ми можемо врахувати. Для цього необхідно додати людей з офісів в інших частинах світу. Крім того, почалася робота над інтеграцією з іншими сервісами компанії, які дали б змогу посилити автоматизацію процесів найму. Також уже намічено плани зі створення API, який дозволив би боту виконувати певні дії за запитом інших сервісів.
Пропоную всім охочим обговорити розробку корпоративних ботів і Slack-ботів у коментарях. Було б цікаво прочитати ваші пропозиції щодо того, про що далі розповісти: корпоративні боти та їхнє застосування у великих компаніях, Slack-боти або аспекти їхньої розробки.