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

Это проблема хранения, и ее необходимо решить в первую очередь. Вам нужен уровень состояния, где каждый агент может записывать наблюдения, и каждый агент может запрашивать контекст. Факты должны сохраняться во всех сеансах, инструментах и ​​машинах. Извлечение должно работать независимо от того, какой агент записал данные и когда. [Neotoma](/posts/truth-layer-agent-memory) существует для решения этой проблемы: независимая от схемы подложка, которая хранит, обслуживает и позволяет запрашивать истину по всему стеку агентов.

Но как только хранилище заработает, вы столкнетесь со второй стеной. Когда один агент записывает новое наблюдение, другие агенты не знают об этом, пока не проверят. «Проверка» означает опрос: повторный запрос через определенные промежутки времени, при запуске сеанса или при ручном запуске. Большинство этих опросов ничего не дают. Те, что имеют значение, приходят с опозданием на несколько минут или часов. Разрыв между «состояние изменено» и «уведомления агента» — это мертвое время, и он создает потолок того, что агенты могут делать вместе.

Это не проблема поиска. Данные есть. Это проблема координации на уровне инфраструктуры, и каждая самодельная система памяти, которую я видел, решает ее одинаково: это не так.

## Координационный потолок

Координация на основе опросов имеет три издержки, которые усугубляются масштабом.

**Задержка.** Интервал между изменением состояния и моментом, когда агент узнает об этом, ограничен частотой опроса. Если агент проверяет каждые пять минут, критическое наблюдение может оставаться незамеченным в течение четырех минут и пятидесяти девяти секунд. Для агентов, координирующих работу с чувствительными ко времени состояниями, такими как только что отправленный отчет об ошибке или финансовая транзакция, требующая сверки, эта задержка является узким местом.

**Напрасная трата вычислений.** Большинство опросов не дают никаких изменений. Агент, который проверяет каждые тридцать секунд в течение рабочего дня, делает почти тысячу запросов, подавляющее большинство из которых подтверждают, что ничего не произошло. Это терпимо для одного агента. Для десяти агентов это налог. При сотне это накладные расходы на инфраструктуру, которые линейно масштабируются и не имеют никакой ценности.

**Потолок координации.** Сочетание задержек и потерь создает практические ограничения на совместное поведение агентов. Шаблоны, которые были бы естественными для осведомленности, управляемой событиями, такие как «Агент Б реагирует на запись агента А в течение нескольких секунд», требуют специального связующего звена: таймеров, хаков веб-перехватчиков, ручных триггеров или специальных демонов опроса, которые сами нуждаются в обслуживании. Шаблоны координации, которые вам нужны, просты. Сантехники, позволяющей им работать с опросами, нет.

Если вы создали многоагентный стек, вы уперлись в эту стену. Уровень состояния надежно хранит истину. Он хранит молчание об изменениях этой истины.

## Что означает сигнализация

Идея исправления проста. После каждой записи уровень состояния генерирует структурированное событие, описывающее, что изменилось. Зарегистрированные потребители, агенты, демоны, одноранговые экземпляры получают событие и решают, что с ним делать. Уровень состояния доставляет сигнал. Потребитель решает ответ.

Это стандартный примитив в системах, которые обрабатывают состояние в масштабе. PostgreSQL создает записи WAL и поддерживает LISTEN/NOTIFY. Никто не утверждает, что PostgreSQL «действует», когда делает это. Он обеспечивает наблюдаемость собственных переходов состояний. Брокер сообщений, такой как Kafka, делает то же самое в другом масштабе. Государственная система сообщает о случившемся. Потребители нижнего уровня фильтруют, расставляют приоритеты и действуют. Уровень отчетности не рассуждает о событиях. Выстреливает и забывает.

Биологическая аналогия здесь полезна. Нервная система одновременно хранит и сигнализирует. Мозг хранит память. Сенсорные нейроны передают информацию о том, что изменилось. Ни один из них не решает пошевелить мышцей. Двигательная система действует. Уровень состояния, который хранит истину и сигнализирует об изменениях, — это мозг и сенсорные нервы. Агентами, которые решают, что делать с этими сигналами, является двигательная система.

