Начну с короткого рассказа, как я докатился до жизни такой ) Меня зовут Егор, мне 28. У меня нет диплома программиста, нет опыта работы в IT и нет ни одного коммерческого проекта в резюме. Зато я всю жизнь очень любил железо — буквально с детства, будучи ещё в детском саду, я чинил себе джойстики на Sega, а потом на PS1. В школьные годы открыл для себя сначала Ucoz, потом Wix, Tilda, WordPress, и уже к институту освоил React. Но так сложилось, что это для меня всегда было просто хобби — как и собирать себе датчики для дома: датчики влажности, открытия дверей и т.д. ))

Возможно, я бы мог стать программистом и зарабатывать приличные деньги, но учился в школе с военным уклоном, а после школы стал предпринимателем — занимались производством металлоконструкций и мебели ) После череды ссор с партнёром стал аккаунт-менеджером в Достависте, и отработал там славные 4 года (и по вечерам програмировал мечтал об магазине аля САМОКАТ ), что, собственно, и позволило мне отправиться в Грузию в 2021 году перезимовать и познакомиться с будущей женой.

Грузия, которая не случилась

Жили в Грузии, всё было кайф. Купил там квартиру не в центре Батуми, буквально на кредитку(было так дешево ), в начале 2022 года — до начала событий . Август 2025. Мы с женой (беременной, она грузинка) пошли в Турцию на визаран — так как ПМЖ мне не давали, а давали справку о том, что я «угроза нац. безопасности». На границе меня разворачивают — аргументируя тем, что я слишком долго туристом у них живу.

Месяц живу в Турции, жена быстро всё продаёт. В Россию не хочется — у меня повестки висят и ничего в России кроме родственников нет. Решили поехать туда, где паспорт по рождению ребёнка и не слишком дорого. Так и выбрали Бразилию.

Почему Бразилия

Так получилось, что приехав сюда я уже был месяца 3 без работы. Понимаю, что так бесконечно нельзя, начал думать — и обнаружил: Бразилия защищает внутренний рынок огромными импортными пошлинами. Электроника из Китая, которая стоит $5 на AliExpress, в Бразилии на полке стоит $15–30 после таможни. Это значит, что если производить что-то локально — можно конкурировать по цене с китайским импортом. В любой другой стране это немыслимо.

Но что делать? Выбор пал на агросектор. Бразилия входит в топ-3 мировых аграрных экономик. Кофе, соя, сахарный тростник, фрукты. Огромное количество мелких и средних ферм. Много частных домов с огородами. Люди довольно технологичные — смартфоны у всех, банкинг через приложения. Но IoT для агро — это пока территория дорогих решений: буквально тут самый банальный еле умный датчик стоит $30+. Так и выбрал нишу. К слову в декабре родили.

Выбор стека: Rust для всего

Я выбрал Rust для всего. Прошивка, приложение, сервер — один язык. производительно надежно , безопасно, и - Для embedded — Rust даёт no_std без аллокатора, гарантии памяти на этапе компиляции, и не нужен сборщик мусора

- Для приложения — Tauri v2: Rust-бэкенд + веб-фронтенд на Preact. Раз уж делать быстро, то на максимум

- Для сервера — Rust + Tokio + QUIC

Mesh-сеть: когда WiFi нет

Начал думать так датчик это не так сложно но главная проблема — датчики стоят в поле огороде, где нет WiFi. Решение: mesh-сеть на ESP-NOW. Я назвал свой протокол Dynamic Wave Batch — данные распространяются «волнами» по хопам, собираются в батчи и маршрутизируются динамически.

ESP-NOW — это протокол Espressif поверх WiFi physical layer. Без TCP/IP, . Устройства общаются напрямую друг с другом на расстоянии до 200 метров (500 м в long-range режиме).

Архитектура:

```

[LEAF] ──ESP-NOW──→ [LEAF] ──ESP-NOW──→ [ROOT] ──WiFi──→ [Сервер]

│ │ │

└── датчик └── датчик └── есть WiFi,

в поле в поле отправляет данные

```

