OpenClaw 编程教程
OpenClaw 是你自己运行在硬件上的永久在线 AI Agent 框架,不是聊天机器人,而是一个能主动替你干活的数字员工。本文是AI编程进阶教程,面向 Cursor 用户,从配置文件到自定义 Skill 的完整开发指南。
目录
-
OpenClaw 的”编程模型”是什么
-
工作区文件编程:SOUL / AGENTS / USER
-
Prompt 工程:写出可靠的指令
-
HEARTBEAT:用自然语言写定时任务
-
SKILL.md 格式完整参考
-
实战一:写一个 Git Commit 生成器 Skill
-
实战二:写一个带外部 API 的 Skill(含凭证管理)
-
实战三:写一个含脚本的复合 Skill
-
Skill 调试技巧
-
Token 成本控制
-
安全编程规范
-
发布到 ClawHub
1. 编程模型
OpenClaw 的”编程”与写代码有什么不同
在 Cursor 里你写代码,代码精确执行。在 OpenClaw 里你写指令文档,LLM 解读后执行。
这个区别很关键:
传统编程: 你写 if (condition) { do_x() } → 机器精确执行OpenClaw: 你写 "当用户问X时,先做A,再做B" → LLM 解读后执行
这意味着:
-
指令越精确,行为越可预测
-
模糊的指令会让 Agent”自由发挥”——有时惊喜,有时翻车
-
## Rules段是你的”断言”,LLM 不遵守时,加规则比加逻辑更有效
三类”编程文件”
| 文件 | 作用类比 | 加载时机 |
|---|---|---|
SOUL.md |
全局配置 / main() 函数 |
每次会话开始 |
AGENTS.md |
权限声明 / .env |
每次会话开始 |
SKILL.md |
函数定义 / 模块 | 技能被触发时 |
HEARTBEAT.md |
Cron Job | 每 30 分钟轮询 |
文件加载顺序与优先级
OpenClaw 加载 Skills 时的优先级(高 → 低):
<workspace>/skills/ ← 项目级,优先级最高(可覆盖全局同名 Skill)~/.openclaw/skills/ ← 全局管理目录bundled skills ← 内置,优先级最低
2. 工作区文件编程
SOUL.md — 写好”全局系统提示词”
SOUL.md 本质上是每个会话注入给 LLM 的系统提示词的核心部分。它决定 Agent 的默认行为。
写法原则:指令而非描述
❌ 弱(描述性):你是一个聪明、乐于助人的 AI 助理。✅ 强(指令性):回复用中文,除非我用英文提问。给建议时:先给结论(一句话),再给理由(不超过三点)。执行任何文件操作前,说出你打算做什么,等我确认。
完整 SOUL.md 模板(开发者场景):
# Agent SOUL## 语言与风格- 用中文回复,英文代码/命令保持原样- 简洁直接,不加没用的客套话- 代码示例用代码块,不要行内混排## 行为规则- 执行不可逆操作(删除、推送、发送)前,先告知再确认- 不确定时,说"我不确定,建议你验证一下",而不是猜测- 遇到歧义,问我一个澄清问题,不要假设## 工具使用- 网页搜索:需要当前信息时自由使用- Shell 命令:描述后等我确认(危险命令除外,危险命令直接拒绝)- 文件读取:只读 ~/projects/ 下的内容## 记忆规则- 对话中出现重要决定或偏好,主动记录到 MEMORY.md- 被问到关于项目、工具、人员的事实性问题,先查 Memory Wiki
SOUL.md 的 Token 成本
每次会话 SOUL.md 完整注入上下文。控制在 500 词以内,否则长期积累大幅增加 API 费用。精炼优于全面。
AGENTS.md — 权限边界编程
AGENTS.md 是权限声明文件,用于约束 Agent 的自主行动范围。
# Agent 权限与规则## 允许自主执行(无需确认)- 网页搜索和信息查询- 读取 ~/projects/ 下的文件- 在 ~/projects/ 内创建和编辑文件- 查询 GitHub Issues 和 PR## 需要确认后执行- 运行任何 Shell 命令- 向外部服务发送请求(邮件、Slack 通知等)- 修改 Git 历史(amend、rebase)- 任何涉及生产环境的操作## 禁止执行- 删除文件(rm 命令)- 推送到 main/master 分支- 访问 ~/projects/ 以外的目录- 向非白名单域名发起请求## 并行执行规则- 需要研究多个独立子问题 → 使用 sessions_spawn 并行- 需要当前对话上下文 → 顺序执行- 单次并行子任务不超过 3 个## 记忆写入规则- 代码决策和架构选择 → 写入 MEMORY.md- 关于项目、依赖、团队成员的事实 → 写入 Memory Wiki
MEMORY.md — 可编程的持久状态
MEMORY.md 既可以让 Agent 自动维护,也可以手动编辑,相当于给 Agent 注入初始状态。
# 项目记忆## 技术栈偏好- 语言:TypeScript(优先),Python(数据处理)- 框架:Next.js App Router,不用 Pages Router- 数据库:PostgreSQL + Prisma,不用 Mongoose- 测试:Vitest,不用 Jest## 进行中的项目### ProjectAlpha- 目标:个人财务追踪工具- 技术栈:Next.js + Supabase + Tailwind- 当前状态:MVP 开发中,认证模块已完成- 关键决定:2026-04-15 决定用 Row Level Security 代替手动权限校验## 重要上下文- 生产数据库在 Supabase,project ref: abc123- Vercel 项目名:project-alpha-prod- 主分支保护规则:需要 1 个审查者 + CI 通过
3. Prompt 工程
写 Skill 和工作区文件,本质是在写给 LLM 的提示词。以下是让 OpenClaw 行为更可预测的核心技巧。
技巧一:用”触发条件 + 执行步骤 + 输出格式”三段式
## 触发条件当用户要求"总结 PR"或提供 GitHub PR URL 时,启动此 Skill。## 执行步骤1. 提取 PR 号或从 URL 解析2. 调用 `gh pr view <number> --json title,body,files,additions,deletions`3. 分析变更文件列表,归纳变更范围4. 生成摘要## 输出格式**[PR #编号] 标题**- 变更类型:[新功能 / Bug 修复 / 重构 / 文档]- 影响范围:[受影响的模块]- 核心改动:[2-3 句话]- 风险点:[如有] 或 无明显风险
技巧二:写 Rules 段约束边界行为
LLM 会在指令空白处”自由发挥”。## Rules 段是你的护栏:
## Rules- 只总结用户明确提供的 PR,不要自行假设 PR 号- 如果 gh 命令失败,报告错误信息,不要尝试其他方式获取数据- 摘要不超过 150 字,不要列出每个文件的修改- 不要在输出中包含 diff 内容
技巧三:负面示例比正面要求更有效
❌ 弱(正面要求):生成简洁的 commit message。✅ 强(负面约束):生成 commit message。不要超过 72 个字符。不要用"Update"、"Fix"、"Add"以外以外的动词开头。不要包含 ticket 编号(除非我明确要求)。不要描述"如何"修改,只描述"修改了什么"。
技巧四:给出确定的失败处理逻辑
## 错误处理- 如果命令退出码非 0:输出命令和错误信息,停止,等待用户指令- 如果 API 返回 4xx:说明错误原因,提示用户检查凭证或权限- 如果输出为空:告知用户"未找到匹配结果",不要猜测原因
4. HEARTBEAT:定时任务编程
HEARTBEAT.md 是 OpenClaw 的 Cron 系统,用自然语言写,每 30 分钟轮询执行。
基本格式
## 任务名称**时间**:[时间表达式]**任务**:[具体指令]
时间表达式写法
# ✅ 可靠写法(明确时间)每天 7:30 AM(Asia/Shanghai)每周一 9:00 AM每月 1 号 2:00 AM每周一、三、五 10:00 AM# ⚠️ 不可靠写法(模糊时间)每天早上每隔几天工作日上午
完整 HEARTBEAT 示例
# HEARTBEAT 定时任务## 每日开发简报**时间**:每天 8:00 AM(Asia/Shanghai)**任务**:1. 运行 `git -C ~/projects/project-alpha log --oneline --since="24 hours ago"` 获取昨日 commits2. 调用 GitHub API 查询分配给我的未处理 Issues3. 搜索关键词 "Next.js" OR "Supabase" 最近 24 小时重要更新4. 整合后通过 Telegram 发给我,格式:---📅 **开发简报 [日期]**🔧 **昨日进展**([N] 个 commits)[commit 列表,每行一个,附简短描述]📋 **待处理 Issues**([N] 个)[Issue 列表]📡 **技术动态**[1-3 条最值得关注的更新]---## 每周依赖安全检查**时间**:每周一 10:00 AM**任务**:1. 在 ~/projects/project-alpha 运行 `npm audit --json`2. 解析结果,筛选 severity 为 high 或 critical 的漏洞3. 如果存在高危漏洞,立即通过 Telegram 发警告4. 如果没有,记录到本周日志,不需要通知我## 月度 Memory 维护**时间**:每月 1 号 3:00 AM**任务**:运行 wiki_lint,检查 Memory Wiki 中超过 60 天未更新的条目对过期条目添加 "⚠️ 待核实" 标记通过 Telegram 发送维护摘要(条目数量、标记数量)
HEARTBEAT 的编程陷阱
陷阱一:任务依赖未准备好的工具
在 HEARTBEAT 里调用某个 Skill 前,先在聊天窗口手动测试这个 Skill。HEARTBEAT 失败时没有交互提示,只会静默失败或记录错误日志。
陷阱二:指令过长导致 Token 消耗爆炸
每次 HEARTBEAT 执行,都要把整个 HEARTBEAT.md 注入上下文。任务越多、描述越详细,每次执行成本越高。建议把复杂任务逻辑封装进 Skill,HEARTBEAT 只调用 Skill 名:
## 每日简报**时间**:每天 8:00 AM**任务**:运行 /daily-brief Skill
5. SKILL.md 格式完整参考
Skill 是 OpenClaw 的模块系统,每个 Skill 是一个目录,包含带有 YAML frontmatter 和指令内容的 SKILL.md 文件。
目录结构
~/.openclaw/skills/└── my-skill/ ├── SKILL.md # 必须,核心文件 ├── scripts/ │ └── run.py # 可选,Skill 调用的脚本 └── templates/ └── output.md # 可选,输出模板
SKILL.md Frontmatter 完整字段
---# 必填字段name: skill-name # Skill 唯一名称,也是斜杠命令名 /skill-namedescription: 一句话说明什么时候触发这个 Skill,用用户会说的话写# 可选核心字段version: 1.0.0user-invocable: true # 是否作为 /斜杠命令 暴露给用户(默认 true)disable-model-invocation: false # 是否从模型提示词中隐藏(默认 false)# 高级调度字段command-dispatch: tool # 设为 tool 时,斜杠命令绕过模型直接调用工具command-tool: exec # command-dispatch: tool 时指定工具名# OpenClaw 专属元数据(必须是单行 JSON)metadata: {"openclaw": { "emoji": "🔧", "requires": { "bins": ["git","gh"],# 必须全部在 PATH 中存在 "anyBin": ["python3","python"],# 至少一个存在即可 "env": ["GITHUB_TOKEN"],# 必须设置的环境变量 "config": ["browser.enabled"]# openclaw.json 中必须为 true 的配置项}, "os": ["darwin","linux"],# 限制操作系统(darwin/linux/win32) "primaryEnv": "GITHUB_TOKEN",# 映射到 openclaw.json 的 apiKey 快捷键 "install": [{ "id": "gh-brew", "kind": "brew",# 安装方式:brew / node / go / uv / download "formula": "gh", "bins": ["gh"], "label": "Install GitHub CLI"}]}}---
Metadata Gating 工作原理
OpenClaw 在加载时根据元数据过滤 Skills:如果 requires 中声明的 bin 不在 PATH 中,或者环境变量不存在,该 Skill 会被静默排除,不注入到系统提示词。这带来两个好处:
-
Agent 不会建议用户使用当前环境无法运行的 Skill
-
减少不必要的 Token 消耗
# 示例:只在有 Docker 时才加载的 Skillmetadata: {"openclaw": {"requires": {"bins": ["docker"]}}}
斜杠命令的两种模式
模式一:经过模型(默认)
user-invocable: true# 用户输入 /my-skill <args># → 模型读取 SKILL.md 指令 → 模型决定如何执行
模式二:直接调用工具(绕过模型)
user-invocable: truecommand-dispatch: toolcommand-tool: exec# 用户输入 /my-skill <args># → 直接执行 exec 工具,参数原样传入# 调用参数格式:{ command: "<args>", commandName: "my-skill", skillName: "my-skill" }
适合用于:确定性命令、不需要 LLM 理解的操作、需要低延迟的场景。
只作为斜杠命令,不自动触发
user-invocable: truedisable-model-invocation: true# 该 Skill 不出现在模型上下文中(节省 Token)# 只能用 /skill-name 显式调用
适合:危险操作、高成本操作、不希望被自动推断触发的 Skill。
6. 实战一:Git Commit 生成器
目标
输入 /commit,Agent 读取当前 staged 变更,自动生成符合 Conventional Commits 规范的 commit message。
创建 Skill
mkdir-p ~/.openclaw/skills/git-commit-gennano ~/.openclaw/skills/git-commit-gen/SKILL.md
---name: git-commit-gendescription: 根据 git diff --staged 内容生成 Conventional Commits 格式的 commit message。当用户说"帮我写 commit"或直接输入 /git-commit-gen 时触发。version: 1.0.0user-invocable: truemetadata: {"openclaw": {"emoji": "📝", "requires": {"bins": ["git"]}}}---## 触发条件用户要求生成 commit message,或输入 /git-commit-gen。## 执行步骤1. 运行 `git diff --staged --stat` 获取变更文件列表和统计2. 运行 `git diff --staged` 获取完整 diff- 如果 diff 超过 200 行,只取前 200 行,并注明"diff 已截断"3. 分析变更内容,判断变更类型4. 生成 commit message## Conventional Commits 规范格式:`<type>(<scope>): <subject>`类型(type)选择规则:- feat:新功能- fix:Bug 修复- refactor:重构(不新增功能,不修复 Bug)- docs:文档变更- test:测试相关- chore:构建/工具链/依赖变更- perf:性能优化- style:格式变更(不影响功能)scope:受影响的模块名,如 auth、db、api。如果跨多个模块,省略 scope。subject:- 用祈使句(英文)- 不超过 72 字符- 首字母小写- 结尾不加句号## 输出格式给出 1-3 个候选 commit message,从最推荐到备选排列:
推荐:feat(auth): add JWT refresh token rotation
备选:feat: add refresh token support to authentication
如果变更涉及 BREAKING CHANGE,在 message 后加:
BREAKING CHANGE: <描述变更影响>
## Rules- 如果没有 staged 变更(git diff --staged 为空),告知用户需要先 git add- 不要自动执行 git commit,只生成 message- 不要在输出中包含完整 diff 内容- subject 用英文,不要用中文
测试
# 在你的某个项目目录cd ~/projects/project-alphagit add src/auth/refresh.ts# 在 OpenClaw Web UI 或 Telegram/git-commit-gen
预期输出:
推荐:feat(auth): add JWT refresh token rotation备选:feat: implement refresh token support in auth module
调试技巧
如果 Skill 没有触发,检查:
# 查看已加载的 Skillsopenclaw skills list# 如果 git-commit-gen 不在列表里,检查 git 是否在 PATHwhich git# 重新加载 Skills(无需重启 Gateway)openclaw skills reload
7. 实战二:外部 API Skill(含凭证管理)
目标
创建一个 Skill,调用 Linear(项目管理工具)API 查询我的待办 Issues,支持凭证安全管理。
凭证管理方式
OpenClaw 有三种注入凭证的方式:
方式一:primaryEnv(推荐,用于单一 API Key 的 Skill)
在 openclaw.json 中用 apiKey 字段管理:
{ "skills": { "entries": { "linear-issues": { "enabled": true, "apiKey": "lin_api_xxxxxxxxxxxx" } } }}
Skill frontmatter 中声明:
metadata: {"openclaw": {"primaryEnv": "LINEAR_API_KEY", "requires": {"env": ["LINEAR_API_KEY"]}}}
方式二:env 对象(多个环境变量)
{"skills": {"entries": {"my-skill": {"enabled": true,"env": {"API_KEY": "sk-...","API_BASE": "https://api.example.com" } } } }}
方式三:envVars 声明(ClawHub 发布规范,含可选变量)
metadata: openclaw: primaryEnv: LINEAR_API_KEY envVars: - name: LINEAR_API_KEY required: true description: Linear API token,在 Settings > API 生成 - name: LINEAR_TEAM_ID required: false description: 可选,指定默认团队 ID,不填则显示所有团队的 Issues
安全原则:永远不要在 SKILL.md 指令文本里打印或传递 API Key。凭证只通过环境变量注入,不出现在提示词里。
完整 Skill 实现
mkdir -p ~/.openclaw/skills/linear-issues
~/.openclaw/skills/linear-issues/SKILL.md:
---name: linear-issuesdescription: 查询 Linear 上分配给我的待处理 Issues。当用户问"我的 Linear 任务"或"待办 Issues"时触发。version: 1.0.0user-invocable: truemetadata: {"openclaw": {"emoji": "📋", "primaryEnv": "LINEAR_API_KEY", "requires": {"env": ["LINEAR_API_KEY"]}}}---## 触发条件用户查询 Linear Issues、待办任务,或输入 /linear-issues。## 执行步骤1. 调用 Linear GraphQL API:- Endpoint: `https://api.linear.app/graphql`- Header: `Authorization: <LINEAR_API_KEY>`- Query:```graphqlquery MyIssues {viewer {assignedIssues(filter: { state: { type: { nin: ["completed", "cancelled"] } } }orderBy: updatedAt) {nodes {identifiertitleprioritystate { name }dueDateurl}}}}
-
解析响应,按优先级排序(urgent > high > medium > low > no priority)
-
格式化输出
输出格式
📋 **我的 Linear Issues**(共 N 个)🔴 紧急• [ENG-123] Issue 标题 → [链接]🟠 高优先级• [ENG-124] Issue 标题(截止:2026-06-01)→ [链接]🟡 中优先级• [ENG-125] Issue 标题 → [链接]
Rules
-
不要在输出中显示 API Key 或任何认证信息
-
如果 API 返回错误,显示错误码和消息,不要重试
-
如果没有任何 Issues,回复”当前没有分配给你的待处理 Issues”
-
只显示未完成的 Issues,不显示 completed 或 cancelled 状态
### 配置凭证```bash# 编辑 openclaw.jsonnano ~/.openclaw/openclaw.json
{"skills": {"entries": {"linear-issues": {"enabled": true,"apiKey": "lin_api_你的真实Token" } } }}
测试
/linear-issues
或自然语言触发:
帮我看一下 Linear 上有哪些待办任务
8. 实战三:含脚本的复合 Skill
有些任务需要精确计算或复杂数据处理,单靠 LLM 指令不够可靠。这时可以在 Skill 目录里放脚本,让 LLM 调用脚本而不是自己计算。
目标
创建一个 Skill,分析项目目录的代码统计(各语言行数、文件数、最近活跃文件),输出可读报告。
目录结构
~/.openclaw/skills/code-stats/├── SKILL.md└── scripts/ └── analyze.py
scripts/analyze.py
#!/usr/bin/env python3"""代码统计脚本用法:python3 analyze.py <项目目录>"""importsysimportosimportjsonfrompathlibimportPathfromcollectionsimportdefaultdictfromdatetimeimportdatetime, timedeltaEXTENSIONS= {'.ts': 'TypeScript', '.tsx': 'TypeScript','.js': 'JavaScript', '.jsx': 'JavaScript','.py': 'Python','.go': 'Go','.rs': 'Rust','.md': 'Markdown','.css': 'CSS', '.scss': 'CSS','.json': 'JSON','.sql': 'SQL',}IGNORE_DIRS= {'.git', 'node_modules', '.next', 'dist', 'build', '__pycache__', '.venv'}defanalyze(root_path):stats=defaultdict(lambda: {'files': 0, 'lines': 0})recent_files= []cutoff=datetime.now() -timedelta(days=7)forpathinPath(root_path).rglob('*'):ifany(partinIGNORE_DIRSforpartinpath.parts):continueifnotpath.is_file():continueext=path.suffix.lower()lang=EXTENSIONS.get(ext)ifnotlang:continuetry:mtime=datetime.fromtimestamp(path.stat().st_mtime)lines=len(path.read_text(errors='ignore').splitlines())stats[lang]['files'] +=1stats[lang]['lines'] +=linesifmtime>cutoff:recent_files.append({'path': str(path.relative_to(root_path)),'lines': lines,'modified': mtime.strftime('%m-%d %H:%M') })exceptException:continuerecent_files.sort(key=lambdax: x['modified'], reverse=True)return {'languages': dict(sorted(stats.items(), key=lambdax: x[1]['lines'], reverse=True)),'recent_files': recent_files[:10],'total_files': sum(v['files'] forvinstats.values()),'total_lines': sum(v['lines'] forvinstats.values()), }if__name__=='__main__':path=sys.argv[1] iflen(sys.argv) >1else'.'ifnotos.path.isdir(path):print(json.dumps({'error': f'目录不存在: {path}'}))sys.exit(1)result=analyze(path)print(json.dumps(result, ensure_ascii=False, indent=2))
SKILL.md
---name: code-statsdescription: 分析项目目录的代码统计:各语言文件数和行数、最近修改的文件。当用户问"代码统计"、"项目大小"或"最近改了什么文件"时触发。version: 1.0.0user-invocable: truemetadata: {"openclaw": {"emoji": "📊", "requires": {"anyBin": ["python3", "python"]}}}---## 触发条件用户查询代码统计信息,或输入 /code-stats [目录路径]。## 执行步骤1. 确定目标目录: - 用户提供了路径 → 使用该路径 - 未提供路径 → 使用 ~/projects/ 下最近活跃的项目目录 - 如果无法确定,询问用户2. 运行分析脚本:
python3 {baseDir}/scripts/analyze.py <目标目录>
注意:`{baseDir}` 是此 Skill 的文件夹路径,由 OpenClaw 自动替换3. 解析 JSON 输出,格式化报告## 输出格式
📊 代码统计:[项目名]
语言分布(共 N 个文件,M 行代码)
| 语言 | 文件数 | 行数 | 占比 |
|---|---|---|---|
| TypeScript | 42 | 8,320 | 67% |
| … |
近 7 天活跃文件(共 N 个)• src/auth/refresh.ts — 234 行(05-16 14:23 修改)• …
## Rules- 使用 `{baseDir}` 引用脚本路径,不要硬编码绝对路径- 如果脚本返回 error 字段,显示错误信息并停止- 行数使用千分位格式(8,320 而非 8320)- 占比四舍五入到整数
{baseDir}是 OpenClaw 的特殊变量,在运行时自动替换为 Skill 目录的绝对路径。
9. Skill 调试
查看 Skill 是否加载
# 列出所有已加载的 Skillsopenclaw skills list# 查看某个 Skill 的详情openclaw skills show git-commit-gen# 强制重新加载(修改文件后)openclaw skills reload
Skill 没被触发的常见原因
原因一:description 写得不好
description 是触发信号,LLM 用它决定哪个 Skill 匹配当前意图。
❌ 弱 description:description: 处理 git 相关任务✅ 强 description:description: 根据 git staged 变更生成 Conventional Commits 格式的 commit message。当用户说"帮我写 commit"、"生成提交信息"时触发。
原因二:Gating 条件不满足
# 检查依赖的命令是否存在which ghwhich python3# 检查环境变量echo $LINEAR_API_KEY
原因三:与其他 Skill description 重叠
两个 Skill 的 description 太相似,LLM 不知道选哪个。解决方法:明确区分触发场景,或合并成一个 Skill。
查看 Agent 实际看到的 Skill 列表
在 Web UI 聊天中输入:
你现在加载了哪些 Skills?把名字和描述列给我看。
Agent 会列出当前注入到系统提示词中的所有 Skills,帮你确认哪些加载了、哪些被 Gating 排除了。
追踪 Token 使用
# 查看最近 24 小时的 Token 消耗openclaw usage --hours 24# 查看按模型分类的消耗openclaw usage --breakdown model
10. Token 成本控制
当有至少 1 个 Skill 时,Skills 列表基础开销为 195 个字符,此后每个 Skill 的成本是确定性的。Skill 越多,每次对话成本越高。
成本来源
每次对话,以下内容全部注入上下文:
-
SOUL.md 全文
-
AGENTS.md 全文
-
MEMORY.md 全文
-
所有已加载 Skill 的 name + description(摘要列表)
-
触发的 Skill 的完整 SKILL.md 内容
优化策略
策略一:用 Gating 减少加载的 Skill 数量
# 只在有 docker 时才加载metadata: {"openclaw": {"requires": {"bins": ["docker"]}}}# 只在有 API Key 时才加载metadata: {"openclaw": {"requires": {"env": ["REPLICATE_API_TOKEN"]}}}
策略二:用 disable-model-invocation 隐藏不常用的 Skill
user-invocable: truedisable-model-invocation: true # 不出现在模型上下文,只能手动 /调用
策略三:HEARTBEAT 任务引用 Skill 而非写完整指令
## 每日简报**时间**:每天 8:00 AM**任务**:运行 /daily-brief# 把复杂逻辑放到 daily-brief Skill 里,而不是全写在 HEARTBEAT.md
策略四:按任务复杂度路由模型
{ "models": { "default": "claude-haiku-4-5", "heartbeat": "claude-haiku-4-5", "reasoning": "claude-sonnet-4-6" }}
策略五:定期整理 MEMORY.md
MEMORY.md 每次会话全量注入。随着时间积累可能变得很大,定期归档过期信息。
11. 安全编程规范
为什么重要
ClawHub 上发布了超过 1,000 个贡献者的 Skills,安全审计发现其中有相当一部分包含恶意 payload。编写和安装 Skill 都要当作代码审查对待。
编写 Skill 的安全规范
规范一:凭证不入提示词
❌ 危险:使用 API Key "sk-abc123" 调用 API✅ 正确:使用 $MY_API_KEY 环境变量调用 API(在 openclaw.json 的 skills.entries 中配置)
规范二:在 Rules 中明确限制文件操作范围
## Rules- 只读写 ~/projects/<项目名>/ 目录内的文件- 不允许访问 ~ 根目录或 /etc /var 等系统目录- 不允许执行任何 rm 命令
规范三:Skill 的最小权限原则
Skill 的指令只申请完成任务所需的最小权限。如果只需要读 Git 信息,不要写”可以操作 Git 仓库”这种模糊的宽权限指令。
规范四:对 ClawHub Skills 做代码审查
安装社区 Skill 前:
# 先查看 SKILL.md 内容,不要直接安装clawhub view <slug># 查看 scripts/ 目录下的所有脚本clawhub inspect <slug>
检查要点:
-
是否有 base64 编码的内容(常见混淆手段)
-
是否在 prerequisite 里要求运行安装命令
-
是否访问
~/.ssh、~/.aws、~/.config等敏感目录 -
是否有不必要的网络请求
规范五:高危 Skill 用 Docker 沙箱隔离
{ "agents": { "defaults": { "sandbox": { "docker": { "enabled": true, "image": "node:24-alpine", "setupCommand": "apk add --no-cache git python3" } } } }}
沙箱内运行的 Skill,文件系统操作和命令执行只影响容器,不影响宿主机。
12. 发布到 ClawHub
发布前检查清单
name在 ClawHub 上唯一description清楚描述触发条件,用用户会说的话requires字段声明了所有依赖的 bin 和 env varenvVars正确声明了可选变量(用required: false)- 凭证只通过环境变量使用,不出现在提示词文本中
## Rules段有明确的失败处理和操作边界- 至少包含
version字段 - scripts/ 中的脚本无混淆代码,可读
发布步骤
# 1. 安装 clawhub CLInpm install -g clawhub# 2. 登录(需要 GitHub 账号,注册超过 1 周)clawhub login# 3. 发布clawhub publish ~/.openclaw/skills/my-skill \--slug my-skill-name \--name"My Skill Display Name" \--version1.0.0 \--tags productivity,github# 4. 后续更新clawhub publish ~/.openclaw/skills/my-skill \--slug my-skill-name \--version1.1.0
好的 Skill description 写法(影响被发现的概率)
# 用用户会搜索的词❌ 弱:description: A useful tool for git operations✅ 强:description: 根据 git staged 内容生成 Conventional Commits 格式的提交信息(commit message)。支持 feat/fix/refactor 等类型自动判断。为什么强:包含了"Conventional Commits"(专有名词)、"commit message"(用户搜索词)、具体功能描述
总结:OpenClaw 编程速查
你想要... 写在哪里 用什么格式──────────────────────────────────改变 Agent 说话方式 SOUL.md 自然语言指令控制 Agent 能做什么 AGENTS.md 权限声明让 Agent 记住你的偏好 MEMORY.md Markdown 笔记定时自动执行任务 HEARTBEAT.md 时间 + 自然语言指令封装可复用的功能 SKILL.md YAML frontmatter + 指令调用外部 API SKILL.md + openclaw.json 凭证用 env 注入需要精确计算/处理 SKILL.md + scripts/ 指令 + Python/Bash 脚本限制 Skill 的触发范围 SKILL.md Gating + disable-model-invocation
基于 OpenClaw v2026.4.7+,官方文档:https://docs.openclaw.ai/tools/skills
夜雨聆风