M3 能力层 · L08

SKILL.md 怎么"到得了"agent 手里:同步与发现

45 min · 精读 openclaw/sync.sh + easel/openclaw_workspace.py(160行) · M3 毕业课

🎒 预备知识:完成上一课「L07」(零基础入口:第 0 课)

本课唯一结论:agent 读不到你仓库里的技能——它只读 OpenClaw workspace。 所以存在一条同步链,而这条链上最大的坑是 workspace 路径不能硬编码(issue #19 的教训)。

一、基础:为什么需要"同步"这件事

先建立一个反直觉的事实:你在 Easel 仓库里写好的 SKILL.md,agent 根本读不到。 原因在架构(A17 三层图):Easel 的 agent 不是个独立程序,是跑在 OpenClaw gateway 里的; 而 OpenClaw 有自己的工作区概念(workspace)——它的文件视野、system prompt 拼装、 技能发现都只认 workspace 目录。你的仓库在 ~/Code/Projects/easel-repo, workspace 却在 ~/.openclaw-easel/workspace——两个世界。

所以需要一条同步链把仓库资产搬进 agent 的视野:

仓库 skills/openclaw/(114 技能)──sync.sh──▶ OpenClaw workspace/skills/
                                              (agent 实际读取处)
同时:workspace/AGENTS.md 注入项目根绝对路径;outputs/ 与 profiles/ symlink 进去

symlink(软链接)值得说一句:workspace 里的 outputs/ 不是副本,是指回仓库真目录的快捷方式—— agent 写产物实际落进仓库,你在仓库里直接看到。副本会分叉,链接不会。

二、核心难题:workspace 路径是个移动靶

sync 到哪?你可能会说"写死 ~/.openclaw-easel/workspace 不就行了"—— Easel 用 160 行代码告诉你为什么不行。OpenClaw 跨版本改过布局: 2026.6.x 是 ~/.openclaw/workspace-easel,2026.9.x 变成 ~/.openclaw-easel/workspace。issue #19 的现象就是硬编码的墓碑: "sync 报成功但 agent 读不到技能"——同步脚本把技能写进了旧路径, agent 在新路径读,两边都"正常工作",就是互相看不见。

这类 bug 的恶劣之处:写入端成功(文件真的写了)、读取端正常(目录真的存在), 故障发生在两端的假设不一致上——没有报错、没有日志,只有"技能怎么不生效"的灵异现象。

三、openclaw_workspace.py 的五级退化解析(160 行的精华)

  1. EASEL_OPENCLAW_WORKSPACE 环境变量(显式指定,最高优先级)
  2. 问 openclaw status --json 拿 workspaceDir——运行时真相,最可靠
  3. openclaw.json 显式配置
  4. 已有 skills 内容的候选目录(启发式)
  5. 按版本猜默认(最后手段)

读这套退化的设计哲学:永远问运行时,猜是最后手段。第 1-3 级都是"问 OpenClaw 自己", 只有前三级全部失败才退化到猜。第 2 级(status --json)是灵魂:路径是 OpenClaw 的内部状态, 问它自己最准——就像想知道别人的收货地址,直接问本人,不要靠上次寄件单记忆。 这个模式可迁移到一切"外部工具的内部路径"问题。

四、端到端串一遍(M1–M3 闭环)

用户 easel skill xhs-note-creator -i "..." → CLI 拼消息(L02)→ agent(workspace 里被 sync 过的技能 + AGENTS.md 规则"先路由 SKILL")→ 读 SKILL.md → cd 项目根(CONTEXT.md 的路径)→ 调 skills/shared/scripts/ → 产物落 outputs/。 你已能讲清每一站。这条链上任何一环断掉的症状各不相同—— L02 断了是"命令没反应",这里断了是"技能不存在",L09 会看到 Web 断了是什么样。

五、常见踩坑

坑 1:同步用复制不用链接。outputs/ 复制进 workspace = 两份产物分叉, "我明明生成了怎么找不到"。坑 2:升级 OpenClaw 后不重新 sync。布局变了, 旧 workspace 里的技能成孤儿——doctor(easel 的环境自检命令)会检查"技能是否同步进 agent 实际读的 workspace" (这就是 doctor 检查清单里那条的意义)。坑 3:自己的 agent 也硬编码路径。 issue #19 人人会踩——写"问运行时"的三行代码,省未来三天的灵异调试。

六、检索练习

七、出口检验 + 动手作业

检验:用自己的话解释 issue #19 的现象、根因、和五级退化如何杜绝它。

作业(M3 毕业物):写一个自己的技能目录:frontmatter 三字段 + SKILL.md(≤60 行) + 一个 references 文件。主题任选(比如"给我的项目生成周报")。发我评审。