Одно устройство (ROOT) имеет доступ к WiFi и отправляет данные на сервер. Остальные (LEAF) передают показания по mesh-цепочке до ROOT. То есть мы получаем высокую дальность почти как у LoRa, но дешевле и немного быстрее.

Многохоповая маршрутизация

Данные летят не напрямую к ROOT — они прыгают через промежуточные узлы. Каждый узел знает своё расстояние до ROOT до каждого соседа в хопах (wave) и выбирает ближайшего соседа как «родителя»:

Node C (hops=2) ──→ Node B (hops=1) ──→ ROOT A (hops=0)

│ │ │

├─ SensorData ──────>│ │

│<──── ACK ──────────┤ │

│ ├─ Forward ─────────>│

│ │<──── ACK ──────────┤

```

Каждый хоп подтверждается ACK — отправитель может сразу уснуть, не дожидаясь, пока данные доедут до ROOT. Есть запасной родитель на случай, если основной пропал. А скорость ESP-NOW позволяет прокинуть данные через 3–4 хопа за доли секунды — это не LoRa, где каждый пакет ползёт.

Бинарный протокол: каждый байт на счету

ESP-NOW даёт максимум 250 байт на пакет. Если пихать туда JSON — влезет пара полей. Поэтому я сделал собственный бинарный секционный формат:

/// Битовые флаги — какие секции включены в пакет
pub const SENSOR_DATA: u8 = 0b00_0001;  // данные датчиков
pub const TIME_SYNC:   u8 = 0b00_0010;  // синхронизация времени
pub const PARENT_INFO: u8 = 0b00_0100;  // инфо о родителе
pub const ROOT_INFO:   u8 = 0b00_1000;  // инфо о ROOT
pub const RELAY_INFO:  u8 = 0b01_0000;  // relay-статус
pub const OTA_INFO:    u8 = 0b10_0000;  // метаданные прошивки

Принцип простой: первый байт — битовая маска, дальше идут только нужные секции. LEAF в обычном режиме отправляет ~55 байт. В setup-режиме — всего ~26 байт. Сравните с JSON, где один ключ "humidity" уже 10 символов.

Выборы лидера

Кто становится ROOT? Тот, у кого лучше WiFi-сигнал. Но что если ROOT сломался или его унесли? Остальные должны сами выбрать нового.

Я реализовал алгоритм выборов:

pub enum ElectionState {
    Idle,                // Всё хорошо, ROOT на месте
    Listening,           // ROOT пропал — слушаем, может появится
    Collecting,          // Не появился — собираем кандидатов
    WaitingConfirmation, // Выбрали — ждём подтверждения
}

Критерии (в порядке приоритета): сила WiFi-сигнала → уровень батареи → MAC-адрес как tiebreaker. Есть защита от split-brain — когда два устройства одновременно думают, что они главные. Зона неопределённости по RSSI — если разница меньше порога, побеждает MAC.

Но можно и по-простому: пользователь через приложение назначает конкретное устройство ROOT-ом (is_designated флаг). Тогда автоматические выборы отступают — designated ROOT имеет приоритет, пока у него нормальный WiFi-сигнал. Удобно, когда знаешь, какой датчик стоит рядом с роутером.

Синхронизация сна и автономность

Датчик бесполезен, если его надо заряжать каждую неделю. Цель — месяцы автономной работы от LiPo.а как это сделать для этого нужно чтоб устройства умели спать и просыпатсья синхронно

Ключевые цифры:

- Deep sleep: 10 µA

- Active mode: 5 секунд раз в 15 минут = 0.56% duty cycle

- LEAF-нода на батарее 2000 мАч: ~5 месяцев

- ROOT (с WiFi): 2-3 недели

Все устройства спят 99.5% времени. Просыпаются раз в 15–30 минут, обмениваются данными за 5–10 секунд и снова в deep sleep.

Проблема: часы ESP32-C3 (RTC) дрейфуют — до 5% у дешёвого кварца. За 30 минут сна это 90 секунд ошибки. Устройства просто не встретятся в эфире.

Решение — компенсация drift:

struct DriftCompensation {
    accumulated_drift_ms: i32,    // Накопленная ошибка
    estimated_error_ppm: i32,     // Оценка частотной ошибки
    cycles_since_sync: u16,       // Циклов с последней синхронизации
}

ROOT при каждом пробуждении передаёт unix time. Узлы сравнивают со своими часами, считают drift в ppm и корректируют следующее пробуждение. Окно синхронизации — ±5 секунд.

Шифрование

Тут я сразу подумал о шифровании. Если бизнес пойдёт, то можно и камеры сделать, и другие датчики, и много чего ещё интересного — и всё это в единой mesh-сети. Но ESP-NOW по умолчанию передаёт данные открытым текстом, а IoT-устройства — любимая цель для атак. Я не хотел быть тем парнем, чьи датчики стали частью ботнета. Поэтому безопасность я закладывал с самого начала, а не прикручивал потом.

Как устройство впервые знакомится с приложением

Когда вы достаёте датчик из коробки, у него нет ни WiFi-пароля, ни ключей шифрования — ничего. Всё начинается с BLE (Bluetooth). И тут важно: даже самый первый контакт между приложением и устройством уже зашифрован.

Схема такая:

1. Приложение и датчик генерируют каждый свою пару ключей ECDH (эллиптическая кривая P-256)

2. Обмениваются публичными ключами по BLE

3. Каждая сторона математически вычисляет общий секрет — не передавая его по воздуху

4. Из этого секрета через SHA-256 получается сессионный ключ AES-256

После этого всё через BLE летит зашифрованным: WiFi-пароль, email владельца, JWT-токен для сервера, список соседей в mesh-сети. Формат каждого сообщения: [длина:2][nonce:12][шифротекст][тег:16]. Тег — это подпись, которая гарантирует, что данные не подменили по дороге.
Регистрация на сервере
Во время провизионирования приложение передаёт датчику JWT-токен. С этим токеном датчик потом регистрируется на сервере — сервер знает, что этот датчик принадлежит конкретному пользователю. Без токена — сервер просто не примет данные. Никакой чужой датчик не сможет подкинуть показания в вашу систему.
Аттестация устройств — как у Apple

Я реализовал систему аттестации, похожую на то, как Apple проверяет подлинность своих устройств. У каждого ESP32-C3 есть уникальный ID, прожжённый в eFuse на заводе — его нельзя изменить или скопировать. На базе этого ID генерируется уникальный ключ устройства.

Сервер может отправить challenge (случайное число), а устройство должно подписать ответ, включающий:

- уникальный ID из eFuse

- версию и хеш прошивки

- статус защиты (secure boot, шифрование flash, отключён ли JTAG)

Если кто-то склонирует прошивку на другой чип — подпись не совпадёт. Если подменит прошивку — хеш не совпадёт.


Шифрование mesh-трафика

Каждый пакет в mesh-сети шифруется AES-256-GCM. Ключ шифрования сети раздаётся при провизионировании — то есть тоже приходит по шифрованному BLE-каналу.

Критический момент — nonce (одноразовое число). AES-GCM категорически нельзя использовать с одинаковым nonce дважды — иначе атакующий сможет расшифровать трафик. Я собираю nonce из трёх частей:

```

