Gateway

CLI 백엔드

OpenClaw는 API 제공자가 중단되었거나, 속도 제한에 걸렸거나, 일시적으로 오작동할 때 로컬 AI CLI텍스트 전용 대체 경로로 실행할 수 있습니다. 이는 의도적으로 보수적인 방식입니다:

  • OpenClaw 도구는 직접 주입되지 않지만, bundleMcp: true인 백엔드는 루프백 MCP 브리지를 통해 Gateway 도구를 받을 수 있습니다.
  • 이를 지원하는 CLI를 위한 JSONL 스트리밍.
  • 세션이 지원됩니다(따라서 후속 턴이 일관성을 유지합니다).
  • CLI가 이미지 경로를 받는 경우 이미지를 전달할 수 있습니다.

이는 기본 경로가 아니라 안전망으로 설계되었습니다. 외부 API에 의존하지 않고 "항상 작동하는" 텍스트 응답을 원할 때 사용하세요.

ACP 세션 제어, 백그라운드 작업, 스레드/대화 바인딩, 지속되는 외부 코딩 세션이 있는 전체 하네스 런타임을 원한다면 대신 ACP 에이전트를 사용하세요. CLI 백엔드는 ACP가 아닙니다.

초보자 친화적 빠른 시작

Claude Code CLI는 아무 구성 없이 사용할 수 있습니다(번들 Anthropic Plugin이 기본 백엔드를 등록합니다):

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

명시적인 에이전트 목록이 구성되어 있지 않으면 main이 기본 에이전트 ID입니다. 여러 에이전트를 사용하는 경우 실행하려는 에이전트 ID로 바꾸세요.

Gateway가 launchd/systemd 아래에서 실행되고 PATH가 최소화되어 있다면 명령 경로만 추가하세요:

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

이것으로 충분합니다. CLI 자체 외에는 키나 추가 인증 구성이 필요하지 않습니다.

Gateway 호스트에서 번들 CLI 백엔드를 기본 메시지 제공자로 사용하는 경우, 이제 구성에서 모델 참조나 agents.defaults.cliBackends 아래에 해당 백엔드를 명시적으로 참조하면 OpenClaw가 소유 번들 Plugin을 자동으로 로드합니다.

대체 경로로 사용하기

기본 모델이 실패할 때만 실행되도록 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

각 항목은 제공자 ID(예: claude-cli, my-cli)를 키로 사용합니다. 제공자 ID는 모델 참조의 왼쪽이 됩니다:

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. 지원되는 경우 세션 ID와 함께 CLI를 실행하여 기록이 일관되게 유지되도록 합니다. 번들 claude-cli 백엔드는 OpenClaw 세션마다 Claude stdio 프로세스를 유지하고 stream-json stdin을 통해 후속 턴을 보냅니다.
  4. 출력을 파싱하고(JSON 또는 일반 텍스트) 최종 텍스트를 반환합니다.
  5. 백엔드별로 세션 ID를 유지하여 후속 턴이 동일한 CLI 세션을 재사용하도록 합니다.

번들 Anthropic claude-cli 백엔드는 OpenClaw Skills에 대해 Claude Code의 네이티브 skill 리졸버를 우선합니다. 현재 Skills 스냅샷에 구체화된 경로가 있는 선택된 skill이 하나 이상 포함되어 있으면 OpenClaw는 --plugin-dir로 임시 Claude Code Plugin을 전달하고, 추가된 시스템 프롬프트에서 중복 OpenClaw Skills 카탈로그를 생략합니다. 스냅샷에 구체화된 Plugin skill이 없으면 OpenClaw는 프롬프트 카탈로그를 대체 경로로 유지합니다. Skill env/API 키 오버라이드는 여전히 OpenClaw가 해당 실행의 자식 프로세스 환경에 적용합니다.

Claude CLI에는 자체 비대화형 권한 모드도 있습니다. OpenClaw는 Claude 전용 정책 구성을 추가하는 대신 이를 기존 exec 정책에 매핑합니다. OpenClaw가 관리하는 Claude 라이브 세션에서는 유효한 OpenClaw exec 정책이 권한의 기준입니다: YOLO(tools.exec.security: "full"tools.exec.ask: "off")는 --permission-mode bypassPermissions로 Claude를 실행하며, 제한적인 유효 exec 정책은 --permission-mode default로 Claude를 실행합니다. 에이전트별 agents.list[].tools.exec 설정은 해당 에이전트에 대해 전역 tools.exec를 재정의합니다. 원시 Claude 백엔드 args에는 여전히 --permission-mode가 포함될 수 있지만, 라이브 Claude 실행은 해당 플래그를 유효한 OpenClaw exec 정책과 일치하도록 정규화합니다.

