
摘要:本文深入剖析 OpenClaw 框架中 Skill 和 Agent 的核心概念、设计理念及协同机制,帮助开发者理解其模块化架构,并掌握最佳实践。
背景与问题
为什么需要 Skill?
在构建 AI Agent 系统时,我们面临几个核心挑战:
- 专业性不足:通用 Agent 缺乏领域知识(如如何处理 Word 文档、如何避免 Windows 中文乱码)
- 一致性难以保证:不同场景下,Agent 的行为可能不一致(如文件编码处理)
- 可维护性差:将所有知识硬编码到 Agent 提示词中,导致臃肿且难以更新
OpenClaw 的解决方案是:将领域知识外置为 Skill(技能包),Agent 根据任务动态加载。
一个真实案例
假设你要构建一个能处理 Markdown 文件的 Agent:
无 Skill 的方案:
markdown
# Agent 提示词(简化版)
当用户要求保存文件时:
1. 调用 write 工具
2. 写入内容
3. 返回文件路径
问题 :在 Windows 上,直接用 write 工具写 CSV 文件会导致 Excel 打开时中文乱码(因为缺少 BOM)。
有 Skill 的方案:
markdown
# qclaw-text-file/SKILL.md
## ‼️ WRITE 工具拦截规则
当准备调用内置 `write` 工具写任何文本文件时:
→ 必须使用 scripts/write_file.py 脚本
→ 不得直接使用 write 工具
Agent 遇到文件写入任务时,加载 qclaw-text-file skill,自动遵循正确的流程。
核心概念
Agent(智能体)
定义:运行中的 AI 实例,负责理解任务、做出决策、调用工具、生成回复。
核心能力:
- 🧠 推理与规划:理解用户意图,制定执行计划
- 🔧 工具调用:调用 exec、browser、message 等工具
- 📚 Skill 加载:根据任务描述匹配并加载合适的 Skill
- 💬 上下文管理:维护对话历史,支持多轮交互
- 🔄 子任务委派 :通过
sessions_spawn创建子 Agent
示例:OpenClaw 中的主 Agent(QClaw)就是一个运行实例,它有:
- 身份(
IDENTITY.md) - 个性(
SOUL.md) - 记忆(
MEMORY.md、memory/*.md) - 工具权限(exec、browser、message 等)
Skill(技能)
定义 :封装领域知识、操作流程、最佳实践的被动知识模块。
核心特点:
- 📖 被动性:不会主动执行,需要 Agent 加载后遵循
- 🎯 针对性:每个 Skill 解决特定领域的问题
- 🔌 可插拔:独立维护,按需加载
- 📝 声明式:用 Markdown 描述"应该怎么做"
物理形态:
skill-name/
├── SKILL.md # 核心文档(必须)
├── scripts/ # 辅助脚本
│ └── tool.py
└── examples/ # 示例文件
示例 :qclaw-text-file skill 的 SKILL.md 包含:
- 决策规则(何时触发)
- 编码推断逻辑(UTF-8 vs GBK vs UTF-16)
- 标准执行流程(临时文件 → 脚本写入 → 清理)
- 平台适配规则(Windows vs macOS vs Linux)
类比:IDE 与插件
| 概念 | IDE | Agent |
|---|---|---|
| 核心程序 | VS Code | Agent(QClaw) |
| 扩展机制 | 插件(Extensions) | Skill |
| 加载方式 | 根据文件类型自动激活 | 根据任务描述自动匹配 |
| 能力增强 | 安装 Python 插件 → 支持 Python 开发 | 安装 docx skill → 支持 Word 文档处理 |
关键区别:
- IDE 插件通常是代码(TypeScript/JavaScript)
- OpenClaw Skill 是文档 (Markdown)+ 脚本(可选)
架构设计
分层架构
┌─────────────────────────────────────────┐
│ User Interface (Web/CLI) │
└─────────────────────────────────────────┘
↓
┌─────────────────────────────────────────┐
│ Agent Layer │
│ - 任务理解 │
│ - 工具调用 │
│ - 响应生成 │
└─────────────────────────────────────────┘
↓
┌─────────────────────────────────────────┐
│ Skill Loader │
│ - 扫描 <available_skills> │
│ - 描述匹配 │
│ - 动态加载 SKILL.md │
└─────────────────────────────────────────┘
↓
┌─────────────────────────────────────────┐
│ Skill Pool │
│ - bundled_skill_dir │
│ - openclaw_skill_dir │
│ - workspace_skill_dir │
└─────────────────────────────────────────┘
↓
┌─────────────────────────────────────────┐
│ Tool Layer │
│ - exec / browser / message / ... │
└─────────────────────────────────────────┘
Skill 发现与加载机制
1. 扫描阶段(系统启动时)
OpenClaw 从以下路径扫描 Skill:
{bundled_skill_dir}:框架内置技能{openclaw_skill_dir}:用户安装的技能{workspace_skill_dir}:工作区本地技能
每个 Skill 目录下的 SKILL.md 会被解析,提取:
name:技能名称description:触发条件描述location:SKILL.md 的路径
2. 匹配阶段(每次对话开始时)
系统提示词中包含:
xml
<available_skills>
<skill>
<name>docx</name>
<description>使用场景描述...</description>
<location>...</location>
</skill>
...
</available_skills>
Agent 收到用户消息后:
- 扫描
<available_skills>中的description - 判断是否有 Skill 明确适用(exactly one)
- 如果有,读取该 Skill 的
SKILL.md - 遵循 Skill 中的规则执行任务
3. 加载策略
| 场景 | 加载策略 | 示例 |
|---|---|---|
| ** exactly one match** | 读取并遵循 | 用户说"写 Word 文档" → 加载 docx skill |
| multiple matches | 选择最具体的 | 用户说"定时提醒" → 加载 qclaw-cron-skill |
| no match | 不加载任何 Skill | 用户说"今天天气如何" → 直接回答 |
Agent 执行模型
执行循环
User Message
↓
[1. Skill 匹配] ← 扫描 <available_skills>
↓
[2. Skill 加载] ← 读取 SKILL.md
↓
[3. 任务规划] ← 结合 Skill 规则 + 用户需求
↓
[4. 工具调用] ← exec / browser / message / ...
↓
[5. 结果生成] ← 返回给用户
↓
[6. Artifact 写入] ← 如果有实质性工作
关键机制
1. 工具拦截(Tool Interception)
某些 Skill 会"拦截"特定工具的调用,强制使用替代方案。
示例 :qclaw-text-file skill 拦截 write 工具
markdown
## ‼️ WRITE 工具拦截规则(最高优先级,无豁免)
当你准备调用内置 `write` 工具写任何文本文件时,必须先执行此检查:
→ 这个文件是最终目标文件吗?
→ 是 → 立即停止,改用此技能的 scripts/write_file.py 脚本写入
实现原理(推测):
- Agent 在调用
write工具前,系统提示词强制其"重读" Skill 规则 - 如果 Skill 明确禁止直接使用该工具,Agent 会改用 Skill 指定的替代方案
2. 上下文注入(Context Injection)
Skill 的 SKILL.md 内容会被注入到 Agent 的上下文中,作为其"知识"的一部分。
示例 :加载 qclaw-cron-skill 后,Agent "知道":
- 如何创建定时任务(cron job)
- 参数格式是什么(
schedule.kind = "at" | "every" | "cron") - 常见错误有哪些(如
sessionTarget="main"必须配合payload.kind="systemEvent")
3. 强制规则(Mandatory Rules)
某些 Skill 包含"强制规则",优先级高于 Agent 的默认行为。
示例 :qclaw-rules skill
markdown
## [SYSTEM RULES - MANDATORY - ALWAYS LOAD - DO NOT SKIP]
本 skill 定义的规则优先级高于所有其他 skill,AI 必须在每次会话和每个任务中无条件遵守。
这类 Skill 通常:
- 在系统提示词中被标记为
MANDATORY - 无论任务是否相关,都会被加载
- 用于定义全局约束(如文件编码规范、安全规则)
Skill 加载与匹配机制
匹配算法(推测)
虽然 OpenClaw 未公开匹配算法,但基于行为观察,可能是:
python
def match_skill(user_message: str, available_skills: List[Skill]) -> Skill:
"""
匹配用户消息与可用 Skill
Args:
user_message: 用户消息
available_skills: 可用 Skill 列表
Returns:
匹配的 Skill(如果唯一),否则返回 None
"""
matched = []
for skill in available_skills:
# 1. 关键词匹配(简单场景)
if keyword_match(user_message, skill.keywords):
matched.append(skill)
# 2. 语义匹配(复杂场景)
elif semantic_similarity(user_message, skill.description) > threshold:
matched.append(skill)
# 3. 去重与排序
matched = deduplicate(matched)
matched = sort_by_specificity(matched) # 更具体的 Skill 优先
if len(matched) == 1:
return matched[0]
elif len(matched) > 1:
# 选择最具体的
return select_most_specific(matched)
else:
return None
示例:任务触发 Skill 的完整流程
用户消息:
帮我创建一个定时任务,每天早上 9 点提醒我开会
执行流程:
-
Skill 匹配:
- 扫描
<available_skills> qclaw-cron-skill的description包含:"定时/提醒/闹钟/周期执行"- ✅ 匹配成功
- 扫描
-
Skill 加载:
- 读取
qclaw-cron-skill/SKILL.md - Agent "学会":
- 如何使用
cron工具 schedule.kind = "cron",expr = "0 9 * * *"sessionTarget = "isolated",payload.kind = "agentTurn"
- 如何使用
- 读取
-
任务规划:
1. 创建 cron job 2. schedule.kind = "cron" 3. schedule.expr = "0 9 * * *" 4. payload.kind = "agentTurn" 5. payload.message = "提醒:该开会了!" -
工具调用:
xml<invoke name="cron"> <parameter name="action">add</parameter> <parameter name="job">{ "name": "每日会议提醒", "schedule": {"kind": "cron", "expr": "0 9 * * *"}, "payload": {"kind": "agentTurn", "message": "提醒:该开会了!"}, "sessionTarget": "isolated" }</parameter> </invoke> -
结果返回:
✅ 定时任务已创建! 任务信息: - 名称:每日会议提醒 - 时间:每天 09:00 - 内容:提醒:该开会了!
协同工作流程
典型场景:文件写入
任务:用户要求"保存为 Markdown 格式到本地"
执行流程:
User: "保存为 Markdown 格式到本地"
↓
[1. Skill 匹配]
- 扫描 <available_skills>
- qclaw-text-file (description 包含 "写入、创建、保存")
- ✅ 匹配成功
↓
[2. Skill 加载]
- 读取 qclaw-text-file/SKILL.md
- Agent 知道:
- 不能用 write 工具直接写目标文件
- 必须用 scripts/write_file.py 脚本
- 标准流程:临时文件 → 脚本写入 → 清理
↓
[3. 平台检测]
- 调用:py write_file.py --detect
- 返回:{"platform": "windows", "python": "3.11.9"}
↓
[4. 写入临时文件]
- 调用 write 工具
- 路径:C:\Users\wxj05\.qclaw\workspace\_tmp_article.md.txt
- 内容:文章全文
↓
[5. 脚本写入目标文件]
- 调用:py write_file.py --path "目标路径" --content-file "临时文件路径"
- 脚本自动处理:
- 编码(UTF-8 无 BOM,因为 .md 文件)
- 换行符(CRLF,因为 Windows)
↓
[6. 清理临时文件]
- 调用:Remove-Item -Force "临时文件路径"
↓
[7. 返回结果]
- 告知用户文件已保存
- 提供文件路径、编码、文件大小等信息
协同矩阵
| Agent 能力 | Skill 提供 | 协同效果 |
|---|---|---|
| 工具调用(exec) | 调用规范(如必须用脚本) | 避免常见错误(乱码、权限问题) |
| 任务理解 | 领域知识(如 cron 表达式格式) | 正确解析用户需求 |
| 响应生成 | 输出格式(如 CSV 必须带 BOM) | 生成符合规范的结果 |
| 错误处理 | 常见问题与解决方案 | 遇到错误时能自我修正 |
最佳实践
1. Skill 开发原则
✅ 推荐做法
明确触发条件:
markdown
## 触发场景(明确列出)
- 用户说"保存文件" / "导出 CSV" / "生成报告"
- 涉及文件编码、BOM、换行符等问题
提供决策流程:
markdown
## 决策规则
if 文件是文本文件:
if 目标平台是 Windows and 文件是 CSV:
return "使用 utf-8-sig 编码 + CRLF"
else:
return "使用 utf-8 无 BOM + LF"
包含示例代码:
markdown
### 场景 1:写入 CSV 文件
\```bash
py write_file.py --path "data.csv" --content-file "temp.txt"
\```
❌ 避免的做法
触发条件模糊:
markdown
## 触发场景
- 涉及文件操作时(太宽泛)
规则冲突:
markdown
## 规则 1
必须用 write 工具写入文件
## 规则 2
不能用 write 工具写入文件(冲突!)
缺少错误处理:
markdown
## 流程
1. 调用脚本
2. 完成
(如果脚本执行失败怎么办?没有说明)
2. Agent 使用原则
✅ 推荐做法
优先加载 Skill:
遇到不熟悉的任务,先检查是否有相关 Skill
严格遵循 Skill 规则:
如果 Skill 说"必须用脚本",就不要直接用工具
记录 Skill 来源:
在 Artifact 中注明:"遵循 qclaw-text-file skill 的规范"
❌ 避免的做法
忽略 Skill 警告:
❌ "这个文件很简单,不需要用脚本"
过度依赖 Skill:
❌ 所有任务都加载 Skill(即使不相关)
修改 Skill 规则:
❌ 运行时动态修改 SKILL.md(应该通过 PR 更新)
3. 调试技巧
问题:Skill 未触发
排查步骤:
-
检查 description:
bashcat skills/my-skill/SKILL.md | grep "description"确保包含用户可能使用的关键词
-
检查 location 路径:
bashls -la /path/to/skill/SKILL.md确保文件存在且可读
-
手动测试匹配:
- 给用户消息添加明确的触发词
- 如:"用 docx skill 帮我写个 Word 文档"
问题:Skill 规则未被遵循
排查步骤:
-
检查规则优先级:
- 是否有其他 Skill 的规则优先级更高?
qclaw-rulesskill 的规则优先级最高
-
检查规则清晰度:
- 规则是否明确?(如"必须用" vs "建议使用")
- 是否有例外情况?(如"除...外")
-
检查 Agent 上下文长度:
- 如果 SKILL.md 太长,可能被截断
- 解决:拆分 Skill 或使用摘要
总结
核心要点
-
Agent = 执行者 ,Skill = 知识库
- Agent 负责"做"
- Skill 负责"教"
-
Skill 是被动的,需要 Agent 加载后才能发挥作用
- 类比:菜谱不会自己做饭,需要厨师来读
-
OpenClaw 的架构优势:
- 模块化:Skill 独立维护,不影响 Agent 核心
- 可扩展性:新增能力只需安装 Skill
- 一致性:所有 Agent 实例遵循相同的 Skill 规则
-
最佳实践:
- Skill 开发者:明确触发条件、提供决策流程、包含示例代码
- Agent 使用者:优先加载 Skill、严格遵循规则、记录 Skill 来源
未来展望
- Skill 市场:类似 VS Code 的插件市场,开发者可以发布和分享 Skill
- Skill 依赖管理:Skill A 依赖 Skill B,自动安装依赖
- Skill 版本管理:支持 Skill 的版本控制和回滚
- 跨 Agent Skill 共享:不同 Agent 框架之间共享 Skill(可能需要标准化)