┌────────────────┬────────────────┬────────────────┐

│ Boot Counter │ Sequence │ Device ID │

│ (4 байта) │ (4 байта) │ (4 байта) │

└────────────────┴────────────────┴────────────────┘

```

- Boot Counter — хранится во flash, увеличивается при каждой перезагрузке → nonce не повторится после ребута

- Sequence — счётчик в RAM, растёт с каждым пакетом → nonce не повторится в рамках одной сессии

- Device ID — последние 4 байта MAC → nonce не совпадёт между устройствами

Replay-защита
Каждый узел помнит последний boot_counter и sequence от каждого соседа. Если прилетает пакет со старыми значениями — он отбрасывается. Нельзя перехватить пакет и отправить его повторно.
Production lockdown

pub const SECURE_BOOT_ENABLED: u8       = 0b0000_0001;  // подпись прошивки
pub const FLASH_ENCRYPTION_ENABLED: u8  = 0b0000_0010;  // шифрование flash
pub const JTAG_DISABLED: u8             = 0b0000_0100;  // отладка отключена
pub const UART_SECURE_MODE: u8          = 0b0000_1000;  // UART залочен
pub const NVS_ENCRYPTED: u8             = 0b0001_0000;  // хранилище зашифровано
pub const DEBUG_DISABLED: u8            = 0b0010_0000;  // дебаг отключён

Когда все флаги включены — устройство запечатано. Нельзя подключиться отладчиком, нельзя считать flash, нельзя подменить прошивку.

Вся криптография — pure Rust, no_std. Никаких openssl, никакого libc. Работает на микроконтроллере с 400 КБ RAM.

OTA: обновления через mesh

Как обновить прошивку датчика, который стоит в поле без WiFi?

Три пути:

1. WiFi → ROOT — ROOT скачивает прошивку с сервера

2. ROOT → LEAF по mesh — каскадная раздача, сначала ближайшим по RSSI

3. BLE-офлайн — пользователь скачивает прошивку в приложение, передаёт по Bluetooth

Flash-память разбита на разделы:

```

