跳转至

CLI 后端

OpenClaw 可以在 API 提供商宕机、限流或行为异常时,运行本地 AI CLI 作为纯文本回退。它有意保持保守:

  • 不会直接注入 OpenClaw 工具,但配置了 bundleMcp: true 的后端可以通过回环 MCP 桥接接收 Gateway 工具。
  • 对于支持 JSONL 流式的 CLI,提供 JSONL 流式输出。
  • 支持会话,因此后续轮次可以保持连贯。
  • 如果 CLI 接受图像路径,图像会直接透传。

将其用作“始终可用”的文本响应安全网,而不是主要路径。对于具有 ACP 会话控制、后台任务、线程/会话绑定以及持久化外部编码会话的完整 harness 运行时,请改用 ACP Agents。CLI 后端不是 ACP。

Tip

正在构建新的后端插件?请参见 CLI 后端插件。本页介绍如何配置和操作已注册的后端。

快速开始

捆绑的 Anthropic 插件会注册默认的 claude-cli 后端,因此除了安装并登录 Claude Code 之外,无需任何配置即可使用:

openclaw agent --agent main --message "hi" --model claude-cli/claude-sonnet-5

在未配置显式代理列表时,main 是默认代理 id。否则请替换为你自己的代理 id。

Gateway 服务必须在其 PATH 中拥有该 CLI。如果部署需要非标准可执行文件路径或参数,请在 CLI 后端插件 中注册该适配器,而不是将启动机制放在 openclaw.json 中。

当模型选择或模型范围的 agentRuntime.id 引用其后端时,OpenClaw 会自动加载所属的捆绑插件。

