让 AI 直接开发一个小工具,经常得到看起来完整、却漏掉关键边界的代码。比如“把笔记导出为文本”只有一句话,模型可能覆盖已有文件、改写原始顺序,或者在标题里插入你没要求的日期。很多返工其实在编码之前就能发现。
本文使用 Superpowers 的 writing-plans Skill,把一个虚构的笔记导出需求整理成可交接的实施计划。最终成果是需求说明、文件职责、接口契约、逐项测试与实施顺序;本文不执行完整开发,也不把一份计划宣称为已经可用的软件。
练习对应下方资源表中的 Superpowers 完整源码包,重点阅读 skills/writing-plans/SKILL.md。资料包不是单独的桌面应用,Skill 也不是替代开发者判断的项目管理系统。
一、先分清需求说明与实施计划
需求说明回答“要得到什么、哪些事情不做”。实施计划回答“哪些文件负责哪些部分、接口怎样连接、用什么测试证明符合需求”。两者不能互相替代:没有确认目标,计划可能只是把错误方向拆得很细;只有目标,没有接口与验收,执行者仍然需要大量猜测。
官方 Skill 强调给未看过代码库的工程师足够上下文,把任务拆成能独立检查的交付单元。任务不能只写“处理边界情况”或“加合适的测试”,而要指出具体输入与预期。另一方面,也没有必要把整个程序提前写进计划,造成“计划比实现更复杂”。
本例使用一个新的空目录,不修改真实笔记。你只需要能阅读 Markdown、在相应工具中使用插件;后续实现若选择 Python,需要确认解释器版本。制定计划与执行计划是两次不同的决定。不应因为计划写完,就让代理顺手修改其他项目。
二、安装并找到对应 Skill
以 Claude Code 为例,官方 Superpowers README 给出的插件安装方式包括:
/plugin install superpowers@claude-plugins-official在 Claude Code 的交互界面输入,不是在系统命令行执行。按客户端提示检查插件是否安装成功;如果没有识别,核对插件状态、客户端版本和市场入口,而不是安装不明来源的同名文件。
使用 Codex、Cursor 或其他工具时,阅读仓库对应的安装章节,各工具的接入方法不能混用。本文的资料下载用于阅读固定版本的说明与许可证;插件市场可能安装不同版本,要记录实际使用版本,不把网盘包自动描述成官方最新发布。
确认可用后,在练习会话中请求使用 writing-plans。如果工具给出了技能调用状态,结合状态与实际产物核对;仅凭模型说“我按 Skill 写了”,并不能证明计划包含正确的接口和测试。
三、把一句需求改成可判定的规格
先建立 docs/specs/note-export.md,写入以下教学约定。这里的精确格式是人为确定的练习规则,不是通用笔记格式标准。
- 输入是一个列表,每项只有非空单行
title和字符串body。 - 保留笔记原有顺序,保留正文中的中文和换行,不自动纠错或摘要。
- 每条笔记渲染为井号、空格、标题、换行、正文、换行。
- 两条笔记之间再增加一个空行;空列表渲染为空文字。
- 输出为 UTF-8 新文件;目标已存在时拒绝覆盖,原文件内容必须保持不变。
- 不提供图形界面,不连接云端,不自动创建父目录,不读取真实账号数据。
用一份手写参照固定格式:标题为“周会”、正文为“确认报名页”,渲染结果应精确等于 # 周会\n确认报名页\n。两条笔记拼接时,前一条末尾换行与分隔空行形成两个连续换行,不能任意多加或少加。
如果团队想支持多行标题、标签、附件或日期,先改规格,再改计划。不能在执行者不知道的情况下把“以后可能需要”混进当前任务。范围小不是功能差,而是便于第一次独立验收。
四、给代理的规划任务应该包含什么
下面的任务只要求规划,不要求执行代码或安装依赖:
请使用 writing-plans,为 docs/specs/note-export.md 写实施计划。
先阅读规格,检查是否存在无法确定的行为;有缺口先列问题。
按现有空项目约定,只使用 Python 标准库。
计划写清创建文件、函数签名、输入输出、测试名、运行命令和预期。
每个任务交付一个可独立检查的成果,不把一个函数机械拆成很多空任务。
覆盖空列表、中文换行、非法标题、已有文件和父目录缺失。
将计划保存到 docs/plans/note-export-plan.md。
本轮不创建应用代码,不运行外部脚本,不执行计划。官方 Skill 有默认计划目录,用户指定的保存位置可以覆盖默认。这里显式指定 docs/plans/,让练习产物易于找到。若实际项目已有约定,沿用项目规范,不为写一个计划擅自重构目录。
五、先确定两个清楚的接口
计划可把职责分成两个部分:note_export.py 中的纯渲染函数,以及负责创建输出文件的函数。测试放在 tests/test_note_export.py。小练习不需要提前引入数据库、网络层和插件系统。
第一个接口是 render_notes(notes: list[dict[str, str]]) -> str。它只验证输入并生成文字,不写文件、不改变输入。非法输入采用明确异常,例如标题为空或含换行时抛出 ValueError;如果要区分类型错误,规格和测试应一致说明,不能在不同任务中各说各话。
第二个接口是 write_new_export(path: Path, text: str) -> None。它接收已经渲染的文字,以 UTF-8 创建新文件;目标存在时抛出 FileExistsError,父目录不存在时保留原有缺目录错误。不能偷偷变成覆盖写入,也不替使用者猜另一个文件名。
这两个接口的连接点必须一致。任务二调用的是 render_notes,不是另起名字的 export_markdown;路径类型也不能在计划后半部分突然变成文件句柄。计划中的接口名是交接契约,不是装饰性描述。
六、每个任务都写出检查闭环
任务一负责“按规格渲染笔记”。写明创建 note_export.py,测试空输入、单条格式、多条顺序、中文正文换行、非法标题与未知字段。先写测试并运行,确认失败原因是尚未实现的目标行为,再写最小实现,最后运行这组测试。
一个可放进计划的测试片段如下,示例假定未来实现采用 unittest。它是待实施的测试,不表示本文已创建该应用:
def test_render_preserves_order_and_newlines(self):
notes = [
{"title": "周会", "body": "确认报名页\n等待图片"},
{"title": "资料", "body": "第二条"},
]
expected = "# 周会\n确认报名页\n等待图片\n\n# 资料\n第二条\n"
self.assertEqual(render_notes(notes), expected)任务二负责“只创建新导出文件”。在临时目录里验证编码与文件内容;预先创建一个含“原文件”的目标,再调用写入函数,应得到 FileExistsError,随后再次读取目标,确认还是“原文件”。只断言抛错、不核对原内容,会漏掉先截断文件再报错的错误实现。
任务三若确有必要,可增加最小命令行入口和使用说明;但本文规格没有要求命令行参数界面,不必为了凑任务数添加。两个完整交付单元已经能形成清晰计划。测试运行命令可约定为 python -m unittest discover -s tests -v,但预期通过数量要等完整测试清单确定,不能提前编造执行结果。
七、检查计划有没有留下隐性猜测
逐条对照规格:谁处理非法输入,谁保证不修改原列表,谁负责文件编码,哪个测试证明拒绝覆盖。再检查两条笔记之间到底是一个空行还是一个换行;这类小歧义最容易在不同执行者之间产生差异。
另外检查父目录缺失、路径无写权限和运行中断。单纯以独占方式创建新文件可以防止覆盖已有文件,但不自动保证所有系统上的完整原子交付。本文规格没有承诺中断后绝不留下部分新文件,计划应明确这个边界;若客户需要,另行设计临时文件与发布策略,不能暗中扩大保证。
没有资料时不编造行号。新项目写创建路径即可;已有代码库的修改点,需要先实际阅读对应文件再写。计划引用不存在的测试函数、文件或依赖,也是未完成的交接,不是执行者应该自行补齐的小事。
八、保存、审核和交接
保存后打开计划文件,确认它独立可读:目标、规格路径、架构、技术栈、全局限制、任务接口和验收方式齐全。官方 Skill 还要求对可能遗漏的输入或失败场景做自查,重点是把实际缺口落实到负责它的任务,而不是机械列五句“注意边界”。
请同事只看规格和计划,复述预期格式与实现顺序。如果对方仍需要猜目标文件是否可以覆盖,就继续修订。内容越长不代表计划越好,能减少关键猜测、又保留合理实现空间,才是有效的交接。
计划通过审核后再决定执行方式。当前只交付规划,可以保留待办框;不能把所有任务预先勾选为完成。执行过程中若规格变化,先更新计划和测试依据,再继续,不让旧计划成为“明明完成却验收不通过”的借口。
本文核对了官方固定版本的 Skill 与 README,并用自编离线参照检查了示例字符串格式和新文件保护约定;没有执行下载包代码、调用真实规划代理或交付完整笔记应用。因此你应把本文当作可操作的规划练习,而非某个工具修复率或开发效率的实测报告。

还没有公开评论,欢迎分享你的想法。