Imported from linjiaqin12138/skills (
skills/clone-from-scrach-tutor/SKILL.md). Install upstream withnpx skills add linjiaqin12138/skills --skill clone-from-scrach-tutor. Copyright stays with the author.
从零手搓开源项目教程生成器
把开源项目转化为面向工程师的交互式学习教程。复刻对象按优先级:
- 架构设计能力(模块切分、边界定义)
- 关键权衡思路(每个决策放弃了什么、赌了什么)
- 可运行的最小复刻(能下载的数据/服务绝不重写)
执行前置(缺失则先问用户)
- 开源项目地址
- 用户技术背景:语言、做过的系统类型、明确不熟悉的领域(用于类比映射与背景卡片的取舍)。
先读本 skill 目录下的
user-prefs.md:已有记录直接沿用,不重复询问;用户纠正背景时立即更新该文件(用户在别的会话纠正也算数,下次启动以此为准)。
工作区约定(可断点续传)
教程的全部状态必须落盘,保证用户下次用任意 agent 打开工作区、零对话上下文也能继续。
- 固定位置:
<当前目录>/<项目名>-from-scratch/,Phase 0 侦察前创建,之后所有产出都在里面。 - 目录结构:
<项目名>-from-scratch/
├── reference/ # 原项目浅克隆,只读对照(不动 /tmp,会被系统清理)
├── docs/
│ ├── STATE.md # 断点续传的唯一入口,见下
│ ├── deviations.md # 偏差登记簿(铁律 8/9 的台账)
│ ├── questions.md # 用户提问与解答记录(含"为什么"类问题的结论)
│ ├── phase-N.md # 每阶段产出归档
│ ├── arch/
│ │ └── original.d2/.svg # 原项目模块划分总图(Phase 1 产出)
│ ├── concepts/ # 概念深读文档,见「概念深读文档」一节
│ │ └── <slug>.md
│ └── milestones/
│ └── m<N>-<slug>/ # 每个里程碑一个文件夹,教程成书的基本单元
│ ├── tutorial.md # 教程章节(写法见 Phase 3 的 writer 约定)
│ ├── acceptance.md # 验收命令 + 实测输出 + 涉及代码文件清单
│ ├── arch.d2/.svg # 本里程碑验收后的系统完整架构图(见「架构图约定」)
│ └── arch-diff.d2/.svg # 相对上一里程碑的架构变动示意图
└── (手搓代码本身) # 代码保持在主工程连续演进,不按里程碑切片——
# 切片会造成代码重复与漂移;里程碑文件夹只放文档
- STATE.md 必须包含:当前 Phase / 里程碑 / Bite 编号与状态(未开始/待验收/已通过)、下一步动作一句话、偏差簿当前计数、关键路径(reference 位置、构建与验收命令、最新架构图路径)、用户偏好文件指针。
- 更新时机:每个 Bite 交付后、每个 Phase 结束后、用户提出影响后续内容的疑问后,立即更新对应文档——不是收尾时补,是当场写。
- 续传流程:被调用时先检查当前目录是否已有
*-from-scratch/docs/STATE.md;有则读 STATE.md + deviations.md + questions.md + 最近一个里程碑文件夹,从记录的状态继续,不重做已完成的工作,不重新询问已记录的偏好。
铁律
- 分阶段产出,每阶段结束停下等用户说"继续",禁止一口气输出全部内容。
- 动手前先侦察:通读仓库 README、目录树、核心文件。读不到的内容明说,并区分【代码确认】与【合理推断】——推断必须显式标注,禁止编造文件内容。
- 背景知识不做前置 dump:在概念首次被用到的地方插入【背景卡片】,一次最多一张。卡片只放压缩版;读者不在这个领域就基本接触不到的概念,必须另写
docs/concepts/<slug>.md深读文档,卡片里给链接(见「概念深读文档」)。 - 每段代码必须从零写起(不贴原仓库源码),并给出可执行的验证命令或断言。
- 每个 Bite 动手前先给"验收标准"。正确性是统计性/行为性的项目(如随机模拟),必须设计分布级断言,不得假装有精确答案。
- 每个关键设计决策输出【决策卡片】,缺一项打回重写。
- 主动用用户熟悉的技术概念做类比,但类比后必须指出差异点,防止错误迁移。
- 终态默认与原项目一致:走完所有里程碑后,手搓工程的技术栈、语言、配置项、公开接口与可观察行为必须与原项目对齐(注释、文档、死代码不复刻)。实现语言默认跟随原项目,用户明确要求才可更换。
- 中间里程碑允许且鼓励偏离原版:从简单起步,只实现当前里程碑验收所需的部分;禁止"底层依赖将来用得到,就提前在本里程碑加入"。每个偏离都是待收敛项而非永久豁免,必须标注预定收敛点。
工作流
Phase 0 · 侦察(一次回复内完成)
- 项目一句话本质(什么输入 → 什么输出)
- 目录地图(顶层目录/文件职责)
- 技术栈与外部依赖(数据来源、外部服务)
- 核心主循环位置
Phase 1 · 自顶向下拆解
- 模块划分总图用 d2 画(按
d2-diagramsskill 的流程:写源码→渲染 SVG→亲自看渲染结果修布局,循环到能交付),落盘docs/arch/original.d2+.svg;每模块另配文字:职责 / 输入 / 输出 / 接口契约 - 3~5 个最关键架构决策,各出决策卡片
- 映射到用户熟悉的概念词汇表(含差异标注)
Phase 2 · 自底向上实现路径
- 按依赖树排序产出里程碑 M0..Mn,每个含: 目标一句话 / 前置依赖 / 验收标准 / 预计工作量 / 等价场景类比
- 里程碑按"当前够用"切分:只排本里程碑验收所需的实现,不为后续里程碑预埋结构
- 每个里程碑相对原版的简化项,标注预定在哪个里程碑收敛(终态对齐见铁律 8)
- 明确标出:哪些直接下载使用,手搓范围只限代码
Phase 3 · 逐层手搓(每个里程碑一轮交互)
双 subagent 分工:每个里程碑由两个 subagent 串行完成,主 agent 只做设计、验收复核与向用户串讲,以保护主上下文。
- coder subagent(写代码)。交接必须自包含(subagent 无任何上下文):
- 目标与验收标准(可直接执行的命令 + 预期输出)
- 工作目录与已有文件清单(哪些文件已存在、不得重写哪些)
- 偏差登记簿当前状态(本里程碑允许偏离什么、禁止提前实现什么)
- 铁律 4 的约束:从零写,禁止抄原仓库源码;可读原仓库文档与接口定义做对照
- 要求返回:改动文件清单、验收命令实测输出、遇到的坑、自认的偏差
- 主 agent 复跑验收命令,通过后才启动 writer。
- tutorial writer subagent(写教程章节 + 架构图)。交接必须包含:里程碑目标与依赖树位置、代码文件清单(它应亲自读代码)、验收实测输出原文、偏差簿变动、本里程碑的架构变动清单(动了哪些模块、哪些边、数据流有没有改向)、user-prefs.md 的类比栈约定、用户在本里程碑提出的疑问(必须写进章节)。产出
docs/milestones/m<N>-<slug>/tutorial.md+arch.d2/.svg+arch-diff.d2/.svg(架构图按「架构图约定」:d2 画模块图、渲染后亲自看图修布局——两张图的 d2 迭代必须交下一级 subagent 做,writer 自己不亲手渲染,只给架构事实与风格要求并验收成图;序列/时序用 mermaid 嵌文),章节按"教程书一章"的标准写:- 动机(为什么是这个里程碑、在依赖树的位置)
- 概念铺垫(背景卡片就地插入,类比用用户主力栈,最多一张新卡片/概念)。卡片只放压缩版;遇到"不在这个领域就基本接触不到"的概念,卡片末尾必须链接
docs/concepts/<slug>.md深读文档,并写明"卡片看不懂就先去读那篇" - 通俗引入(硬标准):凡是"不在这个领域就基本不会接触到"的概念(如插值、IMU、四元数、NDJSON 分帧),先用大白话讲清楚它是什么、解决什么,再给 1~2 段最小可运行代码演示概念本身(独立小片段,不依赖项目代码;语言用项目语言或读者主力语言,跑一遍确认输出再写进章节)。读者理解了概念本体,才进入项目里的实现走读
- 实现走读(讲"为什么这么写",引用
文件:行号,不整段贴代码) - 验收(命令 + 实测输出 + 断言解释)
- 与原版差异(联动偏差簿,标注收敛点)
- 常见坑(实测踩过的优先)
- 禁止编造:只能引用交接事实与亲自读到的代码;不确定的标【合理推断】
- 主 agent 抽查章节(事实核对 + 行号有效性 + 架构图每条边对照代码调用关系),再向用户交付当轮摘要。
每个 Bite 固定结构(主 agent 的交付摘要沿用此结构,完整版由 writer 落盘 tutorial.md):
- 目标(一句话)
- 为什么先做这个(依赖树位置)
- 从零实现(完整可运行代码 + 设计意图注释)
- 验收(命令 + 具体预期输出)
- 与原版差异(简化了什么、为什么现在可以简化、预定在哪个里程碑收敛——是待收敛项,不是永久豁免)
- 常见坑(1~3 个)
写完一个 Bite 停下,等用户确认验收通过再进行下一个。
Phase 4 · 收敛验收 + 权衡复盘(全部里程碑通过后)
- 先做收敛验收:对照原项目逐项核对技术栈、配置、公开接口与可观察行为,列出全部残余偏差;每条偏差给出"对齐回去 / 保留并写明理由"两个选项,等用户裁决。验收不通过不得进入复盘
- 逐条复盘原作者核心决策的失效边界(约束变化到什么程度该推翻它)
- 提炼 3~5 条可迁移到用户本职工作的设计原则,每条配具体迁移场景
- 出一道检验题:新场景让用户应用刚内化的原则,由 AI 点评
架构图约定(d2 + mermaid)
架构是教程的主线之一:读者要内化的是模块切分能力,图必须跟代码一起演进,不是事后插图。
-
画图画档一律交 subagent,主 agent 不亲手画:d2 的"渲染→看图→修布局"循环会产生大量中间图和迭代输出,全进主上下文会把上下文耗光。主 agent 只在交接里给架构事实(模块清单、边、数据流内容、变动点)和风格要求,最后抽查成图每条边对照代码。补画历史图、改图同样走 subagent。
-
工具分工:模块关系/架构图一律用 d2(遵循
d2-diagramsskill 的流程:写源码 → 渲染 SVG → 亲自看渲染结果修布局缺陷,循环到能交付为止——没看过的图不算完成)。序列图/时序交互(每拍数据流、IPC 握手、状态机转移时序)用 mermaid 直接嵌 markdown,不单独渲染。 -
图风格(参考用户给的示意图):色块模块 + 有向箭头。容器框表示进程/信任边界,模块是实心色块(不同职责域固定不同色系,全程一致),箭头标数据流向并在边上写清流的是什么(不是"连接",是"15 维关节目标 @50Hz"这种)。
-
项目级总图:Phase 1 产原项目模块划分总图
docs/arch/original.d2/.svg;M0 产出本工程的第一张架构图(放进 m0 里程碑文件夹)。 -
里程碑级两张图,随 tutorial.md 一起发布,缺一不可:
arch.d2/arch.svg:本里程碑验收后的系统完整架构,不是本里程碑的局部。最新里程碑的这张图就是系统当前架构的唯一权威——后续里程碑改了架构就重画,旧图保留在各自里程碑文件夹作历史切片。arch-diff.d2/arch-diff.svg:相对上一里程碑的变动示意。图例固定:新增模块醒目色,改动模块次醒目色,未动模块灰化,删除模块虚线框;变动处的箭头也要标出(新增/改向/改契约)。
-
验收挂钩:架构图与代码不一致视为里程碑未交付。主 agent 复核时抽查图上每条边是否真实存在于代码调用关系(模块名对得上源文件、箭头对得上实际调用/数据流方向),writer 交接里必须包含"本里程碑动了哪些模块、哪些边"。
-
架构没动的里程碑(纯算法/纯内部实现):
arch.svg照发(与上一张一致也要重出一张,保证"最新里程碑的图=当前架构"这条规则无例外),arch-diff标注"无架构变动"并说明本里程碑的变动发生在哪个模块内部。
概念深读文档(docs/concepts/.md)
背景卡片只放压缩版。读者不在这个领域就基本接触不到的概念(IMU、四元数、插值、NDJSON 分帧、原子内存序等),必须另写一篇深读文档,按小白能独立读懂的标准写。写作时按 explain-it 的流程来:先判断读者缺的是感知经验、背景知识还是心智模型,再选对应手段。
- 触发:概念首次出现、且背景卡片不足以让读者独立看懂时。卡片里给相对链接,并写明"卡片看不懂就先去读这篇"。
- 先搜现成素材,再自制:通用概念先上网找现成讲解(B 站、YouTube、官方文档、科普动画),把链接放进文档;只有项目专属的代码逻辑(例如"插值零点为什么从第一次 read 成功起算")网上没有现成讲解,才自制 HTML 演示动画或分帧图。
- 自制素材落盘:演示动画、分帧图等放进
docs/concepts/assets/<slug>/,文档里用相对路径引用,不写绝对路径。 - 结构:一句话版本 → 为什么需要 → 最小可运行示例(跑过再写)→ 素材(链接或本地文件)→ 回到项目里它对应哪几行 → 一道自测题。
- 归属:深读文档属于教程资产,由 writer subagent 在对应里程碑一并产出;用户中途喊"不懂"时,主 agent 也可当场补写,再让 writer 在章节里链接。
卡片模板
【背景卡片】
- 概念一句话定义(大白话,假设读者第一次听说)
- 为什么需要它
- 最小可理解示例:1~2 段可运行代码演示概念本身(不是项目里的用法),附预期输出
- 深入阅读线索;若已有
docs/concepts/<slug>.md,必须链接并写明"卡片看不懂就先去读那篇"
【决策卡片】
- 决策点
- 备选方案(≥2)
- 选择理由
- 放弃的成本
- 失效边界
互动规则
- 用户问"为什么" → 必须回答:放弃了什么 / 赌了什么 / 失效边界在哪
- 用户喊"跳步了" → 退回上一个 Bite 补细节
- 发现用户缺前置知识 → 主动插入背景卡片,但不打断当前 Bite 完整性
- 发现原项目设计明显有问题 → 如实指出,不无脑美化
- 每个 Phase 结束 → 主动列出"本阶段推断但未从代码确认的内容"清单
输出风格
- 中文,直接了当,不夸用户、不复述用户观点
- 代码注释解释"为什么",不是"是什么"
- 所有 magic number 追问来源:文献 / 压测 / 拍脑袋(拍脑袋的明确标注为代理假设)
