技能工程的九种黑暗艺术:把 Skill 从提示词做成 Harness 扩展

Paul Bakaus · Impeccable 作者 · 2026-09-29
听中文精华AI 合成朗读00:00
提示词是咒语,harness 工程才是魔法。
— Paul Bakaus

关联

「提示词是咒语,harness 工程才是魔法。」说这话的是 Paul,Impeccable(一个给 Claude Code、Codex 等编程智能体用的开源前端设计技能,impeccable.style)的作者,更早以前他还创造了 jQuery UI。

过去一年他构建大型企业应用时,发现智能体能很快生成能看的界面,但要拉回设计系统非常难,于是从第一个 normalize 技能起步,一路把 Impeccable 打造成了一套「设计 harness」。这场工作坊讲的就是他踩坑踩出来的九种「技能工程的黑暗艺术」——核心论点:提示词只是入门,构建 skill 时应该把它当成对编程 harness 的扩展来设计,就像 MCP 一样,而不是「打包起来的一段 prompt」。

先说他起步的地方:Anthropic 的前端设计 skill——约 55 行「命名禁令」,没有脚本、没有路由,纯文字描述。问题是 Slop(AI 生成的千篇一律的垃圾审美)是个移动靶子:早期是紫色渐变,现在变成了「Claude 米色」背景加斜体衬线。

禁令有两个致命问题,第一,禁令只是把问题挪了个地方——你告诉它别用 Inter,它就去潜空间里抓下一个最近的替代品(比如 Space Grotesque),并没有变得更有创造力。Paul 在这里吃了历史级的苦头:当年他做 jQuery UI,默认主题是橙色,以为大家会改主题,结果一夜之间把整个互联网变成了橙色——中位数就是模型的引力,连 250 行精心打磨的技能散文都拗不过它。

第一招:让它争论

让 Claude Code 或 Codex 评审自己写的代码,等于让学生给自己批作业——它会锚定在自己已创建的东西上,通常打出高分。解法是对抗性提示:启动两个互不知晓对方存在的子智能体。Impeccable 的 critique 命令就是这么做的:一个子智能体扮演设计总监,用浏览器工具像人类一样看层级、找 slop;另一个子智能体运行确定性检测器(一个能查出对比度差、字体过多、元素贴边等问题的设计 linter),并收集浏览器证据。主线程最后把两份意见综合成一份平衡的批评。这解决了一个真实陷阱:如果检测器和评估在同一线程里跑,模型看到「500 个问题」就会断定好设计很糟,或者看到「零问题」就把空页面夸成好设计。一句话:两个盲评胜过一个自信的猜测。代码审查、安全审计、RFC 批判、输出排序都适用。

但这里有坑:Codex 的权限模型不同,用户不显式授权它就不生成子智能体——分发技能时你没辙。唯一的办法是在技能里明说:「如果有子智能体能力但没权限,立即停下询问用户」。另一个心机:Codex 发现能蒙混过关就蒙混,所以还得写上「如果不能使用子智能体,必须声明你正在给用户降级体验」——Codex 讨厌承认降级,利用这一点逼它就范。

第二招:用反吸引子强制发散

禁令只在模型自己的偏好簇里挪动它,想真正发散要主动制造「随机种子」。三种从易到难的做法:① 削掉安全候选——让模型说出前三个推荐字体然后全部扔掉,重复三次,等于手动切到潜空间更远的地方(但迟早还是会收敛);② 大量生成 + 盲评子智能体排序——Paul 做着色器库 Radiant Shaders 时,每次要新创意都得到重复结果,他用「Rihanna 作为一个着色器会是什么样」这种意外种子生成一百个创意,再让一个对会话上下文一无所知的子智能体来排序(必须子智能体,否则它会沿用先前上下文的排序);③ 用脚本生成随机种子——Impeccable 启动项目时调用 color.js,里面有 100 多个手工挑选的主色,模型以它为创意火花搭建调色板。同一个简报因此能产出截然不同的结果——「我不想让整个互联网看起来千篇一律」。

第三招:像模型一样路由(专家混合)

把所有东西塞进一个技能,指令遵循会变糊。反例:Anthropic 旧版前端设计 skill 写着「避免系统字体」——这对落地页成立,对产品 UI 恰恰相反(产品要尽量原生)。用巨大的 if-else 块又复杂、费 token、效果差。Impeccable 的做法是专家混合(Mixture of Experts,多数现代模型的架构思路:按任务激活不同专家)式的技能:调用 impeccable critique 或 polish 时后台加载不同的 MD 文件;更少人知道的是,它还会根据你的简介判断你是在做品牌向设计(落地页)还是产品设计,然后为两种「语域」加载完全不同的规则。

