从 Claude Code 到 QClaw:AgentSkills 规范的跨生态实践与工程取舍!

腾讯在 2026 年 3 月前后陆续上线了 QClaw、WorkBuddy、CodeBuddy 三款 AI Agent 产品,加上更早开源的 OpenClaw 框架,业内将其合称为 Claw 系列。

一、AgentSkills 规范的工程价值

1.1 Skill 出现之前:几种方案的局限

在 Skill 这种抽象出现之前,工程师把工具的"使用说明"塞给 LLM 的常规手段大致有三种。

第一种是 function calling 或 tool use 的 description 字段。这是 OpenAI 在 2023 年提出 function calling 规范之后形成的事实标准,Anthropic 的 Claude tools 与之兼容。每个工具声明里有一段简短的英文描述,告诉 LLM 这个工具能做什么。问题是这段描述受限于 JSON Schema 的字符长度,实际工程中很少超过 200 字,无法承载"什么时候应该用、用之前要检查什么、典型错误如何识别"这类上下文。

第二种是 system prompt 中的工具使用指南。把每个工具的使用建议写进 system prompt,规避了 description 的长度限制。问题是 system prompt 是全局的,每个工具的说明会被加载到每一次对话中。随着工具数量增加,system prompt 急剧膨胀,最终触碰上下文上限。同时,没有任何机制能保证"工具使用说明"与"工具本身"同步更新------很多团队的工具实现被改了,但 system prompt 中的说明仍然停留在三个月前。

第三种是 RAG 检索式指令。在 vector store 中保存每个工具的使用指南,通过用户查询的语义检索动态加载到 prompt 中。这在理论上解决了膨胀问题,但实践中检索的命中率高度依赖 embedding 质量与查询表述。Agent 在请求"帮我生成今日工作日报"时,能否检索到"日报相关工具说明",取决于这两段文本在 embedding 空间中是否足够近。

Skill 的设计是这几种方案的综合改良。它继承了 system prompt 方案的"完整上下文承载"特性,但通过文件化解决了膨胀问题------只有"被认为可能相关"的 Skill 才会被注入 prompt,且加载策略可配置。它继承了 RAG 方案的"按需加载"特性,但避开了 embedding 检索的不确定性,改用基于 description 与用户请求的 LLM 自主选择。它把 function calling 的 description 字段从"参数说明"扩展为"完整的使用上下文",并通过 Markdown 格式让人类工程师能直接阅读、审计、版本管理。

1.2 AgentSkills 规范的演化时间线

Anthropic 在 2025 年下半年公开 Claude Code Skills 时,并没有把它定位为一个开放规范,而是 Claude Code 这个 CLI 工具的内部特性。设计本身并不复杂:在 .claude/skills/ 目录下放一个 SKILL.md 文件,YAML frontmatter 声明 name 和 description,正文以自然语言书写 Agent 在何种场景下、按何种步骤使用该 Skill。

随后几个月,社区中出现了多个独立项目试图复用这一格式,并逐步收敛出 AgentSkills 这一开放规范,明确了字段语义、加载顺序、命名约定。Cursor、Codex 等工具相继支持读取与 Claude 兼容的 Skill 目录。具体的版本与时间点可参考各项目的发布说明。

腾讯的 OpenClaw 在 2026 年初发布时直接选择实现 AgentSkills 规范。 OpenClaw 官方文档(docs.openclaw.ai/zh-CN/tools/skills)开篇明确写道:"OpenClaw 使用兼容 AgentSkills 的技能文件夹来教智能体如何使用工具。"这一表述很审慎------它没有声称自己是 AgentSkills 的"参考实现",也没有声称完全兼容 Claude Code Skills 的所有行为,而是声称兼容规范本身。

这一时间线对工程师有现实意义。任何符合 AgentSkills 规范的 Skill 文件理论上可以在所有兼容实现中运行,但各厂商的扩展字段(如 OpenClaw 的 metadata.openclaw、Claude Code 的某些内部工具引用)属于规范之外的部分。跨生态迁移时,规范内的字段是安全的,规范外的字段需要逐个验证。

1.3 设计的两个隐含选择

回到 Skill 本身。这一设计的价值不在文件格式,而在两个隐含选择。

第一,使用自然语言而非 JSON Schema 描述工具的使用上下文。JSON Schema 擅长描述参数的形状------类型、必填、范围、枚举值。但 LLM 真正缺乏的并不是参数形状,而是"何时应该调用这个工具""调用前需要确认什么""典型错误如何识别"。这些信息用 JSON Schema 表达成本极高,用自然语言反而更精确,也便于工程师阅读和审计。一段自然语言能直接传达"如果用户问的是宽泛的调试请求而不是具体的代码评审,不要触发本 Skill",但用 JSON Schema 表达同样的语义会非常笨拙。

第二,将工程上下文显式化为版本化文本。在没有 Skill 体系之前,Agent 的"使用规范"散布在 system prompt、tool description、用户指令、对话历史之中,难以做版本管理。Skill 把这部分知识抽离为独立文件,可以独立提交、独立 review、独立测试。这是 Skill 与 prompt 的本质区别------prompt 是临时的,Skill 是工程化的。

1.4 跨厂商兼容现状

按 AgentSkills 规范来写的 SKILL.md,理论上在 Claude Code、QClaw、Codex 等兼容实现之间可以原样运行。但实际迁移中,"规范内"与"规范外"的字段会带来不同的兼容体验。

规范内字段(name、description、SKILL.md 文件布局、目录结构)在各家实现中行为一致,是迁移的"安全区"。一份只用规范内字段的 SKILL.md,几乎可以零修改跨生态运行。

规范外字段则需要按厂商分别处理。例如 OpenClaw 的 metadata.openclaw 命名空间在 Claude Code 里会被忽略;Claude Code 的某些内置工具名(如 Read、Bash、Grep)在 OpenClaw 中没有对应映射。这部分差异是迁移时主要的工作量。

迁移失败的常见原因有两类:

第一,SKILL.md 正文中显式引用了某家生态的内部工具名。例如正文写"调用 Read 工具读取文件",到了 OpenClaw 里 LLM 找不到 Read 工具,触发后报错"未知工具"。解决方法是把工具名引用改成功能描述,让 LLM 自主选择目标生态可用的等价工具。这部分会在第四节展开。

第二,metadata 中使用了某家专属字段而对方解析器不接受。例如 OpenClaw 要求 metadata 是单行 JSON,多行嵌套会直接报错;而 Claude Code 对 metadata 字段的容错更宽松。这部分差异通常在第一次加载时就会暴露。

总体而言,跨生态迁移的工作量主要集中在工具名映射与 metadata 调整上,不在 Skill 框架本身。这意味着 AgentSkills 规范作为跨厂商生态基础是成立的,前提是 SKILL.md 写作时遵循"规范内为主、规范外明示降级"的纪律。

二、SKILL.md 字段:跨生态对照与 OpenClaw 的增强

2.1 最小可用 SKILL.md

打开 QClaw 桌面客户端,欢迎页右上方就是一张"安装你的第一个 Skill"的引导卡片。Claw 系列在产品引导上把 Skill 放在了优先级最高的位置------不是工作流,不是 RAG,而是 Skill。这反映了产品团队对 Skill 这一抽象的判断:它是 Agent 与用户日常交互的主要载体。

在文件资源管理器中导航至 C:\Users\<用户名>\.qclaw\ 目录,可以看到 16 个子目录,其中 skills 是 Skill 文件的实际加载路径。注意目录名是 .qclaw 而非官方文档示例中的 .openclaw------Windows 桌面版的实际路径与文档存在偏差。这种偏差在跨平台开发时需要留意,文档示例不能直接拷贝。

最小的 SKILL.md 仅需 name 和 description 两个字段:

markdown 复制代码
---
name: daily-report
description: 读取最近的 git log,生成结构化的工作日报
---

# Daily Report

当用户要求生成日报时,按以下步骤执行:
1. 运行 git log --since="00:00" 拉取今日提交
2. 按 Conventional Commits 类型归类
3. 输出 markdown 格式

这份文件在 Claude Code 与 QClaw 中都可以直接运行。从这里开始,文章将逐步增加字段,展示完整的工程化 Skill 长什么样。

2.2 字段对照表(按用途分组)

