
在飞书里让 OpenClaw “安装一个 Skill”,Agent 明明已经把提案生成出来,流程却停在 pending。接下来还得再发一句“批准并应用”,Skill 才会进入可用状态。
这个行为适合多人共用、权限边界复杂的环境。放在单用户、受控的 OpenClaw 实例里,审批会把一次完整请求拆成两轮:第一轮生成,第二轮确认。自动化链路也会因此中断。
这次调整的目标很具体:用户在飞书里明确提出“安装”或“创建 Skill”时,Agent 在同一轮完成创建和应用;普通聊天不能触发安装;已有的安全扫描继续保留。
实施时按优先级分成三层:
- 配置层把 Workshop 审批策略设为
auto,这是权限基础。 - 工作区指令明确“安装/创建”请求包含 apply 授权,这是行为策略。
- 如果当前版本仍受内置提示词限制,再对编译产物做兼容补丁。
三层并非在所有版本里缺一不可。配置和工作区指令相对耐升级,但仍要留意 Schema 迁移或工作区重建;编译补丁只解决特定版本的冲突,升级后很可能被覆盖。本文现场版本为 OpenClaw 2026.9.8,其他版本应先核对实际行为。
为什么只改 approvalPolicy 还不够
这次卡住的对象是一个名为 lobster-hub 的 pending 提案。表面看,问题出在审批工具:apply 需要确认。继续往下查,会发现限制分成两部分。
一部分是工具调用前的硬拦截。当前安装包会读取:
{
"skills": {
"workshop": {
"approvalPolicy": "auto"
}
}
}
当 approvalPolicy=auto 时,apply、reject、quarantine 等生命周期动作可以跳过强制审批。这一层决定工具是否允许执行。
另一部分来自系统提示词。当前编译产物仍在告诉 Agent:生成的 Skill 默认保持 pending;只有用户单独提出 approve、use 或 apply,才能执行应用。工具已经放行,模型却仍可能主动停下。
因此,仅改配置可能出现一种很别扭的状态:门锁已经打开,Agent 仍站在门外等第二句确认。
工作区指令负责补齐用户意图。用户说“安装这个 Skill”时,合理的任务终点是 Skill 已经 live,而不是只生成一份 pending 提案。编译文件补丁则清掉当前版本提示词里的冲突文案。
三层方案各自解决什么
| 层级 | 修改位置 | 解决的问题 | 升级后是否保留 |
|---|---|---|---|
| 配置层 | openclaw.json |
取消 Workshop 生命周期动作的强制审批 | 通常保留 |
| 工作区指令层 | workspace/AGENTS.md |
定义“安装/创建”请求已经包含 apply 授权 | 保留 |
| 编译文件补丁层 | 全局 OpenClaw 安装目录的 dist/skill-workshop-prompt-*.js |
消除当前系统提示词里的保守限制 | 可能被覆盖 |
这三个层级不能混为一谈。
配置层是权限基础,工作区指令是行为策略,编译补丁是特定版本的兜底。应先完成配置和指令,只有端到端测试仍停在 pending 时,才考虑第三层。把三者分开记录,后续升级时才知道哪些要复查,哪些可以撤掉。
第一步:把 Workshop 审批策略改成 auto
操作前先备份配置文件。配置文件的真实位置取决于部署方式,本文环境位于 Agent 目录下。
cp agent/openclaw.json agent/openclaw.json.bak
openclaw config set skills.workshop.approvalPolicy auto
openclaw config validate
openclaw config get skills.workshop
预期结果:
approvalPolicy: auto
Config valid
当前版本的 schema 已支持 skills.workshop.approvalPolicy。如果目标环境提示字段不存在,先用对应版本的配置 schema 或官方文档核对,别直接把其他机器的配置复制过去。
这里有一个边界需要说清:auto 放宽的是 Workshop 生命周期动作。它不会自动赋予 Agent 原本没有的文件权限、网络权限或工具权限,也不会替代 Skill 内容扫描。
第二步:在 AGENTS.md 定义“安装”的完成语义
配置开关只负责允许执行。Agent 是否愿意在同一轮执行 apply,还要看工作区指令如何解释用户请求。
在 agent/workspace/AGENTS.md 末尾追加一段类似下面的规则:
## Skill 安装策略
- 用户明确要求安装或创建 Skill 时,任务完成标准是 Skill 已创建并应用生效。
- 使用 skill_workshop 创建提案后,在同一轮执行 apply,不再等待第二次确认。
- 用户从 Skillhub 或市场明确要求安装 Skill 时,同样完成安装和启用。
- 只对明确的安装、创建、应用请求执行上述流程;讨论、审阅、比较或引用 Skill 不构成安装授权。
- 继续执行现有的内容扫描、权限检查和来源校验。
这里的边界要写清楚:放行审批不等于把所有提及 Skill 的消息都当成安装命令。文章评审、代码讨论、市场搜索都不该触发 apply。
工作区指令也是升级后的兜底。全局 npm 包更新后,AGENTS.md 通常会保留,可以继续告诉 Agent 什么才算任务完成;如果部署流程会重建工作区,则要把这段规则纳入配置管理。
第三步:修正当前编译产物里的限制文案
这一步最脆弱,也最容易被误用。
当前环境里没有对应的 TypeScript 源文件,只有 npm 全局安装目录下的编译产物。文件名带构建哈希,例如:
/home/gem/.npm-global/lib/node_modules/openclaw/dist/
skill-workshop-prompt-Ro8fA5Wx.js
不同版本、安装方式和操作系统下,目录与哈希文件名都会变化:npm、Homebrew、容器和源码部署不能照抄同一路径。不要把示例文件名写进长期脚本,应先搜索包含目标文案的实际文件:
rg -l "Generated skills are pending proposals by default" \
/home/gem/.npm-global/lib/node_modules/openclaw/dist
找到文件后先备份到项目目录:
mkdir -p tmp
cp /path/to/dist/skill-workshop-prompt-*.js \
tmp/skill-workshop-prompt.js.orig
需要调整两类文案。
原限制大意是:
Generated skills are pending proposals by default.
Do not apply them unless the user explicitly asks for that separate action.
调整为:
Generated skills may be applied immediately via action=apply
when the user asks to install or create the skill;
approvalPolicy is auto.
另一处 Use action=apply... 的约束也要同步改成:用户明确要求安装或创建时,可以在同一轮执行 apply。
补丁只改提示词文案,不要碰工具调用前的审批判断。当前环境中,审批判断已经能识别 approvalPolicy=auto,继续改它只会扩大维护面。
修改后加载模块做语法验证:
node -e "import('/path/to/dist/skill-workshop-prompt-实际哈希.js').then(() => console.log('ok'))"
输出 ok 只能证明模块能解析和加载,无法证明运行中的 Gateway 实际引用了这个文件,更无法证明审批链路已经放开。后面还要新建会话或刷新快照,并从飞书做端到端测试。
还要注意,全局 dist 补丁可能影响同一套 OpenClaw 安装下的其他 Agent,并不天然限定在飞书实例。共享安装环境必须先评估影响范围。
为什么编译文件补丁只能算临时方案
全局 dist 目录属于安装产物。npm 更新、OpenClaw 自更新或重新安装都可能覆盖它。
所以补丁要具备三个特征:
- 有原文件备份。
- 有可重复执行的搜索和替换记录。
- 升级后重新检查目标文案,不能盲目套旧补丁。
更稳的长期解法是把这类行为做成官方配置语义,让系统提示词根据 approvalPolicy 动态生成。配置为 manual 时强调单独审批;配置为 auto 时,明确允许“安装/创建”请求在同一轮 apply。这样配置和提示词不会互相打架。
在官方行为完成统一前,配置层和 AGENTS.md 是长期基线,dist 补丁属于版本修复。
重启前后怎么验证
skills.* 配置可能触发会话快照重建。为了排除旧快照和热加载残留,本次修改后执行了完整重启。
具体重启命令取决于部署方式。项目自带 restart.sh 时可以使用它;受托管的 OpenClaw Gateway 应使用平台提供的重启入口,避免直接杀进程。
重启后检查三组状态:
openclaw gateway status --json
openclaw channels status --probe
openclaw config get skills.workshop
验收关注点:
- Gateway RPC 返回
ok=true。 - 飞书 Channel 为
enabled、configured、running、works。 - Workshop 返回
approvalPolicy: auto。 - 补丁模块仍能 import。
命令行健康不代表飞书链路已经成功。最终验收必须从飞书发起。
端到端测试应该怎么做
可以先处理已有的 pending 提案。auto 只取消审批拦截,不保证提案一定有效;状态、内容扫描、来源策略、文件权限、插件策略或版本兼容性仍可能阻止 apply:
把 lobster-hub 提案 apply 生效
随后再做一次完整安装测试:
安装一个用于验证的 Skill,并在当前轮完成应用。完成后告诉我 Skill 名称和状态。
合格结果应该满足:
- Agent 识别出明确的安装意图。
- Skill 提案创建成功。
- 同一轮执行 apply。
- 状态从 pending 变为 applied 或 live。
- Skill 能被重新发现,或在新会话中正常调用。
- 飞书端没有出现额外审批拦截。
- Agent 返回实际状态,而不是只回复“已经开始处理”。
测试 Skill 应当来源清楚、内容可审阅、权限范围小。验证完成后按正常流程保留或卸载,别拿未知市场包测试自动安装能力。
放开审批后,安全边界发生了什么
approvalPolicy=auto 让 Agent 可以把提案直接变成正式 Skill。单用户、可信输入、tools.profile=full 的实例通常能接受这个取舍。多人群聊、公开机器人或输入来源复杂的环境风险会高很多。
自动 apply 扩大的是代码执行与持久化能力,风险远不止少了一次确认。主要风险包括:
- 恶意或被污染的 Skill 进入正式环境,读取文件、访问网络或调用现有工具权限。
- 提示注入诱导 Agent 把“讨论安装”误判为“执行安装”。
- Skill 写入持久指令后持续影响后续会话。
- 全局 dist 补丁波及同一安装下的其他 Agent。
- dist 补丁在升级后失效,行为悄悄退回 pending。
- 配置、提示词和工作区指令不一致,导致行为难以预测。
建议至少保留这些护栏:
- 只在私聊或受控会话开放自动 apply。
- 限制可安装来源,市场包先做来源白名单和内容审计。
- 保留 guardian 或等价内容扫描,但不能把扫描当成安全保证。
- 按最小权限配置文件、网络和外部系统能力。
- 高风险 Skill 继续要求人工确认。
- 记录创建、apply、启用和回滚日志。
- 保留原文件备份和补丁记录,明确备份保留周期。
- 每次升级后跑一遍端到端回归。
如果实例服务多人,或者能接触生产凭据、支付、云资源和公开发布渠道,建议继续使用人工审批。省掉一句确认,不值得换来不可控的供应链风险。
升级后的回归清单
每次更新 OpenClaw 后检查下面几项:
[ ] skills.workshop.approvalPolicy 仍为 auto
[ ] AGENTS.md 的 Skill 安装策略仍存在
[ ] dist 中限制性提示词是否已经由官方修复
[ ] 如果仍未修复,旧补丁能否安全重打
[ ] Gateway 和飞书 Channel 健康
[ ] pending 提案可以 apply
[ ] 新 Skill 能从飞书端同轮创建并生效
[ ] 内容扫描与权限限制仍然工作
如果官方版本已经统一了配置和提示词,就应撤掉 dist 补丁。临时补丁长期存在,会让后续排障越来越难。
需要回滚时,顺序也应写进变更记录:恢复原始提示词文件,把审批策略改回原值,撤回工作区自动 apply 指令,按部署方式重启或重新加载 Gateway,然后新建会话并确认审批拦截已经恢复。
最终判断
这次调整能成立,依赖的是三层职责分离:配置层放开硬审批,工作区指令定义用户意图,提示词补丁修正当前版本的行为冲突。
真正需要长期维护的是前两层。编译产物补丁只服务于当前版本,必须带着备份、版本记录和升级回归一起使用。
对于可信的单用户实例,这套方案能把飞书里的 Skill 安装恢复成一次完整任务。对于多人或高权限实例,保留审批更稳。