## Строка, которая должна остаться

Уровень состояния, который передает сигналы, может легко стать оркестратором, механизмом рабочего процесса или самостоятельным агентом. Искушение реально. Как только вы сможете отправлять события, вы захотите их фильтровать, расставлять приоритеты, маршрутизировать, добавлять логику повторов, создавать условную доставку. Каждый шаг звучит разумно по отдельности. Вместе они превращают субстрат во что-то, что принимает решения о том, что важно, а что нет.

Эта линия должна остаться.

Что такое сигнализация:

- **Наблюдение за изменением состояния, а не действие над состоянием.** Субстрат сообщает, что изменилось. Он не оценивает, важно ли изменение.
- **Доставка по принципу «выстрелил и забыл».** Если потребитель недоступен, носитель регистрирует сбой. Он не повторяет попытку эскалации, не возвращается к альтернативным действиям и не меняет свое поведение.
- **Производный результат конвейера записи.** Существующий конвейер — это запись, пересчет моментальных снимков, обновление временной шкалы. Эмиссия событий — это еще одна запись в этой последовательности, точно так же, как снимок представляет собой данные наблюдения. Он запускается после фиксации транзакции записи, а не во время нее. Если запись завершается неудачей, событие не срабатывает. Если доставка не удалась, запись все равно остается в силе. Сигнал следует за истиной; оно никогда не закрывает его.

Чем сигнализация не является:

- **Не принятие решений.** Подложка не фильтрует, какие события стоит отправлять. Он излучает их всех. Потребители фильтруют.
- **Не поведение агента.** Субстрат не подписывается на собственные события. Он не запускает циклы. Это не причина.
- **Не оркестрация.** Никакой приоритезации, никакого планирования, никакой условной маршрутизации. Демоны, которые обрабатывают события и принимают меры, являются потребителями рабочего уровня, а не частью субстрата.

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

## Уточненная граница

Старая граница: субстрат хранит и служит истине.

Новая граница: субстрат хранит, служит и сигнализирует правду. Когда истина меняется, субстрат сообщает об изменении. Ответственность за то, что происходит дальше, лежит на потребителе.

Это расширение, а не противоречие. Существующий конвейер записи уже выполняет производную работу после каждой записи: пересчет моментального снимка, создание событий временной шкалы, генерация внедрения, автоматическое связывание. Эмиссия событий — еще одна запись в списке. Он не требует новой модели данных. Это не меняет того, что сохраняется или как разрешаются запросы. Он добавляет исходящий канал для информирования об изменении состояния.

Терминология имеет значение. «Сигнализировать» и «издавать», а не «уведомлять» или «предупреждать». Уведомить подразумевает суждение о важности. Оповещение подразумевает оценку срочности. Сигнал нейтральный. Субстрат сигнализирует. Потребитель интерпретирует.

Стоит четко указать, какое место в этой картине занимает стратегия. Планы, постоянные правила, предпочтения и предварительные решения сами по себе являются государственными. Они являются объектами, хранящимися в подложке, как и любые другие, запрашиваются, сокращаются и передаются таким же образом. Они не работают на каком-то отдельном уровне. Граница не проходит между «стратегией живет в другой системе» и «государством живет в субстрате». Это между «субстратом, хранящим и сигнализирующим» и «потребителями решают и действуют в соответствии с тем, что они читают». Благодаря этому артефакты стратегии можно проверять, воспроизводить и передавать каждому потребителю, который их читает, не перетаскивая основу для принятия решения.

## От памяти к нервной системе

Большинство людей, создающих мультиагентные системы, по-прежнему описывают общий субстрат как «память». Эта формулировка точна, насколько это возможно. Память — это хранилище и извлечение: система записывает то, что произошло, и агенты запрашивают ее, когда им нужен контекст. Это основа, и она должна работать, прежде чем что-либо еще будет иметь значение.

