Gateway

Бэкенды CLI

OpenClaw может запускать локальные AI CLI как текстовый резервный вариант, когда API-провайдеры недоступны, ограничены по частоте запросов или временно работают некорректно. Это намеренно консервативный режим:

  • Инструменты OpenClaw не внедряются напрямую, но бэкенды с bundleMcp: true могут получать инструменты Gateway через loopback MCP-мост.
  • Потоковая передача JSONL для CLI, которые ее поддерживают.
  • Сессии поддерживаются (поэтому последующие ходы остаются согласованными).
  • Изображения можно передавать сквозным образом, если CLI принимает пути к изображениям.

Это задумано как страховочная сеть, а не основной путь. Используйте это, когда вам нужны текстовые ответы, которые «всегда работают», без зависимости от внешних API.

Если вам нужна полноценная среда выполнения harness с управлением сессиями ACP, фоновыми задачами, привязкой к треду/диалогу и постоянными внешними сессиями кодирования, используйте ACP Agents. CLI-бэкенды не являются ACP.

Быстрый старт для начинающих

Вы можете использовать Claude Code CLI без какой-либо конфигурации (встроенный Anthropic Plugin регистрирует бэкенд по умолчанию):

bash
openclaw agent --agent main --message "hi" --model claude-cli/claude-sonnet-4-6

main — это идентификатор агента по умолчанию, когда явный список агентов не настроен. Если вы используете несколько агентов, замените его на идентификатор агента, который хотите запустить.

Если ваш Gateway работает под launchd/systemd и PATH минимален, добавьте только путь к команде:

json5
{  agents: {    defaults: {      cliBackends: {        "claude-cli": {          command: "/opt/homebrew/bin/claude",        },      },    },  },}

Готово. Не нужны ни ключи, ни дополнительная конфигурация аутентификации сверх самой CLI.

Если вы используете встроенный CLI-бэкенд как основного провайдера сообщений на узле Gateway, OpenClaw теперь автоматически загружает владеющий встроенный Plugin, когда ваша конфигурация явно ссылается на этот бэкенд в ссылке на модель или в agents.defaults.cliBackends.

Использование как резервного варианта

Добавьте CLI-бэкенд в список резервных вариантов, чтобы он запускался только при сбое основных моделей:

json5
{  agents: {    defaults: {      model: {        primary: "anthropic/claude-opus-4-6",        fallbacks: ["claude-cli/claude-sonnet-4-6"],      },      models: {        "anthropic/claude-opus-4-6": { alias: "Opus" },        "claude-cli/claude-sonnet-4-6": {},      },    },  },}

Примечания:

  • Если вы используете agents.defaults.models (список разрешенных моделей), вы также должны включить туда модели вашего CLI-бэкенда.
  • Если основной провайдер завершится с ошибкой (аутентификация, ограничения частоты, тайм-ауты), OpenClaw попробует CLI-бэкенд следующим.

Обзор конфигурации

Все CLI-бэкенды находятся в:

Code
agents.defaults.cliBackends

Каждая запись индексируется по идентификатору провайдера (например, claude-cli, my-cli). Идентификатор провайдера становится левой частью ссылки на модель:

Code
<provider>/<model>

Пример конфигурации

