2026/9/9 6:04:34

Skill不是Prompt!从设计到测试,大模型Agent技能工程化全解析

Skill不是Prompt!从设计到测试,大模型Agent技能工程化全解析 最近很多做 AI 应用和 Agent 开发的朋友跑来问我同一个问题Skill 到底是个什么东西怎么越看越像 Prompt为什么官方文档里把它吹得天花乱坠我用起来却总是不痛不痒有这个困惑的不在少数。过去大半年Codex、Claude Code、Trae 这些终端型 Agent 陆续把 Skill 推到了台前GitHub 上各种 skill 仓库如雨后春笋连“skill 推荐”“skill creator”这类热词都跟着起来了。但风口越热大家就越容易走偏。我见过有人把几十个 Skill 一股脑塞进 Agent结果模型在选 Skill 的时候比干活还慢也有人把一条简单的 Prompt 套上 Skill 的壳就发出来宣称“工程化落地”更常见的是Skill 写了一大堆测试一跑就翻车翻完车也不知道是该改提示词、改脚本还是改目录结构。这篇文章我不打算做名词科普而是想从工程实践的角度把一个 Skill 从设计、编写、测试到迭代的完整链路拆开讲透顺便泼几盆冷水哪些场景根本不需要 Skill哪些做法是在给 Agent 系统埋雷。看完之后你至少能回答三个问题——Skill 的本质是什么一个及格的 Skill 是怎么落地实现的以及怎么判断自己是不是正在滥用它。1. Skill 概念的来龙去脉以及它到底在解决什么问题1.1 从“会聊天”到“会干活”Agent 缺的是可复用的能力单元要理解 Skill得先看大模型产品形态的演进。最早我们接触的是对话机器人模型的任务是“回答”而不是“完成”。后来有人把多轮对话、工具调用、记忆管理拼在一起做出了 Agent 的雏形——模型开始能调 API、读文件、写代码。到了这个阶段问题就变了模型虽然什么都会一点但它在面对某个特定领域任务时没有任何“职业习惯”。什么概念你让一个刚毕业的高材生去写周报他能写出来但写出来的东西要么格式不对要么啰嗦得像个流水账。你让他去分析日志他会用 grep 把报错抓出来但他不会先按时间窗口切分数据再逐层聚合错误码最后给你一份带着趋势判断的报告——因为这些是你在公司里带了他三个月之后他才学会的“岗位技能”。Skill 就是给大模型做“岗前培训”的那个载体。它不是模型参数里的能力也不是一次性的对话指令而是一套结构化的、可复用、可版本化、可被多个场景装载的“能力单元”。可以说Agent 负责“临场发挥”Skill 负责“有章法”。我在实际项目里的体感是没有 Skill 的 Agent 像一个什么都懂但没有任何工作经验的实习生有了 Skill 的 Agent 才像一个带过一段时间的正式员工。这句话听起来很简单但它决定了 Skill 在设计上必须同时包含“说明”和“执行”两个维度——光告诉模型要怎么做不够还得给它提供可执行的具体工具脚本和参考样例。1.2 Skill、Prompt、Plugin、Agent 的边界在哪里这四者的关系几乎是每次分享必被问的问题。我先说结论Skill 是一种介于 Prompt 和完整 Agent 之间的工程形态它不是单纯用来“提示”模型的文本也不是一个独立自主的智能体它是可以被 Agent 随时调用的一组流程化能力。如果画一条轴最左边是 Prompt——一段文本只在你输入的那一次会话里生效没有固定的存储结构没有可复用的执行逻辑。最右边是 Agent——一个具备目标拆解、多步规划、工具调度、自我纠偏能力的完整系统。Skill 落在中间偏右的位置它有固定的格式有一定的执行脚本但自身不做复杂规划它的“决策权”受限本质上是供一个更大的智能体使用的模块。那 Plugin 呢Plugin 在多数框架里指的是系统层的扩展点比如给某个应用插一个鉴权中间件或者给 IDE 插一个语言服务器。它关注的是“软件系统的集成”Skill 关注的是“模型能力的复用”。一个 Skill 内部可能会调用一个或多个工具脚本这些脚本可以长得像 Plugin但 Skill 的边界更偏向“提示词 脚本 元数据”的组合。我用一句话给团队讲清这件事Prompt 是你说的一句话Skill 是你沉淀下来的一份 S.O.P.Plugin 是你工具箱里的一把螺丝刀Agent 是那个拿着螺丝刀按 S.O.P. 干活的人。1.3 为什么 Skill 在最近半年突然成了香饽饽热词不会凭空出现。Skill 之所以爆发是因为几个条件恰好凑齐了。第一模型底座的能力到了临界点。代码型 Agent 已经能稳定完成多步文件操作和命令行调用模型需要在“调用之前”知道该遵循什么流程——Skill 完美补上了这个接口位。第二终端型 Agent 产品Codex、Claude Code、Trae 这类开始流行它们天然允许用户在自己的工作目录里塞一个.claude/skills或类似的结构化目录这让 Skill 的“可分发”属性大大增强。第三社区生态起来了越来越多的开发者开始公开自己的 SKILL.md大家发现同一个 Skill 可以跨项目复用于是“skill 推荐”“skill creator”这类新热词就跟着长了出来。但繁荣背后有个隐患门槛太低了。写一个 Skill 的真实门槛并不高谁都能把一段话包装成 Skill但一段话包装出来的东西根本撑不起“工程化”三个字。所以接下来我重点拆解真正合格的 Skill 到底该由哪些部分构成。2. Skill 的本质拆解一份“可执行的说明书”背后有什么2.1 Skill 的真实形态是“结构化知识 可执行逻辑”的复合体很多人把 SKILL.md 看成“更长的 System Prompt”这是目前最大的误解。Prompt 的目标是影响模型的输出风格和内容而 Skill 的目标是让模型在特定任务上“按流程办事、按标准产出”。我拆过很多个公开的 Skill发现凡是好用的内部都藏着一个共性结构先告诉模型“这个技能什么时候该用、边界在哪里”再给它“完整可执行的操作步骤”最后给它“参考工具脚本和验收标准”。这有点像传统软件开发里的“接口文档 单元测试”——前者定义行为契约后者验证行为正确。举个例子一个“日志分析 Skill”如果只写“你需要分析日志并找出错误”那它连 Prompt 都不如。合格的版本应该写清楚日志文件可能多大、什么格式、常见的错误码含义、按什么维度聚合、最终输出什么结构同时附一个统计脚本自动把高频错误和异常趋势算出来。这样才能保证无论谁来调用产出的质量和格式是稳定一致的。2.2 Skill 的核心组成声明、说明、参考实现、测试我把一个工程化的 Skill 拆成四个模块来看。第一是元信息声明。包括 Skill 的名字、描述、触发条件、依赖环境。这部分不是给人看的是给 Agent 的“路由系统”看的。描述写得好不好直接决定了模型在遇到任务时会不会选到这个 Skill。很多 Skill 不好用的首要原因就是描述太差模型根本判断不出什么时候该调用它。第二是行为说明。这是 SKILL.md 的主体告诉模型“按什么顺序、用什么方式、输出成什么样子”。行为说明要足够细——步骤要编号边界要写死异常分支要讲清楚。第三是参考实现。也就是配套的脚本或模板代码。它们的作用是把“确定的部分”从模型的推理压力里解放出来。比如解析 JSON、计算聚合指标这类操作交给脚本做又快又稳不需要模型自己发挥。第四是测试用例。一套能验证 Skill 是否正常工作的输入输出样例。没有测试Skill 就是个盲盒没人知道它在下一次调用中会不会打出离谱的结果。2.3 一个好 Skill 应该满足的三个标准我衡量一个 Skill 是否合格只看三个标准。第一可触发。模型读到对应任务时能够稳定地把这个 Skill 选出来。换句话说它的描述和业务场景之间要有足够明确的映射不能是那种模棱两可的泛泛而谈。第二可执行。按照 SKILL.md 里的流程配合参考脚本确实能跑通产出符合预期。第三可验收。你有一套明确的检查办法能判断 Skill 的输出到底对不对而不是“看起来差不多”。不可验收的 Skill 写得再漂亮也无法迭代。这三个标准听着简单但当我拿它去检视自己手头的 Skill 时会发现一大批项目连第一条都过不了——因为描述写得不清不楚Agent 在关键时刻根本不调用它。3. 工程实现手把手教你写一个能用的 Skill3.1 目录结构与命名规范先搭好一个不会乱的架子我建议每个 Skill 在项目里单独占一个目录目录名就是 Skill 的名字内部再按“说明、脚本、资源、测试”拆分子目录。以一个通用的格式为例skill-name/ ├── SKILL.md ├── scripts/ │ ├── run.py │ └── utils.py ├── assets/ │ ├── templates/ │ └── examples/ └── tests/ ├── case1.md └── case2.md目录命名必须短、具体、一眼能看懂用途。比如log-analyzer就比analysis-tool好得多——前者明确了对象和动作后者是个谁都能往里塞东西的筐。scripts目录放 Skill 运行时需要调用的脚本。assets放模板文件、参考输出样例。tests放测试输入和预期的输出结果。这个结构不是硬性标准不同框架的约定略有差异但“说明、脚本、测试三者分离”的思路是通用的。3.2 SKILL.md 该怎么写才不会被模型当作空气这是全场最关键的一步。SKILL.md 写不好后续的工作白搭。我根据自己的踩坑经验把它拆成几个区块来写。第一块是身份与能力边界。开头就要直接告诉模型这个 Skill 叫什么、在什么范围内有效。比如“本 Skill 用于服务端日志文件的错误模式分析不处理前端埋点数据”。能力边界写得越清楚模型越不会乱用。第二块是触发条件。要明确列出什么情况应该使用、什么情况坚决不要用。触发条件不能太窄太窄了模型想用的时候找不到它也不能太宽太宽了模型会在无关场景下硬套。我的经验是至少列出三个肯定触发的场景作为正例再列两个禁止触发的场景作为负例。第三块是执行步骤。用有序列表逐步描述工作流。每一步都要具体到“做什么、怎么做、产出什么”。不要只写“分析日志”要写“先用脚本提取时间窗口内的错误码分布再按错误码聚合相关上下文最后输出 JSON 格式的汇总报告”。第四块是输出规范。直接用模板定义一个输出格式可以是 JSON、Markdown 表格或自定义文本格式。最好是给一个完整的输出样例让模型照着填。这一步能显著提升结果的可控性。第五块是失败兜底。告诉模型在遇到什么情况时应该放弃、向上报告或者尝试降级处理。没有兜底的 Skill 一旦出错Agent 就可能陷入死循环。用我自己的一个精简版为例# Log Analyzer 本 Skill 用于分析服务端日志文件定位错误模式并输出量化摘要。 不对前端埋点、业务订单数据做分析。 ## 适用场景 - 用户反馈接口报错率上升需要快速定位错误码分布。 - 上线后需要检验日志中是否出现新的异常类型。 - 定时巡检多个服务的错误日志。 ## 不适用场景 - 实时流式日志的监控请交给告警系统。 - 需要逐条阅读的深度业务日志。 ## 执行步骤 1. 确认日志路径与格式必要时先预览前 50 行。 2. 调用 scripts/run.py 统计错误码分布和时间趋势。 3. 对 TOP5 错误码提取各自的典型上下文。 4. 按输出规范生成摘要。 ## 输出规范 { time_window: ..., total_errors: 0, top_errors: [], trend: increasing/decreasing/stable } ## 失败兜底 - 日志文件不存在或为空直接返回提示信息。 - 脚本运行出错附上原始报错并停止流程。这里最容易被忽略的是“失败兜底”这一段。没有它模型在脚本报错时往往会凭想象力编一个结果——这错得很隐蔽很致命。3.3 参考脚本的设计原则不要什么都指望模型推理Skill 里要不要带代码是很多人的纠结点。我的原则很简单凡是确定性逻辑全部下沉到脚本凡是开放判断才留给模型。打个比方统计错误码出现次数这种逻辑是确定的人类看一眼代码就能验证让模型去数反而可能数错就应该写成脚本。而“整体报错趋势是上升还是下降”这种需要结合业务上下文判断的结论则适合让模型综合输出。脚本的价值是把模型从“计算器”这个不称职的角色里解放出来让它专注做“分析师”。设计脚本时还要注意容错。日志格式千奇百怪脚本至少要做到文件不存在时给出明确报错、解析失败的行跳过而不是中断、输入超大文件时有合理的采样策略。这些细节看着琐碎但真到了 Agent 自动运行的时候每个没有兜底的分支都可能变成一个白痴行为。另外脚本的运行方式要写清楚最好在 SKILL.md 里给出标准命令。不要让模型猜是python3 run.py还是bash run.sh。能显式规定的就不要留给模型自由发挥。3.4 测试与调优怎么确认 Skill 真的在生效很多 Skill 发布了就没人管这是工程化的大忌。我建议每个 Skill 至少要配三组测试一组典型正常场景一组边界场景一组不该触发场景。典型正常场景就是技能最核心的任务验证“走正常流程能不能跑通”。边界场景测试的是“输入有变化时Skill 是否能优雅处理”。不该触发场景测试的是“模型在无关任务上会不会误用这个 Skill”。三组测试都过了Skill 才敢说基本可用。做完测试还要做“可观测性验证”。一个常见困惑是怎么知道模型到底有没有按我的 SKILL.md 走我的做法是让 Skill 在流程中留下“执行痕迹”——比如规定模型在输出摘要的末尾附加一个元信息块或者固定调用一个能写日志的脚本。这样当你审查结果时能一眼看出它到底走了没有。调优时优先检查触发条件和执行步骤不建议一上来就改提示词的口吻。大部分 Skill 失灵问题都出在“模型压根没选到它”或者“选到之后不知道下一步具体该做什么”上。4. 你大概率正在滥用 Skill 的 5 个信号4.1 信号一把 Skill 当成了 Prompt 收藏夹这是我见到的最高频错误。很多人写的 Skill 其实是“换个格式的精美 Prompt”“你是一位资深的产品经理请用结构化思维分析这个问题……”——Stop。Skill 必须有可执行性至少要包含操作步骤、工具调用或输出规范这些“带骨架”的内容。如果一段话去掉“Skill”的外壳之后本质上还是“请帮我做好 X”那它就是 Prompt 披了个马甲。把这种内容挂到 Agent 上不会让模型变强只会让你的配置文件变长、路由开销变高。我自己的判断标准是如果写完的 Skill 没有任何脚本、没有任何能机器校验的输出规范也不包含特定领域的分步方法论那我就不该叫它 Skill。4.2 信号二一个 Agent 挂了十几个互不相关的 Skill有人为了追求功能齐全把市场调研、周报生成、代码审查、PPT 排版全挂到同一个 Agent 上结果每次任务触发时模型都要在十几个 Skill 描述里做一次“路由决策”。决策空间越大选错的概率越高选错了后续输出就跑偏而且跑偏得很隐蔽——因为模型常常会表现得“看起来很像那么回事”。我在项目里的经验是单个 Agent 上同时挂载的 Skill 最好不超过四五个且这些 Skill 应该在领域上有某种相关性。如果业务场景差异太大拆成多个不同的 Agent分别挂各自的 Skill 组合效果会比“一个大而全的 Agent”好得多。4.3 信号三重复发明轮子把模型原生能力包成了 Skill模型的上下文理解、通用推理、基础文本改写这些能力本身就是内置的你不需要为它们写 Skill。比如“将一段英文翻译成中文并润色”这种任务直接对话就能完成包一层 Skill 除了增加截断风险毫无帮助。优雅的边界是什么样的判断标准是“是否需要领域知识或固定流程”。如果任务每一步都依赖模型临场发挥没有外部依赖、没有固定步骤、没有独特产出规范那它就是原生能力不该包装成 Skill。Skill 应该用在“一个外行无法通过简单对话直接完成”的领域任务上比如法律文书一致性审查、行业数据源汇总、复杂报表生成。这些任务里有固定的业务规则和产出标准才需要沉淀成 Skill。4.4 信号四只写不给测Skill 成了盲盒Skill 本质上是代码资产不测试就是负资产。我见过很多团队兴致勃勃地写完一个日志分析 Skill结果真实日志里只要出现一种 SKILL.md 没覆盖的格式脚本就崩了模型就在崩溃边缘疯狂补丁越补越离谱。正确的做法是把测试当成 Skill 开发的一部分每次改动 SKILL.md 或者脚本都至少要跑一遍回归。我不是说一定要上 CI/CD但至少你心里要对“这个 Skill 现在能不能用”有一个明确答案。连这个答案都给不出就不要把它放进任何会自动运行的系统里。我一直强调不可验收的 Skill 是无法迭代的。因为你在出问题的时候根本不知道是脚本的问题、SKILL.md 指导的问题还是模型执行的问题最后只能靠猜。4.5 信号五版本混乱、没有维护责任人Skill 这种形态很容易让人低估它的维护成本。Skill 会依赖模型版本、依赖脚本环境、依赖所在项目的具体情况任何一个变量变了它都可能开始“发神经”。我在实际的工作中有个体会Skill 库和代码库一样需要版本管理、变更记录、一个明确的责任人。否则三个月后模型版本升了某个 Skill 突然开始产生奇怪结果你翻遍记录都找不出它是什么时候变的、为什么变只能从头排查。5. 常见问题与排查技巧实录5.1 Skill 加载了但不生效先分清是“没看到”还是“做不到”Skill 不生效需要先确认故障在哪一层。把排查分成三层加载层、选择层、执行层。加载层是 Skill 文件有没有被正确放到 Agent 约定读取的目录命名、格式是否符合规范。很多框架对目录名和 SKILL.md 文件名有严格约定一个字符错了就静默失败。选择层是模型面对当前任务时到底有没有把这个 Skill 纳入候选。这一步最容易出问题。如果你想测试我建议直接在一个新会话里问模型“当前环境下有哪些 Skill 可用”先看它能不能报出你的 Skill 名字再给一个明确触发场景看它会不会主动选择。选不到的话问题一般出在 SKILL.md 的描述语句上——太泛、太偏、和目标任务同名性太弱都会让路由失败。执行层是模型选择并读取 SKILL.md 之后有没有按步骤执行、脚本有没有跑起来。这一层需要看工具调用日志。如果脚本根本没被调用说明 SKILL.md 里的步骤写得不够显式模型选择性地跳过了如果脚本调用了但结果不对再回到脚本本身的容错上排查。5.2 模型总是不按 SKILL.md 的步骤走怎么办这一步的根因通常是步骤粒度太粗。多数模型执行长流程时倾向于按自己的“常识”来理解一步操作而不会脑补你没有写的细节。比如你写“提取错误码”模型不知道是要用 Python 脚本还是用 grep这时它的选择就不可控了。解决方法是把每一步写成像机器指令一样明确。建议给每个步骤配上“用什么工具、执行什么命令、读取哪个文件、产出什么中间结果”。宁可多写几行也不要留给模型发挥空间。我测试过同一个 Skill把步骤从“2. 统计错误码”改成“2. 运行 scripts/run.py --input 日志路径 --output /tmp/error_summary.json”执行准确率提升非常明显。另外一个容易踩的点是SKILL.md 太长。如果一份 SKILL.md 超过了上下文窗口的舒适区模型在后续生成过程中可能会“遗忘”后半段的规范。好东西要学会精炼步骤能合并就合并说明能去冗余就去冗余。5.3 多个 Skill 冲突了怎么办冲突场景最典型的是同一个任务既能由 Skill A 处理也能由 Skill B 处理结果模型二选一的时候选错了。我的处理办法是给 Skill 设置显式的边界声明在描述里直接写明“本 Skill 优先处理 X 场景Y 场景请交给 Z 处理”。如果冲突仍然存在就要回到触发条件设计的正反例上。把常见的易混淆场景分别放进两个 Skill 的“不适用场景”段里。这样等于在路由层面做了人工消歧能显著降低选错概率。5.4 Skill 写太多之后 Agent 变笨了怎么处理这是系统性问题的症状不是单个 Skill 的问题。Skill 多了以后每个 Skill 的描述都要占用模型的注意力路由决策变慢错误率变高。我会定期做归档操作把低频使用的 Skill 移出默认加载列表改成按需加载把高频使用的 Skill 合并同类项把已经证明无效的 Skill 直接删除。不要有不舍得删的心理——Skill 是资产但它首先应该是“可用资产”不可用的东西躺在那里只会继续消耗上下文和注意力。判断一个 Skill 留不留我只有一个问题如果这个 Skill 被删了这些任务你会不会真的觉得不方便如果答案是不会或者不确定那它就该被归档或重写。写在最后的几句实在话Skill 是好东西但它是一种工程产物不是玄学道具。我个人的经验是在决定要不要造一个 Skill 之前先回答三个问题这个任务是否会反复出现三周以上它是不是有固定的多步操作流程它是否需要结合外部脚本或模板才能稳定完成如果三个答案里至少有两个是肯定的再考虑把 Skill 提上日程否则写 Prompt 就够了。代码写多了之后人会对“封装”产生本能好感但在 Agent 领域每一次封装都在给系统的路由和决策增加成本。克制本身就是一种工程能力。希望这篇拆解能帮你在下一次动手前多想一步你到底是在打造一件趁手的兵器还是仅仅在往工具箱里囤积一件精美的摆设。