factory (1.3MB) — заводская прошивка, fallback

ota_0 (1.3MB) — основной слот

ota_1 (1.3MB) — запасной слот

```

Если новая прошивка не загрузилась 3 раза подряд — автоматический откат на factory. Устройство не превращается в кирпич.

Корпус

Ну тут все просто , ASA + TPU + 3д принтер ) а на и ацетоновая баня в конце

один из прототипов корпуса
один из прототипов корпуса
уже ближе к итоговому вариант у
уже ближе к итоговому вариант у

Приложение: Tauri + Preact

Для приложения я выбрал Tauri v2 — это как Electron, только бэкенд на Rust вместо Node.js, а фронтенд на любом веб-фреймворке. Приложение весит ~15 МБ вместо 200 МБ у Electron. Работает на macOS, Windows, Linux, а в перспективе — iOS и Android.

Фронтенд — Preact + Signals. Preact — это React на минималках (3 КБ), а Signals — реактивные сигналы без virtual DOM overhead. Локализация на 6 языков из коробки: русский, английский, португальский, испанский, немецкий, китайский.

Провизионирование в 3 клика

Самая первая задача — подключить новый датчик. Я хотел, чтобы это было максимально просто:

1. Нажми «Добавить устройство» — приложение сканирует BLE, находит все датчики с префиксом enddelIOT-

2. Выбери WiFi-сеть — приложение само сканирует доступные сети и показывает список. Если пароль уже сохранён — подставляет автоматически

3. Готово — приложение по BLE передаёт датчику зашифрованные WiFi-креды, JWT-токен, список соседей в mesh-сети, и датчик перезагружается уже в рабочем режиме

Под капотом за эти 3 клика происходит: ECDH-хендшейк → генерация сессионного ключа → шифрование AES-256-GCM → чанкованная передача данных (BLE MTU ограничен 244 байтами) → регистрация на сервере. Но пользователь этого не видит — для него это «нажал, подождал 5 секунд, работает».

Визуализация mesh-сети

Отдельный экран — интерактивная диаграмма mesh-топологии. Рисуется на Canvas:

- ROOT в центре, LEAF-ноды расположены кольцами по хопам

- Анимированные линии между узлами — показывают поток данных

- Цвет линий меняется по RSSI: зелёный = хороший сигнал, красный = на грани

- «Пульс» от ROOT наружу — визуализация волны синхронизации WaveBatch

- Дуги заряда батареи вокруг каждого узла

- Pan, zoom, тап по устройству для детальной информации

Можно назначить ROOT вручную, сменить роль устройства, задать приоритетного «родителя» — всё через UI.

Паспорт растения

Каждому датчику можно привязать профиль растения с диапазонами влажности: оптимальный, предупреждение, критический. После этого открывается «паспорт» — полная карточка:

- Текущая влажность с индикатором статуса (оптимально / сухо / залито)

- График влажности за 24 часа / 7 дней / 30 дней с пороговыми линиями

- Температура и уровень заряда

- Таймлайн поливов — приложение автоматически определяет полив, когда влажность резко прыгает вверх (>10%), и записывает историю

- Статистика: средняя частота поливов, последний полив

главный экран и некоторые настройки приложения

Home Assistant прямо из приложения

В настройках можно подключить свой MQTT-брокер: хост, порт, логин, пароль. Кнопка «Test Connection» проверяет связь. После включения — все датчики автоматически появляются в Home Assistant через auto-discovery. Управление интеграцией — из приложения, без правки конфигов.

Безопасность на уровне приложения

- ECDH-шифрование в Rust-бэкенде — тот же код, что и в прошивке. Один протокол на обоих концах

- TLS 1.2+ для всех HTTP-запросов (reqwest + rustls)

- JWT-токены с автоматическим рефрешем за 5 минут до истечения

- Offline-first: приложение кеширует устройства и токены, работает без интернета. При восстановлении связи — синхронизация

- Zeroize: чувствительные данные (ключи, пароли) зануляются в памяти после использования


Сервер: Axum + QUIC + вся обвязка

Сервер, как и всё остальное, на Rust. Но тут я не просто поднял REST API — я построил полноценную инфраструктуру с несколькими протоколами, очередями и real-time доставкой.

Два уровня связи

Датчики → сервер: ROOT-нода, у которой есть WiFi, отправляет данные по HTTPS (TCP + TLS 1.3). На ESP32-C3 я поднял TCP-стек через smoltcp + embedded-tls — полноценный HTTPS-клиент на микроконтроллере без операционной системы. Это надёжно и работает через любой роутер.

Приложение ↔ сервер: а вот тут QUIC — протокол от Google/Cloudflare поверх UDP. Быстрее TCP, встроенный TLS 1.3, мультиплексирование потоков. Для real-time обновлений в приложении это идеально. Я использую [tokio-quiche от Cloudflare](https://blog.cloudflare.com/async-quic-and-http-3-made-easy-tokio-quiche-is-now-open-source/) + второй вариант на Quinn.

Сейчас приложение временно подключается по WebSocket, потому что Railway.app (где хостится сервер) не поддерживает UDP. Код для QUIC уже написан и готов — ждёт хостинг с UDP.

Стек данных

```

