为什么大多数 AI Skill 活不过一个月?
前阵子有个团队找小王做技术咨询,让小王看看他们写了三个月的 Agent Skill。
小王说:「你们挑几个跑得最久的给小王看看。」
他们翻了半天,只有一个skill, 用的时间最长,也只用了两周而已。
其余的,基本写出来用几天就废了,然后就换一个新的。
不是什么巧合——看过十几个团队,九成 Skill 活不过一个月。
因为,压根没人按生产级标准写 Skill。
今天把这两年写 Skill 踩过的坑,总结成六条铁律,每条附一个亲眼见过的反面教材。
1 锁死边界,别让 AI 自己猜「该干什么」
反面教材 #1
有个团队写了一个「批量扫描代码漏洞」的 Skill。工程师图省事,没限定扫描范围,觉得 AI 会自动识别「哪些是项目代码,哪些是第三方库」。
结果呢?AI 把 node_modules 里几万个文件全扫了一遍。跑了四个小时还没跑完,把 CI 机器 CPU 打满了。最后运维手动 kill 了进程。
边界交给 AI 判断,结果就是四个小时扫 node_modules。
边界要在代码里写死,别指望 AI 理解你的「潜台词」。
# ❌ 让 AI 自己决定范围files_to_check = ai_find_all_files(『.』)# ✅ 代码锁定范围SOURCE_DIRS = ['src/', 'lib/', 'tests/']EXCLUDE_DIRS = ['node_modules/', 'vendor/', '.git/']files_to_check = []for d in SOURCE_DIRS:if not Path(d).exists():continue # 目录不存在就跳过,不崩files_to_check.extend(Path(d).rglob(『*.py』))
AI 价值在「理解意图」,不在「替你做安全决策」。让 AI 做选择题,给选项;别让它做填空题,它填什么你都不知道。
2 流程拆成原子步,一步崩了不影响全局
反面教材 #2
另一团队写了个发布 Skill,一个函数干完所有事:拉代码→编译→打包→上传→发通知。听起来很简洁。
编译到一半报错了。但日志输出的是「拉代码成功」和「编译失败」混在一起。没人知道是代码没拉到,还是编译环境有问题。排查花了大半天。
工业级的 Skill,一步只做一件事。
步骤 1:前置校验(目录存在?依赖装了?权限够?)↓ 失败 → 报具体错误,整体跳过步骤 2:拉取代码(带超时,带重试)↓ 失败 → 只重试这一步步骤 3:编译构建(捕获 `stdout`/`stderr`)↓ 失败 → 输出构建日志,不走下一步步骤 4:制品打包↓ 失败 → 标记失败,不影响其他步骤步骤 5:结果汇总
每步独立:
- 哪错了一目了然
不用猜 - 单步可重试
不用从头再来 - 单点故障不雪崩
一个步骤炸了,不影响其他任务
3 所有步骤必须能「优雅失败」
反面教材 #3
小王见过最离谱的 Skill:脚本没找到,执行了 rm -rf {$path}。结果 $path 变量是空的。
代码只写了「成功的路径」,没写「失败的路径」。
新手写 Skill 的通病:脑子里只有「一切顺利」。生产环境可不惯着你。
# ❌ 只写成功逻辑def process_script(name):result = subprocess.run([f'scripts/{name}.sh'], capture_output=True)return result.`stdout`# ✅ 写好失败兜底def process_script(name):script_`path` = f'scripts/{name}.sh'if not Path(script_`path`).exists():log.warning(f'脚本不存在: {script_`path`}')return {'status': 'skip', 'reason': '目标不存在'}try:result = subprocess.run([script_`path`], capture_output=True, timeout=30)if result.returncode != 0:return {'status': 'fail', 'output': result.`stderr`}return {'status': 'ok', 'output': result.`stdout`}except subprocess.TimeoutExpired:return {'status': 'fail', 'reason': '执行超时'}
写每一步都要想:「万一这步出错了呢?」所有分支都走通了,才叫生产级。
4 输出必须结构化,别让下游猜你的意思
反面教材 #4
有个团队写了个「代码覆盖率分析」Skill。输出长这样:
检查了 15个文件,大部分覆盖率还行,有几个函数比较低,建议优化一下。小王追问:「哪几个函数?覆盖率多少?什么叫『比较低』?」
答不上来。AI 随手写的回复,每次输出都不一样。
下游系统要的是固定字段、固定格式的数据,不是一段散文。
{"target": "user_login.py","coverage": 72.5,"status": "warning","low_coverage_funcs": ["login_handler", "validate_token"],"error_msg`: ""}
结构化输出之后,下游可以: - 自动接入 BI 报表 - 自动触发告警(覆盖率低于 60% 就通知) - 自动生成趋势图(这周 vs 上周)
输出是写给系统和下一个人看的。
5 配置参数全抽离,绝不硬编码
反面教材 #5
小王见过这样的代码:
def run():report_`path` = '/home/admin/reports/2026/06/07/report.txt'log_dir = '/var/log/myapp/'max_retry = 3
下个月改个目录,或者换台机器部署,就得改代码。这种 Skill 的生命周期,基本等于「写它的人还在这个组」。
# 全局配置区,一目了然REPORT_DIR = os.getenv('REPORT_DIR', './reports')LOG_DIR = os.getenv('LOG_DIR', './logs')MAX_RETRY = int(os.getenv('MAX_RETRY', '3'))def run():report_`path` = f'{REPORT_DIR}/{datetime.now():%Y/%m/%d}/report.txt'...
把路径、文件名、阈值、重试次数全抽成变量。 换环境只需要改配置,不拆代码。
6 版本化,能回滚才是好 Skill
反面教材 #6
有一次线上出问题了,团队想回退到上周的 Skill 版本。结果发现——根本没版本。上次改了什么,没人记得。只能重新写。
这不是技术问题,是管理问题。
成熟的做法:
v1.0 — 初始版本:基础扫描功能v1.1 — 增加并发控制v1.2 — 修复路径编码 Bugv2.0 — 重构为异步架构,支持大文件
每次迭代记录变更点,每次发布标记版本号。出了事,一条命令回滚到上一版。
不版本化的 Skill,就是一次性脚本。你不敢改它——改坏了修不回来。
7 写在最后
有个团队跟我说,他们对 Skill 的定位就是「让 AI 帮自己干点杂活」。
对。但杂活也得 7×24 稳定跑。
如果这个 Skill 明天就要用,今天你敢不改代码直接部署?
敢的,才叫生产级。不敢的,就一条条对着改。
这六条铁律,每一条都是我和身边团队拿加班时间换回来的。
写完一个 Skill,说「搞定了」之前,先看看这六条你做到了几条。