Skill真正省心是从脚本开始的

2026-10-19 15:25:48 10阅读

刚开始用 Skill 的时候,我其实不太愿意写脚本,更愿意用文字。原因很直接:Codex 本来就能理解中文。我要它怎么做、不要怎么做、输出什么格式、哪些目录不要碰、遇到异常怎么处理,写成一段清楚的说明不就行了。

文字好读,也好审。脚本就要考虑路径、参数、异常、系统差异,还要自己维护,看起来反而多了一层负担。所以很长一段时间里,我写 Skill 的习惯是尽量把规则写详细、把边界写清楚、把例子写充分,能用文字约束的就不写脚本。

最近项目做大之后,我的想法变了。不是文字 Skill 不好,而是它只适合一部分场景。需求简单、输出自由、偶尔用一次,文字约束很舒服;可一旦项目变大、功能变复杂、团队要反复使用,还希望输出格式稳定、结果可检查、流程可复现,光靠文字就开始吃力。

更关键的是,文字规则会持续消耗上下文。每次运行,Codex 都要重新读一遍、理解一遍、权衡一遍。项目越大、规则越多,上下文里塞进去的文字越多,真正留给代码、日志、错误信息和现场约束的空间就越少。

我越来越觉得,成熟的 Skill 不应该是"写得很详细的提示词"。它应该是:脚本做确定动作,文字讲工程判断。

文字 Skill 最大的问题不是不懂,而是不稳

文字 Skill 的优势很明显。比如做一个嵌入式代码注释 Skill,可以这样写:

# 嵌入式代码注释

只处理用户自研代码。

必须跳过:
- CMSIS
- HAL 驱动库
- FreeRTOS
- 第三方组件
- 自动生成文件

优先补充:
- 对外接口函数
- 函数参数和返回值
- 状态机迁移
- DMA 缓冲区
- 中断回调
- 全局变量和跨任务共享变量

不要写语法翻译式注释。
不要把不确定的硬件意图写成事实。

这种 Skill 对单次任务很有效,Codex 能理解,也能照着做。问题出现在批量化之后:同一套文字规则,今天处理 App/Motor 没问题,明天处理 BSP 可能就漏掉生成文件;这次函数注释格式统一,下次又混进几句"该变量用于保存数据"的低价值注释;这次输出清单完整,下次字段名换了,后面的自动汇总脚本就接不上。

这不是 Codex 不聪明,恰恰是它太会理解、太会根据上下文调整表达。创造性任务需要这种能力,团队标准输出却害怕这种波动。小任务里,波动可以接受;大项目里,波动会变成成本。

上下文不是无限的,规则写太长也是负担

以前我喜欢把 Skill 写得很细:排除目录写一遍、注释格式写一遍、错误处理写一遍、输出模板写一遍、示例再写几段。一开始觉得这是严谨,后来发现 Skill 本身也在吃上下文。

Codex 不是只读 Skill,它还要读用户需求、当前对话、项目文件、错误日志、测试输出、代码片段。Skill 写得越长,留给真正任务现场的空间就越少。

这跟嵌入式工程师对资源敏感的道理很像:上下文窗口就像 RAM,规则、代码、日志、历史讨论都要放进去。你把一大堆可以机械执行的规则都塞进 RAM,真正要处理的现场数据就被挤掉了。

脚本的好处就在这里。一个扫描规则,如果写成文字,每次都要让 Codex 读、理解、执行;如果写成脚本,Codex 只需要知道"运行这个脚本,读取结果"。脚本内部的排除规则、路径过滤、格式校验,不需要每次全部塞进上下文里重新解释。这不只是稳定性问题,也是上下文资源问题。

脚本不是替代 Codex,而是把确定动作拿出去

我现在会把 Skill 分成两层:文字层负责讲清楚目标和判断,脚本层负责做稳定、重复、可校验的动作。

  • 文字适合写:为什么要这样做、哪些场景适用、哪些操作禁止、遇到不确定情况怎么处理、输出给谁看。
  • 脚本适合做:扫描文件、排除目录、提取函数和变量、检查格式、生成固定 JSON、统计修改结果、校验输出字段。

这跟嵌入式项目很像:设计文档告诉你系统怎么工作,但真正稳定执行的是驱动、接口、测试脚本和 CI。你不会指望团队成员每次靠记忆手动检查所有中断里有没有阻塞日志,你会做封装、做规则、做静态检查。Skill 也是一样。