[Датчик] → HTTPS/TCP → [Axum API] → [RabbitMQ] → [Worker] → [PostgreSQL]

[Redis pub/sub] → [WebSocket] → [Приложение]

[MQTT broker] → [Home Assistant]

```

- Axum 0.7 — веб-фреймворк. REST API + WebSocket на одном порте. Rate limiting через tower_governor, gzip-компрессия, CORS.

- PostgreSQL через sqlx — и тут фишка: sqlx проверяет SQL-запросы на этапе компиляции. Если ты опечатался в названии колонки — код не соберётся. Не в рантайме упадёт, а в cargo build.

- RabbitMQ — показания с датчиков не записываются в базу напрямую. Они падают в очередь, а worker забирает их батчами по 50 штук раз в секунду. Это развязывает приём данных и запись — сервер не тормозит, даже если база задумалась.

- Redis — кеш, real-time состояние устройств (онлайн/офлайн), pub/sub для мгновенной доставки обновлений в приложение.

Background-воркеры

На сервере крутятся несколько фоновых задач:

- SensorReadingsWorker — достаёт показания из RabbitMQ, пишет в PostgreSQL, рассылает по WebSocket и пробрасывает в MQTT

- MeshVisibilityWorker — отслеживает, какие устройства видят друг друга, строит карту топологии

- OfflineDetector — если устройство не вышло на связь дольше таймаута — помечает его офлайн и уведомляет приложение

- CleanupWorker — чистит старые данные, чтобы база не пухла бесконечно

Аутентификация

JWT-токены с HS256. Два способа входа: email + пароль (Argon2 хеширование) и Google OAuth — для мобильного приложения это удобнее. Пароли хешируются Argon2 — тот же алгоритм, что рекомендует OWASP.

Home Assistant и путь к open source

Отдельная тема — интеграция с Home Assistant. Сервер умеет пробрасывать показания в любой MQTT-брокер в формате Home Assistant auto-discovery:

```

