Запуск нескольких шлюзов одновременно
Управляйте несколькими профилями — каждый со своими токенами ботов, сессиями и памятью — как управляемыми сервисами на одной машине. Эта страница охватывает эксплуатационные вопросы: запуск всех вместе, просмотр логов по профилям, предотвращение перехода хоста в спящий режим и восстановление после распространённых проблем launchd/systemd.
Если вы запускаете только одного агента VibeOS, эта страница вам не нужна — см. Профили для основ.
Когда это использовать
Эта настройка нужна, когда у вас есть два или более агентов VibeOS, которые должны быть онлайн одновременно. Распространённые причины:
- Личный ассистент на одном Telegram-боте и агент для программирования на другом
- Один агент на члена семьи или один на рабочее пространство Slack
- Песочница и продакшн-экземпляры одной конфигурации
- Исследовательский агент + писательский агент + бот по расписанию — каждый с изолированной памятью и навыками
Каждый профиль уже получает собственный LaunchAgent для платформы
(ai.vibeos.gateway-<имя>.plist) или пользовательский сервис systemd
(vibeos-gateway-<имя>.service). Это руководство добавляет шаблоны для управления
ими коллективно.
Быстрый старт
# Создание профилей (один раз)
vibeos profile create coder
vibeos profile create personal-bot
vibeos profile create research
# Настройка каждого
coder setup
personal-bot setup
research setup
# Установка каждого шлюза как управляемого сервиса
coder gateway install
personal-bot gateway install
research gateway install
# Запуск всех
coder gateway start
personal-bot gateway start
research gateway start
Всё — три независимых агента, каждый в своём процессе, автоматически перезапускающиеся при сбое и при входе пользователя в систему.
Альтернатива: один шлюз для всех профилей (мультиплексирование)
Модель выше запускает один процесс на профиль. Это поведение по умолчанию и является правильным выбором для большинства конфигураций. Но на хосте с множеством профилей — или в контейнерном развёртывании, где один процесс на профиль операционно тяжёл — вы можете запустить один мультиплексирующий шлюз: шлюз профиля по умолчанию становится единственным входящим процессом и обслуживает сообщения для каждого профиля на машине.
Это опционально и отключено по умолчанию. Когда это выключено, ничего на этой странице не меняется — всё описанное ниже неактивно.
Когда предпочесть мультиплексирование
- Развёртывание в контейнере/VPS, где N супервизорных юнитов, N портов и N PID-файлов являются обузой.
- Много низкотрафиковых профилей, каждый из которых не оправдывает отдельный процесс.
- Вы хотите один объект для запуска, мониторинга и перезапуска.
Придерживайтесь модели «один процесс на профиль», когда вам нужна жёсткая изоляция на уровне процессов между профилями (отдельные области памяти, независимые области сбоев, возможность перезапустить один профиль, не затрагивая другие).
Как включить
Установите флаг в профиле по умолчанию (он владеет мультиплексором) и перезапустите его шлюз:
vibeos config set gateway.multiplex_profiles true
vibeos gateway restart
Эквивалентно, в ~/.vibeos/config.yaml профиля по умолчанию:
gateway:
multiplex_profiles: true
(Флаг также принимается как multiplex_profiles: true на верхнем уровне для
удобства.) При следующем запуске шлюз по умолчанию перечисляет все профили,
запускает включённые платформы каждого профиля с его собственными
учётными данными и направляет каждое входящее сообщение профилю, которому оно
принадлежит. Каждый виток разрешает конфигурацию, навыки, память, SOUL и ключи
провайдера маршрутизированного профиля — учётные данные никогда не разделяются
между профилями.
Вам не нужно запускать vibeos gateway start для вторичных профилей —
шлюз по умолчанию обслуживает их. См. изменения контракта ниже.
Что меняется при включённом мультиплексировании
Включение флага меняет поведение нескольких вещей. Всё это возвращается в исходное состояние, как только флаг выключен.
1. Вторичные профили не должны запускать свой собственный шлюз
При работающем мультиплексоре vibeos gateway start / run для именованного
профиля является жёсткой ошибкой, указывающей вам на мультиплексор:
Шлюз по умолчанию работает как мультиплексор профилей и уже обслуживает
профиль 'coder'. ...
Мультиплексор — это единственный входящий процесс; второй шлюз профиля
привёл бы к двойной привязке платформ этого профиля. Используйте --force
только если вы намеренно хотите отдельный процесс для этого профиля (не рекомендуется
при работающем мультиплексоре). Кросспрофильный скрипт-обёртка жизненного цикла,
представленный ранее на этой странице, поэтому не используется в режиме
мультиплексирования — вы управляете только шлюзом по умолчанию.
2. HTTP-входящие платформы доступны через префикс URL /p/<профиль>/
Трафик вебхуков (и других HTTP-входящих платформ) для вторичного профиля поступает на слушатель по умолчанию с префиксом профиля, а не на второй порт:
# профиль по умолчанию
POST http://host:8644/webhooks/<маршрут>
# профиль "coder", тот же слушатель
POST http://host:8644/p/coder/webhooks/<маршрут>
Неизвестный или ненастроенный профиль в префиксе возвращает 404. Поскольку один
общий слушатель уже обслуживает каждый профиль таким образом, вторичный профиль
не должен включать платформу, привязывающую порт, сам по себе — это является
ошибкой конфигурации, и шлюз отказывается запускаться, указывая профиль и
платформу:
Профиль 'coder' включает платформу 'webhook', привязывающую порт, но
gateway.multiplex_profiles включён. ... Удалите platforms.webhook из config.yaml
профиля 'coder' (настройте его только в профиле по умолчанию).
Платформы, привязывающие порт, подпадающие под это правило: webhook, api_server,
msgraph_webhook, feishu, wecom_callback, bluebubbles, sms. Настраивайте
любую из них только в профиле по умолчанию; каждый профиль доступен через
свой префикс /p/<профиль>/.
3. Платформы с отдельными учётными данными всё ещё требуют свой токен на профиль
Платформы опроса/подключения (Telegram, Discord, Slack, Matrix, Signal, …)
работают нормально в режиме мультиплексирования, но каждый профиль, который их
включает, должен предоставить свой токен бота — один и тот же токен не может
одновременно опрашиваться двумя профилями. Если два профиля настраивают
одинаковый (платформа, токен), запуск завершается ошибкой с указанием обоих
профилей (см. Безопасность конфликтов токенов —
правило не изменилось, просто теперь оно применяется внутри одного процесса).
4. Ключи сессий разделены по профилям
Сессии каждого профиля хранятся в пространстве имён agent:<профиль>:…, чтобы
два профиля на одной платформе/чате никогда не конфликтовали в общем хранилище
сессий. Профиль по умолчанию сохраняет историческое пространство имён
agent:main:… побайтово, поэтому существующие сессии профиля по умолчанию не
затрагиваются — никакой миграции, никакой потерянной истории.
5. Один PID/блокировка и одна поверхность состояния
Существует один PID и блокировка на уровне процесса (мультиплексор, в домашней
директории по умолчанию). vibeos status сообщает о мультиплексоре и профилях,
которые он обслуживает; vibeos status -p <имя>сужает до одного профиля. Каждый профиль по-прежнему записывает свой собственныйruntime_status.json` в своей
домашней директории, поэтому существующие читатели по профилям продолжают работать.
Что не меняется
Изоляция учётных данных .env по профилям сохраняется и, если что,
становится строже: ключи профиля разрешаются из его собственной области и никогда
не объединяются в общее окружение (это также означает, что подпроцессы, такие как
MCP-серверы и рабочие процессы Kanban, видят только секреты своего профиля).
Kanban, навыки/память/SOUL с областью видимости профиля и маршрутизация моделей
ведут себя по профилям точно так же, как и с отдельными шлюзами.
Запуск, остановка или перезапуск всех шлюзов одновременно
CLI поставляется с командами жизненного цикла для одного профиля. Чтобы выполнить
действие для каждого профиля, оберните их в цикл оболочки. Поместите приведённый
ниже фрагмент в ~/.local/bin/vibeos-gateways и выполните chmod +x:
#!/bin/sh
set -eu
# Добавляйте или удаляйте имена профилей здесь по мере создания/удаления профилей.
profiles="default coder personal-bot research"
usage() {
echo "Использование: vibeos-gateways {start|stop|restart|status|list}"
}
run_for_profile() {
profile="$1"
action="$2"
if [ "$profile" = "default" ]; then
vibeos gateway "$action"
else
vibeos -p "$profile" gateway "$action"
fi
}
action="${1:-}"
case "$action" in
start|stop|restart|status)
for profile in $profiles; do
echo "==> $action $profile"
run_for_profile "$profile" "$action"
done
;;
list)
vibeos gateway list
;;
*)
usage
exit 2
;;
esac
Затем:
vibeos-gateways start # запустить каждый настроенный профиль
vibeos-gateways stop # остановить каждый настроенный профиль
vibeos-gateways restart # перезапустить все
vibeos-gateways status # статус по всем
vibeos-gateways list # делегирует `vibeos gateway list`
Профиль default обрабатывается командой vibeos gateway <действие> (без -p), а не vibeos -p default gateway <действие>. Обёртка выше обрабатывает обе формы.
Управление одним профилем
Команды быстрого доступа, которые устанавливает каждый профиль:
coder gateway run # передний план (Ctrl-C для остановки)
coder gateway start # запустить управляемый сервис
coder gateway stop # остановить управляемый сервис
coder gateway restart # перезапустить
coder gateway status # статус
coder gateway install # создать LaunchAgent / systemd-юнит
coder gateway uninstall # удалить файл сервиса
Это эквивалентно vibeos -p coder gateway <действие>— полезно, если псевдоним профиля не находится вPATH` или если вы динамически обращаетесь к
профилям из скрипта.
Файлы сервисов
Каждый профиль устанавливает свой собственный сервис с уникальным именем, поэтому установки никогда не конфликтуют:
| Платформа | Путь |
|---|---|
| macOS | ~/Library/LaunchAgents/ai.vibeos.gateway-<профиль>.plist |
| Linux | ~/.config/systemd/user/vibeos-gateway-<профиль>.service |
Профиль по умолчанию сохраняет исторические имена: ai.vibeos.gateway.plist /
vibeos-gateway.service.
Просмотр логов
Каждый профиль пишет в свои собственные файлы логов:
# Профиль по умолчанию
tail -f ~/.vibeos/logs/gateway.log
tail -f ~/.vibeos/logs/gateway.error.log
# Именованный профиль
tail -f ~/.vibeos/profiles/<имя>/logs/gateway.log
tail -f ~/.vibeos/profiles/<имя>/logs/gateway.error.log
Потоковая передача логов всех профилей одновременно:
tail -f ~/.vibeos/logs/gateway.log ~/.vibeos/profiles/*/logs/gateway.log
CLI также имеет структурированное средство просмотра логов:
vibeos logs -f # следить за профилем по умолчанию
vibeos -p coder logs -f # следить за одним профилем
vibeos logs --help # фильтры, уровни, вывод JSON
Определение того, что на самом деле запущено
vibeos profile list # профили + модель + состояние шлюза
vibeos-gateways status # полный статус по каждому профилю
launchctl list | grep vibeos # macOS — PID и метки
systemctl --user list-units 'vibeos-gateway-*' # Linux — юниты
Редактирование конфигурации
Каждый профиль хранит свою конфигурацию внутри собственной директории:
~/.vibeos/profiles/<имя>/
├── .env # API-ключи, токены ботов (chmod 600)
├── config.yaml # модель, провайдер, наборы инструментов, настройки шлюза
└── SOUL.md # личность / системный промпт
Профиль по умолчанию использует ~/.vibeos/ напрямую с теми же тремя файлами.
Редактируйте их любым редактором или через CLI:
vibeos config set model.model anthropic/claude-sonnet-4 # профиль по умолчанию
coder config set model.model openai/gpt-5 # именованный профиль
После редактирования .env или config.yaml перезапустите соответствующий шлюз:
coder gateway restart
# или, для всего:
vibeos-gateways restart
Предотвращение перехода хоста в спящий режим
Процесс шлюза может работать весь день, но операционная система всё равно будет пытаться перейти в спящий режим при простое. Два шаблона:
macOS — caffeinate
caffeinate встроен в macOS и предотвращает сон, пока работает. Установка не
требуется.
caffeinate -dis # блокировать сон дисплея, бездействия и системы
caffeinate -dis -t 28800 # то же самое, авто-выход через 8 часов
caffeinate -i -w $(cat ~/.vibeos/gateway.pid) & # не спать, пока работает шлюз по умолчанию
# Постоянно: запустить в фоне и забыть
nohup caffeinate -dis >/dev/null 2>&1 &
disown
# Проверка / остановка
pmset -g assertions | grep -iE 'caffeinate|prevent|user is active'
pkill caffeinate
| Флаг | Эффект |
|---|---|
-d | блокировать сон дисплея |
-i | блокировать сон системы при бездействии (по умолчанию) |
-m | блокировать сон диска |
-s | блокировать сон системы (только Mac с питанием от сети) |
-u | имитировать активность пользователя (предотвращает блокировку экрана) |
-t N | авто-выход через N секунд |
-w P | выход, когда PID P завершится |
caffeinate не может переопределить аппаратный сон при закрытии крышки на MacBook.
Для работы с закрытой крышкой измените настройки Energy Saver / Battery или
используйте сторонний инструмент.
Linux — systemd-inhibit или loginctl
# Заблокировать приостановку, пока выполняется команда
systemd-inhibit --what=idle:sleep --who=vibeos --why="шлюзы работают" \
sleep infinity &
# Разрешить пользовательским сервисам продолжать работу после выхода из системы (рекомендуется)
sudo loginctl enable-linger "$USER"
После включения lingering ваши пользовательские systemd-юниты (включая
vibeos-gateway-<профиль>.service) продолжают работать после отключения SSH
и перезагрузок.
Безопасность конфликтов токенов
Каждый профиль должен использовать уникальные токены ботов для каждой платформы. Если два профиля используют общий токен Telegram, Discord, Slack, WhatsApp или Signal, второй шлюз отказывается запускаться с ошибкой, указывающей конфликтующий профиль.
Для аудита:
grep -H 'TELEGRAM_BOT_TOKEN\|DISCORD_BOT_TOKEN' \
~/.vibeos/.env ~/.vibeos/profiles/*/.env
Обновление кода
vibeos update загружает последний код один раз и синхронизирует новые встроенные
навыки в каждый профиль:
vibeos update
vibeos-gateways restart
Пользовательские навыки никогда не перезаписываются.
Устранение неполадок
«Could not find service in domain for user gui: 501»
Вы запустили vibeos gateway start после предыдущего vibeos gateway stop.
Команда stop в CLI выполняет полную launchctl unload, которая удаляет сервис из
реестра launchd. CLI перехватывает эту конкретную ошибку при start и
автоматически перезагружает plist (↻ задание launchd было выгружено; перезагрузка определения сервиса). Сервис запускается нормально. Ничего исправлять не нужно.
Устаревший PID после сбоя
Если шлюз профиля показывает not running, но процесс всё ещё жив:
ps -ef | grep "vibeos_cli.*-p <профиль>"
cat ~/.vibeos/profiles/<профиль>/gateway.pid
kill -TERM <pid> # корректное завершение
kill -KILL <pid> # если это не сработало через несколько секунд
<профиль> gateway start
Принудительный жёсткий сброс одного сервиса
# macOS
launchctl unload ~/Library/LaunchAgents/ai.vibeos.gateway-<профиль>.plist
launchctl load ~/Library/LaunchAgents/ai.vibeos.gateway-<профиль>.plist
# Linux
systemctl --user restart vibeos-gateway-<профиль>.service
Проверка здоровья
vibeos doctor # профиль по умолчанию
vibeos -p <профиль> doctor # один профиль