一个注释 Skill 的真实演进

第一版通常是纯文字:

# 嵌入式代码注释

请为项目中的用户自研 C 代码补充注释。
跳过开源库、芯片库、生成文件。
重点注释函数参数、返回值、状态机、DMA、中断和全局变量。
不要写低价值注释。
输出修改文件列表。

这版适合单次使用。

第二版开始就应该加入脚本,比如增加一个扫描脚本 scripts/scan_user_code.py,它做几件固定的事:遍历仓库,排除 CMSIS、HAL_Driver、FreeRTOS、third_party,跳过自动生成文件,找出 .c、.h、.cpp、.hpp,标记可能包含状态机、DMA、中断回调的文件,输出候选清单。Codex 不再每次自己判断扫描范围,而是读取脚本结果。

第三版再加检查脚本 scripts/check_comment_style.py,检查是否出现"变量赋值""进入循环"这类低价值注释、函数注释是否包含参数和返回值、是否改到了禁止目录、输出摘要字段是否完整。

这样流程就变得比纯文字稳定得多,因为最容易漏、最容易抖的动作,被脚本接管了。

团队使用时,输出必须能被机器检查

个人使用 Skill,结果能看懂就行;团队使用,结果必须能检查。如果输出只是"已按要求补充注释,整体符合规范",这句话没有多少价值。更适合团队的其实是结构化输出:

{
  "处理文件数": 18,
  "跳过文件数": 42,
  "新增函数注释": 31,
  "新增变量注释": 16,
  "检查结果": "通过",
  "问题清单": [
    {
      "文件": "App/Motor/motor_state.c",
      "问题": "状态机注释缺少故障态退出条件"
    }
  ]
}

这种结果可以进代码评审,也可以被后续脚本读取。如果输出字段每次都变,团队就没法自动化,这也是脚本重要的原因——脚本可以生成固定字段、可以校验字段、可以在失败时明确告诉你哪里不符合。

什么时候文字就够,什么时候必须脚本

我现在会按任务的脆弱程度来判断:

场景更适合的方式
写文章、总结经验、分析思路文字 Skill
一次性代码解释文字 Skill
小范围修改文字为主,配合命令
批量扫描文件脚本必须参与
固定格式输出脚本生成或校验
团队反复使用脚本加文字
涉及删除、覆盖、系统修改脚本兜底
要接入 CI 或评审流程结构化脚本输出

如果任务允许自由发挥,文字 Skill 很好;如果任务要求稳定复现,脚本就该上场。尤其当 Skill 里开始出现大量"必须、禁止、固定格式、批量、团队、校验、自动化"这些词时,就应该考虑脚本化。

成熟 Skill 应该长什么样

我现在更喜欢这种结构:

embedded-comment-skill/
├─ SKILL.md
├─ scripts/
│  ├─ scan_user_code.py
│  ├─ check_comment_style.py
│  └─ summarize_result.py
└─ references/
   └─ comment_rules.md

SKILL.md 不需要特别长,只写流程;详细规则放到 references/comment_rules.md,扫描和校验交给脚本,Codex 负责理解代码、补充注释、处理不确定情况。这样上下文更干净,流程也更稳。

我现在对 Skill 的理解,已经从"提示词增强"变成了"工程化工作流"。文字仍然重要,没有文字,Codex 不知道目标、边界和取舍;但只靠文字,很难支撑复杂项目里的稳定输出,也会持续占用上下文资源。项目越大、团队使用越多、输出越标准化,就越应该把确定动作写成脚本,把复杂规则拆成可执行、可检查、可复用的步骤。

这不是不相信 Codex,恰恰相反,是让 Codex 做它最擅长的事:理解、判断、修改和补齐。而那些重复、机械、容易漏、必须稳定的部分交给脚本。嵌入式工程里我们一直在做这件事:把经验固化成驱动,把检查固化成测试,把危险操作放进受控接口。Skill 走到最后,也应该这样。


作者:不脱发的程序猿
链接:https://www.aiddithome.com/p/82737737c3eb.html
本作遵循 [CC BY 4.0 署名] 许可,版权归作者所有。若存在违规行为,您可以点击 “举报”。


登录 后发表评论
3条评论

把排除规则写进脚本,就不用每次让AI重新理解了

修啥都行二哥
2楼 · 2天前

团队用还是要结构化输出,能检查才行

确实是,文字Skill输出不稳定,脚本接管确定动作会稳很多