Опубликовано 22 августа 2026 г.

3D-мозг как живой орган: визуализация флота агентов в виде анатомии
В предыдущем посте я утверждал, что roster не является router — то есть способ, которым вы visualize флот агентов, формирует ваше представление о нём. Плохой список заставляет агентов казаться взаимозаменяемыми. Граф заставляет их казаться конвейером. Ни один из них не отражает того, что действительно происходит, когда девять агентов работают, делегируют, эскалируют и тихо гудят в разных ритмах.
Итак, я создал то, что хотел увидеть: орбитальный 3D-мозг, где каждый агент — это регион, а регионы пульсируют живой телеметрией. Это инженерный журнал того, как это работает.
Сопоставление
Девять агентов, девять регионов. Это не метафора, растянутая до разрыва — это слабое структурное соответствие, полезное именно потому, что оно неверно правильным образом. Главный агент отвечает за планирование и диспетчеризацию верхнего уровня, поэтому он расположен в дорсолатеральной префронтальной коре (dlPFC) — части мозга, отвечающей за исполнительные функции. Агенты‑кодеры отвечают за язык и синтаксис, поэтому они находятся в левой нижней лобной извилине (L-IFG) и предпремоторной дорсальной области (pre-PMd). И так далее:
| АгентРегион(ы)Роль | ||
| главный | дорсолатеральная префронтальная кора | Исполнительный контроль, диспетчеризация |
| кодер | левая нижняя лобная извилина | Синтаксис, генерация кода |
| лёгкий кодер | преддорсальная премоторная кора | Обработка более лёгкого синтаксиса |
| творческий | правое височно-теменное соединение + правое фронтальное полюс | Дивергентное мышление, социальный контекст |
| WhatsApp-гость | правое верхнее височное борозда + правое нижнее лобная извилина | Разговор, язык, ориентированный на гостя |
| исследователь | гиппокамп + энторинальная кора | Извлечение памяти, маршрутизация знаний |
| операции | Базальные ганглии | Циклы привычек, автоматизация инфраструктуры |
| диагност | aIns + aACC | Интерцепция, обнаружение ошибок |
| диагност-light | pIns | Лёгкая интерцепция |
Геометрия
Каждый регион — это процедурно генерируемый blob. Я начал с подразделённого икосаэдра и применил к позициям вершин фрактальное броуновское движение (fbm) с 3 октавами — смещение в стиле Перлина, которое придаёт каждому региону органичный, слегка комковатый контур вместо идеальной сферы. Амплитуда смещения определяется телеметрией, поэтому загруженный регион буквально набухает и дрожит сильнее, чем простаивающий.
Весь мозг находится внутри стеклянной оболочки. Здесь three.js r128 меня подвёл. Я хотел настоящий физический стеклянный материал с transmission — свойство, которое заставляет свет преломляться через поверхность. Но MeshPhysicalMaterial.transmission появились в r144. В r128 ближайшее приближение — это transparent: true с низкой непрозрачностью, clearcoat для спекулярного блика, и side: DoubleSide чтобы вы могли видеть заднюю часть оболочки сквозь переднюю. Оболочка работает при непрозрачности 0.14 и clearcoat 0.6. Это не физически корректно. Но выглядит правильно, а это важнее.
three.js поставляется локально — без CDN. Вся библиотека обслуживается из маршрутов /vendor/* на панели управления. Это избавляет от зависимости от стороннего хоста и делает панель самодостаточной.
OrbitControls обеспечивает демпфирование, ограничение расстояния [2, 20] и ограничение полярного угла, чтобы вы не могли перевернуться под мозгом и потеряться. Клик по региону заставляет камеру плавно перемещаться за 700 мс, чтобы обрамить его, все остальные регионы затемняются до 10 % непрозрачности, а панель деталей с эффектом glassmorphism выдвигается, показывая цепочку модели, живые статистики и выпадающий список переопределения. Кликните в другое место — и всё восстанавливается.
Телеметрия → Движение
Панель управления опрашивает /api/state каждые 500 мс. Этот JSON управляет всем визуальным: интенсивностью излучения каждого региона, амплитудой смещения вершин, искрами частиц в горячих зонах и импульсами вдоль соединительных линий.
Ключевым решением стало присвоение каждому региону motion signature — различное ритмическое ощущение, позволяющее мгновенно отличать агентов без чтения меток:
- главный — гамма-мерцание на 40Hz. Быстрое, доминирующее, то, на что сначала падает взгляд.
- кодер — бета-волна на 20Hz. Стабильное, механическое.
- кодер-лёгкий — 12Hz. Более мягкая версия ритма кодера.
- диагност — всплеск значимости на 60Hz используя
pow(sin(t), 8). Острые пики, не плавная волна. Выглядит как внимание, сфокусировавшееся резко. - диагност-лёгкий — 100Hz рябь. Очень быстро, почти мерцание.
- исследователь — тета-гамма вложение: несущая частота 3Hz, модулированная гамма-оболочкой 40Hz. Это мой любимый. Это выглядит как глубокие медленные волны с быстрым мерцанием сверху, что буквально соответствует тому, как выглядит тета-гамма-связь в реальных гиппокампальных записях.
- творческий — дыхание на 1.5Hz с случайными искрами частиц. Медленное, расширяющееся, немного мечтательное.
- операции — низкочастотный гул на 1.2Hz. Фоновый пульс, который вы чувствуете больше, чем видите.
- whatsapp-guest — 2Гц. Темп разговора.
Дуги CatmullRomCurve3 между регионами активируются при событиях делегирования и эскалации. Когда основной передаёт задачу программисту, дуга загорается между dlPFC и L-IFG, пульсирует один раз и гаснет. Дуги не являются декоративными — они представляют собой журнал маршрутизации, визуализированный как анатомия.
Апостроф
Вот ошибка, которая заняла самое долгое время для обнаружения.
Дашборд отдаёт страницу дашборда, HTML которой собирается на сервере из шаблона. В одной строке этого шаблона содержалось слово brain's — с апострофом. Шаблонный движок отрендерил его корректно. Браузер получил его корректно. Но строка была встроена в блок <script> как часть строкового литерала JavaScript, и апостроф prematurely завершил строку. Остальная часть блока скрипта — вся инициализация three.js, цикл телеметрии и настройка OrbitControls — превратилась в синтаксическую ошибку. Тихо. Нет 3D-мозга. Нет ошибки во вкладке сети. Просто пустой холст и ошибка консоли, спрятанная под шумом фреймворка.
Исправление состояло из одного слова: строка была переформулирована, чтобы полностью избежать апострофа. Без экранирования, без кодирования сущностей — просто переформулировано. Это такое исправление, которое кажется поражением, пока не осознаёшь, что это исправление, которое попадает в релиз.
Эта ошибка также тихо ломала клиентский JS оригинального плоского дашборда. 3D-мозг не ввёл её — он просто сделал поломку видимой, потому что внезапно появился холст, который должен был содержать что-то, но не содержал.
Резерв и доступность
Два резервных пути. Если WebGL недоступен — безголовые браузеры, старые машины, корпоративные ноутбуки с блокировкой — 3D‑вид заменяется на .brain3d-fallback примечание, объясняющее, чего вы лишены, и указывающее на плоскую панель управления. Нет поломанного канваса, нет спама ошибок.
Если у пользователя prefers-reduced-motion установлено, смещение вершин и искры частиц отключены. Регионы всё ещё подсвечиваются телеметрией — интенсивность излучения в норме, проблема в движении — но мозг не дышит и не дрожит. Импульсы соединительных линий всё ещё срабатывают, поскольку они информативны, а не декоративны, но они короткие и не зацикливаются.
Что я выношу
3D‑мозг не является лучшей панелью управления, чем плоский список. Это другая панель. Плоский список отвечает на вопрос «что делает каждый агент прямо сейчас?» 3D‑мозг отвечает на вопрос «Как флот чувствует во время работы?» Это разные вопросы, и оба стоит уметь задавать.
Наиболее меня удивили сигнатуры движения. Я ожидал, что геометрия и стеклянная оболочка будут сложной частью. Это не так. Сложной частью было заставить девять элементов пульсировать так, чтобы это ощущалось как различимое, но не хаотичное. Theta‑gamma nesting для исследователя стал прорывом — как только у меня появился регион, который ощущался категорически иначе, чем остальные, остальные встали на свои места как спектр от «быстро и резко» (диагност) до «медленно и дышаще» (креативщик).
Ошибка с апострофом — это урок, который я постоянно переосмысливаю: когда что‑то сломано и вы не можете найти причину, ищите символ, который выполняет две функции. В шаблоне апостроф — это английский символ. В блоке скрипта он является разделителем. Когда один и тот же байт выполняет обе роли, одна из них проигрывает.