homeassistant/sensor/enddel_{device_id}/humidity/config → конфигурация

enddel/{device_id}/humidity → значение

enddel/{device_id}/temperature → значение

enddel/{device_id}/battery → значение

```

Подключил — и датчики автоматически появляются в Home Assistant. Без ручной настройки.

И тут я думаю о более серьёзном шаге: в перспективе я хочу сделать серверную часть open source. Почему? Потому что когда речь идёт о датчиках, которые стоят у вас на участке и собирают данные — вы должны быть уверены, что ваши данные это ваши данные. Не мои, не облака, не третьей стороны. Открытый код сервера означает, что любой может развернуть его у себя, проверить, что он делает, и не зависеть от моего хостинга. Хочешь — используй мой облачный сервер. Не хочешь — подними свой. а с открытым сервером вся цепочка становится прозрачной.


Общение с клиентами: когда ты не говоришь на языке клиента

Предыстория: мечта о магазине

Когда я еще жил в грузии я активно програмировал себе магазин как и говорил выше и в том числе экспериментировал с чатиком хотел что то типо KRISP но бесплатно и с ллм . Тогда это был просто виджет для сайта + админка. Но фундамент заложился именно тогда. но теперь это пригодилось так как нужно понимать: мои клиенты — это бразильцы, а может и кто угодно, но точно не русскоговорящие. Им нужно как-то помогать, у них будут вопросы. Они увидят рекламу в Instagram, напишут — и что, мне с Google Translate сидеть? Это не работает, когда у человека не подключается датчик и он нервничает.

Поэтому я написал свою чат-систему — ecoChat. ( ТЕХНИЧЕСКОЕ НАЗВАНИЕ ТИПО ЭКОЛОГИЯ)

Архитектура

Три компонента:

- ecoChatWidget — виджет, который встраивается на сайт или в приложение. Клиент открывает чат и пишет на своём языке.

- ecoChatAdmin — админка для меня (Next.js, PWA). Вижу все чаты, отвечаю, управляю настройками. Поддерживает push-уведомления, работает с телефона.

- ecoChatServer — бэкенд на Go. WebSocket для real-time, PostgreSQL для хранения, Redis для кеша. Подключается к Instagram и WhatsApp — сообщения из мессенджеров падают в ту же админку.

интерфейс чата
интерфейс чата


LLM-переводчик

Ключевая фишка: каждое сообщение автоматически переводится через LLM. Клиент пишет на португальском — я вижу на русском. Отвечаю на русском — клиент получает на португальском. Перевод проходит через Qwen 3.5 4b no think через vllm на пк и тунелем черз ngrock , так же применются оптимизациии токенов (формат TOON экономит ~40%). Переводы кешируются в базе, чтобы не гонять повторные запросы.

Мультиагентный оркестратор

Раз уж я начал осваивать ллм я сделал — автоответчик. Когда меня нет онлайн (или просто не хочу отвечать на типовые вопросы), включается система из трёх AI-агентов: работающих на qwen 3.5 9b think

интерфейс админки чата
интерфейс админки чата

[Клиент] → [Оркестратор] → выбирает агента:

├─ PlantExpert — всё про растения

├─ DeviceSpecialist — настройка, проблемы, mesh

└─ SupportSpecialist — FAQ, приложение, контакты

```

Оркестратор (Supervisor Agent) анализирует сообщение клиента и определяет intent:

- plant_care — «какая влажность нужна для монстеры?» → PlantExpert

- device_setup — «как подключить датчик к WiFi?» → DeviceSpecialist

- troubleshooting — «датчик не отвечает» → DeviceSpecialist

- mesh_config — «как работает mesh-сеть?» → DeviceSpecialist

- общие вопросы → SupportSpecialist

Что умеют агенты

PlantExpert — встроенная база из 89 видов растений с порогами влажности, температуры, освещения. Умеет подбирать растения по условиям, сравнивать виды, давать рекомендации по уходу. Это не ChatGPT-обёртка — у него есть реальные данные о каждом растении.

