模型老是交半成品:full-output-enforcement 的禁用模式清单
本文所有仓库信息核对日为 2026-08-09,以上游仓库最新内容为准。
你让模型把逻辑拆成 5 个文件,它给了你 2 个,中间补一句 “the rest follows the same pattern”;你要一整份实现,它给你一个骨架,函数体里躺着 // TODO。taste-skill 仓库里有一份 49 行的 SKILL.md 就是冲着这件事去的:文件夹叫 output-skill,install name 是 full-output-enforcement。
一、十三个 skill 里最短的那一份
taste-skill 的 skills/ 目录下有十三份 SKILL.md,体量差得很远:imagegen-frontend-mobile 有 1465 行,默认的 taste-skill(install name design-taste-frontend,当前内容是 v2 experimental)有 1206 行,而 output-skill 只有 49 行——这是十三份里最短的。
短,是因为它管的事很窄。仓库里绝大多数 skill 在管审美:字体、配色、间距、动效。output-skill 一条设计规则都不写,它的 frontmatter description 说的是:覆盖 LLM 默认的截断行为,强制完整代码生成,封杀占位模式,干净处理 token 上限的分割。
所以它和设计类 skill 根本不在同一个坐标轴上。设计类 skill 决定”生成出来的东西长什么样”,这一份决定”东西有没有生成完”。判断要不要用它,别拿它跟 design-taste-frontend 比谁强,那是两个问题。
安装时有个这个仓库里的通用坑要先说:--skill 后面填的是 install name,不是你在 GitHub 上看到的文件夹名。README 给的单装命令形态是这样的:
npx skills add https://github.com/Leonxlnx/taste-skill --skill "design-taste-frontend"
要装本文讲的这一份,--skill 后面要填的是 full-output-enforcement,而不是文件夹名 output-skill。这两个名字对不上的情况在这个仓库里相当普遍,我们另有一篇专门做对照表。
它的 Baseline 一段原文立场很硬:把每个任务都当成生产关键,部分输出就是坏掉的输出;不要为简洁优化,要为完整性优化;要整个文件就给整个文件,要 5 个组件就给 5 个组件,没有例外。
二、三类禁用模式,分类方式比清单本身有用
被禁的输出模式被分成三类,每一类都标为硬失败:
| 类别 | 典型条目 |
|---|---|
| 代码块里 | // ...、// rest of code、// implement here、// TODO、/* ... */、// similar to above、// continue pattern、// add more as needed,以及裸的 ... 代替被省略的代码 |
| 散文里 | ”Let me know if you want me to continue”、“I can provide more details if needed”、“for brevity”、“the rest follows the same pattern”、“similarly for the remaining”、用来替代真实内容的 “and so on”、“I’ll leave that as an exercise” |
| 结构性偷懒 | 要求完整实现却输出骨架;只给首尾跳过中间;用一个例子加一段描述替代重复逻辑;描述代码应该做什么而不是把代码写出来 |
清单本身你扫一眼就懂,真正值得琢磨的是这三类的可检测性差得很远,这直接决定了你能把哪部分挪进自己的流程。
第一类是字符串级的。它们全都是固定形态的注释,落在你的代码文件里,你自己就能检索,也能在 CI 里加一条针对性的检查。这一类是最容易脱离 skill 自行兜底的。
第二类同样是字符串级的,但它们不在代码里——它们在对话窗口里。你的 lint 扫不到,代码 review 的 diff 里也看不到,因为那句 “for brevity” 从来没进过仓库。这类内容的唯一读者是当时坐在屏幕前的你,一走神就漏过去了。把这几句原文记住,比装什么都管用。
第三类没法机械检测。“输出骨架”和”输出实现”在语法上都是合法代码,都能跑(或者至少能编译过去),差别在语义层。清单里”用一个例子加一段描述替代重复逻辑”这条尤其阴——输出看上去是完整的、自洽的、有解释的,只有当你去数交付物个数时才会发现少了。
所以这份清单给你的实际增量是:前两类可以变成检查,第三类只能变成习惯。
三、执行流程里最值钱的是第一步
它给的执行流程只有三步:
- Scope:读完整需求,数清有多少个独立交付物(文件、函数、章节、答案),把这个数字锁住。
- Build:完整生成每一个交付物,不要半成品,不要”你以后可以自己扩展”。
- Cross-check:输出前重读原始需求,把交付物数量与 scope 的数字对比,缺什么先补上再回复。
三步里,第一步是全篇最可迁移的一句话。它做的事情是把”完整”这个形容词换成一个可对账的整数。“你写完整点”这种要求没法验收,“应该有 7 个文件,你给了几个”可以当场数。
反过来说,这也划出了它的适用边界:如果你的任务本身就数不出交付物个数——比如”帮我看看这段代码哪里有问题”、“这个方案你怎么看”——那第一步就悬空了,后面的 Cross-check 也就没有对照物。交付物可枚举,是这套流程成立的前提。
第三步的定稿自检还有一份 Quick Check:确认上述禁用模式一个都没出现、用户要的每一项都在且已完成、代码块里是真正可运行的代码而不是对代码的描述、没有为省空间而缩短任何内容。注意这四条是让模型自己核对自己,它的可靠性等于模型自查的可靠性,这一点下面还要说。
四、撞上 token 上限时的断点协议
这是这 49 行里我认为设计得最讲究的一段。响应接近 token 上限时,它给了三条否定和一条肯定:不要压缩剩余章节硬塞进来、不要跳到结论、写到一个干净的断点(函数结束、文件结束、章节结束)为止保持完整质量,然后以这一行结束:
[PAUSED — X of Y complete. Send "continue" to resume from: next section name]
收到 “continue” 时,从停下的地方精确接续,不复述、不重复。
值得留意的是这行里的 X of Y——它复用的正是第一步锁住的那个数字。整套东西是自洽的:先数清 Y,中断时报出 X,续写时不必重新对齐上下文。它把”被截断”从一次事故,改造成一次带状态的交接。
同样值得留意的是它禁掉的那两件事。“压缩剩余章节硬塞”和”跳到结论”有一个共同点:产出看起来是完整的——结尾不会留下任何”这里断了”的痕迹,你拿到的是一份形式上收了尾、内容被压掉一截的东西。相比之下,一个显式的 [PAUSED — ...] 标记哪怕丑,也是可见的。至于模型在预算不够时实际更倾向于哪种做法,这份 49 行的 SKILL.md 没有给任何数据,我们也没有测过,这里只陈述它禁了什么。
五、同一个仓库里,另外几份 skill 在体量方向上给的是相反的指令
这一点在实际配 agent 时会撞上,所以单独说。
output-skill 的立场是完整优先:部分输出就是坏掉的输出,要整个文件就给整个文件。
而同一个 skills/ 目录下的 redesign-skill(install name redesign-existing-projects),它的 Rules 一节写的是:配合既有技术栈,不要迁移框架或样式库;不要破坏既有功能,每次改动后测试;改动要可评审、聚焦,小而定向的改进优于大重写。
两份文件在”一次该吐出多少东西”这个方向上给出的指令是相反的。这是仓库里可核实的客观差异,我们只陈述到这里,不推断哪一条更对、也不推断作者的意图。对你来说要做的判断只有一个:当前这个任务,你要的是一份完整交付物,还是一次可评审的小改动。这两种诉求同时压给一个 agent 时,你得自己想清楚哪一边优先。
六、这 49 行是提示词,不是工程保障
这是全篇最需要带走的一条判断依据。
这个仓库的顶层目录里没有 src/、没有 npm 包、没有构建产物,核心资产就是 skills/*/SKILL.md 这些纯 Markdown 规则文件,output-skill 也不例外——它就是一份 Markdown 文本。上面那三类禁用模式、三步流程、断点协议,全部都是写给模型看的指令,不是 lint 规则,不是 CI 检查,也不是类型系统。“禁止 // TODO” 的性质是”告诉模型不要写”,而不是”装了之后你的代码里就不会出现 // TODO”。前者是指令,后者是结果,中间隔着一个模型会不会照做的问题。
Quick Check 那一节尤其要按这个前提读:它要求模型在定稿前自查有没有违反禁令,而这个自查动作本身也是由同一个模型执行的。一个会输出骨架的模型,未必就会在自查时判定自己输出了骨架。
所以如果你需要的是确定性,真正该做的是在自己这边补一道机械环节:把交付物数量写进任务描述里,回复到手后自己按数字对一遍;代码类的产出,在自己的构建链或 CI 里加一条针对占位注释的检索。这属于通用工程做法,不是该仓库文档里的内容,skill 能起的作用是把倾向往前推一格。
还有一件 SKILL.md 里没有提的事,按常识提醒一句(仓库没有给任何这方面的数据):强制完整输出意味着更长的响应,等待时间和 token 消耗都记在你自己账上。这在做小改动时未必划算。
七、顺带说一句 research/
仓库里有一个 research/ 目录,下面有一块以 laziness(模型偷懒)为主题的文档,自述是一份关于”为什么大模型产出不完整输出、有哪些被记录的恢复方法”的结构化分析。主题上它和这份 skill 挨得很近。
需要提醒的是:那里面所有的研究名称、百分比和实验结论都是该仓库的文档自己写的,我们一条都没有独立核实过,也没有读过它引用的原始论文。想了解那部分内容的边界在哪,我们另有一篇专门讲,这里不展开,更不要拿那些数字当结论去调你的 prompt。
八、什么时候值得装它
按上面几节的依据,可以收敛成一条很短的判断路径:
- 交付物能数出来(N 个文件、N 个组件、N 个章节),而且你确实要全量——这份 skill 对着的就是这个场景。
- 你要的是一次聚焦的小改动,或者任务本身是探索性的问答——第一步就锁不住数字,装了也不解决你的问题,还可能把响应拖长。
- 你需要的是”保证不出现占位符”这种确定性——那 49 行文本给不了,得靠你自己那一道检查。
它值钱的地方其实不在那份清单有多全,而在于它把一个含糊的抱怨(“模型老是偷懒”)拆成了可以逐条对照的形态。哪怕你一个 skill 都不装,把第一步的”锁住交付物数量”和第二类那几句散文原话记在心里,也已经拿走大半。
本文依据 taste-skill 官方仓库(github.com/Leonxlnx/taste-skill)的 README、CHANGELOG、
skills/ 下的 SKILL.md 与 .claude-plugin/ 清单整理,核对日 2026-08-09。
本文内容为仓库文档口径,我们没有安装或运行过其中任何一个 skill,
文中所有规则均为写给模型的提示词约束,不构成对输出结果的保证。
skill 内容随上游更新而变动,默认 skill 当前自标为 v2 (experimental) 且仍在迭代,请以仓库最新内容为准。
文中援引的研究结论均出自该仓库 research/ 目录的自述文档,我们未核实其原始出处,不作为事实主张。