用于会话摘要、进度叙述和工具调用标题的实用补全也会使用所选模型的运行时。Claude CLI 会使用其自身的身份验证运行一次全新的、无工具的补全。这包括配置了 agentRuntime.id: "claude-cli" 的规范 anthropic/* 引用。

将其用作回退

将 CLI 后端添加到你的回退列表中,使其仅在主要模型失败时运行:

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

当主要提供商失败(身份验证、速率限制、超时)时,已配置的回退项仍然可用,即使它们不在 agents.defaults.modelPolicy.allow 中。只有当用户也应能直接选择 CLI 后端模型时,才将其添加到该策略中。直接选择是指 /model、会话覆盖或 --model。agents.defaults.models 仅负责每个模型的别名、参数和元数据。

配置

用户通过模型和运行时策略选择已注册的后端。请保持模型引用规范,并按模型选择 CLI 运行时:

{
  agents: {
    defaults: {
      model: "anthropic/claude-opus-5-5",
      models: {
        "anthropic/claude-opus-5-5": {
          agentRuntime: { id: "claude-cli" },
        },
      },
    },
  },
}

凭据仍保留在 OpenClaw 身份验证配置文件或所属插件的配置中。命令、argv、环境、解析、会话、图像和看门机机制都是使用 api.registerCliBackend(...) 注册的插件代码。

工作原理

  1. 根据提供商前缀(claude-cli/...)选择后端。
  2. 使用相同的 OpenClaw 提示和工作区上下文构建系统提示。
  3. 使用会话 id(如果支持)执行 CLI,以保持历史记录一致。捆绑的 claude-cli 后端直接与已安装的 Claude Code 可执行文件通信,并在兼容的代理轮次之间保持其已认证子进程处于热状态。
  4. 解析输出(JSON 或纯文本)并返回最终文本。
  5. 按后端持久化会话 id,以便后续请求复用同一 CLI 会话。

超时与长时间运行的任务

CLI 后端有两个独立的限制:

  • agents.defaults.timeoutSeconds 限制整个代理轮次。普通 Gateway 轮次继承 48 小时默认值。0 表示轮次预算无限制。存储的覆盖值(例如 600)会替换该默认值。
  • CLI 无输出看门机会停止保持静默的子进程。每个后端插件拥有独立的新建/恢复配置文件,即使整体轮次预算无限制,看门机仍然保持活动。

移除较短的整体超时覆盖值以恢复 48 小时默认值,或设置明确的预算(例如 12 小时):

# Return to the 48-hour default:
openclaw config unset agents.defaults.timeoutSeconds

# Or choose an explicit 12-hour limit:
openclaw config set agents.defaults.timeoutSeconds 43200

在 CLI 内部启动的后台工作仍然是该 CLI 子进程的一部分。如果父轮次达到其整体限制,OpenClaw 会同时停止该子进程及其 CLI 内部后台任务。对于需要持久化的长时间任务,请使用分离的 OpenClaw 子代理 或 ACP 代理。分离的子代理默认没有运行超时。

当 Claude Code 在工具超时后将前台 Bash 命令移到后台时,OpenClaw 会保持该轮次处于活动状态,直到 Claude 处理完成并返回最终答案。后续工具仍需要当前轮次的主机权限。显式在后台启动的命令不会保持轮次打开。如果其中一个命令仍需要后续处理时轮次失败或被取消,OpenClaw 会关闭该子进程,并为下一轮次启动一个全新的子进程。

在原生后台代理或工作流继续运行时,已完成的 Claude 答案可以通过正常回复管道到达通道,而无需等待后续处理完成。即使禁用原始预览和块流式传输,这也有效。已交付的答案片段不会在最终结算时再次发送;失败的交付仍符合重试条件。交付答案不会结束已接受的轮次,也不会为其后台工作授予另一轮次的权限。

openclaw agent 命令也有自己的请求截止时间。其 600 秒回退默认值适用于该命令调用,而不是普通 Gateway 轮次。参见 openclaw agent。

Claude CLI 细节

内置 Anthropic 插件通过其结构化 stdio 协议直接与已安装的 Claude Code 可执行文件通信。Claude Code 拥有其现有的本地登录和 订阅。OpenClaw 使用非机密路由标记。它从不读取、持久化、 刷新或转发原生令牌,也不发送合成的 Anthropic API 请求。兼容的 agent 轮次共享一个热 Claude Code 子进程。 模型、系统提示或工具策略发生变化时,会启动 新的子进程。持久化的 Claude 会话 ID 在 Gateway 或子进程重启时仍可提供会话连续性。

对于本地插件管理的轮次,prompt-build hook 上下文保持私有:Claude 将其作为原生 hook 附件接收,而 OpenClaw 历史保留原始用户消息。 原生会话保留该上下文以便恢复。导入的可见历史和 跨提供商回退前言不会复制私有 hook 附件。

已保存的会话笔记也会作为引用参考数据到达新的和恢复的轮次。 OpenClaw 从当前重置/压缩窗口中重放符合条件的笔记, 包括框架在内的总限制为 2,000 个加权字符。 较新的笔记优先。被省略或截断的笔记会被标记。笔记可能会重复,因为 CLI 绑定不会跟踪原生会话已消费了哪些 OpenClaw 笔记。 瞬态运行时上下文以及被排除在模型上下文之外的笔记不会被重放。

保持 Claude Code 更新,尤其是当 OpenClaw 报告已安装的可执行文件不兼容时:

claude --version
claude update
# Restart the OpenClaw Gateway after updating.

内置 claude-cli 后端优先使用 Claude Code 的原生 skill 解析器。当当前 skills 快照中至少有一个已选 skill 具有已物化路径时,OpenClaw 通过 --plugin-dir 传递一个临时 Claude Code 插件。然后它会从附加的系统提示中省略重复的 OpenClaw skills 目录。如果没有已物化的插件 skill,OpenClaw 会保留提示目录作为回退。Skill 环境变量/API 密钥覆盖仍适用于本次运行的子进程环境。

OpenClaw 使用 CLAUDE_CODE_DISABLE_GIT_INSTRUCTIONS=1 禁用 Claude Code 内置的 Git 工作流说明和启动时 Git 状态快照。Claude Code 在进程恢复时会重建该快照,否则工作区编辑或提交 会使缓存的会话历史失效。Git 工具和工作区 说明仍然可用。这并不能防止在提示 更改、压缩、模型或思考更改或缓存过期后出现缓存未命中。

OpenClaw 始终以默认权限模式启动 Claude Code。 OpenClaw 的权限响应和 PreToolUse hook 使原生工具保持在 宿主控制之下,包括当用户或企业设置本会 预先批准调用时。原生请求在 exec 策略和批准之前通过规范的 before_tool_call 策略,并将原生工具名称和文件 参数投影到其 OpenClaw 等价项。每个 agent 和会话 限制仍然覆盖更广泛的全球策略。OpenClaw 拥有的 MCP 工具 仍由 Gateway 授权,而不是接收重复的原生 批准。其他 MCP 工具仍受宿主权限控制。

Claude 的原生 AskUserQuestion 使用 OpenClaw 的结构化问题流程。当 OpenClaw 拒绝格式错误的问题时,它会报告失败的字段和 约束,而不重复提交的文本,并要求 Claude 更正 该字段并重试。无效问题不会提示用户。如果用户 跳过有效问题,Claude 会改用其最佳判断继续。

当有效 exec ask 设置为 on-miss 或 always 时,OpenClaw 将 需要批准的原生或扩展工具请求中继到会话的 通道:允许一次 允许单次调用,始终允许 允许同一 热实时会话中的该工具名称,只要每个后续轮次的策略 和可用工具仍允许它,并且 拒绝、超时、无法到达的 批准路由或已关闭的轮次都会拒绝该调用。授权保存在内存中,在 该确切实时会话被替换时结束,并且从不应用于 Bash。从不 提示的策略保持其现有行为:security: "deny" 拒绝 每个请求,ask off 且安全级别低于完整安全时,会直接拒绝而不询问。

原生 Bash 与 exec 允许列表

当 ask: "on-miss" 时,claude-cli 后端会将原生 Bash 命令 与 agent 的 exec 允许列表 进行核对。例如:

openclaw approvals allowlist add --agent main /usr/local/bin/gog

OpenClaw 复用其 exec shell 评估器,仅当每个命令段都解析为显式允许列表中的二进制文件 并且可以完全分类和绑定时,才允许调用而不提示。 可执行文件可以是绝对路径,也可以通过 CLI 启动 PATH 解析,其中包含 agent 配置的 exec PATH 前置项。已批准的输入会固定 解析后的可执行文件路径。成功匹配会更新允许列表使用元数据。 可绑定的未命中会提示第一个未匹配段或分类 原因。批准绑定守卫无法绑定的命令,包括管道、 命令替换、子 shell、写入重定向和无法解析的语法, 在提示之前仍保持拒绝。环境变量前缀覆盖、shell 展开 以及 eval/exec/source 包装器不会自动允许。

ask: "always" 仍会对允许列表中的命令进行提示。security: "deny" 仍会拒绝,ask: "off" 保持上述行为。始终 允许 对 Bash 仍不可用,截断的 Bash 批准描述 仍会失败关闭。

这是应用于 Claude Code 将运行的命令的参数级策略, 而不是 OpenClaw 的沙箱化执行。Claude Code 拥有 cwd、PATH、环境 和沙箱化。当需要沙箱化执行时,请使用 配对节点 或带有 沙箱化 的嵌入式运行时。

Claude 浏览器工具和 1Password 登录

Claude Code 可以通过 Claude in Chrome 扩展 驱动 Chrome 浏览器,包括 1Password for Claude 凭据自动填充。内置后端不会启用它。注册一个 CLI 后端插件,该插件会为 claude-stream-json 方言后端的启动参数追加 --chrome。OpenClaw 在常规运行中保留已配置的 --chrome,并始终在具有受限工具策略的运行(例如侧边问题)中强制使用 --no-chrome。Chrome 窗口、扩展以及任何 1Password 审批提示都位于 Gateway 主机上。必须有人在该机器旁才能批准凭据使用。

后端将 OpenClaw 的 /think 级别映射到 Claude Code 的原生 --effort 标志:minimal/low -> low、medium -> medium,以及 high/xhigh/max 直接透传。对于允许固定思考预算的模型,它还会使用 MAX_THINKING_TOKENS 启动 Claude Code:off=0、minimal=1024、low=2048、medium=8192、high/xhigh=16384 以及 max=32768。正数固定预算会禁用自适应思考。需要自适应思考的模型会省略固定预算并继续使用 --effort。adaptive 会移除已配置的 effort 标志和固定预算环境变量覆盖,因此 Claude Code 会从自身环境、设置和模型默认值解析有效思考。其他 CLI 后端需要其所属插件在 /think 影响派生的 CLI 之前映射所选级别。

对于原生登录,请在 Gateway 主机上登录 Claude Code:

claude auth login
claude auth status --text
openclaw models auth login --provider anthropic --method cli --set-default

普通代理轮次也可以在不进行原生登录的情况下使用已保存的订阅令牌:

openclaw models auth paste-token --provider anthropic

新会话通过已配置的账户顺序选择已保存的订阅凭据,并通过受保护的文件描述符将其转发给 CLI。现有会话会保留其账户,直到你选择其他账户或移除其已保存的配置文件。显式账户选择和空账户顺序仍然具有权威性。为 anthropic 提供商保存的 API 密钥需要显式选择;它们不会自动替代原生订阅登录。

Docker 安装需要在持久化容器主目录内包含 Claude Code 和所选凭据,而不仅仅在主机上。参见 Docker 中的 Claude CLI 后端。

Gateway 服务必须在 PATH 中解析 claude。对于非标准路径,请注册一个小型包装器后端插件。

会话

  • 如果 CLI 支持会话,请设置 sessionArgs 并包含 {sessionId} 占位符(例如 ["--session-id", "{sessionId}"])。
  • 如果 CLI 使用带有不同标志的 resume 子命令,请设置 resumeArgs(恢复时替换 args),并可选地设置 resumeOutput 用于非 JSON 恢复。
  • sessionMode:
  • always:始终发送会话 ID(如果没有存储则使用新的 UUID)。
  • existing:仅当之前已存储会话 ID 时才发送会话 ID。
  • none:从不发送会话 ID。
  • claude-cli 默认使用 liveSession: "claude-stdio"、output: "jsonl" 和 input: "stdin"。所属的 Anthropic 插件会通过其直接 CLI 传输,为兼容的连续代理轮次保持一个 Claude Code 子进程处于热状态。如果 Gateway 重启或空闲进程退出,OpenClaw 会从存储的 Claude 会话 ID 恢复。存储的会话 ID 会在恢复前对照可读的项目转录进行验证。如果缺少转录,则会清除绑定(记录为 reason=transcript-missing),而不是在 --resume 下静默启动新会话。
  • 存储的 CLI 会话是由提供商拥有的连续性。默认禁用自动重置。/reset 以及显式的每日或空闲 session.reset 策略仍会切断它们。
  • 新的 CLI 会话可以在其独立账户边界与所选凭据匹配时,从规范会话 SQLite 数据库恢复 OpenClaw 历史。压缩后的恢复包括最新摘要、保留的消息以及活动分支上的后续轮次。后端可以通过 reseedFromRawTranscriptWhenUncompacted: true 选择加入压缩前的有界恢复,包括在其原生会话绑定被清除之后。恢复包括已保存的工具结果文本和错误标记。它不会执行过去的工具。当前用户轮次只发送一次,位于恢复的历史之外。
  • 带有调用方拥有的内存转录的辅助运行使用该历史用于钩子、有界会话笔记和新会话重新播种,包括压缩前的有意义历史。即使运行携带另一个会话的存储标识,空内存仍保持为空。上下文引擎维护会在辅助函数返回前重写同一内存,即使引擎请求后台维护。持久转录保留其后台维护路径。显式拥有的原生 CLI 绑定仍可以恢复。恢复的轮次会发送当前提示和有界会话笔记,而不重放对话历史。

当提示内容更改时,兼容的 CLI 会话可以在当前用户提示之前使用 OpenClaw 上下文笔记恢复。聊天历史首先将导入的 Claude 用户轮次与完整本地文本进行匹配,包括笔记的任何字面引用。如果未匹配,则忽略一个完全匹配的上下文笔记进行比较,因此同一轮次只出现一次。存储的转录文本和未匹配的导入轮次保持完整。

历史记录账户边界

原生会话兼容性与重放已保存 OpenClaw 历史的权限是分开的。清除或替换原生绑定不会建立对较旧转录行的所有权。OpenClaw 会在被接受的 CLI 轮次之前记录私有账户指纹和连续转录覆盖范围,然后使用该轮次的规范写入推进覆盖范围。它永远不会在此元数据中存储凭据值。

自动持久恢复需要已解析的静态凭据或具名 OAuth 账户。不透明的 CLI 登录、无身份的 OAuth 凭据、无来源信息的旧版转录、导入的或其他方式无法追溯的内容,以及不兼容的来源版本,均无法授权自动重放。原生恢复在后端的现有规则下仍然可用。切换账户会使混合历史失去资格,即使成功替换、之后清除或切回原账户也是如此。新会话或空重置可以建立新的边界。保留消息的重置无法重新标记它们。

这使用现有的会话元数据和转录生成/序列计数器。不会发生 SQLite 架构迁移或转录删除。现有对话不会从其最新的原生绑定回填。旧版二进制文件不强制实施此新的恢复边界。降级及后续转录写入后,再次升级会拒绝自动重放,因为这些写入不在覆盖范围内。不要依赖降级来保留新的安全行为。

显式的调用方拥有的内存上下文仍然是调用方提供的输入,而不是读取携带相同标识符的持久对话的权限。身份验证失效仍会拒绝其恢复 prompt 和已保存的会话笔记。当自动恢复被拒绝时,已保存的转录保持完整。下一个 CLI 进程接收当前请求,但不包含已保存的历史或笔记。

序列化:serialize: true 保持同一通道运行有序(大多数 CLI 在一个提供商通道上序列化)。当所选身份验证身份变化时,OpenClaw 还会丢弃已存储的 CLI 会话复用。当 CLI 暴露其中一项时,身份验证配置文件 id、静态 API 密钥、静态 token 或 OAuth 账户身份的变化均算数。仅 OAuth 访问 token 和刷新 token 轮换不会切断会话。如果 CLI 没有稳定的 OAuth 账户 id,OpenClaw 会让该 CLI 执行其自身的恢复权限。

来自 claude-cli 会话的回退前言

一次 claude-cli 尝试可以故障转移到 agents.defaults.model.fallbacks 中的非 CLI 候选项。然后 OpenClaw 会使用从 Claude Code 本地 JSONL 转录中收集到的上下文前言来为下一次尝试播种。该转录位于 ~/.claude/projects/ 下,按工作区作为键。这提供了 CLI 拥有的上下文,这些上下文可能不存在于 OpenClaw 的 SQLite 会话转录中。

  • 前言优先选择最新的 /compact 摘要或 compact_boundary 标记,然后追加边界后最近的轮次,直到字符预算。边界前的轮次会被丢弃,因为摘要已经代表它们。
  • 工具块被合并为紧凑的 (tool call: name) 和 (tool result: …) 提示,以保持 prompt 预算准确。过大的摘要会被截断并标记为 (truncated)。
  • 同一提供商的 claude-cli 到 claude-cli 回退依赖 Claude 自身的 --resume,并跳过前言。
  • 该种子复用现有的 Claude 会话文件路径验证,因此无法读取任意路径。

图像

插件作者使用 imageArg 声明图像路径支持:

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

OpenClaw 将 base64 图像写入临时文件。如果设置了 imageArg,这些路径会作为 CLI 参数传递。如果未设置,OpenClaw 会将文件路径附加到 prompt(路径注入),这对于从普通路径自动加载本地文件的 CLI 有效。

输入和输出

  • output: "text"(默认)将 stdout 视为最终响应。
  • output: "json" 尝试解析 JSON 并提取文本以及会话 id。
  • output: "jsonl" 解析 JSONL 流,并在存在时提取最终代理消息以及会话标识符。
  • 对于 Gemini CLI JSON 输出,当 usage 缺失或为空时,OpenClaw 从 response 读取回复文本,从 stats 读取使用情况。捆绑的 Gemini CLI 适配器使用 stream-json。

双引号横幅文本中的 JSON 示例不被视为响应或错误记录。 对于 JSONL,横幅扫描在每一行重新开始。

输入模式:

  • input: "arg"(默认)将 prompt 作为最后一个 CLI 参数传递。
  • input: "stdin" 通过 stdin 发送 prompt。
  • 如果 prompt 非常长且设置了 maxPromptArgChars,则改用 stdin。

插件拥有的默认值

CLI 后端默认值是插件接口的一部分:

  • 插件使用 api.registerCliBackend(...) 注册它们。
  • 后端的 id 成为模型引用中的提供商前缀。
  • 命令、argv、环境、解析器、会话和看门狗行为保留在插件代码中。
  • 后端特定的规范化通过可选的 normalizeConfig 钩子保持由插件拥有。

Anthropic 拥有 claude-cli,Google 拥有 google-gemini-cli。OpenAI Codex 代理运行通过 openai/* 使用 Codex app-server 框架。没有捆绑的 codex-cli 后端。

捆绑的 Anthropic 插件为 claude-cli 注册:

键 值
command claude
args -p --output-format stream-json --include-partial-messages --verbose --setting-sources user --allowedTools mcp__openclaw__* --disallowedTools ScheduleWakeup,CronCreate,Bash(run_in_background:true),Monitor
output jsonl
键 值
input stdin
modelArg --model
sessionArgs ["--session-id", "{sessionId}"]
sessionMode always
agent runtime 到已预热、会话范围的 Claude Code 子进程的直接 stdio 传输
imageArg @
imagePathScope workspace
systemPromptFileArg --append-system-prompt-file
systemPromptMode append

在 Claude Code 2.1.98 或更高版本中,捆绑的后端会在首次 CLI 执行时进行有界的版本探测,然后添加 --exclude-dynamic-system-prompt-sections。并发执行共享该探测。API 目录发现 不会启动它。较旧、未知或失败的探测会保留既定 argv。

捆绑的 Google 插件为 google-gemini-cli 注册:

键 值
command gemini
args --skip-trust --approval-mode auto_edit --output-format stream-json --prompt {prompt}
resumeArgs 相同,但包含 --resume {sessionId}
output / 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),并且所选 模型必须具有受支持的 Google AI Studio API 密钥配置。现有 有效的旧版 Gemini CLI OAuth 配置在运行时仍保持兼容,但 OpenClaw 不会创建或修复它们。

Gemini CLI 输出说明:

  • 默认 stream-json 解析器会读取助手 message 事件、工具事件、最终 result 用量以及致命的 Gemini 错误事件。
  • 当 usage 缺失或为空时,用量会回退到 stats。stats.cached 会规范化为 OpenClaw 的 cacheRead;如果 stats.input 缺失,则输入 token 数由 stats.input_tokens - stats.cached 推导。

文本转换覆盖

需要小型 prompt/message 兼容性垫片的插件可以声明双向文本转换,而无需替换 provider 或 CLI 后端:

api.registerTextTransforms({
  input: [{ from: /red basket/g, to: "blue basket" }],
  output: [{ from: /blue basket/g, to: "red basket" }],
});

input 会重写传递给 CLI 的系统 prompt 和用户 prompt。output 会在 OpenClaw 处理其自身控制标记和通道投递之前,重写流式助手文本和解析后的最终文本。对于由 provider 支持的模型调用,它还会在流修复之后、工具执行之前,恢复结构化工具调用参数中的字符串值。原始 provider JSON 片段保持不变。消费者应使用结构化的 partial、end 或 result 负载。

对于发出 provider 特定 JSONL 事件的 CLI,请在该后端的配置中设置 jsonlDialect:Claude Code 兼容流使用 claude-stream-json,Gemini CLI 的 stream-json 事件使用 gemini-stream-json。声明 claude-stream-json 是一项契约:后端的 result 记录承载 Claude Code 的终止语义,包括 terminal_reason。没有回复的 result 可以携带一个 terminal_reason,表示 CLI 在可能已经执行了工作之后有意结束了该轮次。这些原因包括 hook_stopped、stop_hook_prevented、aborted_tools、aborted_streaming、budget_exhausted 和 max_turns。OpenClaw 会将其视为已记录的轮次停止。它会向用户报告原因,并且不会在回退模型上重放该轮次,因为后端的工具操作可能已经执行。

原生压缩所有权

一些 CLI 后端会运行一个会压缩自身转录的 agent。OpenClaw 不得对这些后端运行其保护性摘要器。这样做会与后端自身的压缩相互冲突,并可能导致回合硬性失败。

claude-cli 没有 harness 端点(Claude Code 在内部进行压缩),因此它声明 ownsNativeCompaction: true。OpenClaw 的自动压缩让位于 Claude Code,而显式 /compact 会恢复绑定的 Claude Code 会话并发送其原生 /compact 命令。OpenClaw 通过 Claude Code 文档中的 CLAUDE_CODE_AUTO_COMPACT_WINDOW 传递本次运行的有效上下文预算,使原生自动压缩与已配置的 Anthropic contextTokens 限制保持一致。像 Codex 这样的原生 harness 会话仍会路由到其 harness 压缩端点。

google-gemini-cli 也拥有自动压缩,并持久化其压缩后的会话以便恢复。OpenClaw 让位于 Gemini CLI,而不是运行第二个摘要器。显式 /compact 在此后端不受支持,因为它未声明手动压缩能力。

api.registerCliBackend({
  id: "my-cli",
  ownsNativeCompaction: true,
  manualCompaction: {
    buildPrompt: (instructions) => (instructions ? `/compact ${instructions}` : "/compact"),
    input: "arg",
    validateOutput: (rawOutput) =>
      rawOutput.includes('"type":"compaction_complete"')
        ? { ok: true }
        : { ok: false, reason: "CLI did not confirm compaction." },
  },
  // ...
});

仅为真正拥有压缩能力的后端声明 ownsNativeCompaction。它必须能够可靠地将自身转录限制在上下文窗口附近,并持久化可恢复的会话,例如 --resume 或 --session-id。否则,被延迟的会话可能仍超出预算。

仅当其命令能够就地压缩已恢复的会话时,才添加原子的 manualCompaction 能力。其 input 选择后端命令实际识别的传输方式,validateOutput 必须要求后端给出明确确认,而不是将零退出码视为成功。OpenClaw 将其作为内部控制操作运行:它不会作为用户回合写入,也不会运行 agent 或 context-engine 的回合钩子。

捆绑 MCP 覆盖层

CLI 后端不会直接接收 OpenClaw 工具调用,但后端可以通过 bundleMcp: true 选择加入生成的 MCP 配置覆盖层。当前捆绑行为:

  • claude-cli:生成严格的 MCP 配置文件。
  • google-gemini-cli:生成 Gemini 系统设置文件。

当启用捆绑 MCP 时,OpenClaw:

  • 启动一个回环 HTTP MCP 服务器,向 CLI 进程暴露 Gateway 工具,并使用按运行上下文授权(OPENCLAW_MCP_TOKEN)进行身份验证,该授权仅在当前执行尝试期间有效
  • 将工具访问绑定到 Gateway 选择的会话、账户和渠道上下文,而不是信任子进程头
  • 加载当前工作区中已启用的 bundle-MCP 服务器,并将其与任何现有后端 MCP 配置或设置结构合并
  • 使用所属插件中由后端拥有的集成模式重写启动配置。

当工具响应或通知流空闲时,回环桥接会发送保活字节,因此 HTTP 空闲超时不会中断长时间运行的工具。这些字节不是工具结果或 agent 进度;客户端请求截止时间以及整个 agent 回合超时仍然适用。

插件替换后,新的 CLI 回合会针对当前插件代际解析桥接工具,而无需重启监听器。已退役的插件实例仍不可用,并且每个回合仍需要其自身有效的上下文授权。

通过 Gateway 的 MCP 桥接,源自渠道的 CLI 回合可以使用 message 工具执行允许的读取和同一会话中的操作,包括表情回应。桥接会保留已准入的发送者、账户和会话;渠道访问权限和写入权限仍然适用。该权限随回合或其取消而结束,包括当热 CLI 进程被复用于后续回合时。

通过桥接创建的自动化会继承其最终允许的工具集和受支持的原生工具能力。当 Claude 的原生 Bash 提供 exec 时,保存的自动化会保留其 Gateway 主机目标,即使显式设置了 toolsAllow: ["exec"] 上限也是如此。当前账户、工具、沙箱和审批限制仍然适用;捕获目标并不会授予更广泛的执行权限。

仅限节点的 exec 工具仅在策略允许且已连接节点通告 system.run 时提供。离线配对设备和仅审批手机不会使远程执行可用。已配置的节点绑定必须标识一个符合条件的节点。它永远不会重定向到另一台设备。当多个符合条件的节点已连接时,请显式选择一个。当策略允许本地执行时,使用 CLI 的原生 shell 执行本地工作。

tools.allow 和 tools.deny 还会约束已配置的原生 MCP 服务器。OpenClaw 通过其会话范围运行时列出每个服务器,分配与嵌入式工具相同的提供方安全 <safe-server>__<safe-tool> 标识,并在进程派生或 Codex thread/start/thread/resume 之前应用完整分层策略。然后它将精确的原始名称投影到每个后端的执行契约中:Claude 接收服务器省略以及裸 --disallowedTools 条目,Codex 接收 enabled_tools 和 disabled_tools,Gemini 接收 includeTools 和 excludeTools。已配置的服务器过滤器和会话覆盖仍然是额外限制。这些后端字段是生成的实现细节。将操作员策略保留在 OpenClaw 配置中。

例如,agents.entries.research.tools.allow: ["docs__read_docs"] 仅从安全的 docs 命名空间暴露该工具,而 deny: ["docs__delete_*"] 会移除匹配的同级工具。空交集会省略受影响的 MCP 服务器。无法建立限制性目录的服务器也会被省略并报告,而不是未经过滤地传递。

带有 toolsAllow 的受限运行(例如 cron 任务)需要后端负责的精确转换。捆绑的 claude-cli 后端会禁用 Claude 的原生工具,以及用户、项目和本地自定义项,包括钩子、插件、代理、技能和 CLAUDE.md。随后,它会通过授权范围限定的 MCP 服务器暴露所有允许的 OpenClaw 工具。这样可让文件系统、进程、exec、审批和沙箱策略保留在 OpenClaw 内部,而不是将权限扩大到 Claude 的原生工具或自定义流程。同一份 MCP 列表会在 Claude 生成的配置中强制执行,并再次由 Gateway 在工具列表和工具执行时强制执行。在签发授权之前,核心会拒绝任何提及原始允许列表之外的 MCP 权限的后端转换。没有精确转换的后端仍会失败关闭。

即使未启用任何 MCP 服务器,当后端选择加入 bundle MCP 时,OpenClaw 仍会注入严格配置,因此后台运行保持隔离。

会话范围的捆绑 MCP 运行时会被缓存以便在同一会话内复用,然后在空闲 10 分钟后被回收。一次性嵌入式运行(例如身份验证探测、slug 生成和 active-memory 召回)会在运行结束时请求清理。因此,Stdio 子进程以及 Streamable HTTP 或 SSE 流不会在运行结束后继续存在。

新的 CLI 会话必须等待其前一个会话的清理完成。如果清理失败或超过截止时间,OpenClaw 会拒绝替换,包括来自后续运行的替换。重试前,请检查清理错误以及后端剩余进程。仅凭命令输出和进程退出并不能确认子进程已停止。

对于 claude-cli,已安装的 Claude Code 进程会使用其当前的原生登录。OpenClaw 使用非机密路由标记,并且从不读取、持久化、刷新、选择或转发原生令牌。 在 Gateway 进程上设置 CLAUDE_CONFIG_DIR,以使用单独的 Claude 配置目录。 显式的由 OpenClaw 管理的 API-key 和 token 配置仍继续使用受保护的、按调用转发的凭据 CLI 路径。

重新播种历史上限

新的 CLI 会话可以从先前的 OpenClaw 转录中播种,例如在 session_expired 重试之后。随后,渲染的 <conversation_history> 块会被限制,以防止重新播种提示无限增长。默认值为 12,288 个字符(约 3,000 个 token)。

Claude CLI 后端会根据解析出的 Claude 上下文窗口来缩放此上限。更大的上下文窗口会获得更大的先前历史切片,直至固定上限。其他 CLI 后端保持保守的默认值。此上限仅控制重新播种提示中的先前历史块。

局限性

  • OpenClaw 不会将工具调用注入 CLI 后端协议。只有当后端选择加入 bundleMcp: true 时,后端才能看到 Gateway 工具。
  • 流式传输因后端而异:一些后端流式传输 JSONL,其他后端则缓冲直到退出。
  • 结构化输出取决于 CLI 自身的 JSON 格式。

故障排查

当本地 Claude Code 子进程失败时,如果可用,其运行错误会包含有界的、已脱敏的 stderr 诊断信息。请检查运行错误或 openclaw logs,以了解底层的启动、权限或运行时故障。成功的回合不会将 stderr 转发到日志。每个存活进程都有自己的诊断缓冲区。由于 stderr 没有回合标识符,热进程的失败可能包含更早的回合。错误会将该输出标记为进程范围,而不是将其归因于失败的回合。超大的不完整行会被省略,因此截断不会暴露凭据片段。原生 stdout 和 MCP 输入不包含在这些诊断信息中。stderr 仅为补充显示文本。它不会改变原生错误的重试、身份验证、超时或回退分类。

症状 修复
CLI 未找到 将 CLI 放到 Gateway 服务的 PATH 中,或更新所属插件的已注册命令。
模型名称错误 更新插件的 modelAliases 映射。
无会话连续性 检查插件的 sessionArgs 和 sessionMode。
图像被忽略 检查插件的 imageArg 以及 CLI 的文件路径支持。

本页原文 Markdown:在 AtomGit 查看·内容源自开源项目 cl/openclaw