5.7 KiB
| name | description |
|---|---|
| skill-creator | 引导用户创建 / 改造自己的 skill(存进用户私有 `.skills/`,只对自己生效)。当用户说"我想做个自己的 skill / 把某个能力固化下来 / 把 zcbot 的某 skill 改成我要的样子 / 每次都要重复交代同一套规矩"时使用。本 skill 教怎么写 SKILL.md、怎么 fork 内置 skill 再改、怎么写好路由用的 description。用户只是要完成一个具体任务(写本子 / 画图 / 查文献)时不用 —— 那直接走对应 skill。 |
Skill Creator - 造你自己的 skill
帮用户把"反复要交代的一套做法"沉淀成一个私有 skill,存在他自己的 .skills/ 下,只对他生效,不影响别人也不动内置 skill。
两种来源:
- 从零写:全新能力,用
save_skill写一份 SKILL.md。 - fork 内置再改(最常见):看中某个内置 skill(如 ppt / proposal)但想调规矩,用
fork_skill整目录拷过来(带它的脚本),再编辑 SKILL.md。
何时用
- 用户说"我想要个自己的 skill / 自定义 skill / 把这套流程固定下来"
- 用户说"zcbot 的 X skill 挺好但我想改成 Y" → fork 再改
- 用户每次任务都要重复交代同一套约束(术语表 / 模板 / 禁忌) → 建议固化成 skill
- 用户问"skill 怎么写 / SKILL.md 什么格式"
何时不用
- 用户只是要完成一个具体任务 → 走对应内置 skill,别绕到造 skill
- 用户要改的是全局行为(所有任务都该这样) → 那是 system prompt / 偏好,不是 skill
- 一次性的事 → 直接做,不值得固化
关键机制(先讲清楚再动手)
存哪:用户 skill 在私有 .skills/<name>/SKILL.md(与 .memory/ 同级,文件面板里隐藏)。你不用、也不该用 write/shell 去手写这个目录 —— 沙箱 fs 的根不指向那里,跨 host/docker 不可靠。一律用下面两个工具,它们 host 侧直接落到正确位置。
两个工具:
save_skill(name, content)— 新建 / 覆盖.skills/<name>/SKILL.md。content是完整 SKILL.md(含 frontmatter)。写时校验 frontmatter 合法且有 description,不合格直接拒。fork_skill(src, new_name)— 把内置(或用户已有)skill 整目录拷到.skills/<new_name>/,脚本 / references 一起带过来,frontmatter 的 name 自动改成new_name。
生效时机:造好 / 改好后,下一条消息才生效(registry 每轮重建)。告诉用户造完这条结束,下次发消息就能用了。
覆盖语义(user wins):用户 skill 与内置同名 → 覆盖内置(只对该用户)。想替换内置就用同名,想两个都留就改名(如 ppt-mine)。覆盖会在 skill 列表里显式标 [你的·已覆盖内置],不静默。
工作流
1. 先问清楚要造什么(BLOCKING)
- 是从零还是基于某内置 skill 改?基于改 → 是哪个、想改什么?
- 这个 skill 解决什么任务?什么时候该触发、什么时候不该?(这决定 description,见下)
- 要不要带脚本 / 模板?
2a. fork 路径(基于内置改)
fork_skill(src=<内置名>, new_name=<用户起的名>)—— 默认建议改名(如ppt→ppt-mine),除非用户明确要覆盖内置。- fork 回包会给出
.skills/<new_name>/路径。用read看 SKILL.md,用edit改用户想改的部分(规矩 / 模板 / 默认值)。 - 改完告诉用户:下条消息起,
<new_name>就在 skill 列表里了。
2b. 从零路径
- 跟用户敲定 name + description + 正文骨架。
save_skill(name, content),content是完整 SKILL.md。- 若校验报错(缺 description / YAML 坏),按提示修了重存。
3. 写好 description —— 这是最关键的一环
description 是唯一进每轮 skill 列表、决定路由的字段。写糊了的代价不是"skill 不好用",而是误触发 + 稀释列表。规则:
- 一句话讲清做什么 + 何时用 + 何时别用
- 给触发词(用户会怎么开口),必要时给反例(像不该触发的近义场景)
- 别写成功能罗列,要写成"路由信号"
照抄内置的结构,比如:
description: 生成 PowerPoint(.pptx)。✅ 触发:PPT / 幻灯片 / slide / deck / .pptx。⛔ 不触发:报告 / 文档 / 纪要(走 documents/proposal)。...
4. SKILL.md 正文骨架(从零时给用户的模板)
---
name: <小写、[a-z0-9_-]、≤64>
description: <路由说明:做什么 + 何时用 + 何时别用 + 触发词>
---
# <标题>
<一句话定位:这个 skill 帮用户做什么>
## 何时用 / 何时不用
- ...
## 工作流
1. ...
## 反模式
- ...
正文要不要分阶段 / 卡 BLOCKING / 带 quality_check,看任务复杂度 —— 简单 skill 几行就够,别硬套。带脚本的:脚本放 .skills/<name>/scripts/,SKILL.md 里用 <skill_dir>/scripts/xxx.py 引(<skill_dir> 是 load_skill 返回头给的路径,host/docker 都对)。
反模式
- 用
write/shell手动往.skills写 —— 用save_skill/fork_skill(沙箱 fs 根够不到.skills,会写错地方) - fork 带脚本的内置 skill(ppt/proposal)却只
save_skill拷了 SKILL.md —— 脚本没带过来,import必崩;带脚本一律fork_skill - description 写成"很厉害的 PPT skill" —— 没有触发信号,路由抓瞎
- 默认就覆盖同名内置 —— 除非用户明说要替换,否则改名并存,别悄悄遮掉内置
- 造完不告诉用户"下条消息才生效",用户当场没看到以为失败
- 把"所有任务都该遵守的全局规矩"做成 skill —— 那该进偏好 / system prompt
输出
完成后给用户:
- skill 名 + 路径(
.skills/<name>/) - 是覆盖内置还是新增 / 并存
- 一句话:下条消息发什么就能触发它(或让 LLM 自动按 description 路由)