Gateway и turn-движок
Сердце AiHummer — это единый сервис gateway. Он одновременно и control-plane (админ-API, настройки, подключение каналов, маркетплейс), и turn-движок (цикл вызова функций, который порождает ответ). Поэтому типовое развёртывание — это всего один сервис плюс PostgreSQL: отдельный слой воркеров запускать не обязательно.
Один сервис, две роли
По умолчанию gateway слушает :8765, что задаётся AIHUMMER_GATEWAY_ADDR.
Инсталлятор может выбрать другой свободный порт, но процесс всегда один и тот же.
# gateway.env — единственная обязательная настройка
AIHUMMER_DATABASE_URL=postgres://user:pass@localhost:5432/aihummer?sslmode=disable
# Админка после старта — на http://localhost:8765/admin/
Единственная жёсткая зависимость — PostgreSQL. Postgres — единый источник истины: агенты, настройки, диалоги, память, outbox и аудит хранятся именно там. Всё остальное — сайдкары, векторное хранилище, шина сообщений, провайдеры моделей — опционально и подключается только тогда, когда вы это настроите.
[!NOTE] Без базы данных gateway стартует в health-only режиме: он отвечает на
GET /healthz, чтобы оркестратор или балансировщик видели, что процесс жив, но ходы (turns) обслуживать не будет.GET /readyzпроверяет PostgreSQL и возвращает503, пока база недоступна.
Что происходит при старте
При старте gateway выполняет несколько шагов в строгом порядке:
- открывает пул соединений с базой данных,
- применяет ожидающие миграции под advisory-локом PostgreSQL,
- разрешает конфигурацию (значение из БД → переменная окружения → встроенное значение по умолчанию) и
- связывает сервисы — роутер, оркестратор, каналы, инструменты, память, доставку — в работающий gateway.
Важное следствие: большинство возможностей подключаются опционально через ключ
настройки. Ненастроенная возможность просто не активируется, и поэтому
рантайм по умолчанию остаётся компактным и предсказуемым. Вы включаете нужное из
веб-админки или переменной AIHUMMER_*, и gateway учитывает это при следующем
старте (или на горячую — для тех параметров, которые это поддерживают).
Turn-движок
Когда сообщение доходит до gateway, за дело берётся turn-движок. Он ведёт цикл вызова функций: модели передаются системный промпт и диалог, она может вызывать инструменты (или порождать суб-агентов), результат каждого инструмента возвращается обратно, и цикл продолжается, пока модель не выдаст финальный ответ. Этот ответ затем передаётся слою доставки.
входящее сообщение
└─▶ turn-движок
├─ сборка слоистого системного промпта
├─ вызов модели ─▶ вызовы инструментов / суб-агенты ─▶ результаты ─┐
│ ▲ │
│ └─────────────────────────────────────────────────────-──┘
└─ финальный ответ ─▶ outbox ─▶ канал-источник
Поскольку цикл строго отслеживает, откуда пришёл каждый вход, ответы формируются из истории диалога и результатов инструментов, а не за счёт внедрения недоверенного текста в инструкции. Именно это свойство делает описанную ниже слоистость промпта не только быстрой, но и безопасной.
Слоистый, дружелюбный к кэшу системный промпт
Системный промпт — не единый блок. Он собирается слоями, намеренно упорядоченными так, чтобы стабильные части шли первыми, а изменчивые — последними. Это важно, потому что провайдеры моделей кэшируют промпт по его префиксу: пока начало промпта байт-в-байт идентично, кэшированный префикс переиспользуется и заново обрабатывается только хвост.
| Зона | Слои (по порядку) | Меняется… |
|---|---|---|
| Стабильный префикс (кэшируемый) | базовая идентичность + гид по инструментам/памяти → арендатор → проект → персона → навыки | редко — на агента/арендатора/проект |
| Изменчивый хвост (добавляется последним) | состояние онбординга → гидрация памяти → текущая дата | каждый ход |
Стабильный префикс несёт всё, что определяет, кто такой агент: встроенную идентичность и гид по тому, как работают инструменты и память, затем слой арендатора, слой проекта, персону агента и отрендеренный блок навыков. Ничего из этого не меняется между двумя соседними ходами одного агента, поэтому это и образует переиспользуемый кэшируемый префикс.
Изменчивый хвост добавляется после стабильного префикса именно для того, чтобы никогда не инвалидировать кэш: состояние онбординга, память, гидрированная под конкретный диалог, и текущая дата меняются от хода к ходу, но раз они стоят в конце, то стоят ровно столько, сколько добавляют.
[!TIP] Этот порядок — причина того, почему живые данные вроде сегодняшней даты могут присутствовать в каждом ходе, не оплачивая повторное кодирование всей идентичности каждый раз. Держите свой контент на агента в стабильных слоях (персона, навыки), а изменчивый хвост оставьте движку.
Куда дальше
- Как изолируются арендаторы — в Мультиарендности и идемпотентности.
- Как возвращаются ответы — в Доставке, outbox и восстановлении.
- Опциональные возможности работают как Сайдкары.