返回博客2026年6月2日2 分钟阅读

写 Agent Skill 就是 TDD - 用 subagent 当 test runner

摘要

为了让任何 Coding Agent 一行命令就能调用 YourWebs API 发布 HTML 页面,我跟着 Jesse Vincent 的 Superpowers 里 writing-skills 这一套方法论做了一个 yourwebs-skill。这篇想分享的不是结果,是过程 - 写 Skill 跟写代码的 TDD 是同一件事,而那个最关键的 test runner,是一个上下文为零的 subagent。

我想给 YourWebs 加一个能力:让任何 Coding Agent - Claude Code、Codex、Cursor 都行 - 不用我每次重新解释 API,就能把一个自包含的 HTML 页面发布出去并拿到公开链接。

最直接的想法是在 dashboard 上放一段文字,让用户复制粘贴给 agent,让 agent 自己现场“发明”一个调用方式。很多 Web 应用就是这么做的。它脆弱 - 每个 agent 对 API 的幻觉都不一样、没有唯一的真相源、跨 session 不可复用。

更好的答案是一个真正可安装的 Skill - 一行命令:

npx skills add sugarforever/yourwebs-skill

但这篇我想写的不是结果,是过程。Jesse Vincent(GitHub obra)开源的 Superpowers 里有一个叫 writing-skills 的 Skill,它把“怎么写 Skill”本身做成了一套方法论。我跟着它走完一遍以后,最大的感受是:写 Skill 跟写代码的 TDD,是同一回事。

写 Skill 就是 TDD

writing-skills 的核心论断只有一句话:

Writing skills IS Test-Driven Development applied to process documentation.

这个类比是精确对应的:

写代码的 TDD写 Skill 的 TDD
先写一个失败的测试把任务交给一个没有 Skill 的全新 agent,看它在哪里出错(RED)
写刚好让它通过的实现写一份 SKILL.md,恰好修掉刚才暴露的问题(GREEN)
重构找到 agent 还在凭猜测填补的盲点,把它们一一关掉(REFACTOR)

它有一条铁律:没有一个失败的测试,就不要写 Skill。 如果你没有先观察过一个 agent 在没有这份文档的情况下怎么挣扎,你其实不知道你的文档教对了东西。你只是在猜 - 而作者是最不适合猜的人,因为他已经知道答案。

这一点我后来反复回味,发现它是整套方法论的支点:写 Skill 的人,是这份 Skill 最差的 reviewer。

方法论怎么落地

我跟着 Superpowers 走了一遍,每一步都对应着 TDD 类比里的某个动作。

设计在前,不写代码 - 等于先把规格钉死再写 test。 Superpowers 的 brainstorming skill 有一条硬性规定:没有共识的设计,不能进入实现。所以我没急着写 SKILL.md,先回答了几个看上去琐碎的问题:终态是什么?一次性粘贴还是真正安装?只服务 Claude Code 还是 agent-neutral?API token 怎么读?这几个回答,每一个都干掉了一种我本来会写出来又扔掉的实现。

事实从源码里挖,不靠感觉 - 等于断言基于真实行为,不是想象。 我没有让 LLM“大概描述一下 YourWebs API”,而是直接读了 YourWebs 自己的 Worker 源码:每一个 endpoint、每一个真实的错误码(invalid_htmlsubdomain_takenrate_limited......)、1 MB 的上限、subdomain 的正则。然后又翻了 npx skills 的 CLI 文档,确认仓库结构 - 根目录放 SKILL.md 就让仓库变成一个单 Skill 仓库,可以直接装。每一条都核对过,不是凭印象。

description 只写“什么时候用”,不写“它做什么”。 这是 writing-skills 提醒最重的一条。如果 description 里复述了工作流,未来的 agent 会跟着 description 走、跳过真正的 Skill body。writing-skills 给过一个真实例子:description 里出现“code review between tasks”,结果 agent 只做了一次 review,而 body 写的是两次。所以 yourwebs-skill 的 description 我只写触发条件 - “当用户想要发布、托管或分享一个自包含 HTML 页面时......” - 完全不剧透步骤。

到这里 GREEN 阶段就结束了:一份看上去挺完整的 SKILL.md。但我没有自信。

为什么 subagent 是最好的 test runner

writing-skills 的 RED 阶段不让你自己读自己的 Skill 来 review。它让你做一件事:派一个 subagent 出去。

具体动作是这样的:spawn 一个全新的 Claude 实例,给它一个空白上下文,让它能读 SKILL.md,然后给它 5 个真实任务(“把这个 HTML 文件发到 subdomain X 上,把链接给我”、“列出我所有页面” ......),让它写出确切要执行的命令;最后让它告诉我哪里有歧义、哪里它是在猜,要它毫不客气地挑刺

这一步是整套方法论里最反直觉的一步。第一次看到的时候我会想:我自己读一遍不就行了吗?或者让一个真人用户试试?

实际跑完才意识到,subagent 这个选择是被三件事共同决定的。

第一,作者永远带着 curse of knowledge - 你看不见自己埋下的隐含假设。 YourWebs 有一个细节:API 在 yourwebs.cc,但发布出来的页面在 yourwebs.app。我太熟悉这件事了,熟到根本不会意识到它本身是一个需要写下来的事实 - 在我眼里两个域名就该不一样。冷上下文的 agent 第一次跑就指了出来:

域名不一致(最大的一个问题)。 API base 用的是 yourwebs.cc,发布后的 URL 在 yourwebs.app。文档完全没解释为什么页面会在另一个 TLD 上。

