45 min · 五层工作流怎么映射到目录结构 · 本地:~/Code/Projects/easel-repo
🎒 预备知识:完成上一课「入门」(零基础入口:第 0 课)
看一个陌生仓库,先看目录怎么分——它泄露了作者的心智模型。两种常见哲学:
按技术分层:models/ controllers/ services/ utils/——每一层放一类代码。 Web 后端常用。问题:业务流程被打散,"发一条小红书"的代码散在五六个目录里。
按业务流分层:discover/ plan/ produce/ publish/ attribute/——每层是一个业务阶段。 Easel 采用这种(技能按六层枚举:discover/plan/produce/publish/attribute/general), 再加上六件套的维度(入口/能力/共享/画像/产物),两套坐标系正交。
为什么 Easel 选业务流?因为它的核心复杂度在流程编排(发现→…→归因)而不在技术实现—— 目录结构应该让最常问的问题最好答。"发帖的代码在哪?"——publish 层,一步定位。 若按技术分层,这个问题要跨目录拼答案。
cd ~/Code/Projects/easel-repo
ls -d */ # 顶层目录
ls skills/openclaw | head # 数一数技能
ls easel easel/commands web openclaw
| 目录 | 六件套角色 | 数据流站点 | 看什么 |
|---|---|---|---|
| easel/ | 入口薄壳(CLI) | 用户输入 → 拼消息发 gateway | cli.py 的 6 个子命令 |
| web/ | 驱动层(FastAPI+React) | 浏览器 → SSE ↔ gateway | app.py 端点分组(L09) |
| skills/openclaw/ | 能力系统(114 技能) | agent 按需读取 SKILL.md | 随便打开一个 SKILL.md(L06) |
| skills/shared/ | 确定性厚脚本(48 个) | 所有碰环境的 IO | scripts/ 文件名清单(L07) |
| profiles/ | 记忆分域 | 每账号六维画像 | _template/ 看六维结构 |
| outputs/ | 产物与状态 | 成品 + 系统目录(_ 目录首次运行后才出现) | 注意 _ 前缀目录的约定 |
| openclaw/ | 大脑配置 | AGENTS.md/SOUL.md + sync.sh | workspace/ 两个 md(L03/L04;CONTEXT.md 由 sync.sh 生成) |
outputs/ 的下划线约定值得单独说:_sessions/ _login/ _publish/ _inbox/
这些下划线开头目录是系统状态(会话快照/登录二维码/发布状态/上传附件),
不是用户内容——Web 内容库刻意忽略 _ 前缀目录。命名前缀承载语义,
零成本的约定胜过一套权限系统。
拿入门课的读仓库六问现场走一遍(答案都在表里,合上表自测): ① 循环在哪?(不在本仓库——在 OpenClaw gateway,本仓库是 harness 无关的业务层,A17) ② 系统提示词由什么组成?(openclaw/workspace/ 两个 md + CONTEXT.md) ③ 能力怎么路由?(技能 frontmatter,skills/openclaw/) ④ 哪些固化在脚本?(skills/shared/scripts/ 的 48 个) ⑤ 状态记忆存哪?(profiles/ 分域 + outputs/_ 系统目录 + ~/.openclaw-easel 会话) ⑥ 边界在哪?(skills/shared/scripts/ 的 guard 脚本群 + SKILL 里的 dry-run 约定) ——30 分钟定位一个 3 万行仓库,这就是六件套坐标系的威力。
坑 1:从 README 目录树开始背。静态树记不住,带着数据流动线走一遍才留得下—— 本课的映射表就是动线。坑 2:忽略"不存在的东西"。Easel 仓库里没有 loop 实现、没有模型调用代码——这个"缺失"本身就是最重要的发现(业务层 harness 无关,A17)。 坑 3:把 skills/shared/ 当工具杂物堆。它是执行层的标准库(L07), 发布引擎全在里面。
不看任何资料,画出「用户在 Web 说一句话 → 成品落进 outputs/」的完整数据流图 (至少经过 6 个目录/进程)。画完回来讲给我听——我按图提问。
一手源:README 的「项目结构」一节 + 亲手 ls。地图是走出来的,不是背出来的。