- BrainTools - https://www.braintools.ru -

В своей прошлой статье про будущее ИТ [1] я писал о важности формулирования новых вызовов в индустрии:
Но мы почти не говорим о нерешённых и, тем более, о непоставленных задачах. Мы не обсуждаем вопросы, которые ещё не заданы. А чтобы задача поставилась, нужно как минимум о ней задуматься.
И постарался этот вызов сформулировать:
На мой взгляд, следующий этап развития ИТ — это переход от системного подхода к средовому.
Теперь настало время начать хотя бы задумываться об ответе на поставленный вопрос, и кому этим заняться, если не мне? 😅
Итак, давайте кратко повторю, что я имел ввиду:
Мы перестанем думать категориями «300 микросервисов, между ними такие-то связи» и начнём думать категориями «вот эта штука ведёт себя по определённым законам, а внутри — рой чего-то, чего конкретно — нам не важно». И архитекторы будущего будут описывать методологию построения таких сред. Это большой новый вызов.
В этой статье я как раз попытаюсь начать набрасывать методологию проектирования ИТ-продуктов в средовом, а не системном подходе. Сразу предупреждаю — это скорее черновик, и мысли или конструирование вслух, хотя местами что-то мне уже удалось проверить на практике, а что-то мы сами того не зная уже давно используем.
Я отношусь к написанному ниже как к гипотезе, которую надо проверять об практику и об другие умы. Собственно этим я и занимаюсь, и продолжу заниматься.
Последние лет 50+ мы живём в парадигме системного подхода. Система — это совокупность компонентов, где мы знаем каждый компонент и каждую связь между компонентами. Знаем сколько их и какие они. Мы декомпозируем, специфицируем, собираем, проверяем. ООП, Монолиты, Микросервисы, контракты, диаграммы — всё это про систему и системный подход.
Средовой подход особенно нужен там, где компонентов или связей становится столько, что учесть каждое взаимодействие на уровне атома уже невозможно. Зато мы знаем, как ведёт себя среда в целом, по каким законам и принципам.
Например, мы знаем закон распространения волн по глади воды, при этом не можем учесть или предсказать каждое столкновение каждой молекулы воды внутри волны.
Ещё одно отличие, на которое обращал внимание [2] в прошлой статье: система реагирует обратной связью, если нагрузили какой-то сайт — он может упасть. Среда воздействие растворяет. Кинул камень в воду — круги разошлись, и через некоторое время поверхность воды снова стала гладкой. Среда поглощает возмущение и возвращается к равновесию.
И для перехода к созданию или проектированию среды рассмотрим ещё одну очень удачную аналогию. По сути это ведь садоводство!
Системный архитектор работает как конструктор: собирает механизм из деталей по чертежу и отвечает за каждую деталь и каждое соединение. Средовой архитектор ближе к садовнику. Он не приклеивает листья к дереву и не вкручивает ветки руками — он задаёт почву, свет, влагу, плотность посадки — то есть условия. А дерево или куст растут сами. И если что-то растёт криво — садовник не дёргает ветку, а например меняет освещение. При средовом подходе: мы возделываем условия, при которых вырастает нужное, а не лепим нужное руками.
В прошлой статье я писал, что ИИ в ближайшее время будет писать хороший код. И ещё — что истинное предназначение архитектуры это борьба со сложностью и её укрощение, и эта борьба остаётся за человеком (в отличие от обязанности написания кода).
Оба этих тезиса подталкивают нас к средовому подходу.
Пока код пишет человек — его мало и он дорогой. И описывать систему поэлементно вполне естественно — мы же каждую строчку кода выстрадали 😅. Но когда компоненты начинает штамповать ИИ — дёшево, быстро и в избытке, — мы оказываемся в средовой ситуации помимо своей воли. Артефактов столько, что отревьюить и специфицировать каждый по-атомно физически некому. А если в вашем ИТ-продукте, есть ещё и самостоятельные встроенные ИИ-агенты (а не только те, которые пишут код вашего ИТ-продукта) — непредсказуемость на нижнем уровне детализации будет ещё выше.
Управлять этим изобилием системными методами просто нечем. Нужен другой подход. Так что методология ниже — это уже даже не про “через 10 лет” (как я думал ещё год назад). А про то, как удержать управляемость уже сейчас, ведь уже сейчас агенты как минимум массово фигачат код.
В системном подходе наш привычный алфавит — компонент, интерфейс, связь, слой, граница. У средового алфавит должен быть другой. Вот что мы должны проектировать вместо компонентов:
Законы среды (её физика; встроенные, нерушимые правила; инварианты или субстрат). Правила, которые держатся всегда и для любого компонента — нынешнего и будущего, написанного человеком или агентом. Например:
У каждой сущности данных ровно одна мастер-система
Взаимодействие через любую границу (компонента/микросервиса/контекста/продукта) — только по контракту
Любой элемент обязан быть дёшево и быстро убиваемым
Раньше для меня это были тесты-проверки постфактум — я про это много писал: каскадное снижение связанности [3], тестирование архитектуры as Code [4], проектирование и тестирование отказоустойчивости [5]. В средовом подходе они становятся первичным предметом проектирования — той физикой, которая в природе изначально влияет на все процессы (а не постфактум проверяет — соответствует ли то, что выросло законам физики). В одном из постов [6] у меня была мысль: в физическом мире есть силы природы, которые не дадут собрать нежизнеспособного франкенштейна, а в ИТ таких сил нет — макаронного монстра ничто не зарубает на корню.

