Цепочка навык → инструмент → LLM на удалённом Mac ломается не из‑за отсутствия vLLM как такового, а из‑за отсутствия единого шлюза, согласованных повторов и короткого failure summary с correlation id. Ниже — воспроизводимый контур: OpenClaw gateway наружу, OpenAI-совместимый слушатель только на loopback, бюджет ошибок и нормализованный ответ при сбое без полного промпта.

Оглавление: матрица входов · развёртывание · навыки и маршрут · ретраи и breaker · сводка сбоя · launchd · типовые сбои · FAQ

См. также LiteLLM за шлюзом, JSON Schema и backoff, IDE-мост и пробы. Здесь — локальный OpenAI-совместимый сервер в духе vLLM и агрегация ошибок на шлюзе.

Три источника ночных инцидентов

Размытый периметр секретов. Когда разработчики держат API-ключ провайдера на ноутбуке, а инференс на Mac в ЦОД, вы теряете единую точку ротации и не можете отозвать доступ только у одного навыка.

Двойные повторы. Клиент шлюза ретраит пятисотые, внутренний HTTP-клиент vLLM делает то же самое, очередь раздувается, метрики GPU остаются зелёными, а пользователь видит только обрыв стрима.

Шум вместо саммари. Без нормализованного конверта ошибки дежурный ищет по гигабайтам логов и не понимает, это rate limit, нехватка KV или сетевой blackhole к loopback.

Добавьте явный контракт между слоями: кто считает попытку, кто пишет итоговый статус в ответ навыку и какой correlation id связывает пользовательский запрос с внутренним логом инференса на том же хосте.

Матрица: где заканчивается доверенный контур

Схема Когда уместна Риск
Порт vLLM открыт в LAN Лабораторный стенд из одной подсети Утечка модели и отсутствие аудита на уровне навыка OpenClaw
vLLM на 127.0.0.1, наружу только OpenClaw Продакшен-навыки и удалённые IDE-клиенты Нужно точно согласовать таймауты стрима и путь /v1
Только облачный hosted API без локального слоя Нет своих весов и жёсткие требования compliance к облаку Нет контроля над задержкой prefill и стоимостью длинного контекста

Развёртывание: от Node до первого completion

1) Node LTS. Node.js 22 LTS через nvm или fnm, engines и lockfile; зависимости шлюза в ~/openclaw-edge отдельно от весов.

2) Каталоги. config, logs, tmp, weights; секреты 0400, не в git.

3) Сервер на loopback. vLLM на 127.0.0.1, лимиты контекста и GPU, базовый URL только в окружении шлюза.

4) Gateway. Второй loopback-порт, навыки read-only, upstream http://127.0.0.1:<VLLM_PORT>/v1, логические имена моделей в репо.

5) Аутентификация. Узкие Bearer из Dashboard dev и prod; путь к файлу токена в plist, не строка в unit.

6) Ретраи. Капы попыток, экспоненциальный backoff с джиттером для 429 и 503; на upstream уберите дублирующие повторы.

7) Приёмка. openclaw doctor --json, curl health, лёгкий chat completions; сценарии с протухшим токеном и перегрузом очереди.

Маршрут цепочки навыков и инструментов

Таймаут и параллелизм на каждый навык; тяжёлые цепочки — отдельный пул. См. LangGraph и gateway; инструменты не должны звать vLLM в обход шлюза.

Бюджет ошибок и circuit breaker

Окно и порог пятисотых или глубины очереди — открытый circuit и контролируемая ошибка до cooldown. Лимитируйте стримы и токен-бюджет на сессию чтобы не выжечь память соседям на узле.

Failure summary обратно клиенту и в лог

Короткий JSON: маршрут, тип провайдера, код, correlation id, стрим, подсказка backoff, без промпта и completion. Дублируйте id в access-лог; трассировки — OpenTelemetry GenAI.

# Минимальная проверка цепочки (подставьте порты и токен шлюза) curl -sf -H "Authorization: Bearer $OC_TOKEN" -H "Content-Type: application/json" \ -d '{"model":"reason-small","messages":[{"role":"user","content":"ping"}],"max_tokens":8}' \ http://127.0.0.1:${OC_GATEWAY_PORT}/v1/chat/completions

Демон: launchd вместо ручного screen

Два LaunchAgent: инференс с env из файла; шлюз после health vLLM. ThrottleInterval, KeepAlive, логи в logs с ротацией.

Типовые сбои при стыковке

502 при живом vLLM. Проверьте префикс пути в навыке, заголовок Host и разницу между connect и read таймаутом на длинном стриме.

401 на шлюзе при рабочем токене в curl. Сверьте что клиент навыка читает тот же файл что plist, нет ли лишних пробелов и не протух ли выпуск из Dashboard.

Лавина 429. Снизьте параллелизм батча, включите отдельный пул, уважайте Retry-After и не умножайте ретраи на двух слоях одновременно.

Стрим обрывается на середине. Чаще всего виноват слишком короткий read timeout на шлюзе или прокси между IDE и узлом; сравните с p95 длины ответа и при необходимости включите heartbeats на транспорте.

FAQ: 429, таймауты, диск

429 не уходит после увеличения max_retries. Часто провайдер лимитирует по параллельным стримам а не по числу повторов одного запроса; урежьте конкуренцию и разведите батч.

Таймаут при нормальной утилизации GPU. Измерьте время до первого токена, проверьте не указывает ли шлюз на старый порт после рестарта, и не лежит ли лог на сетевом томе который добавляет секунды fsync.

Диск заполнен и всё деградирует. Очистите старые логи и временные чанки, перенесите кэш моделей с внешнего USB на внутренний APFS, следите за inode при миллионах мелких файлов чекпойнта.

Итог: шлюз даёт узкий периметр и аудит, loopback vLLM держит совместимый OpenAI surface под контролем, согласованные ретраи и breaker защищают квоту, а короткий failure summary ускоряет разбор без утечки промптов.

Чтобы повторить весь контур на выделенном узле Apple Silicon без простоев на ноутбуке команды, откройте страницу покупки удалённого Mac — она доступна без входа в аккаунт; актуальные тарифы и инструкции по SSH смотрите в центре помощи, затем перенесите plist и манифесты в репозиторий инфраструктуры без секретов.