它还顺手挑出了几条更小的:subdomain_invalid(要让用户改)跟 subdomain_taken(自动重试)的区分要不要写、“≤ 1 MB”是指 HTML 原始字节还是 JSON body 总长。这些都不是我马虎漏掉的 - 是我处在“看不见”的位置上。

第二,真人用户在这个位置上反而不好用。 真人贵、慢、稀缺。更麻烦的是,真人会客气 - 他会自己补一下你没写清楚的地方,然后告诉你“挺好的”。你拿不到那份“我是猜的”的清单。subagent 不会客气,因为你明确要求它“尽量挑刺”。这是结构化的不客气,不是性格问题。

第三,subagent 是这三个选项里唯一可重复、零成本、零延迟的。 改完 Skill 想再测一次?再 spawn 一个就行了。迭代 5 轮、10 轮都不会有成本压力。这跟真人用户的反馈循环完全不在一个量级。

把这三条放在一起看,subagent 就不再是一个“凑合用”的选项 - 它是工程约束下唯一合适的选择。它在 TDD 类比里扮演的角色就是 test runner:失败要可见、要可重复、要便宜到你愿意每次改完都跑一遍。

更进一步:这一招的应用范围远不止 Skill。任何“另一个 agent 要照着执行的文档”都成立 - runbook、prompt template、agent 的 system prompt、内部工具的 README。只要执行者是一个没法跟作者澄清的 agent,作者的盲点就一定会变成线上的故障。冷上下文的 subagent 是这类文档目前唯一像样的验证手段。

关掉盲点,发布

第二次跑 subagent 之前,我把所有暴露出来的 gap 补齐:加了一段明确写“两个域名是有意为之”的说明、把 subdomain 错误处理写清楚、钉死“1 MB”是哪个值、补上 rate-limit 的退避策略。重跑,冷上下文的 agent 这次 5 个任务全部能写出正确命令,零猜测。

然后才是 commit、push、在 YourWebs dashboard 上加一张一行安装卡、部署上线。

回头看,这套从设计到验证的工作流我以后写每一个 Skill 都会复用:先 brainstorm 把设计敲定 → 用真实事实而不是感觉做支撑 → 写一份精简的 SKILL.md → 派一个冷上下文的 subagent 当陌生用户来测 → 关掉它暴露的所有 gap。

TDD 不只是给代码用的

TDD 真正强的地方从来不是“测试覆盖率”这种指标,而是它强制把“我以为别人会怎么用”这件事变成可观测的。你不写测试,你的假设永远在你脑子里;你写了测试,你才看得见自己漏了什么。

写 Skill 把同一件事搬到了文档上 - 你以为读者(agent)会怎么读,写下来、跑一遍、看它真的怎么读。Superpowers 的 writing-skills 没有发明新的方法论,它只是把一套已经在代码上行之有效的纪律平移到了一种新的“代码”上 - 让另一个智能体照着跑的指令。


相关文章

2026年5月31日

【AI早读 0531】Anthropic 把 Claude「关在笼子里」的安全设计

Anthropic 公开了三条产品线的 Agent 隔离方案 - claude.ai 用 gVisor、Claude Code 用 Seatbelt/Bubblewrap、Cowork 用全 VM;Claude Code 早期 93% 的批准率反而成为安全风险,被 auto mode + 架构改造替代;AI Engineer 大会上「砍掉 95% Agent 技能反而更好」成为新共识;SoftBank €750 亿建法国数据中心,OpenRouter 完成 $1.13 亿 B 轮。

2026年5月26日

【AI早读 0526】Addy Osmani 提出「你才是编排税」,Hugging Face 重新区分 Model / Scaffolding / Harness / Agent

Addy Osmani 用 Python GIL 比喻揭穿多 agent 并发的真正瓶颈 - 是开发者本人;Hugging Face 发出官方词汇表,把 Model / Scaffolding / Harness / Agent 这四个被混用的概念锚定下来;Google DeepMind 的 Nicholas Kang 与 Michael Aaron 分享大规模 agent 评估的工程化做法;Bounded Autonomy 把「自由意志 vs 确定性」落到 harness 工程里;Simon Willison 发布 datasette 1.0a30 的可扩展 Jump 菜单 + datasette-agent 联动。

最近一封 · Sample

【AI早读 0603】Agent 生态全面爆发

微软 Build 2026 上 GitHub 推出 agent-native 桌面应用 Copilot app,COO Kyle Daigle 在 Latent Space 披露 AI agent 推动 commit 量年增 1400%、Actions 用量翻 4 倍;H Company 发布 Holo3.1,首次加入 FP8 / Q4 / NVFP4 量化权重,NVFP4 吞吐量是 BF16 的 1.74 倍,AndroidWorld 得分从 67% 跃至 79.3%;AWS 给出 AgentCore Gateway + OAuth 保护 MCP 服务器的完整教程;Together AI 用 MiniMax Sparse Attention 让 MiniMax-M3 在 1M 上下文上 prefill 提速 9 倍、decode 提速 15 倍;a16z 提出视觉 AI 下一站是生成代码,而非像素。

—— william

Letters

来信

里面装的是

  • 新文章 — 写完一篇就寄一封,不攒货
  • 这周读到的、看到的、好用的工具
  • 正在折腾的实验,附带翻车记录

约莫 1–2 周一封 · 随时退订

合作伙伴

CompeteMap — 英国及爱尔兰学生竞赛一站式搜索

数学、编程、科学、写作等各类竞赛信息汇总,支持按年龄和科目筛选,再也不错过报名截止日。

准备开始了吗?

先简单说明目标,我会给出最合适的沟通方式。