Когда команда переносит RAG на арендованный удалённый Mac, Chroma часто выбирают как локальное векторное хранилище: мало трения, встраивается в Python и удобно соседствует с OpenClaw Gateway. Разрыв между демо и продакшеном — операционка: где лежат файлы, как делать снимки без порчи SQLite, какие зонды доказывают, что стек жив, и как не дать одному медленному запросу к индексу заблокировать сессию агента. Этот материал — для тех, кто доставляет ИИ-вычисления на железо, до которого нельзя дотянуться рукой: заходите по SSH, фиксируете пути в runbook и спите спокойнее, зная, что векторные данные не исчезнут молча. Базовую установку шлюза сверьте с гайдом по Docker, прокси и усилению, метрики и пороговые правила — с материалом про метрики шлюза и алерты в духе Prometheus. Если Chroma делит диск с контейнерами, загляните в матрицу pull-кэша Docker/Podman за привычками к запасу на APFS до масштабирования инжеста.
Каталог персистентности Chroma и шаги снимков
В режиме встроенного клиента и в режиме сервера Chroma сводит состояние к каталогу персистентности, который вы задаёте сами. На машине аренды относитесь к нему как к компактной СУБД: один канонический абсолютный путь, владелец — пользователь автоматизации, том с предсказуемым свободным местом — по возможности не системный раздел. Экспортируйте, например, CHROMA_PERSIST_DIRECTORY=/Volumes/Data/chroma-prod в профиль shell, plist launchd или bind mount Docker и ссылайтесь на ту же переменную из навыка OpenClaw, который открывает коллекции.
Рецепт снимка (согласованный на уровне файловой системы). Сначала остановите писателей: завершите процесс Python с PersistentClient или остановите контейнер chroma run, чтобы SQLite и сегменты не оказались в середине транзакции. Второй шаг — манифест: имена коллекций, идентификатор модели эмбеддингов и строка версии Chroma; прогоны восстановления бессмысленны, если мажор клиента разошёлся с on-disk форматом. Третий — архивация с сохранением метаданных:
# замените пути; выполняйте только когда Chroma остановлена
export SRC="$CHROMA_PERSIST_DIRECTORY"
export STAMP=$(date -u +%Y%m%dT%H%M%SZ)
tar -C "$(dirname "$SRC")" -czf "/backup/chroma-${STAMP}.tgz" "$(basename "$SRC")"
shasum -a 256 /backup/chroma-${STAMP}.tgz > /backup/chroma-${STAMP}.tgz.sha256
rsync -a --delete на сетевой том или шлюз объектного хранилища уместен при доверенном канале; держите как минимум два поколения на площадке и одну копию вне узла, если Mac — единственная точка отказа. Четвёртое — верификация: распакуйте в scratch на другой машине, поднимите клиент только для чтения, если версия позволяет, или выполните простой count() по каждой коллекции. Пятое — снова включите сервис и запишите команду восстановления рядом с cron резервного копирования.
Почему не копировать «на горячую»? Copy-on-write на macOS снижает часть рисков, но Chroma смешивает SQLite с блоб-сегментами; горячая копия даёт восстановления с database is locked или разорванными страницами. Для RPO меньше минуты переходите на бэкенд с онлайн-бэкапом или планируйте короткое окно обслуживания — дёшево в ночных слотах батчей.
Зонды здоровья OpenClaw и шаблоны алертов
OpenClaw Gateway отдаёт /healthz и /readyz на HTTP-слушателе (часто 127.0.0.1:18789). Это ритм control plane: если пробы падают, навык с Chroma не должен притворяться, что ассистент «в порядке». С хоста аренды:
curl -fsS http://127.0.0.1:18789/healthz
curl -fsS http://127.0.0.1:18789/readyz
Повторите тот же паттерн scrape, что и для остальных сервисов (Prometheus, управляемый blackbox и т.д.); критичны лейблы — env=prod, role=openclaw-gateway, идентификатор инстанса у провайдера, чтобы маршрутизация оповещений не путалась между средами.
Алерты в духе квоты диска ставьте рядом со здоровьем шлюза. Рост Chroma связан с числом документов, размерностью эмбеддингов и слияниями сегментов; тихое заполнение диска убивает и SQLite, и кэш страниц ОС. Экспортируйте свободное место через node_exporter, простой cron с df -Pk, пишущий метрику в файл, или агент вендора. Стартовые пороги: предупреждение, когда на томе Chroma остаётся порядка 20 ГБ (подстройте под размер батча эмбеддингов), и критическое ниже 5 ГБ или когда по скользящей скорости приёма до полного тома меньше двух часов.
| Сигнал | Условие (старт) | Замечания |
|---|---|---|
| Шлюз /healthz | HTTP ≠ 200 два опроса подряд | 15–30 с для пользовательских сценариев |
| Шлюз /readyz | Ошибки при зелёном /healthz | Чаще зависимость или конфиг; смотрите логи до Chroma |
| Свободные байты тома | avail < 20e9 warn / < 5e9 crit | По тому, где лежит персистентность, не по корню агрегата |
| HTTP Chroma (опционально) | TCP или HTTP к известному порту | Только в server mode с фиксированным интерфейсом |
Каналы уведомлений берите уже отработанные — Slack, PagerDuty, почта — и в аннотации алерта кладите ссылку на runbook: «проверить ротацию токена шлюза», «сверить диск», «откатиться на последний tarball Chroma».
Параметры таймаута запросов и предохранителя
Задержка запросов к Chroma растёт с размером коллекции, сложностью фильтров и конкуренцией за HNSW. Инструмент OpenClaw без дедлайна может голодать воркер сессии и размножить повторы по каналам. Ставьте таймаут на самом узком слое — у функции, вызывающей collection.query, или у HTTP-клиента к chroma run, а не только у расплывчатого «таймаута LLM» выше по стеку.
Стартовые значения для интерактивного RAG. 4–8 секунд дедлайна на top-k с умеренными фильтрами для коллекций до нескольких миллионов векторов на Apple Silicon; 15–30 секунд оставьте для оффлайн-сверок и сверки батчей вне критического пути. Вместе с дедлайном задайте максимальную конкуренцию (например 2–4 параллельных запроса на процесс шлюза), чтобы всплески из групповых чатов не устроили штурм индекса.
Эскиз предохранителя (circuit breaker). Ведите скользящее окно сбоев (таймауты, 5xx или «пустой индекс»). После трёх подряд неудач за пять минут откройте предохранитель на 30–120 секунд: возвращайте агенту детерминированный деградированный ответ («векторное хранилище временно недоступно — используем кэшированное резюме») и логируйте error_class=chroma_breaker_open. После охлаждения — half-open с одним пробным запросом. Тот же контур хорошо сочетается с независимыми счётчиками API и предохранителями по проектам, если вы дополнительно ограничиваете вызовы эмбеддингов.
# иллюстрация дедлайна в asyncio
import asyncio
async def query_with_cap(coro, seconds=6.0):
return await asyncio.wait_for(coro, timeout=seconds)
Для синхронного стека достаточно httpx.Client(timeout=6.0) или опций gRPC-канала. Зафиксируйте выбранные числа в манифесте навыка, чтобы дежурный отличал настройку от реальной аварии.
FAQ: типичные ошибки прав доступа и путей
PermissionError: [Errno 13] на пути персистентности. Пользователь аренды, под которым крутится OpenClaw, не владеет каталогом — типично после клонирования образа диска или восстановления из Time Machine. Исправьте sudo chown -R $USER:staff "$CHROMA_PERSIST_DIRECTORY" или пересоздайте дерево и перенесите данные rsync -a.
sqlite3.OperationalError: database is locked. Два процесса открыли один каталог, либо бэкап копировал *.sqlite* во время записи. Остановите все экземпляры Chroma, убедитесь через lsof, что путь свободен, поднимите одного владельца.
Относительные пути под launchd и SSH. В plist и compose всегда абсолютные пути; ~/chroma раскрывается по-разному для GUI и SSH-сессий.
Регистр имён и чувствительность к регистру. Внешние тома с иной политикой APFS по сравнению с ноутбуком разработчика дают «file not found» в автоматизации — нормализуйте имена каталогов снимков к одному регистру.
Docker bind mount на Mac. Хостовый путь должен существовать до docker compose up; при переносе воркеров на Linux те же принципы прав и меток сохраняются, даже если фокус статьи — bare-metal аренда.
Итог
Chroma на арендованном удалённом Mac остаётся «скучной в хорошем смысле», когда персистентность лежит на выделенном томе, снимки холодные (писатели остановлены), а зонды OpenClaw срабатывают раньше пользователей. Алерты по диску подключайте с первых дней — плотный векторный том ломается шумно, когда файловой системе уже тесно. Завершайте контур явными дедлайнами запросов и коротким предохранителем, чтобы один плохой день индекса не расползся по сессиям агентов.
Публичные страницы тарифов, оформления заказа и справочного центра доступны без обязательного входа — подберите конфигурацию Mac под долгоживущий шлюз и векторный слой, когда runbook готов.