Как я поднял сервис через LLM, ничего не настраивая, и стал не архитектором сетей, а параноиком

от автора

«Не знаю языка, не написал ни строчки кода, я архитектор» — всё чаще попадаются такие статьи. Даже на Хабре в комментариях встречаются люди, которые недоумевают, за что такие статьи огребают минусы. Хочу рассказать на примере своего опыта, в чем неправ вайбкодер, делающий такие выводы. Получилось многовато текста. Для llm сокращятелей и тех кому лень читать — поднимал сервис через llm в области знаний где я профан, он ломался экзотическими (наверное) способами после каждой итерации, теперь он вроде работает но может и нет — ответить на это я не могу потому что недостаточно экспертизы.

Обо мне: я Android-разработчик со стажем более 10 лет. У меня есть несколько домашних pet-проектов под Android, которые были созданы как полностью вручную, так и с полной генерацией, в режиме yolo, иногда даже не глядя. Но вот познания в системном администрировании у меня весьма ограниченные. Я, конечно, смогу настроить Docker-контейнер по инструкции и даже не перепутаю маскировку трафика с обфускацией, но большая часть знаний, которые у меня есть, получена из развлекательных видео о сетях на канале небезызвестного Дмитрия Бачило. Поэтому с точки зрения настройки сетей я как раз выступаю тем человеком, который до этого «не писал ни строчки кода».

О решаемой задаче: исторически сложилось, что у меня есть три разные VPN-сети, все внутри страны, на разных технологиях, для подключения к разным локациям и собственным сервисам. Мне хотелось как-нибудь получить единую точку отказа/взлома входа с висящим на ней демоном мониторинга, который будет стучаться в разные сети и собирать информацию о работе сервисов. Правильным решением, наверное, было бы объединить всё это в единую адекватную сеть на одной технологии, но есть масса причин, почему я не хочу этим заниматься. Наверное про конкретику этого сетевого безобразия можно написать еще одну статью, но тут нам дальнейшие подробности не важны.

В общем, одним прекрасным днём я пришёл к идее: сисадмина для настройки сети я, конечно, нанимать не планирую, сам я вопрос буду изучать ещё года два, чтобы въехать на должном уровне, а при таких затратах оно мне уже и не нужно. Но есть же LLM-агент, который вполне подойдёт для решения задачи в роли сисадмина.

Да-да, я прекрасно осознавал, что может получиться дыра в безопасности, портал призыва демонов или сервер крутящий 24/7 рикролл на интернет радио — ведро со святой водой чтобы залить им сервер в случае неприятности было подготовлено.

Сам процесс описывать не вижу особого смысла: собираем техническое задание, небольшими этапами двигаемся вперёд. Единственное, что важно для истории: я добавил в корневой .md-файл указания вести скрипт, который позволит повторно развернуть всё, что уже было настроено, и файл с короткой документацией о том, какие действия были сделаны и для чего.

Первые ощущения тут такие же, как у всех: чудеса, магия, успех. Первые две сети с самыми простыми настройками были подключены, входная точка в общую объединённую сеть настроена, правила трафика работали. Я не стал сразу идти дальше и решил погонять это неделю, чтобы посмотреть, будут ли проблемы.

Первые проблемы тоже пришли быстро. Через три дня выяснилось, что, хотя трафик между сетями идёт, стоит начать передавать большой файл — и ровно на одном и том же проценте соединение падает полностью.

Тут я извиняюсь: всем, наверное, интересно, почему такое происходило. Я даже читал ответ llm на этот счёт, но закономерно не могу гаратнировать что правильно его понял. Речь там шла о том, что присутствует петля, из-за которой пакеты с одного сетевого интерфейса проходят через него несколько раз и вылезают за счётчик допустимого количества пакетов, которые должны были покинуть VPN-интерфейс. (Вроде все логично, но все равно чувствуется этот запах работы с тем, чего не понимаешь — запах магии). Соответственно, что в таком случае делают вайбкодеры? Правильно: «LLM, не работает, почини». И всё починилось: трафик идёт, проблем нет.

Далее, через пару недель стабильности, я добавил ещё один VPN, описал нужные мне правила — и оно опять заработало сразу и как нужно. Опять вау, круто, магия. Проверил тесты с отключением сети, перезагрузкой, выключением сервисов — всё прекрасно, сеть восстанавливается.

