Appearance
OpenClaw CLI后端插件允许你将本地AI命令行工具注册为文本推理后端,使其可作为 acme-cli/acme-large 这类模型引用使用。需要创建 package.json、openclaw.plugin.json 和 index.ts,调用 api.registerCliBackend(...) 并设置 command、args、output、input 等字段。用户可在 agents.defaults.cliBackends.<id> 下覆盖默认配置。验证时运行 openclaw plugins inspect <id> --runtime --json 和一条真实模型推理指令。
OpenClaw CLI后端插件构建与配置
CLI后端插件让OpenClaw能够调用本地AI命令行工具作为文本推理后端。该后端会以provider前缀出现在模型引用中,例如:
text
acme-cli/acme-large当上游集成已经作为本地命令暴露、CLI持有本地登录状态,或者API provider不可达时,使用CLI后端是一个合适的回退方案。
INFO
如果上游服务暴露的是正常的HTTP模型API,请改用provider插件。如果上游运行时拥有完整的智能体会话、工具事件、压缩或后台任务状态,请使用agent harness。
插件拥有的合约
一个CLI后端插件有三个合约:
| 合约 | 文件 | 用途 |
|---|---|---|
| 包入口 | package.json | 告诉OpenClaw插件运行时模块的位置 |
| manifest所有权 | openclaw.plugin.json | 在运行时加载前声明后端ID |
| 运行时注册 | index.ts | 调用 api.registerCliBackend(...) 并提供命令默认值 |
Manifest是发现阶段的元数据。它不执行CLI,也不注册运行时行为。运行时行为从插件入口调用 api.registerCliBackend(...) 开始。
最小后端插件
创建包元数据
json{ "name": "@acme/openclaw-acme-cli", "version": "1.0.0", "type": "module", "openclaw": { "extensions": ["./index.ts"], "compat": { "pluginApi": ">=2026.3.24-beta.2", "minGatewayVersion": "2026.3.24-beta.2" }, "build": { "openclawVersion": "2026.3.24-beta.2", "pluginSdkVersion": "2026.3.24-beta.2" } }, "dependencies": { "openclaw": "^2026.3.24" }, "devDependencies": { "typescript": "^5.9.0" } }发布的包必须包含已构建的JavaScript运行时文件。如果源码入口是
./src/index.ts,则需要在openclaw.runtimeExtensions中指向编译后的JavaScript文件。参见入口点。声明后端所有权
json{ "id": "acme-cli", "name": "Acme CLI", "description": "通过OpenClaw运行Acme的本地AI CLI", "cliBackends": ["acme-cli"], "setup": { "cliBackends": ["acme-cli"], "requiresRuntime": false }, "activation": { "onStartup": false }, "configSchema": { "type": "object", "additionalProperties": false } }cliBackends是运行时所有权列表。当配置或模型选择中出现了acme-cli/...时,OpenClaw会自动加载该插件。setup.cliBackends是基于描述符的安装表面。当模型发现、引导或状态检查需要在没有加载插件运行时也能识别该后端时,添加此字段。只在静态描述符足够完成安装时使用requiresRuntime: false。注册后端
typescriptimport { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry"; import { CLI_FRESH_WATCHDOG_DEFAULTS, CLI_RESUME_WATCHDOG_DEFAULTS, type CliBackendPlugin, } from "openclaw/plugin-sdk/cli-backend"; function buildAcmeCliBackend(): CliBackendPlugin { return { id: "acme-cli", liveTest: { defaultModelRef: "acme-cli/acme-large", defaultImageProbe: false, defaultMcpProbe: false, docker: { npmPackage: "@acme/acme-cli", binaryName: "acme", }, }, config: { command: "acme", args: ["chat", "--json"], output: "json", input: "stdin", modelArg: "--model", sessionArg: "--session", sessionMode: "existing", sessionIdFields: ["session_id", "conversation_id"], systemPromptFileArg: "--system-file", systemPromptWhen: "first", imageArg: "--image", imageMode: "repeat", reliability: { watchdog: { fresh: { ...CLI_FRESH_WATCHDOG_DEFAULTS }, resume: { ...CLI_RESUME_WATCHDOG_DEFAULTS }, }, }, serialize: true, }, }; } export default definePluginEntry({ id: "acme-cli", name: "Acme CLI", description: "通过OpenClaw运行Acme的本地AI CLI", register(api) { api.registerCliBackend(buildAcmeCliBackend()); }, });后端ID必须与manifest中的
cliBackends条目一致。注册的config只是默认值;运行时用户配置agents.defaults.cliBackends.acme-cli中的值会合并覆盖它。
配置形状
CliBackendConfig 描述了OpenClaw如何启动和解析CLI:
| 字段 | 用途 |
|---|---|
command | 二进制名称或绝对命令路径 |
args | 新运行的基础argv |
resumeArgs | 恢复会话的替代argv;支持 {sessionId} 占位符 |
output / resumeOutput | 解析方式:json、jsonl 或 text |
input | 提示传送方式:arg 或 stdin |
modelArg | 模型ID前的标志 |
modelAliases | 将OpenClaw模型ID映射为CLI原生ID |
sessionArg / sessionArgs | 如何传递会话ID |
sessionMode | always、existing 或 none |
sessionIdFields | OpenClaw从CLI输出中读取的JSON字段 |
systemPromptArg / systemPromptFileArg | 系统提示的传送方式 |
systemPromptWhen | first、always 或 never |
imageArg / imageMode | 图片路径支持 |
serialize | 同一后端运行时是否保持有序 |
reliability.watchdog | 无输出超时调优 |
优先使用最简洁的静态配置来匹配CLI。只将真正属于后端的行为添加到插件回调中。
高级后端钩子
CliBackendPlugin 还可以定义:
| 钩子 | 用途 |
|---|---|
normalizeConfig(config, context) | 合并后重写遗留用户配置 |
resolveExecutionArgs(ctx) | 添加请求级标志,如思考努力度参数 |
prepareExecution(ctx) | 在启动前创建临时认证或配置桥接 |
transformSystemPrompt(ctx) | 应用最终CLI特定的系统提示转换 |
textTransforms | 双向的提示/输出替换 |
defaultAuthProfileId | 优先使用某个OpenClaw认证配置 |
authEpochMode | 决定认证变更如何使存储的CLI会话失效 |
nativeToolMode | 声明CLI是否具有始终开启的原生工具 |
bundleMcp / bundleMcpMode | 选择OpenClaw的环回MCP工具桥 |
保持这些钩子由provider拥有。当后端钩子可以表达行为时,不要在核心中添加CLI特定分支。
MCP工具桥
默认情况下,CLI后端不会收到OpenClaw的工具。如果CLI可以消费MCP配置,显式选择加入:
typescript
return {
id: "acme-cli",
bundleMcp: true,
bundleMcpMode: "codex-config-overrides",
config: {
command: "acme",
args: ["chat", "--json"],
output: "json",
},
};支持的桥接模式:
| 模式 | 用途 |
|---|---|
claude-config-file | CLIs接受MCP配置文件 |
codex-config-overrides | CLIs在argv上接受配置覆盖 |
gemini-system-settings | CLIs从其系统设置目录读取MCP设置 |
只在CLI确实能消费MCP时才启用桥接。如果CLI有自己的内建工具层且无法禁用,请设置 nativeToolMode: "always-on",以便当调用方要求无原生工具时OpenClaw可以安全地失败。
用户配置
用户可以覆盖任何后端默认值:
json5
{
agents: {
defaults: {
cliBackends: {
"acme-cli": {
command: "/opt/acme/bin/acme",
args: ["chat", "--json", "--profile", "work"],
modelAliases: {
large: "acme-large-2026",
},
},
},
model: {
primary: "openai/gpt-5.5",
fallbacks: ["acme-cli/large"],
},
},
},
}文档中应记录用户最可能需要的最小覆盖。通常仅当二进制不在 PATH 中时才需要覆盖 command。
验证
对于打包的插件,在builder和setup注册周围添加一个聚焦测试,然后运行插件的有目标测试通道:
bash
pnpm test extensions/acme-cli对于本地或已安装的插件,验证发现和一条真实模型运行:
bash
openclaw plugins inspect acme-cli --runtime --json
openclaw agent --message "reply exactly: backend ok" --model acme-cli/acme-large如果后端支持图片或MCP,添加一个使用真实CLI的冒烟测试来证明这些路径。不要依赖静态检查来验证提示、图片、MCP或会话恢复行为。
检查清单
- [x]
package.json包含openclaw.extensions和已构建的运行时入口(针对发布的包) - [x]
openclaw.plugin.json声明了cliBackends和明确的activation.onStartup - [x] 当设置/模型发现应该冷启动识别后端时,提供了
setup.cliBackends - [x]
api.registerCliBackend(...)使用了与manifest相同的后端ID - [x]
agents.defaults.cliBackends.<id>下的用户覆盖仍然生效 - [x] 会话、系统提示、图片和输出解析器设置与真实CLI合约一致
- [x] 有目标测试和至少一次真实CLI冒烟测试证明后端路径
相关
- CLI后端 - 用户配置和运行时行为
- 构建插件 - 包和manifest基础
- 插件SDK概览 - 注册API参考
- 插件manifest -
cliBackends和安装描述符 - Agent Harness - 完整的外部智能体运行时
常见问题
CLI后端插件manifest中的cliBackends必须和runtime注册的id一致吗?
是的,必须一致。manifest中的 cliBackends 列表用于发现时关联,api.registerCliBackend() 中传递的 id 也必须匹配,否则插件注册可能不会触发。
用户怎么覆盖CLI后端的命令路径?
在 agents.defaults.cliBackends.<id> 中设置 command 字段,例如:"acme-cli": { "command": "/opt/acme/bin/acme" }。如果二进制不在PATH中,这是最常用的覆盖。
如何验证CLI后端插件已正确注册并可用?
运行 openclaw plugins inspect <id> --runtime --json 检查运行时状态。然后用 openclaw agent --message "reply exactly: ok" --model <id>/<model> 执行一次真实推理,看输出是否正常。