要让人看懂一件事,可以写字、画图、做网页、录视频。四种形式的成本差很多。这个 skill 让模型按内容选最便宜、又讲得清的那一级。视频默认不做:模型先提一句,你点头才做。
示意:问题是举例,计数是本动画里落下的次数,不是统计。
出处:Karpathy 2026-10-02 的帖子把读懂 AI 输出的形式排成这四级。代码变便宜了,以前不值得做的一次性网页、讲解视频,现在可以随手要。级别高不等于好:写清楚的一段文字,是最快让人看懂的那一级。
| 读者要的是 | 用 | 在哪看 | 这个 skill 给什么 |
|---|---|---|---|
| 结论、数字、一步操作 | 1 文字 | 终端 | STE 打八折的写法,「用 STE 讲」开关,check_ste.py |
| 关系:谁调用谁、哪个同步哪个、卡在哪一级、状态怎么切换 | 2 图 | 终端(ASCII) | ≤ 80 列、汉字算两列;正式出图指向设计 skill 的图例库 |
| 一大批同类记录、一条长时间线、要过滤 / 排序 / 按行号跳 | 3 网页 | 浏览器 | page_kit.py 生成单文件页,check_page.py 四项检查 |
| 随时间展开的过程,先后顺序和时机本身就是要点 | 4 视频 | 播放器 | 默认不做;先提一句,点头才用 record_page.cjs 录 |
ASD-STE100(简化技术英语)本来是飞机维修手册用的受控英语:读者常常不是母语者,读错了没处问。AI 写的长句、被动句、同一个东西换着叫,正是读错的来源。原标准太严,照搬会写成电报,所以只取八成。中文同样适用。
开关:说「用 STE 讲」,之后每条回答都这样写;说「停止」关掉。只在本次会话有效。
位移图按球面圆顶的高度和折射定律(水 n=1.333)烘出:中间放大约 1.4 倍(从烘好的位移图读出:半径 4–14px 处 1.38–1.44 倍)、边缘压缩;同一次烘焙带出它投在页面上的焦散和阴影(乘进页面,亮处看得见、黑处看不见),以及边缘的 Fresnel 反光和小高光。
$ printf '%s' "<原文>" | python3 check_ste.py --stdin <stdin>:1 S1 句子 94 字,超过 50:「位移图按球面圆顶的高度和折射定律(水 n=1.3…snel 反光和小高光。」 共 1 处
位移图按球面圆顶的高度和折射定律(水 n=1.333)烘出。中间放大约 1.4 倍,边缘压缩。从烘好的位移图读出:半径 4–14px 处放大 1.38–1.44 倍。同一次烘焙还带出三样东西:投在页面上的焦散和阴影、边缘的 Fresnel 反光、小高光。焦散和阴影乘进页面:亮处看得见,黑处看不见。
$ printf '%s' "<改写>" | python3 check_ste.py --stdin 没有发现
原文:skills/glass-design/SKILL.md:69(提交 a49d13c),一整行里被报的五句之一。改写后内容一样,换成五句。
谁调用谁、哪个仓库同步哪个、启动卡在哪一级 —— 这类问题写成一段字,读者要自己在脑子里画一遍。终端里先画几行 ASCII 图:不超过 80 列,汉字按两列算。图必须带出文字里看不出的判断;只是把文字框起来的图,不如不画。
按键中断进来后调用 gpio_keys_gpio_isr(),它在 wakeup 按键时处理唤醒,然后看 debounce_use_hrtimer:为真就用 hrtimer_start() 起一个高精度定时器,到期时 gpio_keys_debounce_timer() 被调用;否则用 mod_delayed_work() 排一个延时任务,到期时 gpio_keys_gpio_work_func() 被调用;这两个函数都调 gpio_keys_debounce_event(),它再调 gpio_keys_gpio_report_event(),最后由 input_event() 把按键值交给 input 子系统。
每个字都对,但「中断函数里没有上报」这件事,得读到第三个分号才拼得出来。
调用链:从上往下,每层挂出处
行号出自一棵 Linux 6.1.141 内核树的 drivers/input/keyboard/gpio_keys.c,只作示意
按键中断
│
▼
gpio_keys_gpio_isr() :417 不上报,只排一个延时
│
├─ hrtimer_start() :439 用 hrtimer 消抖时
│ └─ gpio_keys_debounce_timer() :407 到期后调用
│
└─ mod_delayed_work() :443 不用 hrtimer 时
└─ gpio_keys_gpio_work_func() :399 到期后调用
gpio_keys_debounce_event() :390 两条路到期后都调它
│
▼
gpio_keys_gpio_report_event() :366
│
▼
input_event() :386 按键值交给 input 子系统
正式出图交给设计 skill 的图例库:anthropic(78 张现成 SVG)· apple · glass · relief(内核 / 硬件类)。设计 skill 不够用时,模型要明说缺什么,不硬套。
下面这页是真的:用 page_kit.py 从固定提交 a49d13c 取 skills 目录的快照,拿同一提交里的 check_ste.py 体检 sky-skills 自己的 25 份 SKILL.md。表能过滤、能排序,原始输出带行号,页尾列出处和 sha256。
p.source() / p.command() 读进来再算。页面越好看,里面的数越像真的;手抄错了,页面上看不出来。file:// 页面,读不到旁边的文件;CDN 在内网下不一定通。这页的 build.py 还自己核对一次:命令输出最后一行必须是「共 N 处」,解析出的条数必须等于 N。命令中途失败时,它停下报错,不会生成一张空页。
$ python3 check_page.py demos/explain-ladder/ste-report ✅ P1 单文件:没有引用外部文件 ✅ P2 出处:2 条出处,文件都在、内容没变 ✅ P3 能重建:重跑 build.py 得到逐字节相同的页面 ✅ P4 打开不报错:打开无报错、无网络请求,3 个控件、2 条出处都画出来了 ste-report:4 通过 / 0 失败 / 0 跳过
P3 是关键:重跑 build.py,和现有页面逐字节比对。手改过页面里的任何一个数,这一项就过不了。
视频做起来最贵,看的人也只能从头看到尾,没法过滤、搜索、跳到某一行。只在三种情况下提:要讲的过程里先后和时机就是要点;看的人要被动看完(转给组里、给新人讲);或者你自己提到视频。
这个分类过程做成 15 秒的无声录屏可能更直观:问题一个个落到哪一级,一眼就能看出来。要做吗?做的话就录上面首屏那段动画,几分钟。
还没点头:不录、不装依赖、不写配音稿。
$ node record_page.cjs index.html --seconds=15 --out=ladder.webm ✅ V1 文件能播:15.48 秒 · 1280×720 ✅ V2 画面动了:5 个时间点和首帧比,最多 0.42% 的像素变了
| 路 | 做法 |
|---|---|
| A 无声录屏 | 先做第 3 级的页面(带动画或分步按钮),再用 record_page.cjs 录成 webm。录完自己打开一遍核对:能播、画面在动。 |
| B 配音 + 字幕 | 走 wechat-video-publisher:edge-tts 配音、逐帧截图、ffmpeg 合成并烧字幕。 |
V2 抓的是「动画在录之前就播完了」「页面开了减少动态效果」这两种情况 —— 录出来都是一张静止图。录屏用的页面最好就是第 3 级做出来、过了检查的那个,视频里的数也就有出处。
全绿的自测不等于查到了:用例只有一种形态时,整条路径可能从来没跑过。所以每个脚本还做了反向验证 —— 把检查故意改坏,对应的用例必须变红。
check_ste.py:11 条必须报出问题。另外把它故意改坏 14 处(汉字按一列算、不分句、分号断句……),14 处都让对应用例变红。
check_page.py:9 条故意做坏(手改页面、源文件变了、引 CDN、脚本报错……)。有一个问题自测查不出:在仓里跑时 node 能自己找到浏览器,从仓外运行就找不到。这是换到仓外手动跑才发现的,已修。
record_page.cjs:静止页、动画录之前就播完的页,都必须报 V2;只有一小块在动的页,必须判成在动。V2 数变化像素的占比:静止页 0%,本页首屏 0.42%,门槛 0.1%。
$ K=~/.claude/skills/explain-ladder/scripts $ python3 $K/check_ste.py --self-test 自测:19 通过 / 0 失败 $ python3 $K/check_page.py --self-test 自测:13 通过 / 0 失败 $ node $K/record_page.cjs --self-test 自测:5 通过 / 0 失败