А потом тест мне решила провести местная сетевая компания, вырубив свет на срок больший, чем прожил ИБП. И сеть не поднялась. Оказалось, что предыдущая настройка не учитывала ситуацию, при которой операторский маршрутизатор физически доступен, но ещё не готов отвечать. В результате сетевые интерфейсы VPN выбрали точкой выхода в глобальный интернет друг друга и успешно никуда не подключились.

После исправления этого косяка спустя четыре дня умер блок питания на ПК, на котором была развёрнута система (справедливости ради, мои правила домашних проектов предполагают, что они собираются из того, что есть под рукой, практически без вложений средств и зависимостей от внешних сервисов, так что это нормально). Это означало, что теперь я протестирую возможность развернуть настройки на другой машине. Наверное, профессиональный системный администратор сразу собирал бы всё в Docker-контейнере, который с лёгкостью перенёс бы куда угодно. Но я не системный администратор и уже огребал с настройками сетевых интерфейсов в Docker, поэтому «бэкап» у меня был sh-скриптом.

И в общем-то повезло, что я не стал его запускать. Я скормил его агенту и попросил развернуть всё на другой машине — с такой же системой, окружением, но уже имеющейся сервером для других задач. Скрипт, вероятнее всего, сломал бы сеть. Агент при развёртывании внёс кучу правок, о которых я и не думал, что они потребуются: сетевые интерфейсы на новой машине назывались по-другому, какие-то зависимости были не тех версий и так далее Получается у меня был «бэкап» шредингера (каждый системный администратор знает — всегда проверяй бэкапы, но я то тут в роли андроид разработчика). Ещё пара часов — и снова «всё работает».

Правда, через неделю выяснилось, что не всё. На самом деле часть, отвечающая за восстановление правил, не пережила переноса, и после того, как один из VPN-серверов ушёл в ребут, сеть снова не поднялась. На вопрос «почему?» агент с леденящим душу спокойствием ответил

Да, такой скрипт и правда был, но я ошибся и не учел, что его нужно зарегистрировать на триггер переподключения соединения.

В процессе регистрации, кстати, он повесил его не на то событие. В результате скрипт выполнялся почти постоянно, переприменяя правила в iptables и dnsmasq — для некоторых сервисов используется своя несуществующая доменная зона. Dnsmasq такого насилия не выдерживал и начал периодически падать, что опять же выяснилось через пару дней (вроде трафик до нужной доменной зоны есть, а вроде иногда 30 секунд на загрузку ресурса который должен грузиться за 1).

Далее суровым указанием «никаких reapply правил по расписанию, только триггеры вида “отвал + подключение сетевого интерфейса”» проблема была решена.

Следующей доработкой был скрипт-переключатель, который позволял переключать адрес до одного из серверов либо через один VPN, либо через другой. Это два сервера-клона, но в разных локациях. И опять же: полчаса написания ТЗ и кручения прогресс-бара — и всё работает прекрасно. Только на самом деле — нет: скрипт-переключатель работал прекрасно сразу после создания, но через три недели, когда я действительно захотел переключить маршрут трафика, после его вызова сеть упала. Вся, кроме локальной. Переключение туда-обратно не помогает, перезагрузка не помогает, даже подключиться к агенту с этого ПК уже нельзя напрямую.

Не смертельно: подключаемся к агенту со своего ПК, даём ему доступ через SSH, описываем проблему. Спустя ещё полчаса кручения прогресс-бара ситуация исправлена. Причина: переключатель написан неатомарно. В процессе перенаправления трафика он не смог получить данные из целевого туннеля и оставил систему в сломанном состоянии.

Честно говоря — это только большие проблемы, были еще маленькие, и еще последующие, но что-то текста и так уже становится слишком много, а написанного выше хватит чтобы раскрыть мою мысль.

К чему в итоге всё пришло. С одной стороны, у меня сейчас как будто есть работающий сервис, решающий поставленную задачу, сделанный непрофильным специалистом в слепую, без «единого ручного вызова скрипта» (это не совсем правда: настройки, которые отвечают за доступность локальной сети, я всё же всегда внимательно проверял, сверяясь с документацией, потому что настраивать headless-сервер, таща к нему монитор, не весело).

