乐于分享
好东西不私藏

OpenClaw 编程教程

OpenClaw 编程教程

OpenClaw 是你自己运行在硬件上的永久在线 AI Agent 框架,不是聊天机器人,而是一个能主动替你干活的数字员工。本文是AI编程进阶教程,面向 Cursor 用户,从配置文件到自定义 Skill 的完整开发指南。


目录

  1. OpenClaw 的”编程模型”是什么

  2. 工作区文件编程:SOUL / AGENTS / USER

  3. Prompt 工程:写出可靠的指令

  4. HEARTBEAT:用自然语言写定时任务

  5. SKILL.md 格式完整参考

  6. 实战一:写一个 Git Commit 生成器 Skill

  7. 实战二:写一个带外部 API 的 Skill(含凭证管理)

  8. 实战三:写一个含脚本的复合 Skill

  9. Skill 调试技巧

  10. Token 成本控制

  11. 安全编程规范

  12. 发布到 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: abc123Vercel 项目名: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 完整字段

---# 必填字段nameskill-name              # Skill 唯一名称,也是斜杠命令名 /skill-namedescription一句话说明什么时候触发这个 Skill,用用户会说的话写# 可选核心字段version1.0.0user-invocabletrue          # 是否作为 /斜杠命令 暴露给用户(默认 true)disable-model-invocationfalse  # 是否从模型提示词中隐藏(默认 false)# 高级调度字段command-dispatchtool        # 设为 tool 时,斜杠命令绕过模型直接调用工具command-toolexec            # 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 会被静默排除,不注入到系统提示词。这带来两个好处:

  1. Agent 不会建议用户使用当前环境无法运行的 Skill

  2. 减少不必要的 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:    primaryEnvLINEAR_API_KEY    envVars:      - nameLINEAR_API_KEY        requiredtrue        descriptionLinear API token,在 Settings > API 生成      - nameLINEAR_TEAM_ID        requiredfalse        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}}}}
  1. 解析响应,按优先级排序(urgent > high > medium > low > no priority)

  2. 格式化输出

输出格式

📋 **我的 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 <项目目录>"""importsysimportosimportjsonfrompathlibimportPathfromcollectionsimportdefaultdictfromdatetimeimportdatetimetimedeltaEXTENSIONS= {'.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=lambdaxx['modified'], reverse=True)return {'languages'dict(sorted(stats.items(), key=lambdaxx[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[1iflen(sys.argv>1else'.'ifnotos.path.isdir(path):print(json.dumps({'error'f'目录不存在: {path}'}))sys.exit(1)result=analyze(path)print(json.dumps(resultensure_ascii=Falseindent=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 var
  • envVars 正确声明了可选变量(用 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