번들 Anthropic claude-cli 백엔드는 OpenClaw /think 수준도 꺼짐이 아닌 수준에 대해 Claude Code의 네이티브 --effort 플래그에 매핑합니다. minimallowlow에 매핑되고, adaptivemediummedium에 매핑되며, high, xhigh, max는 직접 매핑됩니다. 다른 CLI 백엔드는 /think가 생성되는 CLI에 영향을 줄 수 있으려면 소유 Plugin이 동등한 argv 매퍼를 선언해야 합니다.

OpenClaw가 번들 claude-cli 백엔드를 사용하려면 먼저 Claude Code 자체가 같은 호스트에 이미 로그인되어 있어야 합니다:

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

Docker 설치에서는 호스트뿐 아니라 지속되는 컨테이너 홈 내부에도 Claude Code가 설치되어 있고 로그인되어 있어야 합니다. Docker의 Claude CLI 백엔드를 참조하세요.

claude 바이너리가 아직 PATH에 없을 때만 agents.defaults.cliBackends.claude-cli.command를 사용하세요.

세션

  • CLI가 세션을 지원하는 경우 ID를 여러 플래그에 삽입해야 하면 sessionArg(예: --session-id) 또는 sessionArgs(플레이스홀더 {sessionId})를 설정하세요.
  • CLI가 다른 플래그를 사용하는 resume 하위 명령을 사용한다면 resumeArgs(재개 시 args를 대체)와 선택적으로 resumeOutput (비 JSON 재개용)을 설정하세요.
  • sessionMode:
    • always: 항상 세션 ID를 보냅니다(저장된 값이 없으면 새 UUID).
    • existing: 이전에 저장된 세션 ID가 있을 때만 보냅니다.
    • none: 세션 ID를 보내지 않습니다.
  • claude-cli의 기본값은 liveSession: "claude-stdio", output: "jsonl", input: "stdin"이므로 후속 턴은 활성 상태인 동안 라이브 Claude 프로세스를 재사용합니다. 이제 전송 필드를 생략하는 사용자 지정 구성도 포함하여 warm stdio가 기본값입니다. Gateway가 다시 시작되거나 유휴 프로세스가 종료되면 OpenClaw는 저장된 Claude 세션 ID에서 재개합니다. 저장된 세션 ID는 재개 전에 읽을 수 있는 기존 프로젝트 트랜스크립트와 대조해 검증되므로, 가짜 바인딩은 --resume 아래에서 조용히 새 Claude CLI 세션을 시작하는 대신 reason=transcript-missing으로 정리됩니다.
  • Claude 라이브 세션은 제한된 JSONL 출력 가드를 유지합니다. 기본값은 턴당 최대 8 MiB 및 원시 JSONL 20,000줄을 허용합니다. 도구 사용이 많은 Claude 턴은 백엔드별로 agents.defaults.cliBackends.claude-cli.reliability.outputLimits.maxTurnRawCharsmaxTurnLines를 사용해 이를 높일 수 있습니다. OpenClaw는 해당 설정을 64 MiB 및 100,000줄로 제한합니다.
  • 저장된 CLI 세션은 제공자가 소유하는 연속성입니다. 암묵적인 일일 세션 재설정은 이를 끊지 않지만, /reset 및 명시적인 session.reset 정책은 여전히 끊습니다.
  • 새 CLI 세션은 일반적으로 OpenClaw의 Compaction 요약과 Compaction 이후 꼬리 부분에서만 다시 시드합니다. Compaction 전에 무효화된 짧은 세션을 복구하려면 백엔드가 reseedFromRawTranscriptWhenUncompacted: true로 옵트인할 수 있습니다. OpenClaw는 여전히 원시 트랜스크립트 재시드를 제한하고, CLI 트랜스크립트 누락, 시스템 프롬프트/MCP 변경, 세션 만료 재시도 같은 안전한 무효화로만 제한합니다. 인증 프로필이나 자격 증명 epoch 변경은 원시 트랜스크립트 기록을 다시 시드하지 않습니다.

직렬화 참고:

  • serialize: true는 같은 레인 실행의 순서를 유지합니다.
  • 대부분의 CLI는 하나의 제공자 레인에서 직렬화됩니다.
  • OpenClaw는 선택된 인증 ID가 변경되면 저장된 CLI 세션 재사용을 중단합니다. 여기에는 변경된 인증 프로필 ID, 정적 API 키, 정적 토큰, 또는 CLI가 노출하는 경우 OAuth 계정 ID가 포함됩니다. OAuth 액세스 및 갱신 토큰 회전은 저장된 CLI 세션을 끊지 않습니다. CLI가 안정적인 OAuth 계정 ID를 노출하지 않으면 OpenClaw는 해당 CLI가 재개 권한을 강제하도록 둡니다.

claude-cli 세션의 대체 prelude