DeviceSpecialist — умеет:

- Запросить через API список устройств пользователя и их статус

- Получить последние показания датчика в реальном времени

- Выдать пошаговую инструкцию по настройке

- Диагностировать проблемы (батарея, сигнал, mesh-связь)

- Объяснить как работает mesh-сеть и OTA

SupportSpecialist — FAQ из 49 вопросов по 8 категориям, информация о приложении, контакты. Отвечает на всё, что не попадает в две другие категории.

Всё это написано на Go с использованием моего форка Google ADK — [adk-go_openai](https://github.com/babasha/adk-go_openai). Оригинальный ADK от Google работает только с Gemini. Я написал кастомный OpenAI-совместимый адаптер, который позволяет подключать любую модель через OpenAI API: и — локальные модели через LM Studio или Ollama Vllm И так далее. Это значит, что агенты могут работать хоть на домашнем сервере без облака. Форк протестирован с Qwen 3.5 и Google Gemma 3.

и да промпты для агентов хранятся в базе данных — могу менять поведение без передеплоя.

Зачем это всё

Один человек не может быть 24/7 в чате. А AI-агент с доступом к реальным данным (показания датчиков, база растений, FAQ) может закрыть 80% вопросов без моего участия. И на любом языке.

ГЛАВА 2 Директор: AI, который управляет AI

Буквально месяц назад я вдохновился проектом [Open Claw](https://github.com/openclaw) и понял, что мои агенты — это хорошо, но им нужен руководитель. Так появился Директор — Level 2 агент, который наблюдает за работой всех остальных агентов и улучшает их.

Архитектура теперь трёхуровневая:

```

Level 0: [PlantExpert] [DeviceSpecialist] [SupportSpecialist]

↑ ↑ ↑

Level 1: [Оркестратор (РОП)]

↑ ↑ ↑

Level 2: [Директор]

```

Что делает Директор:

1. Анализ работы агентов. Директор собирает саммари всех чатов и анализирует: сколько эскалаций (клиент попросил живого человека), сколько пустых ответов, какие темы повторяются. Используется мощная модель (Claude/GPT-5.4 или типо того ), пока агенты работают на более лёгких.

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

3. Автоматическая оптимизация промптов. Если Директор видит, что агент плохо справляется с определённой темой — он сам переписывает промпт этого агента. Промпты хранятся в базе данных с версионированием. Директор создаёт новую версию, сохраняет изменения и причину. Можно откатить в любой момент.

4. Автоматическое создание скиллов. Директор анализирует паттерны использования тулов за последние 7 дней. Если видит повторяющийся сценарий (например, «клиент спрашивает про доставку» 5+ раз) — автоматически создаёт новый скилл. Лимит: максимум 10 автоскиллов, не чаще 1 в день.

5. Event-triggered анализ. Директор не работает по расписанию — он реагирует на события. 3 эскалации за час? Директор запускает анализ. 5 пустых ответов за день? Анализ. Тулы падают с ошибками? Анализ. Cooldown 30 минут между триггерами, чтобы не гонять модель без толку.

6. Дайджесты. Раз в неделю и раз в месяц Директор генерирует сводный отчёт: что было, какие тренды, что улучшилось, что ухудшилось.

7. Identity. У Директора есть собственная «личность», которая кешируется и определяет тон и стиль рекомендаций. При первом запуске он создаёт identity с дефолтами и потом дорабатывает по мере обучения.

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


Что дальше

Сейчас март 2026. Я в Блумэнау, жду документы. Проекту ~5 месяцев без учета месенджера . Есть рабочие прототипы, весь стек написан, mesh работает. как только получу внж побегу делать ИП и отркывать старницу на местном Амазоне и аналогах , к тому моменту думю отполирую чат поддержки , и отсниму рекламу дай бог все получится ) ну если нет наверное придется идти тарелки мыть или даже не знаю )

PSS экомику бизнеса не стал описывать так как это большая тема с местными приколами , но если в кратце тот тут можно импортировать компоненты почти без импортного налого будучи бизнесом а налог примерно 100% , и то что тут продается за какие деньги приложу