Средовой подход на это отвечает прямо: раз природа законы не даёт, установи их сам и сделай нерушимыми. На практике это Policy as Сode, admission-контроллеры в кубере или в целом любая платформа, которая делает недопустимое состояние попросту невозможным.
Стимулы вместо команд (силовые поля, градиенты). Направления наименьшего сопротивления, вдоль которых течёт (или выстраивается) поведение [7]. Компоненту не приказывают, где жить или как себя вести — делают так, что правильное размещение и поведение [8] дешевле или быстрее. Например, кубер разместит поды туда, где ресурсы свободнее/дешевле; балансировщик направит меньше трафика на медленный инстанс. Backpressure-механизм и квоты — туда же.
Приём один: сделать правильное путём наименьшего сопротивления.
Ниши. Термин я взял у Юрия Мануйлова — у него есть проработанная теория [9] средового подхода (правда, в педагогике). Суть в том, что ты проектируешь не сам компонент, а форму пустого слота, в котором компонент определённого рода может появиться: точки расширения/плагины, события/топики как ниши, шаблоны, app store, описание mcp-сервера… Заполняет ниши уже среда без центральной координации. Спроектировать нишу — значит описать условия появления, а содержимое оставить открытым.
Отбор и гомеостаз. То, что поощряет пригодное и растворяет непригодное. Прохождение Fitness-функций и тестов: кто не прошёл — до прода не доехал. Все разнообразные метрики Fitness-сигналов (SLO / уровень ошибок / latency) поднимают долю годного и убивают негодное.
Канареечный релиз с плохими сигналами автоматически откатывается, с хорошими — повышается до боевого. Метрика решает судьбу версии.
Что измеряешь, по тому и идёт отбор — поэтому кривая метрика приводит к кривому результату (классический закон Гудхарта: показатель, ставший целью, перестаёт быть хорошим показателем). Если награждать только за прохождение тестов — среда эволюционирует в сторону обмана тестов, а не качества
Полупроницаемые мембраны. Граница в среде — не бинарная стена можно/нельзя, а градиент проницаемости: например, внутри ходить дёшево, а наружу уже дороже, стоимость растёт с уровнем перехода через границу (модуль-микросервис-контекст-продукт). По сути — это мой принцип каскадного снижения связанности [3], переписанный на язык средового подхода
Системный цикл мы знаем наизусть: требования → декомпозиция и спецификация → разработка → тестирование → …
Средовой цикл я бы построил так:
Определить макрозаконы продукта. Свойства поведения целого, которые мы хотим гарантировать. Например:
время отклика не растёт при увеличении данных в 10 раз,
отказ любой части не приводит к отказу всего,
подключение нового партнёра (службы доставки, платёжки) занимает не больше 2 дней.
… и так далее
Вшить нерушимые правила для каждого элемента (что среда запрещает всем) Правила поведения частного, каждого элемента по отдельности. Например:
у каждой сущности данных ровно одна мастер-система
взаимодействие только по API-контракту (без прямых подключений в чужую БД)
любой сервис обязан быть stateless и убиваемым в любой момент без потери данных
… и т.д.
Спроектировать стимулы (градиенты) так, чтобы агент (человек или ИИ), производящий компонент, сам тянулся к нужной реализации и конфигурации.
Нарезать ниши — формы слотов, которые будут заполняться уже без нашего ведома
Включить отбор и гомеостаз — проверка fitness-сигналов, поглощение внешнего воздействия — возврат к равновесию (паттерны отказоустойчивости [5]).
Наблюдать макроповедение. Отслеживание соблюдения законов и показателей эмерджентных свойств (свойств целого, а не метрик каждого компонента по отдельности). Бизнес-метрики или общая доступность продукта – хорошие примеры эмерджентных свойств.
Настраивать силовые поля. Если поведение поплыло — крутим стимулы (градиенты), пробуем править законы и правила отбора. В отдельный конкретный компонент не лезем, даже если знаем что он ведёт себя не подобающе. Помним, что мы — садовники.
Такой цикл не отменяет наших передовых текущих подходов. Гипотезы, метрики, тесты, фитнес-функции, платформизация и т.д. — всё на месте, просто теперь это инструменты возделывания среды. И гипотезы мы проверяем не про компонент, а про среду в целом: «если сдвинуть стимул [10] вот так, рой микросервисов перераспределится туда-то, и макрометрика поедет». Доказательность и предсказуемость остаются, просто переезжают на уровень выше.
Если у системного мира есть SOLID, DDD, оркестрация и хореография, то для средового я бы выделил следующий набор. Часть уже живёт в теории распределённых и роевых систем, часть можно достроить под ИТ-продукты. Наверняка список неполный.
Стигмергия. Координация через следы в среде, а не через прямое взаимодействие. К примеру, муравьи не устраивают созвонов на весь муравейник, они оставляют феромоны, по которым выстраивается поведение всего отряда. В ИТ это общий журнал событий или разделяемое состояние (которое компоненты читают и в которое пишут, вместо оркестрованных цепочек вызовов). Похоже на event-driven, и наполовину это он — но в средовой рамке это базовый способ координации роя, а не один из вариантов интеграции.
Аттрактор/градиент вместо явной маршрутизации. Размещение и направление по градиентам метрик. Ничего (или почти ничего) не должен решать центр (оркестратор) — всё само вытекает из заданных законов силовых полей. Помимо примеров выше, приведу ещё один: Pull вместо push (очередь как поле). Воркеры сами забирают задачи из очереди в своём темпе — работа автоматически утекает к свободным мощностям. Свободный воркер — это низина градиента, задача в неё скатывается. Нет никакого диспетчера, раздающего задания поимённо.
Правило как физический закон Инвариант, который среда делает нерушимым. Например, типизация и сборка кода компилятором, ограничения и правила в БД (Not NULL, FK, …), read-only доступы и т.д. Среда или платформа отвергает нелегальное состояние. Эти законы нельзя нарушить даже очень захотев под дедлайн.
Ниша + колонизация. Пустой слот с описанными условиями появления чего-либо, который заполняют агенты (внешние или внутренние).
Отбор и выбраковка (свойство растворения). Правила отбора и верификации, о которых писал выше, должны работать :)
Популяция вместо экземпляра. Надёжность измеряется и проверяется статистикой роя, а не корректностью каждого элемента.
Гомеостатические петли. Как пример — практики отказоустойчивости автоскейлинг, переподключение, Circuit Breaker и т.д. Проектируем не чтобы не упало, а чтобы вернулось в равновесие после того, как качнулось (как это делается в отдельной моей статье, которую уже упоминал выше: https://habr.com/ru/articles/764904/ [5]).
Если брать классическую ИТ-науку, в дополнение к паттернам можно попробовать сформулировать и принципы проектирования сред. Позволю себе сделать это кратко
Возделывай условия вместо самостоятельной лепки результата.
Делай желаемое путём наименьшего сопротивления — выравнивай градиенты с целью.
Управляй законом, а не инструкцией: закон держится для всех элементов, включая ещё не существующие.
Доверяй отбору больше, чем спецификации — пусть пригодность решает, какие компоненты живут.
Надёжность бери из популяции, а не из совершенства отдельного элемента.
Наблюдай и рули на макроуровне.
Встраивай растворение: каждый элемент обязан быть дёшево убиваемым.
Помни роли: архитектор возделывает поля и законы, компоненты выращивают агенты — белковые человеческие и ИИ
Береги разнообразие: монокультура среды хрупка.
Последний принцип поясню. К примеру, если у нас только один провайдер интернета – это плохо для отказоустойчивости, ошибка [11] в едином конфиге, раскатывающимся везде — туда же. Тут тонкая грань между случайным зоопарком решений и технологий и осознанным многообразием по оси отказа — ради отсутствия единой причины, которая может положить всё.
|
Измерение |
Системный подход |
Средовой подход |
|---|---|---|
|
Объект проектирования |
компоненты и связи |
законы, поля, ниши, отбор |
|
Единица |
компонент/сервис |
поле/закон/популяция |
|
Способ управления |
команда, спецификация |
влияние, градиент, условие |
|
Как происходит изменение |
перепроектировал и пересобрал |
сдвинул поле — рой перетёк сам |
|
Источник надёжности |
корректность каждого элемента |
гомеостаз и популяция (растворение) |
|
Роль архитектора |
конструктор механизма |
садовник среды / законодатель физики |
|
Верификация |
доказать поведение артефакта |
доказать, что законы держатся + статистика макроповедения |
|
Типичный отказ |
сломалась деталь |
патологическая эмерджентность (автоколебания, лавинообразный рост нагрузки, вечные циклы) |
|
Что значит «хорошо» |
соответствие чертежу |
устойчивое нужное макроповедение |
Итак, внимательный и прозорливый читатель уже наверняка провёл аналогии. Если вы работали с ИИ по SDD (Spec-Driven Development) – совпадения легко прослеживаются.
Посмотрите, как мы работаем с ИИ-агентами, когда работаем всерьёз: мы же не диктуем агенту код строка за строкой — это абсурд, тогда уж проще самому написать. Мы задаём ему обвязку: рабочие файлы, ADR, примеры, стайл-гайды, тесты, CI, линтеры, политики, бизнес-цель, ограничения и т.д. В мире LLM это и называют harness — вся обвязка или оснастка вокруг модели, в которой она действует: инструменты, контекст, проверки, петли обратной связи, правила игры.
А теперь приглядитесь, из чего harness состоит. Законы — это линтеры, типы, policy и admission-проверки, которые агент не может нарушить. Отбор — тесты и evals: годное проходит, негодное не доезжает. Наблюдение за макро — ты смотришь не на каждую сгенерённую строчку, а на результат целого, соблюдение законов и метрики. Т.е. на те же самые средовые примитивы, просто под другими именами.
На мой взгляд стимулы (градиенты) — это то, куда harness’ы будут развиваться в ближайшее время. В дополнение к жёстким запретам и проверкам мы будем встраивать мягкие сигналы, которые бы плавно подталкивали агента к лучшей конфигурации. Насколько я знаю, удачных решений тут пока нет.
Я уже пару месяцев принимаю участие в разработке нового harness’а (ну или SDD-фреймворка на максималках), и, честно скажу, до меня только совсем недавно внезапно дошло, что harness для ИИ и есть та среда, в которой ИТ-продукт взращивается сам или руками ИИ-агентов. Мы задаём не код, а условия, направления и отбор, а реализация вырастает внутри. Слово в слово определение средового проектирования. LLM-инженерия пришла к нему с другой стороны и назвала своим термином.
Я уже отмечал, что на смену промпт-инженеру приходит контекст-инженер: формулировать научились все, а вот собирать контекст — навык, который только формируется. Теперь думаю, что и контекст-инженер — тоже промежуточная остановка. Дальше — средовой инженер, архитектор среды: тот, кто проектирует не контекст под одну задачу, а устойчивую обвязку, в которой рой агентов сам и многократно решает целые классы задач. То есть сейчас мы уже занимаемся средой для взращивания ИТ-продукта. Я думаю, скоро будем проектировать и среды, где он живёт (функционирует). Ведь сейчас harness заканчивается до кнопки deploy to prod.
Когда я прошлой осенью впервые на докладе сказал, что к средовому подходу в ИТ мы придем через лет 10 — я глубоко ошибся в большую сторону ) А когда я сам начал использовать и развивать SDD — я, кажется, проглядел очевидное под носом. Мы туда уже пришли и обживаемся. А если брать отдельные наши практики — так мы там вообще давно, только не называли это средовым подходом.
Смотрите сами. Kubernetes — это не «запусти вот этот процесс вот здесь», а «вот желаемое состояние и законы, держи его сам, а как именно — твоё дело». Чистый гомеостаз. Автоскейлинг — гомеостатическая петля. Фитнес-функции, evals, тесты и метрики статического анализа — отбор. Платформенная инженерия и internal developer platform — построение среды и ниш, в которые продуктовые команды встраиваются. Policy-as-code и admission-контроллеры — законы физики среды. FinOps — градиент стоимости. Service mesh — поле, через которое течёт трафик.
Harness — всё то же самое, но для ИИ-агентов.
Каждый кирпичик мы внедряли по отдельности, решая свою локальную боль [12]. Но если отойти и посмотреть на картину целиком — это симптомы одного большого сдвига. Мы всё меньше собираем системы деталь за деталью и всё больше возделываем среды, в которых нужное поведение заводится и держится само. По привычке зовём себя конструкторами, хотя наполовину уже садовники.
Та задача из прошлой статьи перестаёт быть фантастикой и становится рабочей повесткой. Архитектору будущего — да чего там, уже настоящего — придётся учиться проводить границу: что в продукте остаётся жёсткой системой, а что отдаётся среде. Платежи, транзакции, безопасность и сами законы среды — это жёсткие ядра, там нужны точные гарантии, и средовая растворяемость там противопоказана. Вокруг ядер — средовые зоны, где код самоорганизуется. Спроектировать для этих зон законы, поля, ниши и отбор — и есть новая работа.
Если говорить про ограничения — средовой подход теряет локальные гарантии: он принципиально не отвечает на вопрос «почему упала вот эта конкретная капля», а в платежах нам нужна именно капля. Эмерджентность работает в обе стороны — самозаводятся и плохие макроповедения: автоколебания, лавинообразные падения, вечные зацикливания. Отладка единичного инцидента в среде дороже.
И есть культурный риск: «это эмерджентно, это среда» — слишком удобная отговорка для того, кто просто не разобрался. Так что, я думаю, это не замена системному подходу, а надстройка и соседняя парадигма для другого класса задач.
Получается поставленный мной в прошлой статье вопрос должен сводится не к замене системного подхода на средовой, а к их совместному осмысленному и эффективному применению.
Не успел дописать в среду, публикую в четверг
Скромно оставляю ссылку на свой тг-канал: Архитектура распределённых систем [13] , останавливаться в изысканиях не собираюсь — подписывайтесь
📝
Автор: razon
Источник [14]
Сайт-источник BrainTools: https://www.braintools.ru
Путь до страницы источника: https://www.braintools.ru/article/32232
URLs in this post:
[1] про будущее ИТ: https://habr.com/ru/articles/1027144/
[2] внимание: http://www.braintools.ru/article/7595
[3] каскадное снижение связанности: https://habr.com/ru/articles/894766/
[4] тестирование архитектуры as Code: https://habr.com/ru/articles/800205/
[5] проектирование и тестирование отказоустойчивости: https://habr.com/ru/articles/764904/
[6] постов: https://t.me/rsa_enc/195
[7] поведение: http://www.braintools.ru/article/9372
[8] поведение: http://www.braintools.ru/article/5593
[9] теория: https://sreda-lab.narod.ru/index/0-11
[10] стимул: http://www.braintools.ru/article/5596
[11] ошибка: http://www.braintools.ru/article/4192
[12] боль: http://www.braintools.ru/article/9901
[13] Архитектура распределённых систем: https://t.me/rsa_enc
[14] Источник: https://habr.com/ru/articles/1051722/?utm_source=habrahabr&utm_medium=rss&utm_campaign=1051722
Нажмите здесь для печати.