claude-cli 시도가 agents.defaults.model.fallbacks의 비 CLI 후보로 넘어가면, OpenClaw는 ~/.claude/projects/의 Claude Code 로컬 JSONL 트랜스크립트에서 수집한 컨텍스트 prelude로 다음 시도를 시드합니다. 이 시드가 없으면 claude-cli 실행에 대해 OpenClaw 자체 세션 트랜스크립트가 비어 있으므로 대체 제공자는 콜드 스타트하게 됩니다.

  • prelude는 최신 /compact 요약 또는 compact_boundary 마커를 우선 사용한 다음, 문자 예산까지 가장 최근의 경계 이후 턴을 덧붙입니다. 경계 이전 턴은 요약이 이미 이를 대표하므로 버립니다.
  • 도구 블록은 프롬프트 예산을 정확하게 유지하기 위해 간결한 (tool call: name)(tool result: …) 힌트로 병합됩니다. 요약이 초과되면 (truncated)로 표시됩니다.
  • 같은 제공자의 claude-cli에서 claude-cli로 넘어가는 대체 경로는 Claude 자체의 --resume에 의존하며 prelude를 건너뜁니다.
  • 시드는 기존 Claude 세션 파일 경로 검증을 재사용하므로 임의의 경로를 읽을 수 없습니다.

이미지(전달)

CLI가 이미지 경로를 받는 경우 imageArg를 설정하세요:

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

OpenClaw는 base64 이미지를 임시 파일에 씁니다. imageArg가 설정되어 있으면 해당 경로가 CLI args로 전달됩니다. imageArg가 없으면 OpenClaw는 파일 경로를 프롬프트에 추가합니다(경로 주입). 이는 일반 경로에서 로컬 파일을 자동으로 로드하는 CLI에 충분합니다.

