同一个 Prompt 我复述了 47 遍:Agent Skills 正在把提示词变成可交付资产

4 阅读1分钟

一、那条约束,我复述了 47 遍

去年做一个后台重构,我给 AI 定了一条规矩:生成任何列表查询,必须带逻辑删除过滤,必须走分页,禁止 SELECT *。

第一次说的时候,效果很好。第二次开新会话,它又给我写了 SELECT *。我复制粘贴了一遍。第三次换了个项目,我重新组织语言说了一遍,顺手补了两句解释。

后来我数了一下:这条约束,加上零碎的「字段命名用小写下划线」「时间字段统一 UTC」「异常不要吞」,在 5 个项目、3 个工具、几十次会话里,我大概复述了 47 遍。

真正的代价不是这 47 遍的口水。是第三十几遍的时候,我漏了半句——只说了分页,没说逻辑删除。生成的查询把已经删除的数据也带了出来,测试没覆盖到,上线第二天客户截图过来,回滚加排查,两天没了。

那天我才想明白:我一直在做「提示词工程」,但产出物连一个文件都不是。

它活在聊天记录里,活在备忘录里,活在我脑子里。换台电脑就没了,换个同事就得重讲,改过哪一版永远说不清。

二、根因:Prompt 的生命周期,被绑死在会话上

这不是模型的问题,是载体的问题。一段 prompt 存在的形式是「一次请求里的上下文」,它天生带着三个结构性缺陷:

  1. 没有地址。 它没有路径,不能被引用、不能被 import、不能被另一个人 clone。你只能「再贴一次」。
  2. 没有版本。 上周调好的那段话,这周手滑改了两句,你没有任何 diff 可看,也没有任何东西可以回滚。
  3. 没有边界。 一段话里既要角色设定、又要输出格式、又要业务约束、又要验收标准,越写越长,越长越容易在中间丢约束——而模型恰好最容易忽略长上下文中段的内容。

Agent Skills 改变的就是这一点:它把「一段话」变成了「磁盘上的一个目录」。

一个 skill 本质上就是一个文件夹,里面有一份 SKILL.md,头部是一小段 frontmatter:

---
name: db-migration-review
description: 审查 DDL 变更是否会导致线上锁表或数据丢失。当用户提交建表/改表 SQL、或提到 migration、DDL、加索引时使用。
---

Agent 启动时并不读全文,只把所有技能的 name 和 description 装进上下文(通常几十个技能也就几百个 token),判断当前任务命中哪个技能,才去加载那个技能的正文。这就是所谓「渐进式披露」:能力和上下文解耦,装一百个技能也不会把窗口撑爆。

机制一换,性质就变了。它不再是一次性的输入,而是可寻址、可 diff、可分发的文件。这也是为什么最近 GitHub 周榜上,Anthropic 官方的 skills 仓库、做 anti-AI-slop 的 hallmark、做设计语言的 impeccable,还有 Karpathy 那份被反复转发的 CLAUDE.md,会扎堆出现——大家发现,值得沉淀的不是「神级提示词」,而是约束本身。

顺带说一句:这些仓库我一个都没照搬。看它们的价值不在抄文案,而在看它们怎么组织约束——一个技能管一件事,长清单拆到子文件,描述里写清触发条件。这是工程结构,不是咒语。

三、三层价值:可复用、可版本化、可交易

把 prompt 变成文件之后,收获是分层的,而且一层比一层值钱。

第一层,可复用。 一次编写,所有会话、所有项目、所有支持这套格式的工具都能用。你不再依赖记忆,也不再依赖「我当时是怎么说的」。新人入职,git clone 下来就有,不用等你心情好时口述。

第二层,可版本化。 这条被低估得最厉害。技能进了仓库,改动就有 diff:这次是把「必须分页」改成了「超过 1000 行必须分页」,还是顺手删掉了逻辑删除过滤,一眼能看出来。能 review、能回滚、能追责——这才是「工程」和「玄学」的分界线。没有 diff 的 prompt,永远只能是个人手感。

第三层,可交易。 这里的「交易」不是卖钱,是能力可以整包交付。一个团队把代码规范、审稿口径、发布检查做成技能包,交给另一个团队,对方装上去就能用——交付物从「文档 + 口述」变成了「可执行的约束」。开源社区已经在这么干了:hallmark 交付的是「怎么避免 AI 味设计」的判断标准,impeccable 交付的是一套设计语言,它们本质都是把某人的审美和判断,压缩成别人能直接调用的资产。

四、为什么你感觉不到它在失效

这类问题最麻烦的地方,是它不会报错。三种失效,全都伪装成别的东西:

失效一:跨会话消失

当场效果很好,关掉窗口就没了。你的感受是「模型今天状态不错」,而不是「我刚才那段话没被保存」。下次效果差,你会归因于「模型变笨了」。

失效二:跨人失效

同事问你要 prompt,你贴了一段过去。他跑出来完全不是那个效果——因为你贴的是结论,没贴前置条件、没贴项目背景、没贴验收标准。一段脱离上下文的 prompt,复制出去就是废的。