三家生态在字段层面的差异如下,按字段用途分组列出:

身份字段:

字段 Claude Code QClaw / OpenClaw 用途
name 支持 支持 Skill 标识符
description 支持 支持 触发匹配的语义描述

UI 字段:

字段 Claude Code QClaw / OpenClaw 用途
homepage 解析但不显示 桌面客户端显示为"网站"链接 跳转到 Skill 主页
emoji 解析但不显示 macOS 客户端 UI 显示 列表项图标

行为控制字段:

字段 Claude Code QClaw / OpenClaw 用途
user-invocable 解析但不生效 暴露为斜杠命令 用户可手动触发
disable-model-invocation 解析但不生效 模型不主动选择,仅斜杠触发 仅作为命令存在
command-dispatch 解析但不生效 可绕过模型直接派发到工具 加速、降低 token
command-tool 解析但不生效 command-dispatch 配套使用 指定派发目标
command-arg-mode 解析但不生效 原始参数转发模式 命令行参数传递

门控字段(OpenClaw 专属):

字段 行为
metadata.openclaw.requires.bins 检查 PATH 上是否有指定二进制
metadata.openclaw.requires.env 检查环境变量是否存在
metadata.openclaw.requires.config 检查 openclaw.json 中的配置项
metadata.openclaw.primaryEnv 标记 Skill 的主要 API key 环境变量
metadata.openclaw.os 限定平台(darwin / linux / win32)
metadata.openclaw.install 安装规格(brew / node / go / uv / download)
metadata.openclaw.always 跳过其他门控,始终包含

这个分组方式比按字段名罗列更便于工程师快速找到自己关心的部分。

2.3 OpenClaw 的 metadata 命名空间

OpenClaw 在规范基础上增加了 metadata.openclaw 命名空间下的一组门控字段,用于控制 Skill 在何种环境下可见:

yaml 复制代码
metadata: { "openclaw": {
  "requires": {
    "bins": ["git"],
    "env": ["OPENAI_API_KEY"],
    "config": ["browser.enabled"]
  },
  "primaryEnv": "OPENAI_API_KEY",
  "os": ["darwin", "linux", "win32"]
} }

requires.bins 在加载时检查 PATH 是否存在指定二进制;requires.env 检查环境变量;requires.config 检查 openclaw.json 中的配置项。任一条件不满足时,Skill 在 Agent 视角中不可见,但日志层面不会主动报错。这种静默过滤是工程化层面的合理设计:可以避免缺依赖时 LLM 被"幻想中的工具"误导。代价是调试时需要查看 Skill 加载日志才能定位为什么某个 Skill 没被触发。

调试时一个值得养成的习惯是:在 OpenClaw 启动后查看 Skill 加载日志(具体命令以官方 CLI 帮助 openclaw skills --help 为准),确认哪些 Skill 被加载、哪些因为门控被过滤。这步检查能避免后续在对话中花时间排查"为什么 Skill 没触发"的问题。

有三个细节值得专门指出。

第一,metadata 字段必须是单行 JSON。OpenClaw 的 frontmatter 解析器采用了较保守的解析策略,多行嵌套结构会直接报错。这是反 YAML 直觉的设计------大多数 YAML 写惯了的工程师第一反应是用缩进表达嵌套。正确的写法是把整个 metadata 写成单行 JSON,可以在 SKILL.md 中用编辑器的折行显示提高可读性,但底层必须是一行。

第二,metadata.openclaw.requires 是 AND 关系。所有 requires 子项必须全部满足才能加载 Skill。如果需要 OR 关系(例如"装了 docker 或 podman 任一即可"),需要使用 requires.anyBins 字段,把"任一二进制满足"作为单独一项。

第三,命名空间名称存在新旧两个版本,目前都被解析器接受。metadata.openclaw 是当前推荐的写法;旧版字段名是 metadata.clawbot,由于历史原因仍被广泛使用,SkillHub 上不少官方 Skill 的 SKILL.md 文件里写的就是 clawbot。OpenClaw 官方文档原文:当缺少 metadata.openclaw 时,仍会接受旧版 metadata.clawbot 块,较旧的已安装技能会保留它们的依赖门控和安装器提示;新的和更新后的技能应使用 metadata.openclaw。换句话说,读到现成的 Skill 看见 clawbot 不必困惑,自己写新 Skill 时推荐用 openclaw。

2.4 加载优先级 6 层的实际用法

OpenClaw 文档列出了 6 层 Skill 加载路径,按优先级从高到低:

