
“提示词写得再好换个人换个场景就废了。”这是我做AI工程化落地这段时间最大的感受。早期我们团队调Prompt基本靠“人肉炼丹”在对话窗口里反复试、反复改好不容易调出一个满意的版本结果换个项目、换个会话上下文效果立刻打回原形。后来接触到Codex、Claude Code这类工具链里的Skill机制才意识到Prompt只是“对话灵感”Skill才是把专家经验真正变成可复用资产的关键载体。所谓Skill本质上就是把一条或一组Prompt连同使用条件、执行步骤、参考样例、甚至脚本工具一起打包形成一套标准化的“技能包”。你可以把它理解成给大模型装了一个“专业插件”它不只是告诉模型“你要做什么”还规定了“在什么情况下做、按什么顺序做、做到什么标准算合格”。这篇文章我想用一个完整案例拆解从Prompt到Skill的封装全过程覆盖设计思路、目录结构、描述文件编写、脚本注入、调试迭代等环节希望能帮正在做Agent应用、Prompt工程或者想把自己领域经验沉淀下来的朋友少走一些弯路。1. 内容整体设计与思路拆解1.1 为什么Prompt不够用还需要Skill这层抽象先聊聊Prompt和Skill的本质差异。Prompt是一次性的文本输入你给它什么它就用什么用完就扔。哪怕你把一段Prompt写得天花乱坠它依然只是“无结构、无状态、无生命周期”的一段字符串。这在简单问答场景下够用了但一旦进入复杂的专家级任务问题很快就暴露出来。第一个问题是上下文长度限制。我自己实测过把一份完整的SQL调优专家经验写成Prompt带上背景知识、判断规则、正反例轻松就超过几千个token。如果每轮对话都往系统提示里塞这么一大坨一是浪费上下文窗口二是模型注意力会被无关细节稀释回答质量反而下降。热词里那个“the number of tokens to keep from the initial prompt is greater than the con...”的错误我见过不止一次就是典型的Prompt过载引发的崩坏。第二个问题是不可组合。真实业务里很少只靠一个Prompt解决所有问题。比如做日志分析你可能需要先做格式识别、再提取异常特征、然后定位根因、最后生成报告这是一条完整的流水线。如果用裸Prompt每一步都要手动去调整上下文和指令中间状态根本没法传递。而Skill可以像乐高积木一样组合一个Skill调用另一个Skill前一个的输出自动成为后一个的输入这才是Agent化工作流的正确姿势。第三个问题是经验没办法沉淀和复用。Prompt写得再好它也只是存在于某个对话历史里的文本换个项目就丢了。Skill则可以被视为一个可版本管理的载体——用Git管理版本放在团队里共享新人拿来即用甚至能做成公开的“技能市场”。这才是知识管理层面真正要紧的事。1.2 标准化封装要解决哪几个核心问题我把“专家经验的标准化封装”拆成三个维度可描述、可执行、可校验。可描述是指一个Skill必须能说清楚自己的用途、适用场景和边界条件。否则模型不知道该在什么时候调用它用户也不知道该在什么场景下安装它。这靠的是Skill的描述文件通常叫SKILL.md里的元信息包括名称、描述、适用平台、允许使用的工具等。可执行是指Skill不能只是一段文本说明必须能真正跑起来。这里包含两层一层是模型层面的执行即告诉模型“拿到这个Skill后要按什么流程做事”另一层是工具层面的执行即通过脚本、命令行工具把模型不好干的活干完。比如日志分析里的正则匹配、数据清洗如果靠模型逐条理解效率低还不稳定不如直接封装一个Python脚本模型负责判断和分析脚本负责跑批处理。可校验是指Skill的输出要能被检查和评估。你不能说“这个Skill好用”就完了要建立一个反馈机制跑完一轮之后结果是否符合预期哪里不对怎么改这一步通常靠测试用例和迭代记录来支撑。我见过很多团队Skill写了一大堆但没有一条测试用例最后模型一更新技能包集体失效根本定位不了问题。1.3 Skill与Agent、插件工具的边界怎么划热词里有人搜“skill和agent的区别”这确实是新手最容易混的地方。我的理解很简单Agent是执行体Skill是知识包插件是工具集。一个Agent可以加载多个Skill每个Skill决定“这个场景下该怎么做”Skill内部可以调用插件提供的工具把具体动作落地。类比一下Agent是外科医生Skill是手术规范手册插件是手术刀。在实际工程里我在Codex和Claude Code这类工具中体验最直接的差异是Skill更像是“加到系统提示词里的动态模块”——只有匹配场景才被加载加载后把完整的执行规范交给模型而Agent更像是一个协调器负责决策当前该调哪个Skill然后编排调用顺序。所以你在设计一个Skill时不要想着什么都往里塞而是要想清楚“这个Skill要在哪个Agent场景下、配合什么工具、达到什么效果”。2. Skill包的目录结构与描述文件编写2.1 一个标准Skill包的目录长什么样先给一个我在实际工程中使用的基础目录结构大家可以先照抄后续按需扩充my-skill/ ├── SKILL.md ├── scripts/ │ └── run_analysis.py ├── references/ │ ├── examples.md │ └── templates/ │ └── report_template.md └── assets/ └── sample_data/SKILL.md是门面负责告诉模型和用户“这个技能是干嘛的”scripts目录放可执行脚本用于处理模型不擅长或者不应让模型处理的机械化任务references目录放参考文档、样例数据、报告模板是“专家经验”的主要载体assets目录一般放附加资源比如示例日志、配置模板。这里有个容易被忽略的细节references目录里的内容默认不会全部塞进上下文。只有模型判断需要时才会用检索或者按路径精确加载的方式去读取。这就能很好地解决我前面说的“Prompt过长”问题。你可以把详细的规则、正反例、模板放在references里SKILL.md只留精简版的执行索引。2.2 SKILL.md的描述元信息怎么写才不会被模型忽略描述信息是整个Skill能不能被正确触发的关键。我踩过一个大坑描述写得又长又泛结果模型在完全不相关的任务里也把这个Skill拉了出来上下文白白被浪费。后来我总结出一套结构写法--- name: nginx-log-analyzer description: 用于分析NGINX访问日志提取异常状态码分布、定位5xx错误来源IP与URL。当用户提到“日志分析”、“排查5xx错误”、“NGINX访问日志”等场景时使用。 allowed-tools: - python3 - grep ---name要短机器可读description是灵魂写清楚“何时触发”。我发现最好用的格式是前半句说“能做什么”后半句直接给触发关键词和场景。这样模型在做意图识别时匹配精准度会高很多。有些实现还支持allowed-tools字段声明这个Skill允许调用哪些外部工具。这个字段不只是权限管理还能帮模型排除无用工具减少误操作。2.3 正文指令设计少写原则多写步骤SKILL.md正文是给模型看的具体执行规范。这块设计有两条原则。第一少写“知识”多写“流程”。知识放进references正文只保留“遇到什么情况做什么”的决策逻辑和操作步骤。比如# Nginx日志分析执行流程 1. 先用scripts/extract_summary.py扫描日志输出请求量、状态码分布、P95耗时。 2. 如果5xx占比超过5%继续执行scripts/locate_errors.py定位错误集中出现的IP段和URL模式。 3. 根据references/examples.md里的案例库分析错误可能的原因。 4. 输出报告报告格式参考references/templates/report_template.md。第二把“判断标准”写清楚。模型不是人它不知道什么叫“异常”。你得告诉它阈值“5xx占比超过5%”“P95超过500ms”“同一IP一分钟内请求超过100次”等。这个实际上就是把你脑子里的专家经验做量化转译。所谓从Prompt到Skill本质就是完成了一次“把模糊经验变成精确指令”的工程化提炼。3. 从零开始开发一个可直接复用的Skill实操3.1 案例选取一个日志分析Skill的开发全流程空谈理论意义不大我来演示一个完整的案例——做一个NGINX访问日志异常分析Skill。选日志分析是因为它典型有明确的输入输出、有可脚本化的机械步骤、也有需要模型智力的判断环节能比较全面地展示封装思路。先收集专家经验。有经验的SRE拿到一堆访问日志脑子里的处理顺序大致是先算整体请求量和耗时分布再看状态码是否异常然后定位异常来源最后看访问模式判断是攻击、代码Bug还是机房抖动。这四步我要它们变成可执行的Skill。第一步建目录结构第二步写SKILL.md描述第三步写分析脚本第四步准备参考案例库和报告模板第五步安装并测试。我用Codex环境的skill命令安装测试但同样的逻辑在任何支持Skill机制的Agent工具里都成立。3.2 scripts脚本哪些事交给代码哪些事留给模型写Skill最容易犯的错是“什么事都让模型干”。模型擅长推理和润色不擅长精确的计算和重复的文本处理。所以在Skill设计里我会把“格式解析、统计聚合、特征提取”全部脚本化模型只做“基于统计结果的分析判断”。下面是我这个日志分析Skill里第一个脚本的简化版功能是扫描日志输入文件输出核心指标#!/usr/bin/env python3 nginx_log_summary.py - 对nginx访问日志做汇总统计 import re import sys from collections import Counter from urllib.parse import urlparse # 140.206.111.50 - - [26/Sep/2024:08:00:12 0800] GET /api/user/info HTTP/1.1 200 532 LOG_PATTERN re.compile( r(?Pip[\d\.]).*?\[(?Ptime[^\]])\] r(?Pmethod\w) (?Purl\S) [^]* r(?Pstatus\d{3}) (?Psize\d) ) def parse_line(line): m LOG_PATTERN.search(line) if not m: return None d m.groupdict() d[path] urlparse(d[url]).path return d def main(): log_file sys.argv[1] status_counter Counter() path_counter Counter() total, fail_5xx 0, 0 with open(log_file, r, encodingutf-8, errorsignore) as f: for line in f: parsed parse_line(line) if not parsed: continue total 1 status_counter[parsed[status]] 1 if parsed[status].startswith(5): fail_5xx 1 path_counter[parsed[path]] 1 print(f总请求数: {total}) print(f5xx错误数: {fail_5xx}, 占比: {fail_5xx/total*100:.2f}%) for status, count in status_counter.most_common(): print(f状态码 {status}: {count} 次) if path_counter: print(5xx高频路径Top5:) for path, count in path_counter.most_common(5): print(f {path}: {count} 次) if __name__ __main__: main()实际封装时脚本还可以再加提取IP频率、计算P95耗时等功能。核心原则是能用一行正则解决的事绝不让模型去猜。顺带说一句脚本要追求“幂等”和“无交互”因为Agent拉起脚本时通常是非交互环境跑不起来就直接崩了。3.3 把“专家判断”写进references案例库脚本处理完批量统计接下来就要靠模型来做归因分析。比如5xx占比高原因可能是后端代码抛异常、数据库连接池耗尽、被恶意刷接口、或者CDN回源超时。模型怎么判断是哪种靠的是案例库。references/examples.md里我会放几个典型的案例模式## 案例请求量正常但5xx集中在某个接口 - 现象总体量平稳/api/order/status 出现大量502 - 可能原因后端服务部分实例异常 - 线索如果同时间该路径错误率冲到80%以上大概率是实例重启或代码发布导致 - 建议动作检查最近发布记录回滚或查看异常堆栈你别小看这个步骤。这正是“专家经验标准化”的要害把你的直觉、经验和判断依据变成可供模型检索的结构化知识。模型没有亲历过故障但你把处理过故障的人的思维过程结构化地喂给她她就能复现这个判断链条。3.4 安装与首次运行一个被低估的测试环节Skill开发完必须测试。测试不是“跑通就行”要看三件事能不能被正确触发、执行步骤是不是符合预期、输出的建议是不是真的有参考价值。我第一次写好这个日志Skill装到Agent环境里用一份生产环境脱敏日志测试结果模型根本没触发这个Skill直接在对话里泛泛而谈“建议检查日志”。排查半天发现是description里没有写“查看访问日志”这个触发词。模型理解的是“访问日志”而非“日志”我的描述里只写了“日志分析”造成语义匹配偏差。把description改成“分析访问日志、查看请求日志”后触发成功率立刻上来了。这类问题非常普遍。很多Skill不是逻辑不行而是“接口设计”不行——描述信息没有对准用户真实说法。建议一边装一边测把不同说法记录下来持续回填到description里。4. 从Prompt到Skill的关键抽象方法4.1 一级抽象把优秀Prompt里的“套路”提炼成步骤链现在聊聊怎么从已有Prompt里提炼Skill。我拿一个常见Prompt做例子。很多人写SQL优化Prompt的时候会写“你是资深DBA请帮我看这条SQL为什么慢给出优化建议”。这个Prompt在单次对话里可能有效但换成Skill就得重新组织语言。一级抽象的做法是把这段Prompt按“角色-任务-流程-输出格式”拆解再重组为步骤链。我的习惯是先写出一版“可完整覆盖专家工作流”的执行流程1. 获取SQL执行计划或SQL文本 2. 提取表结构、索引信息 3. 对执行计划做扫描类型判断全表扫描、索引扫描等 4. 定位瓶颈算子 5. 基于规则库给出索引、改写、参数调整建议 6. 输出优化报告模板你看Prompt只负责“替模型立人设、布置任务”而Skill则是把“一个专家从接到需求到交付结论”的完整链路拆成一步步。这一步最花功夫因为它要求你对自己的领域工作流有清晰认知。4.2 二级抽象把判断条件做成“规则树”专家经验里最金贵的东西是什么是“条件判断”——什么时候这么做什么时候那么做。比如DBA判断一条SQL是否需要加索引经验老手不会只看有没有全表扫描还要看数据量级、查询频率、写放大成本。这些判断要沉淀成规则树用结构化方式描述。规则树的落法可以是SKILL.md里的条件段落也可以是references里的决策表。模型拿到决策表后推理的精度会明显提升。比如## 索引建议决策参考 | 场景特征 | 优先级权重 | 建议动作 | |---------|-----------|----------| | WHERE条件含高频筛选列 数据量10万 | 高 | 优先建议单列索引 | | 排序字段无索引且P95排序耗时200ms | 中 | 建议覆盖索引 | | UPDATE频繁但SELECT占比10% | 低 | 不建议加索引避免写放大 |这个表就是从“老DBA的脑子里”搬出来的。传统做法是你找专家聊两小时记下各种“如果怎样就怎样”的直觉判断再整理成判定规则。有了规则表Skill就不再是空泛的“你是一个DBA”而是实际可推理的专家系统。4.3 三级抽象沉淀“反例”和“边界”这是我把Prompt升级成Skill后最受益的一层。人脑学习多看错题模型也一样。Skill如果只有正例模型容易把专家经验套到所有场景做出过度自信的错误判断。所以我在每一个Skill的references里都会留一个“反例与边界”章节。拿日志分析Skill举例我会明确写“如果日志时间跨度小于10分钟或者采样请求数低于100条统计结果不可靠不要给药方建议应提示数据量不足。”这种边界条件的价值在真实故障排查中能避免模型给出“根据高概率判断是DDoS”这类没有数据支撑的瞎猜。写反例的核心心法是回想你在领域里犯过的错或者带新人时反复纠正的问题那基本就是最好的反例。把这些攒进去Skill才真正开始像一个老师傅。5. 常见问题与排查技巧实录5.1 问题速查表与对应解法Skill开发中会遇到很多看似诡异的问题我把最常见的整理成一个速查表方便大家排查症状可能原因排查与解决Skill从未被触发description触发词与用户说法不匹配收集用户真实提问句式回填触发词检查description是否描述具体场景而非抽象能力触发频繁但回答质量差SKILL.md正文太泛缺少流程约束把执行步骤改为数字编号强制模型按序执行补充“输出格式”段脚本执行报错路径写死或依赖未声明脚本内用相对路径在SKILL.md头部声明依赖工具和运行方式上下文被撑爆references内容全部被加载检查是否有SKILL.md里写了“读取整个references目录”的指令改为按需读取模型给出了无关内容允许工具范围过大在allowed-tools里收窄可用工具减少误入歧途的机会升级模型后Skill行为变化模型对指令的遵循能力变了建立回归测试集模型版本升级后跑一遍基线测试及时修订表述5.2 从“模型乱来”到“稳定复现”我的调优心法Skill调优和Prompt调优有本质区别。Prompt调优是改句子Skill调优更像“改代码”。你必须把Skill当一个长期维护的代码库来对待。我的调优闭环分四步样本输入、结果评估、差异分析、规则修订。每次跑完一轮都先把模型输出和领域专家预期结果放在一起对比标注差异点。如果差异集中在“认识问题不准”就修references如果差异集中在“步骤混乱”就修SKILL.md正文的流程如果差异集中在“触发时机不对”就修description。核心思路是每个问题都要有对应的“修改面”不能一股脑地加提示词。另一个很重要的心得是“版本锚定”。Skill依赖两个容易变的东西模型能力和依赖脚本。我建议在SKILL.md开头记录开发时用的模型版本、脚本依赖版本、测试数据摘要。这样模型升级、依赖更新后行为变化你能快速定位是哪个环节漂移了。没有这个习惯的话Skill就是黑盒出了问题只能瞎猜。5.3 调试时的日志与跟踪技巧很多Skill框架并不提供显式调试面板Skill内部的执行日志往往被埋没在Agent的长对话中。我的办法是在SKILL.md正文里显式要求模型输出“简短执行记录”。比如## 执行记录要求 执行结束后输出以下信息 - 已加载的脚本名和输出结果摘要 - 使用的参考案例编号 - 给出的建议项数这样等于强着行家把脚本和引用的案例都摆在明面上。模型不敢瞎编排查时也能立刻看出“它到底看了什么材料才得出这个结论”。这个操作在Agent应用里尤其重要它让Skill的“可解释性”从口号变成现实。如果你正在做To B场景这个技能值得优先落地。6. Skill与Prompt工程、Agent开发之间的协同关系聊到这里很多人的困惑可能不是“Skill怎么做”而是“Skill在更大的技术栈里到底站什么位置”。结合近期社区里关于Codex Skill、Agent Skill的热度我再捋一下这层生态关系。Prompt工程是地基没有高质量的Prompt设计经验你根本提炼不出好Skill。Skill是Prompt的工程化升级它把一次性的文本指令固化成了可复用、可测试、可版本化的资产。Agent是调度层负责决定当前任务该激活哪个Skill并在多轮对话里协调状态。工具链是手脚脚本、API调用、数据库查询负责执行具体动作。这四层是递进关系。所以如果你问“我该先学Prompt还是先学Skill”我的答案是一定要先练Prompt基本功但别把时间全耗在雕琢单条Prompt上。尽早意识到“这条Prompt值得被沉淀成Skill”开始做结构化的拆解和封装你的效率会成倍提升。另外有人在搜索“skill和agent的区别”我再说直白一点你把Agent想象成一个拥有多本“操作手册”的工人。Skill就是操作手册Agent是那个负责翻手册并执行动作的工人。工人只有一个手册会有很多本不同场景翻不同的手册。设计Skill时不要考虑Agent内部状态怎么管理那是另一个层面的活你只需要保证手册能被准确检索、能被清晰执行。7. 高级玩法让Skill自己学会“学习”既然都已经把经验封装成技能包了能不能更进一步让Skill自身具备“学习”能力这里说的学习不是让模型微调而是在Skill内部建立一个“经验反馈循环”。比如在做客服问答场景的Skill时我会在SKILL.md里加入一段“未知问题记录”当模型无法根据当前参考文档回答用户问题时必须把问题单独追加到references/unanswered.md文件里。每周我只需要去跑一遍这个文件提取高频的新问题更新到正式知识库里Skill就肉眼可见地“变聪明了”。类似地在日志分析Skill里也可以设计“误判记录”当用户反馈建议不适用时把案例特征追加到反例库。我经常会用这种方式来沉淀团队里每次故障复盘里那些“当时要是在场就好了”的经验。经过几个月积累这套Skill能达到普通员工看手册都比不上的诊断水准。这套玩法的关键在于你得把Skill当产品来运营而不是当文档来写。初始版本可能只覆盖80%常见场景留给模型“不知道就说不知道”的处理空间加上反馈闭环Skill才能持续成长。反过来如果你试图第一天就做成100%覆盖的专家系统大概率会陷入内容太多、质量稀释的泥潭。最后讲一点自己的真实体会做了这一段Skill工程化实践后我对“专家经验数字化”这件事的看法有了很大改变。过去总觉得专家系统的门槛很高需要知识图谱、规则引擎那一套重型基础设施。现在的模型能力配合Skill这种轻量级封装普通人也能把脑子里那套方法沉淀下来而且落地速度快、迭代成本低。把手里的优秀Prompt改写成第一个Skill吧哪怕它只是解决一个单一小任务跑通之后再扩展你会发现这条路远比想象中好走。