
一、先说个场景
你在 ~/.openclaw/skills/ 全局目录里装了一个 weather,又在某个 workspace 的 skills/ 目录里自己写了一个也叫 weather 的 skill。结果聊天里让 OpenClaw 查天气,它一直用 workspace 那个半成品,而不是你精心装的官方版。
这就是 OpenClaw 的技能加载顺序在起作用。同名冲突时,高优先级的来源会遮住低优先级的来源。不理解这个优先级,你会反复遇到”明明装了,agent 却不用”的诡异问题。
二、为什么是这样
OpenClaw 启动时会扫描多个 skill root,每个 root 下出现 SKILL.md 的地方就会被发现。不同 root 对应不同生命周期和可见范围:
- workspace 目录只影响当前 agent;
- 全局目录影响本机所有 agent;
- project-agent 目录影响某个 workspace 的 agent;
- 共享的 managed 目录影响所有使用该状态目录的 agent;
- Workshop 目录是提案队列,只对某个 agent 可见。
当同一个 name 出现在多个 root 时,OpenClaw 不能同时用两个。它按优先级取最高的那个。这个规则让 workspace 可以覆盖全局,让个人设置可以覆盖共享设置,也让 Workshop 里的提案不会污染正式发布。
为什么是”静默覆盖”而不是弹窗报错?因为如果每次冲突都报错,你在本地实验 skill 时会被满屏警告淹没;而 OpenClaw 假定”更靠近当前工作环境”的来源就是用户此刻想要的那份。代价是排查更难——你没法靠报错来发现冲突,只能靠主动检查。这也就是为什么这篇文章反复强调要用 openclaw skills list 去确认,而不是凭感觉判断。
另外要理解”快照”的概念。OpenClaw 在会话启动或 Gateway 启动时,会把当时发现的技能拍成一份快照(snapshot)。之后你增删磁盘上的 skill,并不会立刻反映到已经运行的会话里,除非触发刷新。这解释了为什么有时候”明明文件都删了,agent 还在用旧 skill”——它读的是快照,不是实时磁盘。刷新方式无非两种:开新会话,或者 openclaw gateway restart。
三、跟着做:分步操作
1. 记住优先级表(高 → 低)
| 优先级 | 来源 | 路径 |
|---|---|---|
| 1 | Workspace skills | <workspace>/skills |
| 2 | Project agent skills | <workspace>/.agents/skills |
| 3 | Personal agent skills | ~/.agents/skills |
| 4 | Managed / local skills | <state-dir>/skills |
| 5 | Workshop skills | <state-dir>/agents/<agentId>/agent/workshop-skills |
| 6 | Bundled skills | 随安装包发布 |
| 6 | Custodian skills | 仅配置了 Custodian agent 时 |
| 7 | Extra dirs + plugin skills | skills.load.extraDirs + 插件技能 |
2. 理解命名规则
技能名来自 SKILL.md frontmatter 里的 name。如果缺失,才回退到目录名或仓库名。同名冲突只看最终 name,不看目录路径。
一个小提醒:决定胜负的是最终解析出来的 name 字段,而这个字段是大小写敏感的。如果你在 A 处写 Weather、在 B 处写 weather,它们会被当成两个不同的技能,不会互相覆盖——这往往又制造了新的困惑:你以为在覆盖,其实是两个技能并存。所以团队内部最好约定统一的命名风格,避免这种”假冲突”或”假并存”。
3. 检查当前哪个来源获胜
openclaw skills list
列表里只显示当前会话加载的技能。如果某个来源的技能没出现:
- 要么被更高优先级同名 skill 遮住;
- 要么被
agents.entries.*.skills白名单过滤; - 要么需要刷新会话或重启 Gateway。
如果 openclaw skills list 里没有出现你期望的技能,先别急着改代码。按这个顺序排查:第一,确认它是否被更高优先级的同名技能遮住了;第二,确认它是否被某个 agent 的 skills 白名单过滤掉了;第三,确认你是否改完磁盘后忘了刷新会话。这三步能解决绝大多数”看不到技能”的问题,而且都不需要打开 SKILL.md。
4. 分组布局不影响名字
mkdir -p ~/.openclaw/workspace/skills/productivity/reminders
只要 ~/.openclaw/workspace/skills/productivity/reminders/SKILL.md 里的 name: reminders 存在,调用名就是 /reminders,不是 /productivity/reminders。
分组目录(如 productivity/、dev/ 这样的中间层)纯粹是为了人类整理方便,OpenClaw 在解析时只认最终的 SKILL.md 和它的 name,中间路径全部忽略。所以你大可以把几十个技能按主题分门别类地放,调用时依然是扁平的 /名字,不会变长,也不会因为嵌套深了就改变优先级。
四、可以复制的指令
# 查看当前加载的技能
openclaw skills list
# 查看 workspace 技能目录
ls ~/.openclaw/workspace/skills/
# 查看全局技能目录
ls ~/.openclaw/skills/
# 查看 project agent 技能目录
ls <workspace>/.agents/skills/
# 重启 Gateway 刷新
openclaw gateway restart
# 显式调用某个 skill,绕过自动选择
/skill weather
这几条命令各有分工:openclaw skills list 看的是”当前会话实际加载了什么”,是排查的第一抓手;两个 ls 看的是”磁盘上到底有什么”,用来确认文件是否真的在对应目录;openclaw gateway restart 用来让修改生效、重建快照;/skill weather 则是绕过自动选择、强行指定调用某个技能。养成”先 list、再 ls、最后 restart”的顺序,能少走很多弯路,也能最快定位是”没装”还是”装了但被遮住”。
五、实战案例
你在全局装了官方的 weather,又在 workspace 写了一个实验性的 weather:
~/.openclaw/skills/weather/SKILL.md # 官方版
~/.openclaw/workspace/skills/weather/SKILL.md # 你的实验版
当你当前 workspace 的 agent 启动时,优先级 1 的 workspace 版会遮住优先级 4 的全局版。
排查步骤:
openclaw skills list确认列表里是哪个weather。- 如果 workspace 版不要了,删除
~/.openclaw/workspace/skills/weather/。 - 重新
/new或openclaw gateway restart。 - 再次
openclaw skills list,确认官方版出现。
补充一点排查心法:当你用 openclaw skills list 看到的是 workspace 版而不是官方版时,不要急着删文件。先想清楚你到底想要哪个版本——也许你的实验版本就该优先,问题只是你忘了自己写过它。确认不要之后,删除或改名实验版,再重启刷新,最后再次 list 验证。整个过程其实就是在”确认胜出者 → 移除干扰项 → 重建快照 → 复核”的循环里走一遍。如果重启后还是不对,八成是目录放错了位置,回去用 ls 核对路径最稳妥,比反复改 SKILL.md 高效得多。
六、常见误区
- 误区 1:同名冲突会报错。不会。OpenClaw 静默取高优先级的那个,不报任何警告。
- 误区 2:目录层级会出现在 skill 名里。不会。技能名只由
SKILL.md的name决定。 - 误区 3:删掉低优先级的就会加载高优先级的。还要刷新会话,否则快照还是旧的。
- 误区 4:
openclaw skills list展示所有磁盘 skill。它展示的是当前会话可见的技能,已被遮住的不会显示。 - 误区 5:Bundled 技能优先级高于 managed。实际上 bundled 和 custodian 同处于第 6 层,extra dirs 和 plugin 在第 7 层。
七、进阶玩法
用白名单显式隔离:在 openclaw.json 里给某个 agent 指定最终技能集。
{
agents: {
defaults: { skills: ["github", "weather"] },
entries: {
writer: { default: true },
docs: { skills: ["docs-search"] },
},
},
}
这里 docs agent 只看 docs-search,不会看到 workspace 或全局里的 weather。注意 entries.*.skills 是替换,不是合并。
关于白名单,最容易踩的坑就是忘记它是”替换”语义。很多人以为在 docs agent 里写了 skills: ["docs-search"],它会”额外”获得这个技能、同时保留全局默认。事实恰恰相反——一旦给某个 agent 指定了 skills,它就只看列表里的那几个,默认集被整体替换掉。所以如果你希望 docs 既能用 docs-search 又能用默认的 github,必须两个都写进去,写成 ["docs-search", "github"]。
用 extraDirs 做公共库:
{
skills: {
load: {
extraDirs: ["~/company-skills"],
},
},
}
这是最低优先级的来源,适合放一些全公司共享但不会覆盖 workspace 的 baseline skill。
至于 extraDirs,它名字里带个”extra”,定位就是”锦上添花的最低优先级来源”。把它当成公司的 baseline 公共库非常合适:里面放一些人人都该有、但又绝不该覆盖任何人本地自定义的通用技能。只要记住它永远排在最后,你就不会被”我放了怎么没生效”困惑——因为它很可能被更高优先级的同名技能悄悄遮住了,这也是为什么公共库里的技能命名要格外谨慎,避免和别人本地的技能撞名。
八、小结
加载顺序和同名冲突是 OpenClaw 技能系统最容易踩的坑之一。记住这张优先级表,就能解释 90% 的”为什么没生效”。核心要点:workspace 最高,全局次之,Workshop 和 bundled 靠后;同名时高优先级静默覆盖;openclaw skills list 只显示当前会话可见的技能。遇到奇怪行为时,先 list,再 ls 各来源目录,最后 gateway restart。别一上来就怀疑 skill 写错了。
