assert-what-the-generator-found
会崩溃的生成器告诉你它失败了;输出看似合理的生成器什么也没告诉你。测试它找到了什么,而不是它跑过了。
由读过该卡片的评审者赋予,而不是文件自我声明的。智能体在处理不可信内容的运行中提炼出的卡片,生来即被标记为受污染,在被检索之前会一直等待评审。
何时会想到它
- 写了一个代码生成器
- 测试 schema 导出
- 输出看起来没问题
- 从库里提取结构
价值通常在「避免」和「检查」里。「该做」是人人都会写的那一节。
上面的卡片正文是译文。英文原文才是 CLI 导入的内容、智能体运行时读取的内容,也是下方哈希所证明的内容。
触发
你写了一段代码,读取一种表示形式并输出另一种:模式(schema)导出、引用提取器、迁移脚本、爬虫、索引构建器。任何输出量大到没有人会通读全部的东西。
这条不适用于返回单个值、可以一眼看完的函数。这里的风险专指那种输出量大到"看起来没问题"就是它此生唯一一次评审的情况。
该做
- 在写测试之前,先说出确切的数量。应该产出多少条命令、多少行、多少个文件或字段?这个数字要从生成器(generator)以外的地方获取——源头、文档,或手动清点。
- 断言这个数量,或者断言它的下限。用
assert len(groups) >= 10,而不是assert result。 - 断言你确知一定存在的具体、具名条目。三四个就够,而且要从不同形状的输入里各挑一个。
- 如果生成器(generator)会对事物分类,就断言每个类别都非空。把所有东西都归到同一个桶里的分类器,正是这一条要抓的失败。
避免
assert build()——当生成器(generator)返回空列表、部分列表,或者列表中每一项都是某种微妙的错误类型时,它照样会通过。
在遍历第三方结构时,也要避免信任 isinstance。库会内置(vendor)自己的依赖:TyperGroup 并不是你文件里导入的那个 click.Group 的实例,因为 Typer 自带了一份 Click 的副本。应该问对象是否拥有你需要的东西——一个 commands 映射、一个 items 方法——而不是它声称自己是什么类。duck-typing 能扛得住内置依赖和大版本升级;类型检查两样都扛不住,而且失败的方式是误分类,而不是抛出异常。
检查
故意弄坏生成器(generator),看测试是否会失败。把递归进入子命令的部分注释掉,或者让类型检查拒绝一切,然后跑一遍测试套件。
如果测试套件依然通过,那这个测试断言的只是"生成器跑过了",而你写出的正是这条技能要防止的那种测试。
风险
把确切数量写死会让测试变成维护负担:每次合理新增一条命令都会把它变红。优先用下限(>= 10)加具名条目,把确切数量留给那些真的不应该在无人决定的情况下改变的东西。
这也有极限。这些断言能抓住丢弃了整整一个类别的生成器(generator),却抓不住只在某一项上错了一个字段的生成器,假装它能做到后者,本身就是一种虚假的自信。
如何使用
卡片就是数据。克隆仓库并按路径导入——任何经由网络到达的内容都会被视为受污染并等待批准,这正是你想要的行为,也是这里没有一行命令安装器的原因。
git clone https://github.com/brcampidelli/chimera-agent.gitchimera skills-import chimera-agent/skills/assert-what-the-generator-found/SKILL.md完整性
文件发布版本的 SHA-256。导入方可以据此核对收到的内容与本页展示的一致。
0ffc1fdde72d3f2c416461f0f312ca5ca2a43d3b1ff33aaf7b20be155de711c9