Но память пассивна. Оно содержит истину. Он не передает информацию об изменениях истины тем частям системы, которые должны реагировать. Уровень памяти, на котором хранится новая финансовая транзакция, не сообщает агенту выверки о прибытии транзакции. Уровень памяти, записывающий новый отчет об ошибке, не сообщает демону сортировки, что что-то требует внимания. Данные есть. Осведомленности нет.

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

Правильным критерием для оценки этого является целостность состояния, а не качество извлечения. Память оценивается по тому, можете ли вы запросить ее обратно. О нервной системе судят по тому, может ли остальная часть системы отреагировать на изменение в тот момент, когда изменение является устойчивым, а не через несколько минут, когда что-то спрашивает. Это разные проблемы с разными режимами отказа.

Биологическое обрамление четкое, а не декоративное. Мозг без сенсорных нервов может прекрасно хранить воспоминания и при этом быть неспособным реагировать на окружающую среду. Недостающая часть не является хранилищем. Это сигнальный путь между тем, что изменилось, и тем, что нужно об этом знать. Это часть, которую вы в конечном итоге строите вручную, по одному циклу опроса за раз, пока не станет очевидно, что она принадлежит подложке.

## Что это открывает

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

**Демон, который обрабатывает входящую работу в течение нескольких секунд после отправки.** Пользователь или внешний агент отправляет отчет об ошибке, запрос на добавление функции или структурированный отзыв. Уровень состояния хранит объект и генерирует событие. Длительно работающий демон получает веб-перехватчик, создает рабочее дерево, запускает сеанс агента с соответствующей базой кода, открывает PR и обновляет состояние объекта. Нет цикла опроса. Нет таймера cron, проверяющего каждые пять минут. Демон подписывается один раз и реагирует, когда поступает работа.

**Межинструментальная координация без связующего кода.** Агент финансовой выверки подписывается на наблюдения за транзакциями. Агент конвейера контента подписывается на черновики изменений состояния. Агент сортировки проблем подписывается на события создания объекта, отфильтрованные по типу. Каждый потребитель регистрирует интерес к области, всем событиям, событиям для определенного типа сущности, событиям для конкретной сущности и предоставляет конечную точку доставки. Субстрат доставляет. Потребитель сохраняет логику. Никакой индивидуальной интеграции для каждой пары агентов.

**Агенты, которые могут общаться друг с другом через подложку.** Связь между агентами уже работает через уровень состояния: потоки разговоров, идентификатор отправителя, семантика многостороннего потока. Чего не хватает, так это толчка. Когда агент А пишет сообщение, предназначенное для агента Б, агенту Б не нужно проводить опрос, чтобы обнаружить его. Субстрат должен подавать сигнал о записи, чтобы обмен данными осуществлялся со скоростью обработки, а не со скоростью опроса.

**Структурированные гостевые отправки с контролем доступа.** Любой тип объекта, а не только особый тип, может быть открыт для внешних отправок с помощью настраиваемых политик доступа. Агент клиента предоставляет структурированный отзыв. Автоматизация партнера передает данные на сверку. Субстрат определяет, кто и что может писать, отслеживает происхождение внешних участников и поддерживает последующие разговоры. Отправка — это устойчивое состояние, а не сообщение, которое исчезает.

## Помимо собственных агентов

Пока это звучит так, как будто все агенты принадлежат вам. Они сидят в вашем редакторе, в ваших заданиях cron, на вашем ноутбуке. Это простой случай. Это еще не вся картина.

Естественным развитием является центральный экземпляр на вашем компьютере плюс вспомогательные экземпляры в другой инфраструктуре: клиентские серверы, командные VPS-дроплеты, удаленные агенты, которыми вы управляете, но не владеете. Когда вы там, голосование становится не просто расточительным. Он структурно слеп. Вы подключаетесь по SSH, запускаете сводки, спрашиваете, «что произошло между этими датами», потому что удаленное хранилище никогда не возвращает информацию туда, где работают ваши координирующие агенты.

