На странице: зависимости и каталоги · токен и исходящий трафик · QueryEngine в коде · журналы и doctor
Материал для разработчиков RAG и агентов, которые уже строят индексы в LlamaIndex и выводят ответы через QueryEngine на арендованном Apple Silicon. Логика согласуется с матрицей LlamaIndex Workflows и стоимостью удалённого узла и с дисциплиной шлюза из HowTo по Haystack 2 и OpenClaw, но фокус — на композиции QueryEngine и Python-инструментах, а не на отдельном фреймворке оркестрации.
Три боли до инцидента. 1. Модель предлагает имя инструмента вне политики арендатора — любой прямой HTTP из процесса обходит аудит. 2. Хвостовая задержка векторного поиска без таймаута и предохранителя блокирует весь ответ, а виноватой выглядит LLM. 3. Тихие сбои retrieval учат модель галлюцинировать источники; нужен короткий конверт ошибки, который читает ResponseSynthesizer.
Зависимости и структура каталогов
На чистом репозитории на удалённом Mac: python -m venv .venv, закрепите llama-index-core и клиент векторного хранилища, держите эмбеддинги рядом с томом индекса, чтобы холодный старт не тянул данные через лишний WAN. Каталоги: schemas/tools/ для JSON Schema аргументов, src/retrieval/ для обёрток retriever, tokens/ с правами 0600 вне git, logs/jsonl/ для воркеров. Зафиксируйте в README таблицу портов loopback для OpenClaw и локального реранкера — одна правда для CI и людей.
Токен шлюза и исходящие ограничения
Выровняйтесь с линией OpenClaw 2026.4.x: Node 22 LTS, обновлённый CLI, openclaw gateway listen только на 127.0.0.1 с --token-file из панели. С ноутбука — обратный SSH-туннель к порту. Bearer — это ограниченная capability: он разрешает лишь маршруты инструментов, которые QueryEngine реально вызывает, а не «весь интернет» из Python. Политика deny by default: исходящий трафик с Mac — только loopback шлюза и сокет векторной БД; побочные HTTP из функций LlamaIndex ведите через общий класс клиента шлюза с заголовками, correlation id и проверкой allowlist до отправки байт.
| Вопрос | Слой шлюза OpenClaw | Слой LlamaIndex QueryEngine |
|---|---|---|
| Политика | Белый список имён и маршрутов, ротация Bearer, лимиты тела запроса. | Выбор retriever, чанкинг, промпт синтеза, фильтры метаданных. |
| Таймауты | Connect и read для HTTP инструментов. | asyncio.wait_for вокруг векторного запроса; счётчик срабатываний и cooldown. |
| Ретраи | Ограниченный backoff на 429 и сетевые обрывы для вызовов шлюза. | Ноль или один повтор пока предохранитель закрыт; без циклов по дорогому поиску. |
| Форма сбоя | HTTP-коды и ошибки валидации шлюза. | Флаги retrieval_skipped и конверт в контексте синтеза. |
Подключение QueryEngine: шаги в коде
Семь шагов в фиксированном порядке — проще ревью и откат.
1. Обернуть retriever. Декорируйте VectorIndexRetriever: каждый aretrieve под asyncio.wait_for с дедлайном порядка 450 ms в разработке и 900 ms на прогретом индексе. По TimeoutError — пустой список узлов и метаданные retrieval_skipped=true.
2. Счётчик предохранителя. Ведите число подряд идущих нарушений по имени индекса; после двух срабатываний за пять минут откройте предохранитель: не вызывайте retrieval до cooldown, в метаданные добавьте fuse_opened_at.
3. Один HTTP-клиент шлюза. GatewayToolClient.post(name, payload) читает базовый URL и токен из окружения, ставит X-Correlation-Id, отвергает name вне зафиксированного в репозитории allowlist.
4. Локальная валидация. jsonschema.validate или Pydantic по файлам schemas/tools/*.json, чтобы неверные аргументы не сжигали ходы модели.
5. Регистрация в LlamaIndex. Только обёрнутые функции как FunctionTool в QueryEngineTool или раннер агента; сырой httpx в промпт не передавать.
6. Сборка QueryEngine. Подключите обёрнутый retriever, инструменты, расширьте шаблон или колбэки response_synthesizer, чтобы failure envelope доходил до финального промпта короткой строкой, а не дампом JSON.
7. Карта ошибок в summary. События шлюза и предохранителя сводите к объекту с ключами stage, code, correlation_id, hint; прокиньте через метаданные source_nodes или параллельный dict, который шаг синтеза явно читает. Тот же словарь полей совместим с подходом из гайда по PydanticAI и OpenClaw.
# инвариант границы: имя инструмента только из ALLOWED_TOOLS
# assert tool_name in ALLOWED_TOOLS
# jsonschema.validate(instance=payload, schema=load_schema(tool_name))
# async with asyncio.timeout(0.45): nodes = await retriever.aretrieve(q)Журналы и обход с openclaw doctor
Одна JSON-строка на вызов QueryEngine: идентификатор пайплайна, correlation id, миллисекунды retrieval, состояние предохранителя, обезличенные имена инструментов. Суточная ротация в logs/jsonl/ упрощает стыковку с syslog Mac и access-логом шлюза без утечки промптов.
После каждого обновления зависимостей сохраняйте вывод openclaw doctor --json рядом с release notes. В деплой-хуке дергайте /health шлюза с тем же Bearer, что у воркеров; провал при расхождении латентности или авторизации — стоп релиза. Публичные страницы без входа: тарифы, покупка и аренда, документация, индекс блога.
Параметры для runbook
- Дедлайн retrieval: 450 ms dev, 900 ms на прогретом индексе; предохранитель после двух подряд таймаутов.
- HTTP шлюза: connect 2 с, read 8 с; backoff от 250 ms с полным джиттером; без ретрая на 401.
- Cooldown: держите предохранитель открытым минимум 120 с перед пробой retrieval в инциденте.
Когда уходите с ноутбучного туннеля на постоянный узел, размещайте шлюз, индексы и эмбеддинги на одном классе машин Mac mini M4, чтобы correlation id оставались осмысленными под нагрузкой.
Итог: модель шлюза OpenClaw 2026 закрывает периметр инструментов; LlamaIndex остаётся владельцем retrieval и синтеза. Белый список, таймауты, предохранитель и failure summary дают воспроизводимый контур на удалённом Mac без смешения ролей слоёв.