第四招:让运行产生复利

技能默认没有长期记忆,但技能文件夹就是存储:Claude 里甚至有解析到技能目录的环境变量(其他 harness 暂不支持,可以变通)。Impeccable 在仓库根目录用 .impeccable 文件夹保存每次 critique 的结果,之后哪怕在另一个会话里让它 polish 页面,它也会读取历史 critique 理解「这个页面我们已经发现了什么」;你在 critique 里说过「我不同意这条,我更喜欢我的参考」,它会记住这是用户偏好并在今后尊重它。Paul 自己的高频用法:让技能跨会话自我派生重构代码,每次只处理一个文件,上下文随时间累积直到整个代码库完成。

第五招:会顶嘴的脚本

埋在长文里的规则,弱模型会略读。解法是把关键指令从脚本的标准输出里给出去:每次调用 Impeccable 都会先跑 context.mjs——它把 ProductMD/DesignMD 注入会话;文件不存在时输出结构化 JSON 明确告诉模型该怎么做;有新版本时提示询问用户是否更新。神奇之处:同样一句话,从脚本标准输出里出来的,模型遵循度远高于散文里的规则。短板要清楚:动态输出会破坏提示词缓存,频繁运行、希望整段缓存的场景不适合,交互式场景才划算。

第六招:会反击的 hooks

被动护栏胜过一条没人记得运行的命令。Impeccable 附带设计 hooks,安装时装进 Claude Code、Cursor、Codex 和 GitHub Copilot,每次编辑都触发检查。有个重要的工程细节:弱模型要用 pre-tool use hook(直接阻止写文件)而不是 post-tool use hook(写完再提醒去修),因为后者有些模型不会照做。体验上通常你什么都不用做,模型自己就修正了。别忘了给用户留忽略规则——hooks 有误报,不能配置的话很快会惹人烦。

第七招:给浏览器接上活线

「你没法对着聊天框调像素。」既然把 skill 当 harness 工程,就该问:这个 harness 有哪些能力可以利用?Claude Code 桌面版内置了应用内浏览器,Paul 把它劫持了:Impeccable 启动一个 live poller 小服务器,向开发服务器注入一段脚本;用户在页面上选中元素、选变体数量、点 go,poller 通过服务器端事件收到操作后自我结束,并在标准输出里留下一条消息——模型读到消息意识到「发生事了,我该干活」,按技能里写好的指令生成该区块的设计变体再送回页面。用户在浏览器里直接点击接受或按 escape 拒绝,还能画图批注、语音操纵整个页面。这是聊天线程和应用内浏览器两种 harness 能力之间的直连,完全没用 MCP。

第八招:为最弱的目标编译

「在我机器上能跑」在分发技能时是重灾区。「symlink 一下 .claude」只适用于自用,跨 harness 有大量差异:子智能体谁能启动(Claude 可编程调用、Codex 需用户批准、Cursor 多由智能体自决);Ask User 工具(Codex 有类似工具但仅 plan 模式可用,所以 Impeccable 里写满了「如果你是 Codex,必须停下来提问,你没聪明到能推断上下文」);后台任务(Claude Code 任务完成会唤醒模型,Codex 不会,所以 live mode 在 Codex 里只能用阻塞聊天线程的前台任务)。模型层面也各有癖好:Gemini 疯狂给图片加悬停动画,Codex 爱糟糕的字距、超圆边框和发丝细边框,而且告诉 Claude 别字距太宽,它会朝反方向调——所以规则不能放进同一个作用域。解法:Impeccable 为每个 harness × 每个模型生成专门的构建版本,含替换变量(按 harness 选对提问工具)和针对各模型的「防过拟合」XML 块。对 GPT 系还有一个绝招:它超爱「gate(关卡)」,所以 Codex 专属的 MD 里就给它八个关卡、要求逐个记录通过结果、不许压缩——因为如果一个关卡可以被跳过,它就会被跳过。顺带一提,常见安装工具不认多目录,所以 Paul 自建了 CLI 安装器。

怎么验证:evals 与品味的极限

