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

Средовой подход на это отвечает прямо: раз природа законы не даёт, установи их сам и сделай нерушимыми. На практике это Policy as Сode, admission-контроллеры в кубере или в целом любая платформа, которая делает недопустимое состояние попросту невозможным.
Стимулы вместо команд (силовые поля, градиенты). Направления наименьшего сопротивления, вдоль которых течёт (или выстраивается) поведение. Компоненту не приказывают, где жить или как себя вести — делают так, что правильное размещение и поведение дешевле или быстрее. Например, кубер разместит поды туда, где ресурсы свободнее/дешевле; балансировщик направит меньше трафика на медленный инстанс. Backpressure-механизм и квоты — туда же.
Приём один: сделать правильное путём наименьшего сопротивления.
Ниши. Термин я взял у Юрия Мануйлова — у него есть проработанная теория средового подхода (правда, в педагогике). Суть в том, что ты проектируешь не сам компонент, а форму пустого слота, в котором компонент определённого рода может появиться: точки расширения/плагины, события/топики как ниши, шаблоны, app store, описание mcp-сервера… Заполняет ниши уже среда без центральной координации. Спроектировать нишу — значит описать условия появления, а содержимое оставить открытым.
Отбор и гомеостаз. То, что поощряет пригодное и растворяет непригодное. Прохождение Fitness-функций и тестов: кто не прошёл — до прода не доехал. Все разнообразные метрики Fitness-сигналов (SLO / уровень ошибок / latency) поднимают долю годного и убивают негодное.
Канареечный релиз с плохими сигналами автоматически откатывается, с хорошими — повышается до боевого. Метрика решает судьбу версии.
Что измеряешь, по тому и идёт отбор — поэтому кривая метрика приводит к кривому результату (классический закон Гудхарта: показатель, ставший целью, перестаёт быть хорошим показателем). Если награждать только за прохождение тестов — среда эволюционирует в сторону обмана тестов, а не качества
Полупроницаемые мембраны. Граница в среде — не бинарная стена можно/нельзя, а градиент проницаемости: например, внутри ходить дёшево, а наружу уже дороже, стоимость растёт с уровнем перехода через границу (модуль-микросервис-контекст-продукт). По сути — это мой принцип каскадного снижения связанности, переписанный на язык средового подхода
Методология: цикл проектирования среды
Системный цикл мы знаем наизусть: требования → декомпозиция и спецификация → разработка → тестирование → …
Средовой цикл я бы построил так:
Определить макрозаконы продукта. Свойства поведения целого, которые мы хотим гарантировать. Например:
время отклика не растёт при увеличении данных в 10 раз,
отказ любой части не приводит к отказу всего,
подключение нового партнёра (службы доставки, платёжки) занимает не больше 2 дней.
… и так далее
Вшить нерушимые правила для каждого элемента (что среда запрещает всем) Правила поведения частного, каждого элемента по отдельности. Например:
у каждой сущности данных ровно одна мастер-система
взаимодействие только по API-контракту (без прямых подключений в чужую БД)
любой сервис обязан быть stateless и убиваемым в любой момент без потери данных
… и т.д.
Спроектировать стимулы (градиенты) так, чтобы агент (человек или ИИ), производящий компонент, сам тянулся к нужной реализации и конфигурации.
Нарезать ниши — формы слотов, которые будут заполняться уже без нашего ведома
Включить отбор и гомеостаз — проверка fitness-сигналов, поглощение внешнего воздействия — возврат к равновесию (паттерны отказоустойчивости).
Наблюдать макроповедение. Отслеживание соблюдения законов и показателей эмерджентных свойств (свойств целого, а не метрик каждого компонента по отдельности). Бизнес-метрики или общая доступность продукта - хорошие примеры эмерджентных свойств.
Настраивать силовые поля. Если поведение поплыло — крутим стимулы (градиенты), пробуем править законы и правила отбора. В отдельный конкретный компонент не лезем, даже если знаем что он ведёт себя не подобающе. Помним, что мы — садовники.
Такой цикл не отменяет наших передовых текущих подходов. Гипотезы, метрики, тесты, фитнес-функции, платформизация и т.д. — всё на месте, просто теперь это инструменты возделывания среды. И гипотезы мы проверяем не про компонент, а про среду в целом: «если сдвинуть стимул вот так, рой микросервисов перераспределится туда-то, и макрометрика поедет». Доказательность и предсказуемость остаются, просто переезжают на уровень выше.
Паттерны средового проектирования
Если у системного мира есть SOLID, DDD, оркестрация и хореография, то для средового я бы выделил следующий набор. Часть уже живёт в теории распределённых и роевых систем, часть можно достроить под ИТ-продукты. Наверняка список неполный.
Стигмергия. Координация через следы в среде, а не через прямое взаимодействие. К примеру, муравьи не устраивают созвонов на весь муравейник, они оставляют феромоны, по которым выстраивается поведение всего отряда. В ИТ это общий журнал событий или разделяемое состояние (которое компоненты читают и в которое пишут, вместо оркестрованных цепочек вызовов). Похоже на event-driven, и наполовину это он — но в средовой рамке это базовый способ координации роя, а не один из вариантов интеграции.
Аттрактор/градиент вместо явной маршрутизации. Размещение и направление по градиентам метрик. Ничего (или почти ничего) не должен решать центр (оркестратор) — всё само вытекает из заданных законов силовых полей. Помимо примеров выше, приведу ещё один: Pull вместо push (очередь как поле). Воркеры сами забирают задачи из очереди в своём темпе — работа автоматически утекает к свободным мощностям. Свободный воркер — это низина градиента, задача в неё скатывается. Нет никакого диспетчера, раздающего задания поимённо.
Правило как физический закон Инвариант, который среда делает нерушимым. Например, типизация и сборка кода компилятором, ограничения и правила в БД (Not NULL, FK, …), read-only доступы и т.д. Среда или платформа отвергает нелегальное состояние. Эти законы нельзя нарушить даже очень захотев под дедлайн.
Ниша + колонизация. Пустой слот с описанными условиями появления чего-либо, который заполняют агенты (внешние или внутренние).
Отбор и выбраковка (свойство растворения). Правила отбора и верификации, о которых писал выше, должны работать :)
Популяция вместо экземпляра. Надёжность измеряется и проверяется статистикой роя, а не корректностью каждого элемента.
Гомеостатические петли. Как пример — практики отказоустойчивости автоскейлинг, переподключение, Circuit Breaker и т.д. Проектируем не чтобы не упало, а чтобы вернулось в равновесие после того, как качнулось (как это делается в отдельной моей статье, которую уже упоминал выше: https://habr.com/ru/articles/764904/).
Принципы
Если брать классическую ИТ-науку, в дополнение к паттернам можно попробовать сформулировать и принципы проектирования сред. Позволю себе сделать это кратко
Возделывай условия вместо самостоятельной лепки результата.
Делай желаемое путём наименьшего сопротивления — выравнивай градиенты с целью.
Управляй законом, а не инструкцией: закон держится для всех элементов, включая ещё не существующие.
Доверяй отбору больше, чем спецификации — пусть пригодность решает, какие компоненты живут.
Надёжность бери из популяции, а не из совершенства отдельного элемента.
Наблюдай и рули на макроуровне.
Встраивай растворение: каждый элемент обязан быть дёшево убиваемым.
Помни роли: архитектор возделывает поля и законы, компоненты выращивают агенты —
белковыечеловеческие и ИИБереги разнообразие: монокультура среды хрупка.
Последний принцип поясню. К примеру, если у нас только один провайдер интернета - это плохо для отказоустойчивости, ошибка в едином конфиге, раскатывающимся везде — туда же. Тут тонкая грань между случайным зоопарком решений и технологий и осознанным многообразием по оси отказа — ради отсутствия единой причины, которая может положить всё.
Табличка с различиями
Измерение | Системный подход | Средовой подход |
|---|---|---|
Объект проектирования | компоненты и связи | законы, поля, ниши, отбор |
Единица | компонент/сервис | поле/закон/популяция |
Способ управления | команда, спецификация | влияние, градиент, условие |
Как происходит изменение | перепроектировал и пересобрал | сдвинул поле — рой перетёк сам |
Источник надёжности | корректность каждого элемента | гомеостаз и популяция (растворение) |
Роль архитектора | конструктор механизма | садовник среды / законодатель физики |
Верификация | доказать поведение артефакта | доказать, что законы держатся + статистика макроповедения |
Типичный отказ | сломалась деталь | патологическая эмерджентность (автоколебания, лавинообразный рост нагрузки, вечные циклы) |
Что значит «хорошо» | соответствие чертежу | устойчивое нужное макроповедение |
Итак, внимательный и прозорливый читатель уже наверняка провёл аналогии. Если вы работали с ИИ по SDD (Spec-Driven Development) - совпадения легко прослеживаются.
Средовой подход — это и есть harness для ИИ
Посмотрите, как мы работаем с ИИ-агентами, когда работаем всерьёз: мы же не диктуем агенту код строка за строкой — это абсурд, тогда уж проще самому написать. Мы задаём ему обвязку: рабочие файлы, 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 — всё то же самое, но для ИИ-агентов.
Каждый кирпичик мы внедряли по отдельности, решая свою локальную боль. Но если отойти и посмотреть на картину целиком — это симптомы одного большого сдвига. Мы всё меньше собираем системы деталь за деталью и всё больше возделываем среды, в которых нужное поведение заводится и держится само. По привычке зовём себя конструкторами, хотя наполовину уже садовники.
Та задача из прошлой статьи перестаёт быть фантастикой и становится рабочей повесткой. Архитектору будущего — да чего там, уже настоящего — придётся учиться проводить границу: что в продукте остаётся жёсткой системой, а что отдаётся среде. Платежи, транзакции, безопасность и сами законы среды — это жёсткие ядра, там нужны точные гарантии, и средовая растворяемость там противопоказана. Вокруг ядер — средовые зоны, где код самоорганизуется. Спроектировать для этих зон законы, поля, ниши и отбор — и есть новая работа.
Если говорить про ограничения — средовой подход теряет локальные гарантии: он принципиально не отвечает на вопрос «почему упала вот эта конкретная капля», а в платежах нам нужна именно капля. Эмерджентность работает в обе стороны — самозаводятся и плохие макроповедения: автоколебания, лавинообразные падения, вечные зацикливания. Отладка единичного инцидента в среде дороже.
И есть культурный риск: «это эмерджентно, это среда» — слишком удобная отговорка для того, кто просто не разобрался. Так что, я думаю, это не замена системному подходу, а надстройка и соседняя парадигма для другого класса задач.
Получается поставленный мной в прошлой статье вопрос должен сводится не к замене системного подхода на средовой, а к их совместному осмысленному и эффективному применению.
Не успел дописать в среду, публикую в четверг
Скромно оставляю ссылку на свой тг-канал: Архитектура распределённых систем , останавливаться в изысканиях не собираюсь — подписывайтесь
📝
