Я главный RPA-разработчик в команде, и мне довелось проинтервьюировать достаточное количество кандидатов и ознакомиться с их кодом, а также довелось заниматься рефакторингом множества уже разработанных роботов.
Я хочу поделиться некоторыми проблемами и личным опытом в разработке RPA-роботов. Данная статья подойдёт больше для молодых команд, которые только начинают внедрение RPA в организации, либо уже накопили с десяток роботов и только наращивают компетенции. Многим разработчикам что-то покажется очевидным, но всё же, надеюсь, будет полезным.
К сожалению, очень часто приходилось сталкиваться с legacy-кодом и тратить множество времени и сил на его поддержание и переработку. Внедрение стандартов разработки является ключевым аспектом роботизации. RPA, как ни крути, является одним из самых лёгких путей входа в разработку, что приводит к тому, что зачастую начинающие и уже не совсем разработчики пренебрегают многими общими практиками разработки, такими как KISS, SOLID, YAGNI и прочими.
RPA предлагает большие возможности для быстрой реализации задач бизнеса и из рекламных буклетов можно часто услышать, что время разработки полноценного робота занимает около пары недель. В действительности, такая спешка в разработке и приводит к тому, что появляются роботы, которые обладают большим техническим долгом, не поддаются масштабированию и имеют повышенные затраты при сопровождении и внесении изменений.
Я хотел бы вкратце перечислить некоторые принципы, на которых основаны стандарты разработки в нашей организации:
1. Автоматизация должна быть гибкой и отказоустойчивой, однако, разработка отказоустойчивости должна быть осознанной и целесообразной.
2. Исходный код должен быть простым и читаемым. Чем более простой и предсказуемой будет реализация проекта – тем проще будет с ним работать в дальнейшем.
3. Каждый робот/скрипт должен сопровождаться документацией, достаточной для общего понимания сути процесса, а также описывающей работу специфичных механизмов работы робота.
4. Документация и сам робот/скрипт должны иметь контроль версионности, а также проходить контроль качества соответствия стандартам.
Данные принципы основаны на перечисленных принципах классической разработки. Однако, в силу специфики RPA, некоторые подходы всё же не совсем применимы. Так, в RPA зачастую трудно реализовать юнит-тестирование, т.к. зачастую очень велика зависимость от интерфейса, от отказоустойчивости используемых систем, а также жёсткой последовательности сценариев. Покрытие всего робота тестами неоправданно увеличит время на разработку, хотя в некоторых кейсах пренебрегать ими не стоит.
Одним из наших стандартов является наличие проверки на завершённость каждой функции — после проведения некоторых манипуляций необходимо проверять, действительно ли функция отработала корректно и ожидаемо.
В целом, мы решили сделать упор на скорости реагирования на инциденты и возможности оперативного внесения изменений и устранения проблем.
Мы используем оркестратор и очереди в большинстве своих роботов.
Для того, чтобы избежать проблем с нестабильной работой систем, мы решили разрабатывать роботов таким образом, чтобы в случае возникновения системных исключений можно было просто решить большинство проблем простым перезапуском робота из оркестратора, без каких-либо дополнительных действий.
Мы реализовали в каждом роботе на этапе инициализации паттерн Dispatcher и проверку своей очереди за последний запуск на наличие системных исключений — в случае, если робот видит элемент очереди, который после нескольких попыток имеет статус Failed и после этого не был обработан успешно или с бизнес-исключением — робот при новом запуске самостоятельно повторяет данный элемент. Данный подход помогает существенно экономить ресурсы на сопровождение существующих роботов. Также в команде ведётся разработка скрипта, взаимодействующего с запусками роботов оркестратором, который аналогично функции проверки очереди мониторит запуски и, в случае неудачного запуска предпринимает несколько попыток перезапуска робота через API оркестратора и в случае неудачи отправляет уведомление команде разработки через Zabbix. Всегда можно также решить проблему нестабильной работы используемых систем расстановкой дополнительных блоков Retry, но в некоторых случаях это просто приведёт к неоправданно длительной обработке каждой транзакции.
Для ускорения выяснения причин исключений каждая диаграмма/блок кода в роботе покрывается Try/Catch блоком, который в случае возникновения ошибки пробрасывает её в блок Try/Catch выше, дописывая в ошибку информацию о входных параметрах, месте возникновения и дописывая код ошибки, который хранится в Config файле. На выходе текст ошибки будет содержать весь стек вызванных функций, что поможет понять последовательность действий робота даже разработчику, не знакомому с логикой процесса и оперативно устранить проблему, не погружаясь в логи без необходимости. Для реализации данного подхода очень важно, чтобы каждая диаграмма/блок кода отвечала принципу единой ответственности и выполняла одну, конкретную задачу.
Ну и напоследок один маленький совет начинающим разработчикам: перед разработкой каждой отдельной функции необходимо ответственно подойти к наименованию функции и входных, выходных аргументов, чтобы в голове сформировалась чёткое представление о том, что должна выполнять данная функция — это хорошо помогает для декомпозиции задачи.
Это моя первая статья и она является моим субъективным мнением и применима в условиях нашей организации и не претендует на истину в последней инстанции. Надеюсь, что коллеги-роботизаторы что-нибудь для себя подчерпнут в данной статье. Также рекомендую попробовать какой-нибудь из движков GPT для генерации кода для простых прикладных задачек, если вы ещё не пробовали.
И пожалуйста, Don't Repeat Yourself ;)
mokridze
Животрепещущий вопрос! Как лучше всего работать в RPA-системах при огромном количестве багов/недоработок в этих системах?
Всем нам пришлось переходить на российские разработки, качество которых... Переменно) Соответственно, иногда разработка превращается в гонки костылей на инвалидных колясках. И всё это желательно как-то отслеживать, чтобы из костылей делать нормальное решение после баг фиксов от вендоров. Да, и чтобы робот не лёг по итогу
dyshess Автор
В целом, мне кажется вы немного драматизируете;) Лично у нас самый болезненный этап работы с вендором был в первые пол года (конец 2023-начало 2024), когда мы выравнивали наши требования с вендором и много взаимодействовали, там действительно было похоже на гонки костылей. Всё равно всё становится с каждым релизом стабильнее, вендор учится, в т.ч. на своих же ошибках.
В целом, на данный момент нас вполне устраивает работа отечественной платформы. Лично я пытаюсь сфокусироваться на том, чтобы поддерживать заготовку (шаблон) для новых роботов, в которой будут использоваться актуальные решения платформы. Ну и стоит поддерживать с вендором обратную связь по платформе. Это максимум, что можно сделать, на мой взгляд