json5
{  agents: {    defaults: {      cliBackends: {        "my-cli": {          command: "my-cli",          args: ["--json"],          output: "json",          input: "arg",          modelArg: "--model",          modelAliases: {            "claude-opus-4-6": "opus",            "claude-sonnet-4-6": "sonnet",          },          sessionArg: "--session",          sessionMode: "existing",          sessionIdFields: ["session_id", "conversation_id"],          systemPromptArg: "--system",          // For CLIs with a dedicated prompt-file flag:          // systemPromptFileArg: "--system-file",          // Codex-style CLIs can point at a prompt file instead:          // systemPromptFileConfigArg: "-c",          // systemPromptFileConfigKey: "model_instructions_file",          systemPromptWhen: "first",          imageArg: "--image",          imageMode: "repeat",          // Opt in only if this backend may reseed safe invalidated sessions          // from bounded raw OpenClaw transcript history before compaction.          reseedFromRawTranscriptWhenUncompacted: true,          serialize: true,        },      },    },  },}

Как это работает

  1. Выбирает бэкенд на основе префикса провайдера (claude-cli/...).
  2. Формирует системный промпт с использованием того же промпта OpenClaw и контекста рабочей области.
  3. Выполняет CLI с идентификатором сессии (если поддерживается), чтобы история оставалась согласованной. Встроенный бэкенд claude-cli поддерживает активный процесс Claude stdio для каждой сессии OpenClaw и отправляет последующие ходы через stdin stream-json.
  4. Разбирает вывод (JSON или обычный текст) и возвращает итоговый текст.
  5. Сохраняет идентификаторы сессий для каждого бэкенда, чтобы последующие ходы повторно использовали ту же CLI-сессию.

Встроенный Anthropic-бэкенд claude-cli предпочитает собственный резолвер skill в Claude Code для OpenClaw skills. Когда текущий снимок skills содержит хотя бы один выбранный skill с материализованным путем, OpenClaw передает временный Plugin Claude Code с --plugin-dir и опускает дублирующий каталог OpenClaw skills из добавленного системного промпта. Если в снимке нет материализованного plugin skill, OpenClaw сохраняет каталог промпта как резервный вариант. Переопределения переменных окружения/API-ключей skill по-прежнему применяются OpenClaw к окружению дочернего процесса для запуска.

Claude CLI также имеет собственный неинтерактивный режим разрешений. OpenClaw сопоставляет его с существующей политикой выполнения вместо добавления конфигурации политики, специфичной для Claude. Для управляемых OpenClaw активных сессий Claude действующая политика выполнения OpenClaw является авторитетной: YOLO (tools.exec.security: "full" и tools.exec.ask: "off") запускает Claude с --permission-mode bypassPermissions, а ограничительная действующая политика выполнения запускает Claude с --permission-mode default. Настройки agents.list[].tools.exec для конкретного агента переопределяют глобальный tools.exec для этого агента. Необработанные аргументы бэкенда Claude все еще могут включать --permission-mode, но активные запуски Claude нормализуют этот флаг в соответствии с действующей политикой выполнения OpenClaw.

Встроенный Anthropic-бэкенд claude-cli также сопоставляет уровни OpenClaw /think с собственным флагом Claude Code --effort для уровней, отличных от off. minimal и low сопоставляются с low, adaptive и medium — с medium, а high, xhigh и max сопоставляются напрямую. Другим CLI-бэкендам требуется, чтобы владеющий ими Plugin объявил эквивалентный mapper argv, прежде чем /think сможет влиять на порождаемую CLI.

Прежде чем OpenClaw сможет использовать встроенный бэкенд claude-cli, сам Claude Code уже должен быть авторизован на том же узле:

bash
claude auth loginclaude auth status --textopenclaw models auth login --provider anthropic --method cli --set-default

Для установок Docker Claude Code должен быть установлен и авторизован внутри сохраняемого home контейнера, а не только на хосте. См. Claude CLI backend in Docker.

Используйте agents.defaults.cliBackends.claude-cli.command только когда бинарный файл claude еще не находится в PATH.

Сессии

  • Если CLI поддерживает сессии, задайте sessionArg (например, --session-id) или sessionArgs (заполнитель {sessionId}), когда идентификатор нужно вставить в несколько флагов.
  • Если CLI использует подкоманду resume с другими флагами, задайте resumeArgs (заменяет args при возобновлении) и при необходимости resumeOutput (для возобновлений не в JSON).
  • sessionMode:
    • always: всегда отправлять идентификатор сессии (новый UUID, если сохраненного нет).
    • existing: отправлять идентификатор сессии только если он был сохранен ранее.
    • none: никогда не отправлять идентификатор сессии.
  • claude-cli по умолчанию использует liveSession: "claude-stdio", output: "jsonl", и input: "stdin", поэтому последующие ходы повторно используют активный процесс Claude, пока он активен. Warm stdio теперь используется по умолчанию, в том числе для пользовательских конфигураций, которые опускают поля транспорта. Если Gateway перезапускается или бездействующий процесс завершается, OpenClaw возобновляет работу из сохраненного идентификатора сессии Claude. Сохраненные идентификаторы сессий проверяются по существующему читаемому транскрипту проекта перед возобновлением, поэтому фантомные привязки очищаются с reason=transcript-missing вместо тихого запуска новой сессии Claude CLI под --resume.
  • Активные сессии Claude сохраняют ограниченные предохранители вывода JSONL. Значения по умолчанию допускают до 8 MiB и 20 000 необработанных строк JSONL на ход. Ходы Claude с большим количеством инструментов могут увеличить их для каждого бэкенда с помощью agents.defaults.cliBackends.claude-cli.reliability.outputLimits.maxTurnRawChars и maxTurnLines; OpenClaw ограничивает эти настройки 64 MiB и 100 000 строками.
  • Сохраненные CLI-сессии — это непрерывность, принадлежащая провайдеру. Неявный ежедневный сброс сессии их не прерывает; /reset и явные политики session.reset по-прежнему прерывают.
  • Новые CLI-сессии обычно повторно инициализируются только из сводки Compaction OpenClaw плюс хвоста после Compaction. Чтобы восстановить короткие сессии, которые инвалидируются до Compaction, бэкенд может явно включить reseedFromRawTranscriptWhenUncompacted: true. OpenClaw все равно ограничивает повторную инициализацию из необработанного транскрипта и применяет ее только к безопасным инвалидациям, таким как отсутствующие транскрипты CLI, изменения системного промпта/MCP или повторная попытка из-за истекшей сессии; изменения профиля аутентификации или эпохи учетных данных никогда не переинициализируют историю необработанного транскрипта.

Примечания по сериализации:

  • serialize: true сохраняет порядок запусков в одной lane.
  • Большинство CLI сериализуются на одной lane провайдера.
  • OpenClaw прекращает повторное использование сохраненной CLI-сессии, когда выбранная идентичность аутентификации меняется, включая измененный идентификатор профиля аутентификации, статический API-ключ, статический токен или идентичность учетной записи OAuth, если CLI ее предоставляет. Ротация токенов доступа и обновления OAuth не прерывает сохраненную CLI-сессию. Если CLI не предоставляет стабильный идентификатор учетной записи OAuth, OpenClaw позволяет этой CLI самостоятельно применять разрешения на возобновление.

Резервная прелюдия из сессий claude-cli

Когда попытка claude-cli переключается на кандидата не-CLI из agents.defaults.model.fallbacks, OpenClaw заполняет следующую попытку контекстной прелюдией, полученной из локального JSONL-транскрипта Claude Code в ~/.claude/projects/. Без этого начального контекста резервный провайдер стартовал бы с пустого состояния, потому что собственный транскрипт сессии OpenClaw пуст для запусков claude-cli.

  • Прелюдия предпочитает последнюю сводку /compact или маркер compact_boundary, затем добавляет последние ходы после границы до лимита символов. Ходы до границы отбрасываются, потому что сводка уже представляет их.
  • Блоки инструментов объединяются в компактные подсказки (tool call: name) и (tool result: …), чтобы честно расходовать бюджет промпта. Сводка помечается (truncated), если она переполняется.
  • Резервные переходы с claude-cli на claude-cli у того же провайдера полагаются на собственный --resume Claude и пропускают прелюдию.
  • Начальный контекст повторно использует существующую проверку пути к файлу сессии Claude, поэтому произвольные пути не могут быть прочитаны.

Изображения (сквозная передача)

Если ваша CLI принимает пути к изображениям, задайте imageArg:

json5
imageArg: "--image",imageMode: "repeat"

OpenClaw запишет изображения base64 во временные файлы. Если imageArg задан, эти пути передаются как аргументы CLI. Если imageArg отсутствует, OpenClaw добавляет пути к файлам в промпт (инъекция пути), чего достаточно для CLI, которые автоматически загружают локальные файлы из обычных путей.

Входы / выходы

  • output: "json" (по умолчанию) пытается разобрать JSON и извлечь текст + идентификатор сессии.
  • Для JSON-вывода Gemini CLI OpenClaw читает текст ответа из response, а usage из stats, когда usage отсутствует или пуст. Встроенное значение по умолчанию Gemini CLI использует stream-json, но старые переопределения --output-format json все еще используют JSON-парсер.
  • output: "jsonl" разбирает потоки JSONL и извлекает итоговое сообщение агента плюс идентификаторы сессии, если они присутствуют.
  • output: "text" считает stdout итоговым ответом.

Режимы ввода:

  • input: "arg" (по умолчанию) передает промпт как последний аргумент CLI.
  • input: "stdin" отправляет промпт через stdin.
  • Если промпт очень длинный и задан maxPromptArgChars, используется stdin.

Значения по умолчанию (принадлежат plugin)

Значения по умолчанию для встроенных CLI-бэкендов находятся у владеющего ими plugin. Например, Anthropic владеет claude-cli, а Google владеет google-gemini-cli. Запуски агента OpenAI Codex используют harness app-server Codex через openai/*; OpenClaw больше не регистрирует встроенный бэкенд codex-cli.

Встроенный plugin Anthropic регистрирует значение по умолчанию для claude-cli:

  • command: "claude"
  • args: ["-p","--output-format","stream-json","--include-partial-messages","--verbose", ...]
  • output: "jsonl"
  • input: "stdin"
  • modelArg: "--model"
  • sessionMode: "always"

Встроенный plugin Google также регистрирует значение по умолчанию для google-gemini-cli:

  • command: "gemini"
  • args: ["--skip-trust", "--approval-mode", "auto_edit", "--output-format", "stream-json", "--prompt", "{prompt}"]
  • resumeArgs: ["--skip-trust", "--approval-mode", "auto_edit", "--resume", "{sessionId}", "--output-format", "stream-json", "--prompt", "{prompt}"]
  • output: "jsonl"
  • resumeOutput: "jsonl"
  • jsonlDialect: "gemini-stream-json"
  • imageArg: "@"
  • imagePathScope: "workspace"
  • modelArg: "--model"
  • sessionMode: "existing"
  • sessionIdFields: ["session_id", "sessionId"]

Предварительное требование: локальный Gemini CLI должен быть установлен и доступен как gemini в PATH (brew install gemini-cli или npm install -g @google/gemini-cli).

Примечания по выводу Gemini CLI:

  • Парсер stream-json по умолчанию читает события message ассистента, события инструментов, итоговое использование result и фатальные события ошибок Gemini.
  • Если вы переопределяете аргументы Gemini на --output-format json, OpenClaw нормализует этот бэкенд обратно к output: "json" и читает текст ответа из поля JSON response.
  • Если usage отсутствует или пуст, использование берется из stats.
  • stats.cached нормализуется в cacheRead OpenClaw.
  • Если stats.input отсутствует, OpenClaw вычисляет входные токены из stats.input_tokens - stats.cached.

Переопределяйте только при необходимости (частый случай: абсолютный путь command).

Значения по умолчанию, принадлежащие plugin

Значения по умолчанию CLI-бэкендов теперь являются частью поверхности plugin:

  • Plugins регистрируют их через api.registerCliBackend(...).
  • id бэкенда становится префиксом провайдера в ссылках на модели.
  • Пользовательская конфигурация в agents.defaults.cliBackends.<id> по-прежнему переопределяет значение по умолчанию plugin.
  • Очистка конфигурации, специфичная для бэкенда, остается в собственности plugin через необязательный хук normalizeConfig.

Plugins, которым нужны небольшие shim-слои совместимости промптов/сообщений, могут объявлять двунаправленные текстовые преобразования без замены провайдера или CLI-бэкенда:

typescript
api.registerTextTransforms({  input: [    { from: /red basket/g, to: "blue basket" },    { from: /paper ticket/g, to: "digital ticket" },    { from: /left shelf/g, to: "right shelf" },  ],  output: [    { from: /blue basket/g, to: "red basket" },    { from: /digital ticket/g, to: "paper ticket" },    { from: /right shelf/g, to: "left shelf" },  ],});

input переписывает системный промпт и пользовательский промпт, передаваемые в CLI. output переписывает потоковые дельты ассистента и разобранный итоговый текст до того, как OpenClaw обработает собственные управляющие маркеры и доставку в канал.

Для CLI, которые выдают JSONL-события, специфичные для провайдера, задайте jsonlDialect в конфигурации этого бэкенда. Поддерживаемые диалекты: claude-stream-json для потоков, совместимых с Claude Code, и gemini-stream-json для событий Gemini CLI stream-json.

Владение нативной Compaction

Некоторые CLI-бэкенды запускают агента, который сжимает собственный транскрипт, поэтому OpenClaw не должен запускать для них свой защитный суммаризатор - это конфликтует с собственной compaction бэкенда и может привести к жесткому сбою хода.

У claude-cli нет endpoint harness - Claude Code сжимает внутренне, - поэтому он объявляет ownsNativeCompaction: true, а OpenClaw возвращает no-op из пути compaction. Сессии native-harness, такие как Codex, вместо этого продолжают маршрутизироваться на endpoint compaction своего harness.

Поскольку бэкенд владеет compaction, старый временный обходной путь с установкой contextTokens: 1_000_000 только для того, чтобы защитный механизм OpenClaw не срабатывал на сессии claude-cli, больше не нужен - его заменяет opt-out.

typescript
api.registerCliBackend({ id: "my-cli", ownsNativeCompaction: true /* ... */ });

Объявляйте ownsNativeCompaction только для бэкенда, который действительно владеет своей compaction: он должен надежно ограничивать собственный транскрипт по мере приближения к своему контекстному окну и сохранять возобновляемую сессию (например, --resume / --session-id); иначе отложенная сессия может оставаться сверх бюджета. Сессии с совпадающим agentHarnessId по-прежнему маршрутизируются на endpoint harness.

Наложения Bundle MCP

CLI-бэкенды не получают вызовы инструментов OpenClaw напрямую, но бэкенд может подключиться к сгенерированному наложению конфигурации MCP с помощью bundleMcp: true.

Текущее встроенное поведение:

  • claude-cli: сгенерированный строгий файл конфигурации MCP
  • google-gemini-cli: сгенерированный файл системных настроек Gemini

Когда bundle MCP включен, OpenClaw:

  • запускает loopback HTTP MCP-сервер, который предоставляет gateway-инструменты процессу CLI
  • аутентифицирует мост с помощью токена на сессию (OPENCLAW_MCP_TOKEN)
  • ограничивает доступ к инструментам текущей сессией, учетной записью и контекстом канала
  • загружает включенные bundle-MCP-серверы для текущей рабочей области
  • объединяет их с любой существующей формой MCP-конфигурации/настроек бэкенда
  • переписывает конфигурацию запуска, используя режим интеграции, принадлежащий бэкенду, из владеющего расширения

Если MCP-серверы не включены, OpenClaw все равно внедряет строгую конфигурацию, когда бэкенд подключается к bundle MCP, чтобы фоновые запуски оставались изолированными.

Сессионные встроенные среды выполнения MCP кэшируются для повторного использования в рамках сессии, затем очищаются после mcp.sessionIdleTtlMs миллисекунд простоя (по умолчанию 10 минут; задайте 0, чтобы отключить). Одноразовые embedded-запуски, такие как пробы аутентификации, генерация slug и active-memory recall, запрашивают очистку в конце запуска, чтобы stdio-потомки и потоки Streamable HTTP/SSE не жили дольше запуска.

Ограничение истории при reseed

Когда новая CLI-сессия заполняется из предыдущего транскрипта OpenClaw (например после повторной попытки session_expired), отрисованный блок <conversation_history> ограничивается, чтобы reseed-промпты не разрастались чрезмерно. Значение по умолчанию: 12288 символов (около 3000 токенов).

Бэкенды Claude CLI автоматически используют больший лимит, производный от разрешенного уровня контекста Claude. Стандартные запуски Claude с 200K токенов сохраняют больший фрагмент транскрипта, а запуски Claude с 1M токенов сохраняют еще больший фрагмент, тогда как другие CLI- бэкенды сохраняют консервативное значение по умолчанию.

  • Лимит управляет только блоком предыдущей истории в reseed-промпте. Лимиты вывода live-сессии настраиваются отдельно в reliability.outputLimits (см. Сессии).

Ограничения

  • Нет прямых вызовов инструментов OpenClaw. OpenClaw не внедряет вызовы инструментов в протокол CLI-бэкенда. Бэкенды видят gateway-инструменты только при подключении к bundleMcp: true.
  • Streaming зависит от бэкенда. Некоторые бэкенды транслируют JSONL; другие буферизуют до завершения.
  • Структурированные выводы зависят от JSON-формата CLI.

Устранение неполадок

  • CLI не найден: задайте command полным путем.
  • Неверное имя модели: используйте modelAliases, чтобы сопоставить provider/model → модель CLI.
  • Нет непрерывности сессии: убедитесь, что sessionArg задан и sessionMode не равен none.
  • Изображения игнорируются: задайте imageArg (и проверьте, что CLI поддерживает пути к файлам).

Связанные материалы

Was this useful?
On this page

On this page