С другой стороны, это сервис-зомби. Я не знаю, как он работает. Никто другой тоже не знает, как он работает. И, что ещё страшнее, я даже не знаю, работает ли он на самом деле. Есть панель мониторинга, написанная по приколу, и она периодически показывает, что какой-то из ресурсов недоступен. Но я не знаю, правда ли он недоступен, или это конкретно на этой машине сломался доступ, или сейчас происходит скрытый reapply правил, из-за чего он недоступен. Первый раз на фразу «при потере соединения, при повторном подключении тоннеля, нужно восстанавливать правила» — llm сделала cron который каждую минуту переприменял правила, в результате чего потецниально (помимо других проблем) 59 секунд трафик мог идти вообще не туда куда нужно.

И я даже могу сказать: «Эй, агент, почему сейчас был статус “недоступен” у сервиса?» — и агент ответит мне: «Ой, была ошибка d%2&#@as5%, я всё починил, больше не повторится». Но я никогда не узнаю, правда ли это. Эта ли была проблема? Может, проблема вообще в другом? Может, ничего на самом деле не работает, а дашборд показывает погоду на Марсе? Может, мой трафик идёт через MITM-сервер хакеров и взломанный сервер Пентагона, и когда они заделают брешь, у меня он оборвётся?

К чему я все это: когда LLM-агент в yolo-режиме писал мне мобильное приложение, мне было вообще не страшно. Вообще пофиг. Пусть хоть всё там зальёт говнокодом. Я могу позволить себе даже не читать, пока не сломается. Но, когда всё сломается, я надену резиновые перчатки, возьму вантуз и без особых проблем, бубня про то, что навайбкодил тут херни, разгребу, что не работает, я весь этот стек знаю, а там где не знаю — разберусь за пару чашек чая.

Но на эту систему маршрутизации трафика мне страшно даже дышать. Вдруг она развалится, если я посмотрю на неё не тем взглядом? Дорабатывать? Увольте. Я не хочу даже использовать фичу по переключению маршрута: чёрт его знает, переживёт ли оно. И это при том, что старый способ доступа у меня остался, а критичность этого сервера — ноль.

Я решительно не понимаю, как люди, которые пишут статьи о том, что они сделали продукт на 20 тысяч строк Python-кода, не зная Python, дорабатывают этот продукт, и их при этом не трясёт от ужаса. Как можно брать деньги или, что ещё хуже, призывать брать деньги за что-то, что может взорваться из-за того, что голубь рядом чихнул неправильно?

Пытался вспомнить, когда испытывал подобные чувства, и вспомнил.

Во времена студенческой юности я проходил курсы по Ruby on Rails — просто так. И после серверов на других решениях там был подход, который назывался convention over configuration: соглашение выше конфигурации. Этот подход предполагал, что, следуя правильным договорённостям в именовании методов, классов, файлов и их расположении, фреймворк автоматически понимал, что класс User связан с таблицей users, а если в контроллере есть метод show, то будет искаться файл разметки с соответствующим именем.

И вот когда ты брал реализацию сервера, использующего этот подход на полную, не будучи при этом профессионалом в Ruby или Rails, ощущалось оно точно так же. Работает — но почему? Я добавил класс точно так же, но тот, что был, работает, а мой — нет, хотя они идентичны. В одном месте тянется один файл разметки, в другом — другой. Но как это исправить, если они нигде не указаны?

Работа с проектом, написанным LLM в незнакомой пользователю области, подобна попытке работать с фреймворком на неизвестном языке, для которого нет документации и который при этом содержит неявные соглашения.

Определенно, область знаний, необходимых рарзаботчику меняется, llm делает очень много вещей которые были сложными — простыми. Возможно, даже не весь сгенерированный код нужно читать (но это не точно, и вопрос очень спорный), и не всегда важно, чтобы он там был идеальный, четко структурированный или еще что-то. Но я совершенно точно уверен в том, что для разработчика и дальше будет невероятно важна способность в случае нобходимости погрузиться глубоко в весь этот сгенерированный код, и найти, понять и исправить там тот самый винтик, который все сломал.

ссылка на оригинал статьи https://habr.com/ru/articles/1031458/