Комментарии 5
Сложность: Средний
Спасибо, посмеялся. Я уже на одной четверти текста перестал связывать одно с другим, а для тиктокера это вообще непролазный лес! Но в целом - я в восторге!! Никогда не смотрел на разработку программ в таком ключе. Получилось очень интересно и познавательно (ну, там, где я понял о чём речь, разумеется :))) ).
Попросил ИИшечку привести пост к моему когнитивному уровню - вроде стало чуть полегче. Выкладываю выжимку, может кому сгодится. Там, правда, под меня "заточено", но каждый может перегнать страницу в PDF, скормить "своей" ИИшке и получить трансляцию идей ТС'а "под себя".
Вот "под меня"
Интересная статья, но, на мой взгляд, её ценность не в том, что программирование буквально «доказывает» Платона, Аристотеля или Лейбница. Философские параллели здесь скорее язык, позволяющий разложить архитектурные решения по независимым вопросам.
В упрощённом виде автор предлагает спрашивать о системе следующее:
Где находится общее: в явно объявленном типе, в фактической структуре объекта или только в именах и соглашениях?
Что первично: устойчивый объект с изменяемым состоянием или поток событий, из которого состояние каждый раз выводится?
Кто может менять состояние: любой обладатель ссылки или только сама сущность через обработку сообщений?
Сохраняется ли форма в runtime: может ли система во время исполнения распознать тип, схему и смысл полученного сообщения?
Кто владеет исполнением: внешний поток, единый event loop, coroutine, actor или отдельный процесс?
Где находится цель: только у пользователя либо представлена внутри системы и самостоятельно ею преследуется?
Из этого получается несколько вполне практических выводов.
Первый: главная проблема конкурентности — сочетание нескольких исполнителей с общим изменяемым состоянием. Лечить её можно в двух независимых направлениях: убрать изменяемость или убрать совместное владение. Отсюда два устойчивых подхода: свободно разделяемые immutable-значения и изолированное mutable-состояние с единственным владельцем.
Второй: у каждого изменяемого состояния должен быть понятный хозяин. Остальные компоненты не должны менять его напрямую — они предъявляют команду или сообщение, а владелец сам решает, как и когда его обработать. Это снижает число возможных комбинаций взаимодействий, хотя оплачивается очередями, сериализацией, задержками и необходимостью согласования.
Третий: интерфейс полезен именно как узкий контракт, а не как способ передавать потомкам кусок готового «бытия». Чем больше состояния и поведения спускается через наследование, тем сильнее связанность и тем сложнее независимо изменять части системы. Поэтому композиция и чистые интерфейсы обычно устойчивее глубоких иерархий классов.
Четвёртый: event sourcing не отменяет объекты, а переносит источник истины. В обычном ООП истина находится в текущем состоянии объекта. В event-sourced-системе — в журнале, а объект становится проекцией истории. Это полезно там, где важны аудит, восстановление, повторная обработка и объяснимость, но не является универсально лучшей моделью.
Пятый: runtime-системе необязательно иметь рефицированные типы самого языка, но ей необходимо какое-то доступное представление протокола — schema, discriminator, валидатор, таблица диспетчеризации или сгенерированный декодер. Замкнутый компонент может самостоятельно интерпретировать сообщение только тогда, когда формат сообщения представлен во время исполнения.
Шестой: автономность исполнения и наличие цели — разные свойства. Actor может иметь собственный цикл обработки и ни к чему не стремиться. Оптимизатор может преследовать цель, оставаясь полностью управляемым внешней петлёй. Для агентных систем это различие принципиально: отдельно должны проектироваться движитель, цель, полномочия и возможность её коррекции.
Наиболее сильной мне кажется последняя часть статьи про LLM-агентов. В обычной системе сообщение и код разделены: данные не должны переписывать поведение обработчика. У языкового агента и инструкции, и данные, и описание цели представлены одним субстратом — текстом. Поэтому message passing сам по себе не обеспечивает изоляции: сообщение может изменить не состояние, а интерпретацию правил и цели.
Практическое следствие — на внутренних границах агентных систем свободный естественный язык, вероятно, должен уступать место более жёстким протоколам:
явно заданному типу сообщения;
разделению данных, инструкций и системных правил;
валидируемому payload;
ограниченным capabilities;
аудируемому журналу действий;
отдельной процедуре изменения цели и полномочий.
Для мультиагентных систем из этого следуют два относительно устойчивых варианта. Либо один большой агент с внутренним разделением ролей, единым контекстом и общей целью. Либо несколько изолированных агентов с явными ролями, полномочиями, аудитом, арбитражем и процедурами согласования. Толпа агентов, свободно общающихся на естественном языке при размытых целях и широких правах, выглядит действительно неустойчивой.
При этом я бы осторожнее относился к сильным тезисам статьи. Аналогия между actor и монадой или между Paxos и предустановленной гармонией красива, но сама по себе ничего не доказывает. Заявленная ортогональность осей тоже не абсолютна: в реальных языках и runtime эти свойства часто сцеплены. А «закон сложности» работает только тогда, когда систему действительно можно разрезать по узким границам. Плохо декомпозированная распределённая система легко оказывается сложнее хорошего модульного монолита.
Поэтому я бы сформулировал практическое ядро статьи так:
Большие системы становятся понятнее, когда состояние имеет явного владельца, взаимодействия проходят через узкие проверяемые протоколы, а форма, исполнение, полномочия и цели не смешиваются в одной конструкции.
Для агентных систем к этому добавляется ещё одно требование: изолировать нужно не только память, но также интерпретацию, инструкции, полномочия и цель. Здесь обычной инкапсуляции уже недостаточно — появляются роли, политики, аудит, арбитраж и ответственность.
В любом случае, есть над чем подумать. Спасибо за статью! (y)
Да, практическая выжимка хорошая, спасибо. Сложность поправил таки на "сложную", тут действительно нужна привычка к специфичному философскому языку. Плюс поправил косяки в последней таблице - MD не всегда правильно рендерится.
На мой взгляд, обьект это не вещь заключенная в отношения. Обьет это устойчивая форма отношения внутри сети..
Сделал при помощи codex-агента скилл на основе этой публикации - architecture-foundations. Можно попробовать применить с ИИ-агентом (claude, codex, opencode,...). Установка через npx :
npx skills add flancer32/skill-architecture-foundations --skill architecture-foundationsили вручную, через копирование каталога architecture-foundations в ~/.agents/skills/.
Интересно попробовать описанные в публикации оси для анализа своих проектов.
Похоже, сейчас такой выбор совершается и на уровне всей AI-архитектуры: строим ли мы несколько централизованных систем, принадлежащих корпорациям, или распределённую систему участников. Вот хороший ролик, где эта развилка показана на примере Gonka: https://youtu.be/_uwgrHV_li0?r=1059

Программирование как экспериментальная метафизика