Impeccable 的每一行都做消融测试(每条规则带唯一标识,移除该行跑全部模型的 eval,再用确定性检测引擎验证确实产生了变化)。他还有一个未开源的 evals 框架,复刻各 harness 的条件与工具,甚至用一个 LLM 扮演用户与另一个 LLM 交互,跨 20 个细分领域(如意大利餐厅)在 GPT-5.5、Opus、Sonnet 等模型上跑。但问到「品味」他给了个犀利的回答:品味在模型层面解决不了,它从根本上属于人类——品味稀缺才成立,人人都用就不再有品味;而且模型评估品味特别糟,往往是「极繁主义者」:Gemini 对第一屏内容塞得越多评分越高,所以他有时干脆构建反转模型响应的评审员——模型评得越高,大概率越不是好设计。他的评审工具「勉强好于随机」,够当第一轮筛选,最终还得靠人眼。

本集带走

  • 先换心智模型:skill 不是打包的 prompt,而是对用户 harness 的扩展——先问「这个 harness 有哪些能力可以利用」,再动手写。
  • 评审类技能用盲评双智能体:让两个互不可见的子智能体(人感评估 + 确定性检测)各自出具意见,主线程综合,避免模型给自己打高分。
  • 别用禁令,用发散机制:扔掉前三推荐、大量生成后让无上下文的子智能体排序、用脚本喂随机种子(color.js 式),都比「别用 Inter」有效。
  • 关键指令走脚本标准输出,遵循度远高于散文规则;但注意会破坏提示词缓存,只用于交互式场景。
  • 能被跳过的检查一定会被跳过:给弱模型上 pre-tool use hooks 阻止写文件、给 GPT 系上必须逐个记录结果的「关卡」,把流程做成不可跳过。
  • 跨 harness 分发要分别编译:子智能体权限、提问工具、后台任务行为、每个模型的过拟合癖好都不同——按 harness × 模型出专门构建,并永远为指令遵循最弱的模型设计。
  • 发布前过 evals:哪怕不用消融测试,也该在目标模型上验证; 分发的技能在作者没用过的模型上跑不好,是这个生态最大的烂账。
全部金句 11 条

提示词是咒语,harness 工程才是魔法。
Prompting is a spell, harnessing is a magic.
—— Paul Bakaus · [07:10]

中位数就是模型的引力。即使是 250 行精心手工打造、优美的技能散文也改变不了这一点。
The median is the model’s gravity. Even 250 lines of like artisanal, crafted, beautiful skill pros cannot change this.
—— Paul Bakaus · [06:12]

于是一夜之间,我把整个网络变成了橙色。我以为人们会去修改主题,但不,他们没有。
So overnight I call it the web orange. I thought people would modify the theme, but no they didn’t.
—— Paul Bakaus · [06:04]

所以,两个盲评胜过一个自信的猜测。
So, two blind opinions beat one confident guess.
—— Paul Bakaus · [12:24]

当你把某个东西从脚本的退出值、从标准输出里输出出来时,不知为何模型对它的遵循度会高得多。
When you put something out from the exit value, from the standard out of a script, somehow the model will follow it a lot more than before.
—— Paul Bakaus · [28:45]

(被动护栏)胜过一条没人记得去运行的命令。
Beat a command no one remembers to run.
—— Paul Bakaus · [32:34]

而这里最重要的教训是:如果一个关卡可以被跳过,它就会被跳过。
And the most important lesson from this is if the gate can be skipped, it will be.
—— Paul Bakaus · [48:29]

较弱的模型有自己的想法没问题,但它失去的是遵循你的想法的纪律。
Our weaker model has opinions just fine, but what it loses is the discipline to follow yours.
—— Paul Bakaus · [47:24]

你没法真正对着一个聊天框调像素。
Now you can’t really tune pixels to a chat box.
—— Paul Bakaus · [34:41]

我不认为品味可以在模型层面被解决。我实际上认为它从根本上是一件属于人类的事情。
I don’t think taste can be solved at a model level. I actually think it’s a fundamentally human thing.
—— Paul Bakaus · [56:41]

因为品味是稀缺且独特的,一旦所有人都使用同样的品味,它就变得无处不在,然后我们就不再觉得它有品味了。
Because taste is scarce and unique and once everybody uses the same taste it becomes ubiquitous and then we don’t think it’s tasteful anymore.
—— Paul Bakaus · [56:48]

接着看

顺着「AI 编程」挖下去

换个口味