失效三:跨工具失效

在 A 工具里调好的技能,换到 B 工具就不触发。多数情况不是模型不行,是格式绑死了:目录名不对、frontmatter 缺字段、描述里没有触发词。

还有一种,是「装太多」

这是最近半年最常见的新问题:一口气装了四十个技能,命中率反而下降。因为描述互相重叠——三个技能都说自己「处理数据库相关任务」,Agent 选哪个全看运气。技能包堆积,本身会变成新的技术债。

五、先定位:你机器上到底有什么

别急着写新技能,先把存量盘清楚。下面几条命令在 Git Bash / macOS / Linux 下都能跑。

# 1. 你机器上到底装了几个技能,分别在哪
for d in ~/.claude/skills ./.claude/skills ./.codebuddy/skills ~/.codebuddy/skills; do
  [ -d "$d" ] && printf "%-32s %s\n" "$d" "$(find "$d" -name SKILL.md | wc -l)"
done
# 2. 列出所有技能的 name / description(查重复与含糊)
find ~/.claude/skills ./.claude/skills -name SKILL.md 2>/dev/null \
  | xargs grep -h "^name:\|^description:"
# 3. 找出 frontmatter 缺失的技能(这类永远不会被正确加载)
find . -name SKILL.md 2>/dev/null | while read -r f; do
  head -5 "$f" | grep -q "^name:" || echo "缺 name: $f"
  head -5 "$f" | grep -q "^description:" || echo "缺 description: $f"
done
# 4. 按正文行数排序:超过 300 行的,基本是把 README 搬进来了
find . -name SKILL.md -exec wc -l {} + 2>/dev/null | sort -nr | head -10
# 5. 技能目录到底有没有被维护过(没有提交历史的,等于没有)
git log --oneline -- skills/ | head -20

判断标准很直接:第 2 条命令的输出里,如果两个技能的 description 读起来可以互换,那它们就是重复的;如果某个 description 里没有任何「什么时候用」的线索,那它大概率从来没被触发过。

六、再修复:把提示词当代码来管

正确的形态不复杂,一个技能一个目录,只放该放的东西:

skills/
└── db-migration-review/
    ├── SKILL.md              # 触发条件 + 步骤 + 验收,控制在一屏
    ├── references/
    │   └── ddl-rules.md      # 长清单,命中后才加载
    └── scripts/
        └── check-lock.sh     # 能跑就别用嘴说

SKILL.md 的正文只写四件事:什么时候用、按什么步骤做、边界在哪、怎么算做完。涉及具体规则的清单,全部拆到 references/ 里——它不会被无条件加载,只在需要时读,这样上下文才不会被无关内容稀释。

四条容易踩的坑:

坑 1:只写「做什么」,不写「何时用」。 技能躺在目录里,从不触发。修法是把触发场景直接写进 description,用用户真实会说的话,比如「提交建表/改表 SQL」「提到 DDL、加索引」,而不是「数据库相关知识」。

坑 2:一个技能什么都管。 从前端规范管到部署流程,结果每次命中都塞进一大段无关内容。修法是按「一类任务」切分,切到不能再切;宁可多一个技能,不要一个万能技能。

坑 3:把长文档整篇搬进正文。 看着很完整,实际每次命中都在烧上下文,模型反而丢掉中间的关键约束。约束的价值不在于写全,而在于被读到。

坑 4:只沉淀,不清理。 技能和代码一样会腐烂。每个月跑一次第五节的清单,合并重复的、删掉三个月没触发过的。

最后一条,也是最容易被忽略的:技能必须有验收用例。 一个技能写完,拿三个真实任务跑一遍——两个该触发的、一个不该触发的。不该触发的那个也触发了,说明描述写宽了;该触发的没触发,说明触发词没写对。这一步不做,你只是把「玄学」从聊天窗搬进了文件夹。

七、验收铁律

❌ 还在把提示词当聊天记录

  • 关键约束存在聊天记录、备忘录、微信收藏里,换台机器就没了
  • 同一条规则在 5 个项目各维护一版,改了一版忘了另外四版
  • 技能描述写「帮助处理数据库相关任务」,什么都像,什么都不准
  • 装了几十个技能从不清理,命中率越来越低,还以为是模型不行
  • 只沉淀不验收,技能写完了从没在真实任务上跑过

✅ 当成资产来管

  • 每条可复用的指令都有磁盘路径,git log 能查到每一次改动
  • 一个技能只做一件事,description 写清「什么时候触发」
  • 正文控制在一屏,长清单拆进 references/ 按需加载
  • 新机器 clone 下来,跑一遍验收用例就知道能不能用
  • 每月清理一次:合并重复的,删掉长期不触发的

写代码的人早就接受一个常识:逻辑要进仓库,不能只存在脑子里。 提示词也一样。它现在是团队里最贵、最不可见、最容易随人流失的那部分知识——而它本来可以是一个能 diff、能 review、能交接的文件。

如果你也在把团队里的「老法师经验」往技能包里搬,或者卡在「装了技能却不触发」这一步,可以私信我聊聊。