ИИ против «кошмара на С++»: рефакторинг 280-строчной функции в OpenBMC
Разработчик из сообщества OpenBMC проверил, способен ли ИИ-агент справиться с рефакторингом перегруженного С++ кода во встраиваемой системе. Эксперимент показал, что нейросеть уверенно выявляет архитектурные проблемы, но итоговый объём кода после правок неожиданно вырос.
В сообществе разработчиков встраиваемых систем появился подробный разбор эксперимента по рефакторингу кода в рамках открытого проекта OpenBMC — платформы для сборки прошивок модулей управления серверами и десктопными системами на базе Linux. Автор взял один из компонентов нижнего уровня из репозитория dbus-sensors, а именно сервис HwmonTempSensor, и попытался с помощью ИИ-ассистента привести в порядок ключевую функцию createSensors. Исходная функция насчитывала около 280 строк и выполняла сразу двенадцать изолированных задач, что делало её практически нечитаемой и крайне сложной для сопровождения. Показательно, что речь идёт не об учебном примере, а о реальном коде нижнего уровня, который компилируется в systemd-сервис и работает на конкретном железе.
Архитектурно сервис представляет собой классический микросервис, работающий в однопоточном асинхронном режиме. Он собирает показания с аппаратных датчиков температуры, давления, влажности, тока и напряжения, после чего публикует их на системной шине D-Bus, откуда данные забирают другие компоненты, например веб-интерфейс. Вся логика сервиса сосредоточена вокруг единственной функции-обработчика, которая асинхронно получает конфигурацию от entity-manager, ищет соответствующие драйверы I2C через sysfs, сопоставляет найденное оборудование с конфигурацией, создаёт и регистрирует объекты HwmonTempSensor на шине, а также управляет порогами, частотой опроса и питанием. Вложенность циклов и условий внутри неё достигала шести-семи уровней, а сама функция поддерживала сразу два режима: полный первичный скан при старте и точечное обновление при изменении конфигурации на лету через события шины. Именно сочетание асинхронности, работы с железом и обработки внешних событий превращало её в тот самый «кошмар на С++», о котором говорят embedded-разработчики.
ИИ-агент, которому было предложено проанализировать функцию, сформулировал чёткий диагноз: перегруженность, спагетти-логика из разнородных задач и нулевая тестируемость. Ассистент предложил семь конкретных шагов, среди которых выделение отдельного класса SensorScanner с публичным методом scan и набором приватных методов по 20–30 строк, устранение дублирования при создании датчиков через единый метод createOrActivateSensor, вынос повторяющихся имён и структур матчинга, а также разделение логики первичного сканирования и точечного обновления. По оценке агента, только устранение копипасты позволило бы избавиться примерно от 60 строк дублирующегося кода. Важно, что предложенная структура оказалась вполне конкретной: buildConfigMap для построения карты конфигураций, findSensorPaths для поиска путей в sysfs, ensureDevice для инстанцирования I2C, processPath для обхода найденных устройств и matchConfig для сопоставления с конфигурацией.
После реализации предложений структура заметно изменилась: вместо монолитной лямбды появился класс SensorScanner, а исходная функция createSensors сократилась до нескольких строк, создающих сканер и запускающих его. Однако графический результат в git-диффе оказался парадоксальным: зелёных строк, обозначающих новый код, стало заметно больше, чем красных, то есть суммарный объём кода вырос. Это объясняется тем, что декомпозиция неизбежно добавляет объявления методов, сигнатуры, структуры данных и разделение ответственности, которые в монолитной функции были скрыты внутри общего тела. Автор подчёркивает, что рост объёма не означает ухудшения — читаемость и тестируемость улучшились, но метрика «строк кода» перестаёт быть показательной. Этот результат хорошо иллюстрирует общую закономерность: любой рефакторинг с выделением абстракций почти всегда увеличивает физический объём исходников, даже если логическая сложность снижается.
Для российского рынка встраиваемых систем и промышленной разработки этот кейс показателен по нескольким причинам. OpenBMC активно используется в серверном оборудовании, в том числе в решениях, поставляемых на локальный рынок, а значит качество и сопровождаемость таких прошивок напрямую влияют на надёжность инфраструктуры. Кроме того, эксперимент демонстрирует реалистичные границы применения ИИ-ассистентов: они хорошо справляются с диагностикой архитектурных проблем и генерацией шаблонного кода, но не заменяют инженера в вопросах проектирования и оценки последствий. В условиях кадрового дефицита в embedded-разработке подобные инструменты могут стать подспорьем, однако требуют квалифицированного контроля. Отдельно стоит отметить, что работа велась с открытым кодом на C++ — языком, где автоматический рефакторинг особенно рискован из-за ручного управления памятью, шаблонов и неявных зависимостей.
По сравнению с альтернативными подходами — ручным рефакторингом, статическими анализаторами или формальными методами верификации — ИИ-агент выигрывает в скорости первичного анализа и предложении структуры, но проигрывает в гарантиях корректности. Статические анализаторы не предлагают декомпозицию, а ручной рефакторинг 280-строчной функции занял бы существенно больше времени. При этом именно человеку приходится решать, какие из семи шагов действительно нужны, как избежать регрессий и стоит ли жертвовать компактностью ради модульности. Нейросеть пока не способна оценить эксплуатационные риски и особенности конкретного железа, а значит её предложения остаются гипотезой, требующей проверки на реальных устройствах.
Дальнейшие перспективы связаны с тем, насколько глубоко ИИ-инструменты смогут интегрироваться в цикл разработки встраиваемого ПО. Открытыми остаются вопросы оценки качества рефакторинга, автоматического прогона тестов на целевой платформе и работы с проприетарными драйверами, где обучающие данные ограничены. Пока же кейс показывает, что ИИ полезен как аналитик и генератор каркаса, но финальное решение о том, каким быть коду, остаётся за инженером. Именно это соотношение ролей, вероятно, и определит практику embedded-разработки в ближайшие годы.