Это координация через границы доверия, а не только между процессами. Когда писатель является чьим-то агентом, «общей памяти» недостаточно. Вам нужны записи, которые вы можете атрибутировать, проверять и проверять постфактум. Это означает проверку личности автора на всех поверхностях (MCP, HTTP, подписанные запросы), уровни атрибуции, которые отличают криптографически проверенного агента от анонимного вызывающего абонента, а также формы диалога, включающие потоки между агентами и многосторонними потоками, поэтому трансграничное общение является структурированным состоянием, а не специальными сообщениями.

Сигнализация дополняет картину. Спутниковый экземпляр, который генерирует события при записи, предоставляет вашим центральным потребителям тот же примитив, на который они уже полагаются локально. В конце концов, два экземпляра могут синхронизироваться в двух направлениях: когда объект изменяется в экземпляре A, экземпляр B получает уведомление и может получить обновление без ручного вмешательства. Центральный узел не требуется. Любой экземпляр может быть равноправным.

«Открытая» часть — это совместимость в соответствии с правилами, а не свобода для всех. Открытые поверхности плюс явная идентичность и семантика потоков позволяют агентам других людей участвовать в работе одной нервной системы, не притворяясь, что каждый вызывающий абонент одинаково доверен или одинаково разборчив. Формирование памяти не соответствует этому требованию. Нервной системы формирования нет.

## Что я строю

Я добавляю эти возможности в [Neotoma](/posts/truth-layer-agent-memory) последовательно, каждая из которых основывается на предыдущей.

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

**Подписка и доставка через веб-перехватчик.** Агенты регистрируют заинтересованность в области и предоставляют конечную точку доставки. Подложка поддерживает реестр и доставляет события через обратные вызовы веб-перехватчика и SSE. Потребитель сохраняет логику. Веб-перехватчики стоят на первом месте, потому что они работают для удаленных агентов в инфраструктуре VPS, локальных демонов на вашем ноутбуке и синхронизации между экземплярами между узлами. Push-уведомления SSE и MCP являются аддитивными.

**Обобщенная отправка сущностей.** В настоящее время существуют структурированные внешние отправки (гостевой доступ, политики доступа, потоки бесед, происхождение внешних субъектов), но они привязаны к одному типу сущностей. Следующий шаг — сделать этот объект независимым от типа объекта: любой тип объекта может быть открыт для гостевых представлений с настраиваемыми политиками доступа, дополнительными внешними зеркалами и потоками разговоров. Агент клиента предоставляет структурированные данные. Автоматизация партнера отправляет отзыв. Подложка обеспечивает контроль доступа и происхождение. Оператор настраивает, что открыто, а что нет.

**Двунаправленная синхронизация между экземплярами.** Существующая инфраструктура поддерживает однонаправленную удаленную отправку: один экземпляр передает данные другому. Расширение является двунаправленным. Когда сущность изменяется в экземпляре A, экземпляр B получает вебхук и может получить обновление. Нет центрального узла. Любой экземпляр может быть пиринговым с любым другим. Таким образом группа сателлитных экземпляров в клиентской инфраструктуре координируется с центральным экземпляром без SSH и cron.

Все это не является самой амбициозной версией того, какой может быть «нервная система». Маршрутизация, фильтрация, преобразование, гарантии доставки, очереди недоставленных сообщений: все это обеспечивают брокеры сообщений. Я намеренно ничего из этого не строю. Задача субстрата — сигнализировать, а не организовывать. Каждая особенность, пересекающая эту линию, делает субстрат менее надежным как нейтральный репортер переходов состояний.

Ограничение — это особенность. Уровень состояния, который сигнализирует, но не принимает решения, — это уровень состояния, о котором вы все еще можете рассуждать. Добавьте к сигнальному пути логику операционного уровня, и вы потеряете свойство, которое в первую очередь сделало подложку полезной: поведение подложки полностью определяется записью, а не политикой.