입력 / 출력

  • output: "json"(기본값)은 JSON을 파싱하고 텍스트와 세션 ID를 추출하려고 시도합니다.
  • Gemini CLI JSON 출력의 경우 usage가 없거나 비어 있으면 OpenClaw는 response에서 응답 텍스트를, stats에서 사용량을 읽습니다. 번들 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 에이전트 실행은 openai/*를 통해 Codex 앱 서버 하네스를 사용합니다. OpenClaw는 더 이상 번들 codex-cli 백엔드를 등록하지 않습니다.

번들 Anthropic Plugin은 claude-cli에 대한 기본값을 등록합니다.

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

번들 Google Plugin도 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가 설치되어 있어야 하며 PATH에서 gemini로 사용할 수 있어야 합니다(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는 OpenClaw cacheRead로 정규화됩니다.
  • stats.input이 누락된 경우 OpenClaw는 stats.input_tokens - stats.cached에서 입력 토큰을 도출합니다.

필요한 경우에만 재정의하세요(일반적으로 절대 command 경로).

Plugin 소유 기본값

CLI 백엔드 기본값은 이제 Plugin 표면의 일부입니다.

  • Plugin은 api.registerCliBackend(...)로 이를 등록합니다.
  • 백엔드 id는 모델 참조에서 제공자 접두사가 됩니다.
  • agents.defaults.cliBackends.<id>의 사용자 구성은 여전히 Plugin 기본값을 재정의합니다.
  • 백엔드별 구성 정리는 선택적 normalizeConfig 훅을 통해 Plugin 소유로 유지됩니다.

작은 프롬프트/메시지 호환성 shim이 필요한 Plugin은 제공자나 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가 자체 제어 마커와 채널 전달을 처리하기 전에 스트리밍된 어시스턴트 텍스트와 파싱된 최종 텍스트를 다시 작성합니다. 제공자 기반 모델 호출의 경우, output은 스트림 복구 후 도구 실행 전에 구조화된 도구 호출 인수 내부의 문자열 값도 복원합니다. 원시 제공자 JSON 조각은 변경되지 않습니다. 소비자는 구조화된 부분, 종료 또는 결과 페이로드를 사용해야 합니다.

제공자별 JSONL 이벤트를 내보내는 CLI의 경우 해당 백엔드 구성에 jsonlDialect를 설정하세요. 지원되는 방언은 Claude Code 호환 스트림용 claude-stream-json과 Gemini CLI stream-json 이벤트용 gemini-stream-json입니다.

네이티브 Compaction 소유권

일부 CLI 백엔드는 자체 트랜스크립트를 압축하는 에이전트를 실행하므로 OpenClaw는 그들에 대해 안전장치 요약기를 실행해서는 안 됩니다. 그렇게 하면 백엔드 자체의 Compaction과 충돌하고 턴이 하드 실패할 수 있습니다.

claude-cli에는 하네스 엔드포인트가 없습니다. Claude Code가 내부적으로 Compaction하므로 ownsNativeCompaction: true를 선언하며, OpenClaw는 Compaction 경로에서 no-op을 반환합니다. Codex와 같은 네이티브 하네스 세션은 대신 해당 하네스 Compaction 엔드포인트로 계속 라우팅됩니다.

백엔드가 Compaction을 소유하므로, 순전히 OpenClaw의 안전장치가 claude-cli 세션에서 발동하지 않게 하려고 contextTokens: 1_000_000을 설정하던 오래된 임시방편은 더 이상 필요하지 않습니다. 옵트아웃이 이를 대체합니다.

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

ownsNativeCompaction은 실제로 Compaction을 소유한 백엔드에만 선언하세요. 해당 백엔드는 컨텍스트 창에 가까워질 때 자체 트랜스크립트의 크기를 안정적으로 제한하고 재개 가능한 세션(예: --resume / --session-id)을 유지해야 합니다. 그렇지 않으면 지연된 세션이 예산을 초과한 상태로 남을 수 있습니다. 일치하는 agentHarnessId 세션은 여전히 하네스 엔드포인트로 라우팅됩니다.

번들 MCP 오버레이

CLI 백엔드는 OpenClaw 도구 호출을 직접 받지 않지만, 백엔드는 bundleMcp: true로 생성된 MCP 구성 오버레이를 선택할 수 있습니다.

현재 번들 동작:

  • claude-cli: 생성된 엄격한 MCP 구성 파일
  • google-gemini-cli: 생성된 Gemini 시스템 설정 파일

번들 MCP가 활성화되면 OpenClaw는 다음을 수행합니다.

  • Gateway 도구를 CLI 프로세스에 노출하는 루프백 HTTP MCP 서버를 생성합니다.
  • 세션별 토큰(OPENCLAW_MCP_TOKEN)으로 브리지를 인증합니다.
  • 도구 액세스를 현재 세션, 계정, 채널 컨텍스트로 범위 지정합니다.
  • 현재 작업공간에 활성화된 번들 MCP 서버를 로드합니다.
  • 기존 백엔드 MCP 구성/설정 형태와 병합합니다.
  • 소유 확장의 백엔드 소유 통합 모드를 사용하여 시작 구성을 다시 작성합니다.

MCP 서버가 활성화되지 않은 경우에도 백엔드가 번들 MCP를 선택하면 OpenClaw는 백그라운드 실행이 격리된 상태를 유지하도록 엄격한 구성을 주입합니다.

세션 범위의 번들 MCP 런타임은 세션 내 재사용을 위해 캐시된 다음, 유휴 시간이 mcp.sessionIdleTtlMs밀리초(기본값 10 분, 비활성화하려면 0 설정)를 지나면 정리됩니다. 인증 프로브, 슬러그 생성, Active Memory recall과 같은 일회성 임베디드 실행은 실행 종료 시 정리를 요청하여 stdio 자식 프로세스와 Streamable HTTP/SSE 스트림이 실행보다 오래 살아남지 않도록 합니다.

재시드 기록 한도

새 CLI 세션이 이전 OpenClaw 트랜스크립트에서 시드될 때(예: session_expired 재시도 후), 렌더링되는 <conversation_history> 블록은 재시드 프롬프트가 폭증하지 않도록 제한됩니다. 기본값은 12288자(약 3000토큰)입니다.

Claude CLI 백엔드는 확인된 Claude 컨텍스트 티어에서 도출된 더 큰 한도를 자동으로 사용합니다. 표준 200K 토큰 Claude 실행은 더 큰 트랜스크립트 슬라이스를 유지하고, 1M 토큰 Claude 실행은 다시 더 큰 슬라이스를 유지하는 반면, 다른 CLI 백엔드는 보수적인 기본값을 유지합니다.

  • 이 한도는 재시드 프롬프트의 이전 기록 블록에만 적용됩니다. 라이브 세션 출력 한도는 reliability.outputLimits 아래에서 별도로 조정됩니다 (세션 참조).

제한 사항

  • 직접 OpenClaw 도구 호출 없음. OpenClaw는 CLI 백엔드 프로토콜에 도구 호출을 주입하지 않습니다. 백엔드는 bundleMcp: true를 선택한 경우에만 Gateway 도구를 봅니다.
  • 스트리밍은 백엔드별로 다릅니다. 일부 백엔드는 JSONL을 스트리밍하고, 다른 백엔드는 종료될 때까지 버퍼링합니다.
  • 구조화된 출력은 CLI의 JSON 형식에 따라 달라집니다.

문제 해결

  • CLI를 찾을 수 없음: command를 전체 경로로 설정하세요.
  • 잘못된 모델 이름: modelAliases를 사용하여 provider/model → CLI 모델을 매핑하세요.
  • 세션 연속성 없음: sessionArg가 설정되어 있고 sessionModenone이 아닌지 확인하세요.
  • 이미지가 무시됨: imageArg를 설정하세요(CLI가 파일 경로를 지원하는지도 확인하세요).

관련 항목

Was this useful?
On this page

On this page