OpenClaw 源码解析(十二):Skills 技能系统与 Agent 行为约束
1. 本期目标上一期我们分析了 OpenClaw 的 Tools 工具系统。Tool 决定 Agent能调用什么能力例如执行命令、读写文件、发送消息、调用浏览器等。这一期继续看和 Tool 密切相关的另一层机制Skills 技能系统。简单来说Tool 解决“Agent 能做什么” Skill 解决“Agent 应该怎么做”。OpenClaw 官方文档说明Skill 是一种 AgentSkills-compatible 的技能目录每个技能目录里包含一个SKILL.md其中既有 YAML frontmatter 元数据也有给 Agent 的 Markdown 指令。OpenClaw 会加载内置技能和本地覆盖技能并根据环境、配置和依赖二进制文件进行过滤。(OpenClaw)本期重点分析1. Skill 和 Tool 的关系 2. SKILL.md 的基本结构 3. Skill 的加载路径与优先级 4. per-agent skill allowlist 5. metadata.openclaw 的 gating 机制 6. user-invocable 与 disable-model-invocation 7. Skill 如何进入 Agent prompt 8. Skill 与 sandbox、env、apiKey 的关系 9. Skill 的安全风险2. 为什么需要 Skill只靠 ToolAgent 只能知道我有 exec 工具 我有 browser 工具 我有 read/write/edit 工具 我有 message 工具。但它不知道在具体任务中应该如何组合这些工具。比如用户说帮我审查这个 PR。Tool 只能提供动作读取文件 执行测试 查看 diff 发送消息。Skill 则提供流程先查看 PR 变更范围 再判断是否需要运行测试 再检查新增逻辑、异常处理、边界条件 最后按 review 格式输出问题、风险和建议。所以 Skill 的本质不是“新工具”而是把某类任务的经验流程写成可复用的 Agent 行为说明。官方创建技能文档也强调Skills 用来教 Agenthow and when to use tools每个 Skill 是一个包含SKILL.md的目录。(OpenClaw)3. Skill、Tool、Plugin 的再次区分到这里可以重新区分这三个概念Tool 具体动作接口。 Skill 工具使用说明和任务流程约束。 Plugin 能力扩展包可以提供 Tool也可以附带 Skill。举例browser 是 Tool browser-automation 是 Skill browser plugin 可以同时提供 browser Tool 和相关 Skill。官方文档也说明Plugin 可以通过openclaw.plugin.json中的skills目录携带自己的 Skill这种方式适合放置“工具说明太长、不适合塞进 tool description但又需要在插件启用时提供给 Agent 的操作指南”。(OpenClaw)可以画成Plugin ├─ 注册 Tool ├─ 注册 Channel ├─ 注册 Provider └─ 携带 Skill Tool └─ 提供可调用动作 Skill └─ 指导 Agent 如何稳定使用这些动作4. SKILL.md 的基本结构一个 Skill 最核心的文件就是SKILL.md官方文档说明SKILL.md至少需要包含name和description并且 OpenClaw 的 embedded agent parser 支持单行 frontmatter key如果使用metadata建议写成单行 JSON object。文档还说明可以在说明中使用{baseDir}引用 skill 目录路径。(OpenClaw)一个最小 Skill 可以写成--- name: hello-world description: A simple skill that says hello. --- # Hello World Skill When the user asks for a greeting, use the echo tool to say: Hello from your custom skill!它分成两部分frontmatter 给 OpenClaw 看的元数据。 markdown body 给 Agent 看的行为说明。其中description很重要因为它不仅是展示信息也会帮助 Agent 判断什么时候应该使用这个 skill。5. Skill 的命名规则官方创建技能文档建议 Skill name 使用小写字母、数字和连字符组成的 hyphen-case并让目录名和 frontmatter 中的name保持一致。(OpenClaw)例如推荐 github-review browser-automation report-polish log-analysis 不推荐 GitHubReview github_review github review这背后有两个考虑第一便于命令行、路径和配置引用。 第二避免同一个 Skill 在不同地方出现命名不一致。6. Skill 的加载路径与优先级OpenClaw 不只从一个目录加载 Skill而是有一套优先级。官方文档给出的加载顺序是1. workspace/skills 2. workspace/.agents/skills 3. ~/.agents/skills 4. ~/.openclaw/skills 5. bundled skills 6. skills.load.extraDirs如果多个位置存在同名 Skill优先级更高的位置会覆盖优先级更低的位置。(OpenClaw)可以理解为workspace skill 最贴近当前 Agent优先级最高。 personal/shared skill 适合多 Agent 共享。 bundled skill OpenClaw 默认自带。 extraDirs 额外技能目录优先级最低。这套优先级的意义是用户可以通过 workspace 下的 Skill 覆盖系统自带 Skill而不用直接修改 OpenClaw 源码。7. per-agent skill 和 shared skill 的区别OpenClaw 支持多 Agent每个 Agent 可以有自己的 workspace。因此 Skill 既可以是某个 Agent 专用也可以是多个 Agent 共享。官方文档说明workspace/skills只对当前 agent 可见~/.agents/skills和~/.openclaw/skills则可以对本机所有 agent 可见。(OpenClaw)可以这样区分workspace/skills 适合某个 Agent 的专属工作流。 workspace/.agents/skills 适合同一个 workspace 下的 agent 技能。 ~/.agents/skills 适合本机 agent profile 共享。 ~/.openclaw/skills 适合 OpenClaw 全局共享技能。举例writer agent 加载写作润色类 skills。 coder agent 加载代码审查、测试、重构类 skills。 ops agent 加载部署、日志分析、故障排查类 skills。这说明 Skill 不只是“功能扩展”也是一种 Agent 分工机制。8. Agent skill allowlist位置和可见性不是一回事一个 Skill 存在于某个目录并不代表所有 Agent 都能使用它。官方文档明确区分了两个概念Skill location 决定 Skill 从哪里加载以及同名冲突时谁覆盖谁。 Skill visibility 决定某个 Agent 实际能不能使用这个 Skill。OpenClaw 可以通过agents.defaults.skills和agents.list[].skills设置 allowlist如果某个 agent 的skills是非空列表那么这个列表就是最终集合并不会和 defaults 合并。(OpenClaw)示例{ agents: { defaults: { skills: [github, weather] }, list: [ { id: writer }, { id: docs, skills: [docs-search] }, { id: locked-down, skills: [] } ] } }含义是writer 继承 defaults可以用 github 和 weather。 docs 只可以用 docs-search不再合并 defaults。 locked-down 不允许使用任何 skill。这和上一期的 Tool policy 很像Skill 也有自己的可见性控制。9. Skill 的加载链路把前面内容串起来一个 Skill 从文件到 Agent prompt大致会经过扫描 skill roots ↓ 读取每个 SKILL.md ↓ 解析 frontmatter ↓ 处理同名冲突和路径优先级 ↓ 根据 metadata.openclaw 做 gating ↓ 根据 skills.entries 做启用/禁用和 env/apiKey 配置 ↓ 根据 agent skill allowlist 过滤 ↓ 生成当前 session 的 eligible skills snapshot ↓ 构造 prompt 中的 available_skills ↓ Agent 在运行时参考 skill 说明选择行为所以 Skill 并不是简单地把所有SKILL.md拼进 prompt而是经过路径、配置、依赖、Agent allowlist 和 session snapshot 多层处理。10. metadata.openclawSkill 的条件加载机制很多 Skill 只有在特定环境下才有意义。例如一个 Gemini CLI skill 需要 gemini 命令存在 一个图片生成 skill 需要 GEMINI_API_KEY 一个浏览器自动化 skill 需要 browser.enabled 一个 macOS 自动化 skill 只适合 darwin。OpenClaw 通过metadata.openclaw做 load-time gating。官方文档列出的字段包括os、requires.bins、requires.anyBins、requires.env、requires.config、primaryEnv、install等如果没有metadata.openclawSkill 默认是 eligible除非被配置禁用或被 bundled allowlist 阻止。(OpenClaw)示例--- name: image-lab description: Generate or edit images via a provider-backed image workflow metadata: {openclaw:{requires:{bins:[uv],env:[GEMINI_API_KEY],config:[browser.enabled]},primaryEnv:GEMINI_API_KEY}} --- # Image Lab Use this skill when the user asks for image generation or image editing workflows.这表示uv 必须在 PATH 中 GEMINI_API_KEY 必须存在或由配置提供 browser.enabled 必须在 openclaw.json 中为真 否则这个 Skill 不会进入 eligible skills。11. requires.bins 和 sandbox 的关系这里有一个容易忽略的点requires.bins在 skill load 阶段检查的是 host 上的二进制文件如果 Agent 运行在 sandbox 中那么该二进制文件还需要存在于容器或 sandbox 环境里。官方文档明确说明sandboxed agent 需要在容器里也有对应 binary可以通过 Docker setupCommand 或自定义镜像安装。(OpenClaw)也就是说host 上有 gemini Skill 可能被判定为 eligible。 sandbox 里没有 gemini Agent 真正执行时仍然可能失败。这说明 Skill gating 和 Tool runtime environment 是两层gating 决定 Skill 是否对 Agent 可见。 sandbox 决定 Skill 指导的工具动作能否真的执行。12. skills.entries启用、禁用和注入配置OpenClaw 可以通过skills.entries对单个 Skill 做配置。官方文档说明bundled 和 managed skills 可以在~/.openclaw/openclaw.json中通过skills.entries设置enabled、apiKey、env、config等字段enabled: false可以禁用一个已安装或内置 Skill。(OpenClaw)示例{ skills: { entries: { image-lab: { enabled: true, apiKey: { source: env, provider: default, id: GEMINI_API_KEY }, env: { GEMINI_API_KEY: GEMINI_KEY_HERE }, config: { endpoint: https://example.invalid, model: nano-pro } }, dangerous-skill: { enabled: false } } } }可以理解为enabled 控制这个 Skill 是否启用。 apiKey 给 primaryEnv 之类的字段提供密钥。 env 为该 Skill 的 agent run 注入环境变量。 config 存放这个 Skill 自己需要的配置。13. 环境变量注入不是全局环境官方文档说明当 agent run 开始时OpenClaw 会读取 skill metadata应用skills.entries.key.env和apiKey到process.env构建包含 eligible skills 的系统提示词然后在 run 结束后恢复原始环境这个环境注入只作用于当前 agent run不是全局 shell 环境。(OpenClaw)可以画成Agent run start ↓ 读取 skill metadata ↓ 注入 env/apiKey ↓ 构建 prompt ↓ 执行 Agent run ↓ run 结束 ↓ 恢复原始 env这有两个好处第一不会永久污染 OpenClaw Gateway 进程环境。 第二不同 Skill 可以有不同的临时配置。但也要注意官方文档同时提醒skills.entries.*.env和apiKey是注入 host process而不是 sandbox在 sandbox session 中这些 host env 对 sandbox 内进程没有效果需要单独配置 sandbox env。(OpenClaw)14. user-invocableSkill 是否变成 slash commandSkill 不一定只靠模型自然触发也可以变成用户可以直接调用的 slash command。官方文档说明user-invocable默认是true当它为 true 时Skill 会暴露为用户 slash command。(OpenClaw)例如--- name: log-analysis description: Analyze service logs and summarize likely root causes. user-invocable: true --- # Log Analysis When the user provides logs, extract errors, warnings, timestamps, and likely root causes.用户可以通过类似方式显式调用/log-analysis ...如果设置user-invocable: false那么这个 Skill 更像是只供 Agent 内部参考不直接暴露成用户命令。15. disable-model-invocation不进入普通 prompt另一个重要字段是disable-model-invocation官方文档说明当它为 true 时OpenClaw 会把该 Skill 的说明从 Agent 的普通 prompt 中移除但如果user-invocable也是 true它仍然可以通过 slash command 显式运行。(OpenClaw)这适合什么场景Skill 内容很长 Skill 只应该由用户显式触发 Skill 是命令式工具封装 不希望它污染普通对话 prompt。可以这样理解user-invocable 用户能不能直接调用。 disable-model-invocation 模型普通推理时能不能看到它。两者组合效果如下user-invocable: true disable-model-invocation: false 用户能调用模型也能自然触发。 user-invocable: true disable-model-invocation: true 用户能调用但模型普通 prompt 看不到。 user-invocable: false disable-model-invocation: false 用户不能直接调用但模型可以参考。 user-invocable: false disable-model-invocation: true 基本相当于隐藏。16. command-dispatch绕过模型直接调工具有些 Skill 不是让模型阅读说明再行动而是把 slash command 直接映射到某个 Tool。官方文档说明当command-dispatch: tool时slash command 会绕过模型直接 dispatch 到command-tool指定的工具command-arg-mode: raw会把原始参数字符串传给工具。(OpenClaw)示例--- name: deploy-status description: Check current deployment status. user-invocable: true disable-model-invocation: true command-dispatch: tool command-tool: gateway command-arg-mode: raw --- # Deploy Status Use this command to check deployment status.普通 Skill 走的是用户请求 ↓ 模型阅读 Skill ↓ 模型选择 Tool ↓ 执行 Tooldirect command dispatch 走的是用户 slash command ↓ OpenClaw command parser ↓ 直接调用 Tool ↓ 返回结果这更适合确定性命令比如状态查询、固定脚本、内部运维入口。17. Skill 如何进入 Agent prompt官方文档说明当 Skills eligible 时OpenClaw 会向 system prompt 注入一个 compact XML list of available skills并给出确定性的字符开销公式基础开销加上每个 skill 的 name、description、location 等字段长度。(OpenClaw)这意味着当前版本的 Skill 暴露更偏向把 Skill 的关键信息压缩成 available_skills 列表 让模型知道当前有哪些技能、每个技能大致适合什么任务 模型再根据用户请求选择是否遵循对应技能流程。可以抽象成available_skills skill namegithub-review/name descriptionReview GitHub pull requests with structured comments./description locationworkspace/location /skill /available_skills这和直接把所有 Skill 全文都塞入 prompt 不同。紧凑列表有助于降低 prompt 体积但也要求 Skill 的description写得足够清楚。18. Skill snapshot 与刷新OpenClaw 不会在每个 token 或每个工具调用时重新扫描技能目录。官方文档说明OpenClaw 会在 session 启动时 snapshot 当前 eligible skills并在后续 turns 复用技能或配置变化通常在新 session 生效。不过在 watcher 开启或新的 eligible remote node 出现时Skills 可以在 mid-session 刷新并在下一次 agent turn 使用更新后的列表。(OpenClaw)可以理解为新 session 生成一次 Skill snapshot。 同一 session 后续 turn 复用 snapshot。 文件变化且 watcher 开启 刷新 snapshot下一轮生效。这避免了每轮都扫描大量文件同时又保留了一定热更新能力。19. Skill Workshop从经验生成 SkillOpenClaw 还有一个比较有意思的扩展Skill Workshop。官方文档说明Skill Workshop 是一个可选、实验性的插件可以根据 Agent 工作过程中观察到的可复用流程创建或更新 workspace skills它默认关闭需要通过plugins.entries.skill-workshop显式启用。文档还说明它只写入workspace/skills会扫描生成内容支持待审批或自动安全写入并在写入成功后刷新 skill snapshot。(OpenClaw)这意味着 Skill 不一定完全手写也可以来自用户纠正 Agent 成功工作流 反复出现的操作流程 团队内部最佳实践。例如用户多次提醒以后生成博客时先给标题再给目标再给正文最后给小结。这类稳定的写作偏好就可以沉淀成一个 Skill。20. ClawHub 与技能安装OpenClaw 支持通过 ClawHub 安装技能。官方文档说明ClawHub 是 OpenClaw 的公共技能注册表可以用openclaw skills install skill-slug安装到 workspace也可以加--global安装到共享 managed/local 目录。文档还列出了 Git skill、本地 skill、更新、验证等命令。(OpenClaw)常见命令包括openclaw skills install skill-slug openclaw skills install skill-slug --global openclaw skills install git:owner/reporef openclaw skills install ./path/to/skill --as my-tool openclaw skills update --all openclaw skills verify skill-slug这里要注意workspace install 只影响当前 agent workspace。 --global 安装到共享目录对本机多个 agent 可见。 verify 用于查看 ClawHub 提供的 skill trust envelope。21. Skill 的安全风险Skill 看起来只是 Markdown但它会影响 Agent 的行为甚至可能指导 Agent 使用exec、browser、write等高权限工具。官方文档明确提醒第三方 skills 要当作不可信代码处理启用前要阅读内容并且对不可信输入和高风险工具优先使用 sandbox。(OpenClaw)风险主要有几类第一恶意指令注入 Skill 可能要求 Agent 执行危险命令。 第二权限扩大 Skill 可能诱导 Agent 调用 exec、write、browser 等工具。 第三密钥泄露 Skill 可能把 env、apiKey 或本地文件内容写入日志或外部请求。 第四持久化污染 Skill 被安装后会在后续 session 中持续影响 Agent 行为。所以安装第三方 Skill 时不能只看 description而要看完整SKILL.md和附带脚本。22. Skill 和 Tool policy 的配合Skill 本身不会绕过 Tool policy。即使 Skill 指令里写着Use exec to run deployment script.如果当前 session 的 Tool policy 禁用了execAgent 仍然不能调用exec。所以二者关系是Skill 告诉 Agent 应该怎么做。 Tool policy 决定 Agent 实际能不能做。可以画成用户请求 ↓ Agent 看到 available_skills ↓ Skill 指导 Agent 选择流程 ↓ Agent 尝试调用 Tool ↓ Tool policy / sandbox / approval 决定是否允许 ↓ 执行结果返回 Agent这也是 OpenClaw 的重要设计Skill 是行为指导层Tool policy 是能力控制层。23. 一个完整例子代码审查 Skill假设我们想写一个repo-reviewSkill指导 Agent 审查代码仓库。可以这样写--- name: repo-review description: Review a code repository by checking changed files, running tests when appropriate, and producing structured review notes. metadata: {openclaw:{requires:{bins:[git]}}} --- # Repo Review Use this skill when the user asks to review a repository, inspect a pull request, or evaluate code changes. ## Workflow 1. Inspect the repository status and changed files. 2. Read the most relevant files before making judgments. 3. Run lightweight tests only when they are available and safe. 4. Separate findings into correctness, security, maintainability, and testing. 5. For each issue, explain the impact and suggest a concrete fix. 6. If no major issue is found, say what was checked and what remains unverified. ## Safety Do not run destructive commands. Do not modify files unless the user explicitly asks for edits. Do not expose secrets from local config or environment files.这个 Skill 的作用不是新增一个repo_review()函数而是让 Agent 在面对代码审查任务时遵循稳定流程。24. 一个完整例子命令式 Skill如果我们希望某个 Skill 只作为 slash command 使用不进入普通 prompt可以这样写--- name: service-health description: Check service health through a deterministic command. user-invocable: true disable-model-invocation: true command-dispatch: tool command-tool: gateway command-arg-mode: raw --- # Service Health This command checks the current service health.它的特点是用户可以显式调用 模型普通对话时看不到 slash command 可以直接 dispatch 到工具 适合固定、可审计、低歧义的运维入口。25. 初学者容易混淆的几个点25.1 Skill 不是 ToolTool 是动作 Skill 是动作说明。例如exec 是 Tool “如何安全运行部署脚本”是 Skill。25.2 Skill 安装了不代表 Agent 一定能用Skill 还会受到路径优先级 metadata gating skills.entries.enabled agent skill allowlist session snapshot sandbox 环境 tool policy。25.3 description 不是随便写的description会影响 Agent 是否知道这个 Skill 适合当前任务。写得太泛Agent 不容易判断写得太窄Skill 可能很少被触发。25.4 user-invocable 和 model invocation 是两件事user-invocable 用户能不能用 slash command 调用。 disable-model-invocation 模型普通 prompt 能不能看到。25.5 Skill 不能绕过安全策略即使 Skill 里写了危险操作Tool policy、sandbox 和 approval 仍然可以阻止对应工具执行。26. 源码阅读建议这一期建议重点看这些文件和关键词第一组Skill 加载与 workspace src/agents/skills/ src/agents/skills/workspace.ts 第二组Skill prompt 注入 formatSkillsForPrompt available_skills skill snapshot 第三组Skill 命令注册 src/auto-reply/skill-commands.ts src/auto-reply/commands-registry.ts src/auto-reply/commands-registry.shared.ts 第四组Skill 配置 skills.entries agents.defaults.skills agents.list[].skills skills.load.extraDirs skills.load.watch 第五组内置 Skill 示例 skills/*/SKILL.md skills/coding-agent/SKILL.md 第六组文档对照 docs/tools/skills.md docs/tools/creating-skills.md docs/tools/skills-config.md docs/tools/slash-commands.md阅读时可以带着这些问题1. OpenClaw 从哪些目录扫描 SKILL.md 2. 同名 Skill 冲突时怎么选择 3. metadata.openclaw.requires.bins 在哪里检查 4. skills.entries.enabled 如何禁用一个 Skill 5. agent skill allowlist 在 prompt building 前还是后生效 6. Skill 如何变成 slash command 7. disable-model-invocation 如何影响 prompt 8. command-dispatch: tool 如何绕过模型 9. session skill snapshot 什么时候刷新 10. Skill 和 Tool policy 的边界在哪里27. 我的理解我认为 OpenClaw 的 Skill 系统最值得学习的地方是它把“经验流程”从代码里抽出来变成一种可安装、可覆盖、可共享、可禁用的行为模块。普通 Agent 项目往往把行为规则写在一个巨大的 system prompt 里你要会写代码 你要会审查 PR 你要会查日志 你要会写邮件 你要会总结会议 你要会控制浏览器 ……这样的问题是 prompt 越来越大也越来越难维护。OpenClaw 的做法更模块化写代码有 coding skill 查日志有 log-analysis skill 浏览器自动化有 browser skill PR review 有 review skill 团队内部流程可以写成 workspace skill。每个 Skill 都是一个独立目录并且可以被不同 agent 按需加载。这使得 Agent 的行为控制从“一个大 prompt”变成了“多个可组合技能包”。28. 本期重点理解这一期可以总结为五点第一Tool 决定 Agent 能调用什么动作Skill 决定 Agent 如何组织这些动作。 第二Skill 的核心是 SKILL.md由 frontmatter 元数据和 Markdown 行为说明组成。 第三OpenClaw 按 workspace、project-agent、personal、managed、bundled、extraDirs 的顺序加载 Skill并用高优先级覆盖低优先级。 第四metadata.openclaw 提供了基于 OS、binary、env、config 的条件加载机制。 第五Skill 可以进入 Agent prompt也可以作为 slash command 被用户显式调用还可以通过 command-dispatch 直接映射到 Tool。一句话概括OpenClaw 的 Skill 系统本质上是把可复用的任务经验、工具使用流程和行为约束封装成可加载、可过滤、可覆盖的 Agent 行为模块。29. 本期小结本期主要分析了 OpenClaw 的 Skills 技能系统。Skill 与 Tool 不同Tool 提供动作能力Skill 提供如何使用这些动作的流程说明。每个 Skill 以SKILL.md为核心包含 frontmatter 元数据和 Markdown 指令。OpenClaw 会按多个目录加载 Skills并根据路径优先级、metadata gating、skills.entries配置、agent allowlist 和 session snapshot 生成当前 Agent 可见的技能集合。Skill 既可以进入普通 Agent prompt也可以通过user-invocable暴露为 slash command如果设置disable-model-invocation还可以避免进入模型普通上下文。对于确定性命令command-dispatch: tool可以让 slash command 直接调用 Tool。这一期可以用一句话总结Skill 是 OpenClaw 中沉淀经验流程的机制它让 Agent 不只是“有工具可用”而是“知道什么时候、按什么规则、以什么顺序使用工具”。下一期可以继续分析OpenClaw 源码解析十三Plugins 插件系统与能力扩展机制下一期重点看 OpenClaw 的插件目录结构、openclaw.plugin.json、插件如何注册工具、技能、Channel、Provider 和 hooks以及 Plugin、Tool、Skill 三者如何组合成完整的能力扩展链路。