优先级 路径 实际用途
1 <workspace>/skills 项目专属 Skill,跟随项目仓库
2 <workspace>/.agents/skills 多 Agent 项目中各 Agent 的私有 Skill
3 ~/.agents/skills 个人多 Agent 配置
4 ~/.qclaw/skills(或 ~/.openclaw/skills 个人通用 Skill
5 内置 安装包自带
6 skills.load.extraDirs 中配置的目录 额外路径

这一分层不只是 OpenClaw 设计上的选择,更直接影响开发者的工作流组织。

工作区 Skill(第 1 层)适合"只在这个项目里需要"的 Skill。例如一个特定项目的 PR 模板生成器,应该跟随项目仓库进入版本控制,避免在其他项目中误触发。

项目 Agent Skill(第 2 层)适合"在这个项目里、但只有某些 Agent 能用"的 Skill。例如在多 Agent 协作场景中,code-reviewer Agent 能用 code-review Skill,而 doc-writer Agent 不应该看到 code-review。

个人 Skill(第 4 层)适合跨项目通用的工具。daily-report、changelog-generator 这类 Skill 适合放在这里,所有项目都能用。

值得注意的是同名覆盖规则:如果两个不同优先级的位置都有同名 Skill,高优先级的会覆盖低优先级。这给了一个非常实用的"项目级覆盖"能力:默认使用个人 Skill,但某个项目需要不同的实现时,把同名 Skill 放进项目目录即可临时替换。

2.5 Token 占用的工程估算

Token 占用是线性可估的。OpenClaw 将每个符合条件的 Skill 的 name + description + location 拼成紧凑 XML 注入 system prompt,公式为:

scss 复制代码
total = 195 + Σ (97 + len(name_escaped) + len(description_escaped) + len(location_escaped))

公式中的 195 是 XML 容器的固定开销,97 是每个 Skill 条目的容器开销。Token 数会随 tokenizer 不同而变化。按 OpenAI 风格的 tokenizer 粗略估算,每个 Skill 大约消耗 24 token 起步,再加 name 与 description 字段的实际长度。装 100 个 Skill 且 description 较短的情况下,system prompt 中常驻在数千 token 量级。

这一开销不会因为 Skill 未被调用而消失。它是一种"固定成本"。

在 token 经济角度,有几个工程化建议:

第一,限制单 Agent 看到的 Skill 数量。OpenClaw 支持在 agents.list 中为不同 Agent 配置不同的 Skill allowlist。一个 code-reviewer Agent 不需要看到 daily-report,限制后单 Agent 的 system prompt 中 Skill 部分能控制在较低水位。

第二,description 字段的长度需要平衡。太短会导致命中率下降,太长会浪费 token 预算。可参考的区间是 50 到 100 个汉字,再视实际命中表现调整。

第三,把 description 中的反例约束写在最简洁的位置。例如"不要在用户问天气、日期时触发"比"在用户询问与工作日报无关的内容(例如询问天气、时间、日期等普通对话内容)时不要被触发"短得多,但传达的语义同样精确。

2.6 SKILL.md 在会话中的加载顺序

理解 Skill 在会话中的加载时机有助于排查问题。OpenClaw 的加载顺序大致如下:

会话开始时,OpenClaw 扫描所有 6 层路径,过滤掉门控不满足的 Skill,按优先级解决同名冲突,得到本会话的 Skill 候选集。这个候选集被快照固定,在整个会话中不会变化,除非显式触发刷新。

每一次用户消息进入后,LLM 在生成回复前会评估"是否应该使用某个 Skill"。这个评估基于 description 与用户消息的语义相似度,由 LLM 自主完成,没有外部检索器介入。

如果某个 Skill 被选中,其完整正文会被加载到当前请求的 context 中。一个常见误解是"Skill 一直在 context 里"------实际上只有 name 和 description 在常驻,正文是按需加载的。

会话过程中如果用户修改了 Skill 文件,需要触发刷新(通常是开始新会话)才能生效。OpenClaw 提供了 Skills 观察器(watcher),默认开启,可以监听文件变化并自动刷新快照。这一行为在某些大型项目中可能造成性能影响,可以通过配置关闭。

三、从一个具体场景说起:代码评审 Skill 的编写

3.1 为什么不选"日报生成器"

许多 Skill 入门教程会用"日报生成器"作为示例。这个例子的问题在于场景过于简单:只需要拉一段 git log、按类型归类、套模板输出。流程是单向的,没有分支判断,没有错误恢复,没有边界声明的必要。它无法体现 Skill 设计在复杂场景下的真正价值。

工程师初次接触 Skill 时一种常见的反馈是"看起来 Skill 跟 prompt 没什么区别,写在 system prompt 里也行"。这个反馈指向的正是入门教程的缺陷------简单场景下 Skill 的工程价值不明显,需要用复杂场景来展示差异。

下面以"代码评审 Skill"为例,展示一份具备工程约束的 SKILL.md 长什么样。

场景:在用户提交 commit 之前对 staged 变更进行评审,输出三类问题:可读性问题、潜在 bug、不必要的复杂度。

3.2 SKILL.md 全文

markdown 复制代码
---
name: code-review
description: 当用户准备提交代码、运行 git commit 之前、或明确要求"审查 / review / 评审 / 看看这段代码"时触发。对 staged changes 进行三维度评审:可读性、潜在 bug、不必要的复杂度。仅评审已 stage 的变更,不评审未 stage 文件,也不修改任何代码。
metadata: { "openclaw": { "requires": { "bins": ["git"] } } }
---

# Code Review

## 触发约束

仅在以下情况触发:
- 用户消息包含"代码审查""code review""commit 前看看"等明确请求
- 用户主动询问 commit 前的检查

不要在以下情况触发:
- 用户问"我的代码有什么 bug",这是宽泛的调试请求,不是 review
- 用户要求"重构"或"优化",这是修改请求,超出 review 范围
- 用户要求"解释这段代码",这是理解请求,应使用其他 Skill

## 前置检查

执行前确认:

1. 当前目录是否在 git 工作区。运行 `git rev-parse --git-dir`,失败则终止并提示用户。
2. 是否有 staged changes。运行 `git diff --staged --name-only`,无输出则告知用户"暂无已 stage 的变更"并终止。
3. 变更行数是否超过 500 行。超过则提示用户"变更过大,建议分批评审",并询问是否继续。
4. 是否包含敏感文件(.env、id_rsa、密钥配置)。如有,跳过评审并提示用户"评审会读取文件内容,建议先 unstage 敏感文件"。

## 评审流程

获取 staged diff:

```
git diff --staged
```

按三个维度分别给出意见。

可读性:变量与函数命名是否表意清晰,控制流是否易读,注释是否冗余或缺失,魔法数字是否被命名。

潜在 bug:边界条件是否处理(空值、零值、负数、空集合),异常路径是否覆盖,资源是否正确释放,并发安全是否考虑,类型转换是否安全。

不必要的复杂度:是否存在过度抽象(一次性使用的接口、过早泛化),是否引入与当前任务无关的修改,是否有可以直接删除的死代码,是否存在重复实现。

## 输出格式

```
评审结果:<filename>

可读性
- [行号] 描述与建议

潜在 bug
- [行号] 描述与建议

不必要的复杂度
- [行号] 描述与建议

总体建议:<accept / minor-fixes / major-rework>
```

## 错误恢复

- 若 git diff 输出超过 1 MB,分文件循环处理,每次只读单文件 diff。
- 若变更涉及二进制文件,跳过并在结果中注明。
- 若用户在评审过程中追问具体问题,暂停整体流程,先回答具体问题。
- 若评审中发现某文件无法解析(例如 minified JS),给出"无法分析"标记而非强行评审。

## 边界

- 不修改代码、不创建新文件
- 不运行任何会产生副作用的命令,除了只读的 git 命令
- 不在结果中给出"应该写成什么"的代码:评审是判断,不是重写
- 不评审 commit message 本身(commit-msg-check 是另一个 Skill 的职责)

3.3 关键设计点

这份 SKILL.md 比"日报生成器"长几倍,但它体现了 Skill 设计的几个核心要点。

触发约束以正反两个方向描述。"在 X 时触发"容易出现误命中,"不要在 Y 时触发"提供了关键的负向信号。在多 Skill 共存时,明确边界能减少冲突。三条反例(不要在调试请求、重构请求、解释请求时触发)覆盖了实际工作中最容易被误触发的几种情况。

前置检查是命题的一部分。Skill 不只是"做什么",还包括"做之前确认什么"。把这部分知识写进 Markdown,等于把工程师的检查表显式化。四个前置检查项中,第 4 项(敏感文件检查)尤其重要------一份没考虑安全的 code-review Skill 可能在评审过程中把 .env 中的 API key 输出到日志或 LLM 推理结果中。

错误恢复路径写明。Skill 是给 LLM 看的,但 LLM 在面对超长输入、二进制文件、用户中途打断时容易卡住或胡来。写明降级策略让 Agent 行为可预测。四条错误恢复策略对应了工程实践中真实出现过的几种边缘情况。

划清边界。"不修改代码""不给出重写""不评审 commit message"这种约束看似多余,但在没有显式约束的情况下,LLM 倾向于"帮人做完事"。结果是代码评审 Skill 自动改了代码,或者顺手把 commit message 也改了。边界声明是 Agent 工程化的必要纪律。

3.4 description 的三个版本演化

description 字段是 Skill 命中率的决定因素,值得反复打磨。下面以同一个 code-review Skill 的 description 三个版本演化为例,说明哪些写法会显著影响命中行为。

版本一(最初的写法):

makefile 复制代码
description: 代码评审 Skill

这是最简短的写法,命中率很低。"代码评审 Skill"只能描述自身是什么,不能让 LLM 判断用户的请求是否应该触发它。当用户说"看看这段代码"、"我这段写得对吗"、"提交前帮我过一遍"等本应触发的请求时,由于没有触发短语锚定,LLM 很可能不会选择这个 Skill。

版本二(加入触发短语):

makefile 复制代码
description: 当用户要求代码评审、code review、查看代码质量时触发,进行 staged changes 的评审。

加入触发短语后命中率显著提升。但会出现新问题:当用户问"这段代码有 bug 吗"时容易被误触发------"代码"和"评审"的语义距离比"代码"和"bug"更近,LLM 可能把这个判定为"想做评审"。

版本三(加入反例约束,即最终版本):

sql 复制代码
description: 当用户准备提交代码、运行 git commit 之前、或明确要求"审查 / review / 评审 / 看看这段代码"时触发。对 staged changes 进行三维度评审:可读性、潜在 bug、不必要的复杂度。仅评审已 stage 的变更,不评审未 stage 文件,也不修改任何代码。

加入反例约束后,误触发率会进一步下降。

这次演化说明几件事:description 不是"越长越好",但是"过短一定不行";触发短语要包含同义表述;反例约束需要明确写出。把这三件事做到位,所付出的成本只是把 description 从 5 个汉字扩到 80 个汉字,回报是命中行为的稳定性。

具体命中率提升幅度依赖于测试集构造、底层模型、Skill 数量等因素,建议读者在自己的真实场景里构造一份 20 条左右的触发预期表做基线测量,再按版本迭代观察变化。

3.5 Skill 的测试用例

把 Skill 当作工程资产管理意味着它需要测试。最简单的测试用例形式是一份触发预期表:

用户消息 应触发? 实测结果
"帮我做代码评审" 通过
"review 一下我的代码" 通过
"看看我刚改的代码有什么问题" 通过
"我这段代码有 bug 吗" 通过
"重构一下这个函数" 通过
"解释这段代码做了什么" 通过
"今天天气怎么样" 通过
"帮我生成日报" 通过

笔者的工程实践是把这份表保存为 tests/code-review.test.md,放在 Skill 同级目录。每次修改 Skill 后跑一遍测试集,确认命中行为符合预期。

更工程化的做法是写一个测试脚本,调用 OpenClaw 的 API 让 Agent 处理每条测试消息,捕获实际触发的 Skill 名称,与预期对比。这种自动化测试在 Skill 较多、迭代频繁时尤其有用------一次 description 修改可能影响其他 Skill 的命中行为,自动化测试能及时发现回归。

四、跨生态运行:从 Claude Code 到 QClaw 的两条路径

4.1 路径一:手工放置(开发者路径)

把上一节的 SKILL.md 写入:

makefile 复制代码
C:\Users\<用户名>\.claude\skills\code-review\SKILL.md

下次 Claude Code 会话启动时自动加载。验证方式是 staged 一段代码后输入"帮我 review 一下"。

迁移到 QClaw 的命令是一行:

powershell 复制代码
Copy-Item -Recurse "$env:USERPROFILE\.claude\skills\code-review" `
                   "$env:USERPROFILE\.qclaw\skills\"

下次 QClaw 启动会话时同样自动加载。

笔者在迁移过程中养成的几个习惯:

第一,迁移前 diff 一遍。即使 SKILL.md 在两个生态都能用,也建议在迁移前确认文件结构。tree ~/.claude/skills/code-review 看一遍目录结构,确保没有 Claude Code 私有文件(如 .claude-cache、.cm 等)混入。

第二,迁移后立即在 QClaw 里跑一次冒烟测试。手动 stage 一段简单代码,输入"帮我 review 一下",确认 Skill 能正常触发与执行。这步发现的问题比阅读文档发现的多。

第三,如果是迁移多个 Skill,建议分批。每次迁移一个,跑完冒烟测试再迁下一个。一次性 copy 整个 skills 目录看起来高效,但出问题时不容易定位。

4.2 路径二:通过 QClaw 对话式安装

这条路径是 QClaw 区别于 Claude Code 的产品决策。在 QClaw 对话框中输入"什么是 skill,怎么安装",QClaw 不会让用户去看文档,而是给出一份口语化的解释,并在底部提供三张 Skill 推荐卡片:实时天气、文件处理、代码开发。

在对话中直接说"请帮我装 summarize 技能",QClaw 会从 SkillHub(鹅厂为 OpenClaw Skills 配套的官方注册表)拉取 summarize Skill 的安装包,自动落盘到 .qclaw\skills\summarize 目录,并返回安装结果:

  • 安装位置:C:\Users\86155\.qclaw\skills\summarize
  • 文件结构:_meta.jsonSKILL.md
  • 默认模型:google/gemini-3-flash-preview
  • 状态:验证通过

整个过程中用户没有打开过文件管理器,没有执行过任何命令。这对没有命令行经验的用户来说是关键的可达性设计。

安装完成后,打开 C:\Users\86155\.qclaw\skills\summarize\ 目录,可以看到刚才安装产生的真实文件结构:_meta.jsonSKILL.md 并列存在,文件内容可读。

用任意文本编辑器打开这个 SKILL.md,可以看到一份完整的 SKILL.md 文件长什么样------frontmatter 中的 name、description、metadata 字段都齐备,正文是 Skill 的使用说明。这就是 SkillHub 上一个公开 Skill 的实际形态,可以作为编写自己 Skill 时的参照。

值得注意 _meta.json 文件------这是 QClaw 在安装时自动生成的元数据文件,记录安装时间、安装来源、版本号等信息。这个文件不是 SKILL.md 规范的一部分,是 QClaw 的扩展。它在 Skill 卸载、更新时被用作元信息查询。手工放置 Skill 时不需要创建这个文件,QClaw 在加载时如果发现 _meta.json 缺失,会自动生成一份默认值。

4.3 工具名映射差异

跨生态迁移时最容易踩到的坑是工具名映射。Claude Code、QClaw、Codex 的内置工具名各有差异,SKILL.md 正文中如果显式引用了工具名,迁移时需要替换。下表整理了几种常用工具的差异:

功能 Claude Code QClaw Codex
文件读取 Read read_file / 文件读写 Skill filesystem.read
文件写入 Write write_file filesystem.write
Bash 执行 Bash exec shell.run
文件搜索 Glob find_files filesystem.glob
内容搜索 Grep search_files filesystem.grep
网络请求 WebFetch http_request network.fetch

跨生态可移植的写法是不在 SKILL.md 中显式引用工具名,而是用功能描述代替:

不推荐:

scss 复制代码
执行 `Read('path/to/file.txt')` 读取文件。

推荐:

bash 复制代码
读取 path/to/file.txt 的内容。

后者让 LLM 自主选择本地可用的文件读取工具,避免与特定生态绑定。

如果 Skill 确实需要引用特定工具(例如必须用 Bash 跑某个命令),最佳实践是在 SKILL.md 中明确声明依赖,并提供降级方案:

bash 复制代码
执行 `git log --since="00:00"` 命令获取今日提交。
若 git 不可用,提示用户"未检测到 git,无法生成日报"并终止。

这种写法在 Claude Code 中会调用 Bash 工具,在 QClaw 中会调用 exec 工具,LLM 能自动适配。

4.4 验证

安装完 summarize 之后,笔者在 QClaw 中提了一个测试请求:"请帮我读取当前文件夹的 git log,生成今日工作日报,按 feat / fix / refactor 分类。"QClaw 调用了多次工具、进行了多次深度推理,最终输出了一份覆盖新功能、问题修复、重构三个分类的工作日报,每项都有时间戳、版本号、文件路径和上下文描述。

日报的"问题修复"章节甚至包含了 QClaw 自己在安装过程中踩过的一个坑:

rust 复制代码
解决 weather 技能安装时的 Unicode 编码错误
错误:UnicodeEncodeError: 'gbk' codec can't encode character '✓'
解决方案:使用 --force 参数强制编码

这是一个 Windows 用户常见的编码问题,但 QClaw 把它纳入了自己的"今日工作"中------它把"我在为你装 Skill 的过程中遇到了什么问题"也视为工作内容的一部分。这个细节体现了 Agent 对自身工作过程的可观测性。

4.5 SkillHub 与 ClawHub 的关系

QClaw 的 Skill 注册表叫 SkillHub。OpenClaw 的文档中提到的 ClawHub 实际上是 SkillHub 在 OpenClaw 上的别名。两者底层是同一套服务,只是品牌不同。

SkillHub 提供了几个能力:

第一,统一的 Skill 注册与发现。开发者可以通过 clawhub publish 命令把自己的 Skill 发布到注册表,其他用户通过 openclaw skills install <slug> 安装。

第二,安全审计。注册表对每个发布的 Skill 进行静态分析(OpenClaw 文档中提到的 ClawScan 工具),安装前在 UI 上展示扫描状态,工程师可以决定是否信任。

第三,版本管理。SkillHub 支持版本号语义化,install 时可指定版本,避免上游变更破坏自己的 Skill 依赖。

实际使用中需要注意的是 SkillHub 上 Skill 的质量参差。官方 verified 的 Skill 比较稳定,社区上传的 Skill 质量需要自己判断。对于关键工作流,建议 fork 一份到自己的目录而非直接依赖远程版本。

五、Skill 与 MCP 的边界

5.1 抽象的本质差异

腾讯在 Claw 系列上做了一个不太寻常的选择:QClaw 走 Skill 路线,WorkBuddy 走 MCP 路线,两款产品并行存在,没有相互覆盖。理解这一选择需要先理解 Skill 与 MCP 这两种抽象的边界。

Skill 是关于"用什么工具、什么时候用、怎么用"的知识,载体是 Markdown。它解决的是 LLM 在面对不熟悉工具时缺少使用上下文的问题。Skill 不引入新的执行能力,只引入"如何使用既有执行能力"的知识。

MCP(Model Context Protocol)是 Anthropic 在 2024 年底提出的服务器端协议,定义了 Agent 与外部数据源、工具之间的通信规范。MCP 的核心是把"能力"以标准协议暴露出来,让 LLM 可以发现、调用、获取结果。MCP 引入的是新的执行能力本身。

两者的边界可以这样划:Skill 是"教 Agent 怎么用既有工具",MCP 是"给 Agent 增加新工具"。

5.2 QClaw 走 Skill 的产品逻辑

QClaw 走 Skill 路线,因为它的目标用户是个人,使用场景是本地任务------整理桌面、生成日报、读取本地文件、整理书签。在这种场景下,Agent 真正需要的不是"接入更多外部服务",而是"知道何时调用本地的哪个能力"。

本地任务的共同特征是:执行能力本身已经存在(用户电脑上已经装好了 git、Python、文件系统),缺的是 Agent 对"什么时候用什么命令"的认知。Skill 是这个认知的载体。

举一个具体例子:用户说"帮我整理桌面"。Agent 需要的不是"调用桌面整理 API",而是知道"先列出桌面文件、按类型分类、移动到对应文件夹"这个流程。这个流程用自然语言描述比用 JSON Schema 描述更自然,所以 Skill 是合适的抽象。

5.3 WorkBuddy 走 MCP 的产品逻辑

WorkBuddy 走 MCP 路线,因为它的目标用户是企业,使用场景是跨工具协作------飞书、钉钉、企业邮箱、内部 CRM、内部知识库。在这种场景下,Agent 需要的是"接入更多企业内部系统",每接入一个就增加一项执行能力。

企业内部系统的共同特征是:执行能力本身不存在于 Agent 视野中,需要专门的协议把数据和操作暴露出来。MCP 提供了标准化的接入协议,避免为每一个集成单独写适配代码。一家企业可能用飞书、钉钉、企业微信任一种通讯工具,写 MCP server 比写三套独立适配器经济得多。

WorkBuddy 的 "Plan / Craft" 双模式也是为了支持 MCP 流程:Plan 模式让 Agent 规划"先调哪个 MCP 工具、再调哪个",Craft 模式则执行规划。这套流程在工具丰富的企业场景下比 Skill 更合适------Skill 假设 Agent 已经知道工具组合方式,MCP 则把工具组合本身交给 Agent 规划。

5.4 Skill + MCP 协作模式

Skill 与 MCP 并非互斥。一个 MCP 工具完全可以配一份 Skill 来说明"何时使用、如何使用"。

理想的协作模式是:MCP 暴露能力("如何调用飞书 API"),Skill 描述使用场景与流程("当用户要求发送周报时,调用飞书 API 的 send_message 接口,先调 list_chats 获取目标群组,再格式化为周报模板发送")。

举一个假设场景:一个 OKR 助手 Agent,由 MCP server 提供与内部 OKR 系统的对接能力,Skill 则描述"季度初新建 OKR""月中 review""季度末总结"等流程。MCP 决定能做什么,Skill 决定怎么做。这种分工让能力层与流程层各自独立演进------MCP 接口稳定时,可以只迭代 Skill 而不动后端;流程稳定时,可以只迭代 MCP server 而不动 Skill。

但当一个生态主要由 Skill 构成(如 QClaw)或主要由 MCP 构成(如 WorkBuddy),其底层的 Agent 推理路径就会显著不同。前者更依赖 LLM 对自然语言描述的语义理解,后者更依赖工具调用协议的可靠性。

5.5 "这个需求该用 Skill 还是 MCP"决策框架

在工程实践中,遇到一个新需求时如何判断该用 Skill 还是 MCP?笔者整理了一个简化决策框架:

第一问:执行能力存在吗?

如果答案是"已经存在,需要的是知道怎么用",那是 Skill 的甜区。例如"整理桌面",文件操作能力本身已经存在,Skill 提供"整理"的流程知识。

如果答案是"不存在,需要新建",那是 MCP 的甜区。例如"对接公司内部审批系统",能力本身不存在于 Agent 视野中,需要 MCP server 把审批 API 暴露出来。

第二问:是否需要跨服务调用?

如果一个任务需要在多个外部服务之间编排("从飞书读取需求 → 在 Jira 创建任务 → 通过钉钉通知相关人"),MCP 是更自然的选择。每个服务一个 MCP server,Agent 在它们之间编排。

如果是单一上下文内的任务("读取本地文件 → 分析 → 生成报告"),Skill 已经足够。

第三问:执行能力的边界是否清晰?

如果能力边界清晰(明确知道有哪些可调用的工具、参数怎么填),MCP 的协议化优势能发挥出来。

如果边界模糊("帮我把这个文件整理得好看一些"),Skill 更适合,因为它能描述"模糊任务的执行流程"。

这三问下来,多数需求能被归类到 Skill 或 MCP 的甜区。少数需求两者都适合,则按团队熟悉度选择即可。

六、Skill 的四种典型失败模式

实际部署 Skill 时会遇到几类失败。这些失败往往不是 Skill 本身写得不对,而是与 Agent 的推理机制有关。

6.1 沉默不触发

最常见的失败:Skill 已加载,用户的请求按理说应该触发它,但 Agent 没有选择该 Skill,直接用通用知识回答。

主要原因是 description 字段写得过短或过泛。LLM 在选择 Skill 时基于 description 与用户请求的语义相似度匹配。例如 description: 生成日报 这种写法的问题是:当用户问"今天天气怎么样"时,"生成"和"今天"在语义空间中有一定相关性,可能误触发;反过来,当用户说"汇总一下我今天的工作"时,"汇总"和"生成日报"在语义空间不够接近,可能不触发。

改进策略是在 description 中显式列出触发短语和反例:

vbnet 复制代码
description: 当用户要求"生成日报""出日报""今日工作总结"时触发。
不要在用户询问"天气""时间""日期"等非工作内容时触发。

笔者的经验是:触发短语越具体,命中率越高。同时包含同义表述("日报"、"工作总结"、"今日做了什么")能进一步提升对各种表述的覆盖。

6.2 多 Skill 描述冲突

当多个 Skill 的 description 描述了相似场景时,Agent 可能在它们之间反复横跳,或者随机选择。例如同时存在 code-review 和 code-quality-check 两个 Skill,描述都涉及"评审代码",Agent 在用户说"看看这段代码"时无法稳定选择。

工程对策有两种。

一是合并:如果两个 Skill 本质做同样的事,合并成一个,用流程分支处理细节差异。例如 code-review 和 code-quality-check 合并成一个,在正文中区分"如果是 commit 前评审走流程 A,如果是 PR review 走流程 B"。

二是显式区分:在 description 中明确各自的专长边界,例如"code-review 处理 commit 前的整体评审;code-quality-check 处理 PR review 中的细节质量"。两个 description 都包含对方的反例约束:"本 Skill 不处理 PR review,由 code-quality-check 负责"。

判断该合并还是该区分的标准是:流程的本质差异是否值得维护两份 Skill。如果只是部分细节不同,合并更经济。如果流程本质不同(例如评审视角、输出格式、目标读者都不同),区分更合理。

6.3 Token 预算溢出

OpenClaw 将所有符合条件的 Skill 的 name + description 注入 system prompt。Skill 数量与单个 description 长度同时增长时,system prompt 中常驻部分会迅速膨胀,与对话历史叠加后容易接近上下文窗口上限。

工程对策有三个。

使用 metadata.openclaw.requires 严格控制 Skill 的可见性。只有当依赖(bin、env、config)满足时才让 Skill 进入候选集。例如某个 Skill 依赖 Docker,可以声明 requires.bins: ["docker"],没装 Docker 的环境下它不会注入 prompt。

利用 OpenClaw 的智能体 allowlist。在 agents.list 中为不同 Agent 指定不同的 Skills 子集,避免单 Agent 看到全部 Skill。例如一个 code-reviewer Agent 只需要少数评审相关 Skill,其余 Skill 对它不可见。

把 description 压缩到 30 字以内,但保留触发短语和反例。在表述精度与 token 经济之间做权衡。

值得指出的是,OpenClaw 在 Skill 加载策略上与 Claude Code 的实现高度相似:6 层加载优先级几乎与 Claude Code 的目录解析机制一致。这种"在已有规范基础上做工程加固"的设计方向,使得跨生态迁移的认知成本显著降低。

6.4 LLM 幻觉调用不存在的工具

第四种失败模式比前三种更隐蔽:Agent 命中了一个 Skill,但 Skill 正文中描述的工具在当前环境中不存在,LLM 试图调用一个并不存在的工具名。

例如某个 Skill 正文写"调用 send_email 工具发送邮件",但当前 Agent 配置中并没有 send_email 工具。LLM 不会拒绝执行,而是会"想象"一个 send_email 调用,生成看起来合理的参数。这次"调用"实际上不会发生任何 IO,但用户在对话中看到的可能是 Agent 报告"邮件已发送"。

这是 LLM 应用中典型的幻觉问题,但它的根源是 Skill 与工具之间没有强校验机制。Skill 正文是自然语言,工具列表是结构化数据,二者之间的对齐由 LLM 自主完成,没有静态检查。

工程对策:

在 Skill 正文中只引用 OpenClaw 内置工具或已 verified 的 MCP 工具。避免引用"应该有但我没确认过"的工具。

为 Skill 编写"工具可用性检查"步骤。在 Skill 正文开头加一段:"执行前确认 send_email 工具可用;不可用则提示用户'未配置邮件发送能力'并终止。"这种主动检查能把幻觉调用转化为显式失败。

定期运行 Skill 测试,捕获幻觉调用。如果某次测试发现 Agent 报告"邮件已发送"但没有任何 IO 痕迹,可能就是幻觉调用。

6.5 工程化监控建议

要让 Skill 体系达到生产可用,监控是必要环节。笔者推荐三个监控点:

第一,Skill 命中率统计。记录每次会话中哪些 Skill 被触发、是否成功执行、用户反馈如何。这些数据反映 description 的质量,是迭代的依据。

第二,单 Skill 的失败率。某个 Skill 经常失败(前置检查不过、错误恢复失效、输出格式错误)说明它的工程化设计有缺陷,需要专项优化。

第三,Token 占用趋势。监控 system prompt 中 Skill 部分的 token 总数。如果这个数字持续增长,说明 Skill 在不断累积但缺乏清理。定期 review 哪些 Skill 已经不再使用,可以裁剪。

OpenClaw 本身没有内置这类监控的可视化界面,但可以通过解析 Agent 日志实现。社区中也有几个 Skill 监控的开源项目,可以作为参考。

七、把入口外延到微信:QClaw 的双通道策略

7.1 连接面板的 20 个集成

QClaw 桌面客户端左侧导航有"连接"入口,其中列出 20 个可对接的外部服务:腾讯文档、ima、腾讯会议、Notion、有道云笔记、企业微信 CLI、飞书 CLI、百度网盘、腾讯微云、腾讯新闻、智绘高迪 PPT、腾讯音乐人、腾讯电子签、美团旅行助手、携程问道、飞猪、个人邮箱、QClaw 邮件推送、金山文档、腾讯问卷。

这一列表的设计意图是 Agent 跨工具协作,每一项接入相当于扩展 QClaw 的"工作面"。值得注意的几点:

腾讯系产品占了较大比例(腾讯文档、ima、腾讯会议、腾讯微云等),这反映了 QClaw 作为腾讯第一方产品的资源优势。这些接入大多是深度集成,不只是简单的 OAuth,而是包含数据查询、内容修改、流程触发等多项能力。

跨厂商接入也保留了(飞书、钉钉相关、Notion、百度网盘)。这种开放性对个人用户友好------不会因为用了腾讯的 Agent 就被锁定在腾讯生态内。

"CLI" 后缀的项(飞书 CLI、企业微信 CLI)值得关注。这些不是简单的 API 集成,而是把第三方工具的 CLI 能力包装到 QClaw 中。Agent 可以通过对话调用这些 CLI 命令,等价于"会用命令行的虚拟同事"。

7.2 小程序 vs ClawBot 的取舍

但更具有产品记忆点的是 QClaw 的微信接入。在 QClaw 桌面端左下角点击手机图标,会弹出一个二维码窗口,底部有两个标签页切换。

这两条路径的选择反映了合规性与可达性之间的权衡。

小程序路径不需要绑定个人微信号,QClaw 与微信账号体系是松耦合的,对个人隐私更友好。小程序的内容受微信平台规则约束,但同时也获得微信的能力支持(推送通知、文件传输、分享)。代价是用户每次使用都需要主动进入小程序,无法在微信主对话列表得到曝光。

ClawBot 路径将 QClaw 关联为微信对话列表中的一项,使用体验最接近"微信好友",曝光性更强。代价是绑定了个人微信号,部分企业合规场景下可能不便。同时 ClawBot 受到微信对第三方机器人的限制------发送频率、消息类型、自动化等级都有上限。

笔者实际体验下来,小程序更适合"主动使用"(我想做某件事,打开小程序发指令),ClawBot 更适合"被动通知"(Agent 完成了某个长任务,主动发消息通知我)。两者并不互斥,可以同时使用。

7.3 端到端实测

在 QClaw 小程序中可以看到会话状态指示------会话项旁边有一个"电脑"标签和绿色在线状态点,表示用户电脑端 QClaw 是否在线。这个状态指示对用户体验很关键------如果电脑端 QClaw 离线,手机端发送的指令无法执行,UI 上明确显示在线状态能避免用户的困惑。

进入会话后,输入"帮我生成今日工作日报",小程序立即将请求转发到电脑端 QClaw。

同时电脑端 QClaw 出现一个新会话名为"QClaw 移动端消息",内容与小程序中一致。会话窗口下方有一行小字说明:"当前为 QClaw 移动端的消息展示窗口,您可以在此查看与 QClaw 移动端的消息记录。"

这一镜像同步机制对远程办公场景具有实际价值。例如周末外出时,可以通过手机微信请求电脑端跑一次本地构建;通勤路上,可以请求电脑端整理今天的待办、生成报告;离开工位时,可以从手机继续指挥未完成的任务。

底层实现上,这条链路是:手机微信、QClaw 微信小程序、腾讯云端服务、用户电脑端 QClaw、本地执行。Agent 的推理与工具调用都在用户本地完成,云端只做消息中转。这与纯云端服务存在本质区别------计算与数据留在本地,云只负责连接。

7.4 微信端的限制

通过微信使用 Agent 不是没有代价。几个限制需要注意:

消息长度限制。微信单条消息有字符上限,超过会被截断或拒绝发送。QClaw 在小程序内对超长输出会做分段处理,但有时分段位置不理想,例如在代码块中间被截断。

文件大小限制。通过微信发送给 QClaw 的文件存在大小上限(具体数值以微信平台规则为准)。这意味着大量数据处理任务不适合通过微信通道发起,更适合在电脑端直接处理。

延迟。微信、QClaw 云端服务、用户电脑端这条链路的端到端延迟,与网络条件密切相关。对延迟敏感的交互(例如代码补全)不适合走微信通道。

合规性。微信对话机器人的内容受微信平台规则约束。某些 Skill 输出可能被识别为敏感内容并被拒绝发送。这一限制对企业敏感数据处理类 Skill 尤其需要注意。

7.5 适用与不适用场景

综上,微信通道适合的场景:

异步任务的指令下发:长跑的任务(构建、测试、数据处理)只需要在手机端发起,结果可以稍后查看。

状态查询:远程查询 Agent 当前状态、最近任务、未完成事项。

简单内容生成:日报、周报、邮件草稿。

被动通知接收:长任务完成后通过 ClawBot 主动通知。

不适合的场景:

实时调试:延迟、消息长度限制、UI 局限都不适合需要快速反复交互的场景。

大量代码处理:代码块容易被消息长度限制截断,跨多条消息阅读不方便。

涉及敏感数据:客户信息、内部代码、API key 不应通过微信通道传输。

八、两个进阶玩法:把 Skill 接上定时器与多 Agent

前面几节讲的是"用户主动发起、Skill 被动响应"的模式------无论桌面对话还是微信小程序,都需要人先开口。这一节讲两个把 Skill 用得更"自动"的玩法:让 Skill 定时自己跑,以及让多个 Agent 各自挂载不同 Skill 组成协作团队。两者都是 QClaw 的内置能力,不需要额外开发。

8.1 定时任务:让 Skill 在固定时间自动执行

QClaw 左侧导航有一个"任务"入口,本质是一个面向 Agent 的 cron 调度器,但配置方式是自然语言而非 crontab 语法。

创建方式很直接:点"创建任务",用一句话描述定时规则和要做的事。笔者创建了这样一个任务:

设置每天 13:40 自动执行:读取我电脑当前项目的 git 提交记录,生成今日工作日报,按 feat / fix / refactor 分类,结果推送给我。从今天开始,持续生效,立即启用。

任务创建后出现在"任务列表"中,显示触发时间(每天下午 1:40)、执行模型(默认模型)、启用状态(开关已打开)。

到了 13:40,任务自动触发。QClaw 在对话区生成了执行结果。但这次的结果不是一份日报,而是:

未能在常用位置找到包含 .git 的项目目录。请告诉我您当前项目的完整路径(如 D:\my-project 或 C:\Users\86155\Projects\xxx),我即可读取今日提交记录并生成工作日报。

在"历史任务"里能看到这次执行的记录:状态标记为"成功",执行时间 05/29 13:40:00。

这个结果值得说明两点。

第一,定时调度本身跑通了。任务确实在指定时间自动执行,无需人工干预,这是"自动化"的核心。

第二,更重要的是执行内容------它没有胡编一份日报。笔者给的任务描述里没有指定项目路径,QClaw 的默认工作区是一个空的 git 仓库(没有任何提交),它在常用位置找不到有提交记录的项目,于是如实反馈"没找到,请告诉我路径",而不是编造一份看起来合理的假日报。

这正好印证了下一节要展开的主题:一个工程化良好的 Agent,在数据缺失时应该承认缺失,而不是用幻觉填补。定时任务这种"无人值守"场景下,这一点尤其关键------如果它每天定时编一份假日报推给你,比不推还糟糕。

实际部署这个玩法时,把任务描述里的项目路径写明确(例如"读取 D:\my-project 的 git 提交记录"),并确认 QClaw 已连接微信通道,就能实现"每天早上醒来,微信里已经躺着一份基于真实提交的工作日报"。

定时任务 + Skill + 微信推送这三者组合,构成了一个完整的无人值守自动化链路:cron 负责"何时触发",Skill 负责"做什么、怎么做",微信通道负责"结果送到哪"。三者各司其职,正好对应本文反复强调的分层思想。

8.2 多 Agent:让不同 Skill 归属不同角色

第二个玩法是多 Agent。QClaw 允许创建多个 Agent,每个 Agent 挂载不同的 Skill 组合,形成职能分工。

点"新建 Agent",提供两种创建方式:自定义创建(网络创建 / 文件创建 / Skill 创建 / 全新自建)和精选专家模板(覆盖营销、金融、产品、工程、办公协同等领域)。其中"Skill 创建"这一项可以直接通过 Skill 链接或名称生成一个挂载该 Skill 的 Agent------这条路径把"装 Skill"和"造 Agent"合并成了一步。

QClaw 还内置了一个"专家广场",里面是一批预设 Agent------Excel 数据处理专家、SRE 站点可靠性工程师、日程管理专家、Word 文档排版专家、1688 采购与供应链专家等,每个都标注了使用人数和点赞数。这实际上是一个 Agent 应用市场,每个"专家"就是一个预配置了特定 Skill 与人设的 Agent。

点开某个专家的详情,可以看到它挂载的 Skill。

"日程管理专家"挂载了 online-search 技能,定位是"发给我你明天的会议和待办,我直接帮你排出最优日程"。

"MBTI 配对师"挂载了 online-search 和 mbti-matcher 两个技能,能力是"输入双方的 MBTI 类型,深度分析两人的性格契合度"。

这里能清楚看到 Skill 与 Agent 的关系:Skill 是能力单元,Agent 是能力的组合与人格化封装。同一个 online-search Skill,既可以被"日程管理专家"用来查日程相关信息,也可以被"MBTI 配对师"用来爬取案例------Skill 复用,Agent 各异。

添加几个专家后,左侧 Agent 列表里就并列出现了多个 Agent:日程管理专家、MBTI 配对师、小红书爆款操盘手,以及默认的 QClaw。切换不同 Agent,等于切换不同的"虚拟同事",每个同事擅长的事情由它挂载的 Skill 决定。

从工程视角,多 Agent 的价值在于上下文隔离与 Skill 范围控制。回到第六节讲的 token 预算问题------如果把所有 Skill 都塞给一个 Agent,system prompt 会膨胀且 Skill 之间容易误触发。多 Agent 是天然的解法:每个 Agent 只挂载自己职能相关的 Skill,既控制了 token 占用,也避免了跨职能的 Skill 冲突。一个"代码评审 Agent"不需要看到"日程管理"Skill,反之亦然。

这与第六节提到的"OpenClaw 的智能体 allowlist"是同一件事在产品层面的体现:底层用 agents.list 配置每个 Agent 可见的 Skill 子集,产品层就表现为"不同专家挂载不同技能"。对个人用户,它是"养一支虚拟团队";对工程师,它是 Skill 作用域管理的 UI 化。

九、Agent 拒绝胡编的工程基础

9.1 一段值得仔细看的回复

回到第七节那次"生成日报"请求。QClaw 在小程序中的回复值得仔细看:

我先查看一下今天的记忆记录,了解工作内容。 已执行 4 个工具

抱歉,我在记忆中找不到今天(2026-05-26)的工作记录。日报需要基于您今天的工作内容来生成。

请您告诉我今天的主要工作内容,我会帮您整理成一份工作日报。您可以简要列出:

  1. 今天完成了哪些工作任务?
  2. 有什么重要进展或成果?
  3. 遇到的问题或需要后续跟进的事项?

这段回复有两个值得关注的地方。

第一,Agent 显式说明了自己的执行过程:"我先查看一下今天的记忆记录"。这是"思维链"展示的产品化形态。在 Agent 反复调用工具的过程中,把"我在做什么、为什么这么做"的中间状态展示给用户,是当前 Agent 产品的一个通用设计趋势。这不只是 UI 设计,而是让用户对 Agent 的执行过程有可观测性,能在 Agent 走错方向时及时发现。

第二,更值得讨论的是:Agent 拒绝胡编。

在没有 Skill 体系的纯 LLM 应用中,用户提"生成今日工作日报"这种缺少上下文的请求时,LLM 倾向于编一份看似合理的日报。原因是 LLM 的训练目标是"产出合理的内容",而不是"诚实地报告缺少数据"。这是 LLM 应用中最常被批评的幻觉问题。

9.2 三个机制的协作

QClaw 这里没有胡编的原因,可以追溯到三个机制的协作。

第一,Agent 内置 memory 工具。当请求涉及"今天""昨天""本周"这类时间锚定的上下文时,Agent 会优先调用 memory 检索而非直接生成。memory 是 QClaw 的核心能力之一,存储用户与 Agent 交互过程中积累的事实、偏好、任务记录。它本质上是一个本地的事件流存储,Agent 在需要时从中检索相关条目。

第二,Skill 的描述中通常包含"查不到数据时如何处理"的指引。一份合格的日报生成 Skill,应该在正文中明确写出"若无 commit / memory 记录,应反问用户而非编造"。这种约束写进 Skill 后,Agent 在面对"无数据"情况时有明确的行为指引。

第三,工具调用的失败信号是显式的。memory 返回"未找到"是一个确定结果,不是模糊语义。Agent 在面对确定的"无数据"信号时,比面对模糊语义更难产生幻觉。

这三个机制中,Skill 是最容易被工程师控制的部分。在编写 Skill 时显式约束"数据缺失时反问",可以显著降低 Agent 的幻觉率。这是 Skill 在企业级 Agent 应用中的核心价值之一------把"不要胡编"这类质量要求,从模糊的训练目标变成可审计的文本约束。

9.3 Skill 与 system prompt 的分工

讨论 Skill 与 hallucination 必然涉及 Skill 与 system prompt 的关系。两者都在 Agent 行为约束中起作用,但分工不同。

system prompt 提供全局约束。它在每一次对话中都生效,不依赖任何 Skill 是否被触发。例如"你是一个谦虚、诚实的 AI 助手,不要编造事实"这样的全局准则,写在 system prompt 中。

Skill 提供局部约束。它只在 Skill 被触发时生效,针对该 Skill 的特定场景。例如"在生成日报时,若无 memory 记录则反问用户"这样的具体行为,写在 daily-report Skill 的正文中。

这种分工的好处是:全局约束保持简洁(避免 system prompt 膨胀),具体行为按需加载(Skill 正文只在触发时进入 context)。

实际工程中容易混淆的是:哪些约束应该放 system prompt,哪些应该放 Skill。判断标准有两个:

第一,是否每次对话都需要这个约束?如果是,放 system prompt;如果只在特定场景需要,放 Skill。

第二,约束是否针对具体任务的执行细节?如果是抽象的行为准则(诚实、谦虚、不编造),放 system prompt;如果是任务执行的具体细节(前置检查、错误恢复、输出格式),放 Skill。

9.4 实践建议

让 Agent 拒绝胡编的几条具体建议:

第一,在每个 Skill 的正文中明确"无数据时的行为"。这一条要求在团队内部 Skill 编写规范中应当被列为必选项。

第二,让工具返回结构化失败而非空字符串。例如 memory 查询失败时返回 { found: false, reason: "no records for date" } 比返回空字符串 "" 更明确。Agent 在面对结构化失败时更容易做出正确的响应。

第三,在 system prompt 中加入兜底约束。例如"如果在执行过程中发现关键数据缺失,应明确告知用户而不是猜测"。这条全局约束作为 Skill 局部约束的补充,能覆盖那些 Skill 没显式声明的场景。

十、适用性边界与结语

10.1 工作室页面:产品定位的视觉化

在 QClaw 顶部切换到"工作室"标签页,会看到一个像素艺术风格的虚拟空间:一只红色龙虾在举哑铃,旁边是工作台、咖啡机、服务器机柜、书架、紫色水晶球。这张图像不影响 Agent 的任何功能,它是 QClaw 团队对 Agent "虚拟同事"形象的视觉化表达。

从产品定位的角度,它传递了一个信号:QClaw 面向个人用户,强调亲和力与拟人化。这种"把 Agent 拟人化"的设计取向在国内 AI 产品中并不少见,但 QClaw 的执行相对克制------龙虾形象只出现在工作室页面与少数引导动画中,对话主体仍然是工程化的对话框,没有让拟人化干扰核心交互。

10.2 AgentSkills 跨厂商的现实意义

回到本文的主线。AgentSkills 规范在 2026 年成为跨厂商的事实标准,对开发者意味着两件事。

一是迁移成本下降。同一份 SKILL.md 在 Claude Code、QClaw、Codex、OpenCode 之间的兼容率达到 80% 以上。这一兼容率不要求开发者重新学习每家的 Skill 体系,只需要在工具名称、平台特定字段上做少量适配。

二是 Skill 不是 Agent 设计的银弹。Skill 解决的是"教 Agent 怎么用工具",但当任务的核心瓶颈是"需要更多工具"时,MCP 是更合适的抽象;当任务的核心瓶颈是"工具调用顺序复杂"时,工作流引擎是更合适的抽象。QClaw 与 WorkBuddy 的分工正反映了这一点。

10.3 什么时候不该用 Skill

工程实践中,过度使用 Skill 也是常见误区。几种典型的"不该用 Skill"场景:

第一,简单到不需要约束的任务。例如"翻译这段话"这种任务,LLM 本身已经处理得很好,不需要 Skill 来约束流程。强行加 Skill 反而增加 token 占用、降低响应速度。

第二,约束已经在 system prompt 中表达过的任务。如果 system prompt 已经声明"使用中文回复",就不需要在每个 Skill 中重复这个约束。

第三,本质上需要新工具的任务。例如"对接公司内部审批系统",本质需要的是 MCP server,而不是用 Skill 描述一个不存在的工具。

第四,临时性、一次性的任务。Skill 是工程化资产,需要维护成本。一次性任务直接用 prompt 表达就够,不需要沉淀成 Skill。

10.4 给工程师的建议

对工程师,几个具体建议。

第一,编写 Skill 时优先把精力投在 description 字段上,而非 Skill 正文的长度。description 决定触发命中率,正文决定执行质量。在一个尚未充分调试的 Skill 中,description 错误的代价远高于正文不完美的代价。

第二,把 Skill 视为版本化的工程文档。它应该进入 Git 仓库,应该有 PR review,应该有测试用例。最简单的测试用例是"在这些请求下应该触发,在这些请求下不应该触发"。把 Skill 当作"提示词"管理是不严肃的,它是会被 Agent 自动加载的运行时资源。

第三,在跨生态部署时关注差异点。不要假设"在 Claude Code 跑通就能在 QClaw 跑通"。差异主要集中在三处:工具名映射、文件路径、metadata 解析方式。提前在 SKILL.md 中规避这些差异,可以减少后期适配成本。

第四,定期 review Skill 库。删除不再使用的 Skill,合并语义重复的 Skill,更新过时的 description。Skill 库的卫生与代码库的卫生同样重要。

第五,团队内部建立 Skill 编写规范。包括 description 的最少字数要求、必须包含触发短语与反例、必须声明前置检查与错误恢复、命名规范等。规范化能显著提升 Skill 库的整体质量。

10.5 跨生态迁移 checklist

最后给一个可以直接复用的跨生态迁移 checklist:

迁移前:

  • 确认 Skill 的源生态与目标生态版本(Claude Code、QClaw、Codex 都有版本号)
  • 列出 Skill 在源生态依赖的工具(Read、Bash、Grep 等)
  • 检查 metadata 字段是否使用单行 JSON
  • 检查 description 长度(建议 50 到 200 字)

迁移中:

  • SKILL.md 复制到目标生态的 Skill 目录
  • 替换 Anthropic 内部工具名为通用描述
  • 增加 metadata.openclaw.requires(如果用 QClaw)
  • 如果是 QClaw,确认目录是 .qclaw\skills 而非 .openclaw\skills

迁移后:

  • 跑一次冒烟测试:用预期触发场景验证 Skill 是否被命中
  • 跑一次反例测试:用预期不触发场景验证 Skill 是否被误命中
  • 检查输出格式是否符合预期
  • 检查执行时间是否符合预期
  • 把 Skill 加入定期测试集

依照这份 checklist 操作,单个 Skill 的迁移加测试时间通常在 15 到 30 分钟。多数兼容性问题可以在迁移阶段就被捕获,不会遗留到生产对话中。

10.6 结语

AgentSkills 规范的演化过程让笔者想到 Web 早期 HTML 的演化。最初每家浏览器有自己的 HTML 方言,写一个跨浏览器兼容的页面需要大量条件分支。后来 W3C 把 HTML 抽成开放规范,各家实现向规范收敛,跨浏览器开发的成本急剧下降。

Skill 似乎正在走类似的路径。Anthropic 在 2025 年发明了 Claude Code Skills 的格式,社区在 2025 年底抽成 AgentSkills 规范,腾讯、Cursor、Codex 等厂商在 2026 年向规范收敛。开发者得到的好处是一份 SKILL.md 可以跨厂商运行,工程化的 Skill 投入不会因为换厂商而打水漂。

这种收敛的速度比 HTML 当年快得多,因为 AI 工具生态本身就在快速演化,开放规范的吸引力比任何单家厂商的封闭实现都大。AgentSkills 是否会成为长期标准还有不确定性,但至少在 2026 年这个时间点,它已经是事实上的跨厂商共识。

对工程师而言,最值得投入的是"学好一遍 Skill 思维",而不是绑定到任何特定厂商。Skill 的设计哲学(用自然语言描述工具使用上下文、把工程约束显式化为版本化文本、保持触发与执行的清晰分工)会比任何具体厂商的实现更长寿。

相关推荐
zhaoshuzhaoshu1 小时前
提示词工程(Prompt Engineering)详细解析
人工智能
RockHopper20251 小时前
智能体的《目的论》模型
人工智能·llm·智能体
J2虾虾1 小时前
Spring AI Alibaba - 人工介入(Human-in-the-Loop)
java·人工智能·spring
兆。1 小时前
LangChain框架深度解析:与FastGPT的优势对比
人工智能·langchain
tzc_fly1 小时前
ELF:连续扩散语言模型
人工智能·语言模型·自然语言处理
昨日之日20061 小时前
MiniCPM5-1B - 随身AI智能助手 擅长工具使用和复杂推理,长上下文处理能力强 一键整合包下载
人工智能
J2虾虾2 小时前
Spring AI Alibaba - Skills 技能
人工智能·python·spring
冰西瓜6002 小时前
深度学习的数学原理(四十)—— Transformer 推理全过程
人工智能·深度学习·transformer
Bingorl2 小时前
机器学习之集成学习
人工智能·机器学习·集成学习