ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

从Prompt到Skills:AI Agent工程化中的技能包实战指南

从Prompt到Skills:AI Agent工程化中的技能包实战指南 如果两年前有人告诉我AI 工程化项目里最核心的资产会是一个叫skills的普通文件夹我一定觉得他在开玩笑。但现在我自己的几个智能体项目里已经躺着十几个这样的文件夹——每一个都比那些动辄几千字的 system prompt 稳定得多也让团队里新来的同学能在十分钟内上手干活。这几年我一直在折腾一件事怎么让大模型在真实业务里稳定地把事办成而不是每次都在“看起来说得过去”和“偶尔翻车”之间反复横跳。从 prompt 工程到 RAG从 function calling 到 agent 编排我都试过一轮。直到认真把skills当一回事去用才发现很多之前靠提示词硬撑的场景其实早就该用技能包来解决。这篇东西就把我踩过的坑、沉淀下来的写法、以及踩过几次坑之后总结的判断标准一次说清楚。1. skills 到底是什么从提示词到技能包的范式变化1.1 一个单词两种理解skills这个单词本身没什么特别的就是“技能”。但在现在的 AI 应用语境里它已经从一个抽象名词变成了一种具体的工程产物——一个由目录、说明文件、脚本和资源组成的独立能力包通常长这样skills/ └── code-review/ ├── SKILL.md ├── scripts/ │ ├── review.py │ └── checklist.md └── references/ └── style_guide.md如果你打开一个SKILL.md里面通常写着这个技能是干什么的、什么时候该触发、具体怎么做、有什么注意事项并且可以引用同目录下的脚本和资料。这个组合起来的东西就是 agent 能反复调用的技能包。1.2 为什么是现在才火prompt 的极限与 agent 的工程化需求说句实在话skills 能火本质是 prompt 工程被逼到了极限。早期我们写 agent什么都往 system prompt 里塞角色设定、业务规则、示例、输出格式、禁忌清单、少样本 demo……prompt 越写越长模型表现却越来越飘。我见过最夸张的一个项目system prompt 写到三万多字符结果就是每次改一句话都可能引发连锁反应模型在长上下文里容易丢失关键约束典型的“什么都写了等于什么都没写”。打个比方prompt 像一个妙手偶得的厨师你给他再厚的菜谱他发挥得好不好还得看当天状态。而 skill 像一道标准化的预制菜流程配料、火候、装盘步骤全部固化厨师只需要知道“今天要做这道菜”然后按流程执行。agent 工程化真正需要的恰恰是这种确定性。当你要把一个 AI 功能交给非技术人员使用或者让多个 agent 协作完成复杂任务时你不可能靠一段文本来约束所有行为。技能包的价值就是把“方法”打包成可复用的模块让 agent 在需要时按需加载而不是在每一轮对话里都背负全部规则。1.3 skills 与 MCP、插件、工作流的边界这半年我经常被问到skills 和 MCP 有什么区别和插件又有什么区别其实它们的侧重点完全不同。MCPModel Context Protocol解决的是连接问题它让模型能够访问外部工具、数据源和资源相当于给 agent 装上了手和眼睛。插件则是围绕某个宿主软件做的扩展机制比如浏览器插件、IDE 插件它依赖特定的平台外壳。工作流则是把一系列步骤固定成编排流程像流水线强调顺序和分支。skills 更接近“方法论 工具 知识”的打包。一个 skill 内部可以调用 MCP 工具可以被插件触发也可以内嵌一段固定流程。它不强调连接方式强调的是“完成某类任务的完整方案”。举个具体例子我想让 agent 帮我做代码审查。MCP 提供的是“读取文件、执行命令、调用 Git API”这些原子能力而一个code-reviewskill 定义的是审查哪些文件、按什么标准审查、发现阻塞性问题怎么办、如何生成结构化报告。前者回答“能做什么”后者回答“怎么做得好”。这也是我在项目里越来越倾向用 skills 组织能力的原因——它站在更高一层的抽象上把乱糟糟的能力碎片整合成了可直接交付的业务模块。2. 动手搭建第一个 skill目录、SKILL.md 与最小可运行示例2.1 一个完整 skill 的目录结构先别急着想复杂的东西我们从最小结构开始。一个可用的 skill 至少要包含一个SKILL.md文件它可以不写任何脚本纯粹靠说明文本来引导模型工作。但实际项目中一个稍微像样的技能包我会按下面这个结构组织skye-review/ ├── SKILL.md ├── scripts/ │ ├── review.py │ └── run_checklist.sh ├── references/ │ └── team_style.md └── assets/ └── examples/ └── good_review.mdSKILL.md是这个包的入口scripts放可执行脚本references放静态参考资料assets放示例或模板。目录名称必须是小写加连字符这个约定能让 agent 在文件系统里快速识别技能名也避免跨平台路径问题。我见过不少新手把脚本、资料、历史输出全堆在一个文件夹里最后技能包越滚越大agent 加载时反而不知道该看什么。所以从一开始就要养成习惯只把“执行这个技能必需的资产”放进目录历史记录和临时文件一律不要放进来。2.2 SKILL.md 怎么写frontmatter 与正文分层SKILL.md不是给模型写作文而是给 agent 的操作手册。它由两大部分组成结构化元信息frontmatter和正文。frontmatter 用 YAML 格式写在文件最上方用---包起来。我常用的字段就这几个--- name: skye-review description: 对指定代码变更进行系统性审查检查安全隐患、性能问题与代码规范并输出结构化审查报告。当用户要求审查代码、Pull Request 或代码片段时使用。 ---这里description是整个 skill 的灵魂。agent 会先扫描所有技能的 description再决定当前任务是否匹配。你有没有遇到过这种尴尬写了个“代码审查”技能结果用户问“这句话语法对不对”agent 也把技能调出来了然后拿着技能里的规则去分析普通聊天文本输出一堆莫名其妙的内容。这就是 description 写得不够精准造成的。我的经验是description 要回答三个问题什么时候用、什么时候不用、输入是什么。可以写得啰嗦一点但一定要把边界说清楚。上面那个例子我会补一句“不适用于需求讨论、架构设计或文档撰写类请求”。正文部分分三层写第一层任务目标与输入来源。明确这个技能想达成什么结果输入从哪来用户直接提供还是需要自己去仓库里找。第二层执行步骤。用有序列表把步骤写清楚每步尽量给出可验证的输出。第三层注意事项与红线。把容易翻车的地方写清楚比如“不得修改原文件”“遇到不确定项必须询问用户”。2.3 最小示例一个“增强代码审查”的完整实现光说不练假把式。我把自己用的code-review技能缩减一下给你看。首先是SKILL.md--- name: code-review description: 对代码变更进行审查检查错误、安全隐患、性能瓶颈与风格问题输出分级审查意见。当用户提到 review code、审查代码、检查 PR 或给出 diff 时使用。若用户只是讨论代码逻辑而不要求审查则不使用。 --- # Code Review Skill ## 任务目标 - 找出代码中的功能性错误、安全问题、性能问题与风格问题。 - 输出按严重程度分级的审查报告阻塞(Blocker)、主要(Major)、次要(Minor)。 ## 输入 - 优先使用用户提供的 diff 或文件路径。 - 如果用户只给了仓库路径先运行 git diff 获取最近变更。 ## 执行步骤 1. 明确审查范围确认是否有文件名、行号、提交范围。 2. 调用 scripts/review.py 获取静态检查结果。 3. 按 rule 文件中的规范逐项人工比对。 4. 输出 markdown 报告每个问题包含文件、行号、问题描述、建议改法。 ## 注意事项 - 未经用户允许不修改任何代码文件。 - 阻塞问题必须给出复现路径或明确证据不能只说“建议优化”。 - 对第三方的、生成器自动生成的代码不做风格类评论。然后是scripts/review.py一个小而实用的静态检查脚本#!/usr/bin/env python3 A minimal static review helper. import re import sys from pathlib import Path def find_todo_markers(path: Path) - list: issues [] for line_no, line in enumerate(path.read_text().splitlines(), 1): if re.search(rTODO|FIXME|HACK, line, re.IGNORECASE): issues.append((path, line_no, line.strip())) return issues def find_overlong_functions(path: Path) - list: issues [] current_func None start_line 0 length 0 for line_no, line in enumerate(path.read_text().splitlines(), 1): if re.match(r\s*(def|async def)\s\w, line): if current_func and length 80: issues.append((path, start_line, current_func, f{length} lines)) current_func line.strip() start_line line_no length 0 elif current_func is not None: length 1 return issues if __name__ __main__: for target in sys.argv[1:]: p Path(target) if not p.exists(): print(fSKIP {target}: not found) continue for issue in find_todo_markers(p): print(fMINOR {issue[0]}:{issue[1]} TODO/FIXME: {issue[2]}) for issue in find_overlong_functions(p): print(fMAJOR {issue[0]}:{issue[1]} {issue[2]} too long ({issue[3]}))这个脚本解决的问题很实际模型看代码时容易漏掉大段代码中的标记或者对“一个函数到底有多长”缺乏准确感知。脚本负责把确定性的统计结果捞出来模型负责对结果做语义层面的判断。两者结合比单纯靠模型读代码稳得多。2.4 命名与放置路径为什么叫 skills 而不叫 plugins关于命名很多第一次接触的人会问为什么目录不叫plugins或extensions从工程角度讲plugins隐含了“必须接入宿主、遵循特定接口”的意思而skills更通用它强调的是一种可以被描述、被加载、被调用的能力。一个技能包本身就是一个自主模块跟宿主之间的耦合很轻。所以我在项目里的约定是凡是一段“描述 脚本 资料”的结构统一放skills/目录按功能分子目录。放置路径也很讲究。我建议技能目录放在项目根目录下与代码目录平级。这样有几个好处一是 agent 遍历文件系统时容易发现二是技能和项目代码分开不会把业务代码卷进技能资产里三是多项目共享技能时直接把这个目录拷走即可。我第一次做技能包时把脚本和业务代码放在同一个 git 仓库的src/里结果每次业务代码迭代技能包也跟着刷版本非常痛苦。后来改成独立目录独立维护清爽多了。3. 让 skill 真正扛活的三个关键细节确定性、上下文压缩、错误恢复3.1 用脚本固化判断逻辑而不是让模型自由发挥模型最大的优点是理解力最大的缺点是“自由发挥”。同一个技能让模型跑十次可能每次结果都不一样。如果你追求的是稳定交付那就要想办法把“不该发挥”的部分抽出去交给脚本。我在设计技能时有一条原则凡是能用一行命令判断的规则绝不让模型去肉眼判断。比如“这个文件里有多少个函数超过 80 行”“代码中是否出现了明文密码”“接口是否缺少鉴权装饰器”这些任务用脚本做准确率是 100%用模型做准确率可能只有 90%。技能包里放着这些脚本agent 只需要执行脚本、读取输出、再针对异常点做语义分析既快又准。这里说的脚本不一定是 Python。我用过 shell、Node.js 甚至 SQL 查询关键不在于语言而在于可复现。同一个输入脚本在任何时刻执行结果都应该一致。一旦摸到这个门道你会发现 prompt 里的“必须、禁止、一定”这类强约束词语出现的频率会直线下降因为确定性逻辑根本不需要靠语气词来约束。3.2 上下文压缩技能里只放“触发时该看的”而不是全部知识这是我最想强调的一点。很多人写技能包时容易犯“信息囤积症”——把所有可能用到的资料都塞进references目录结果 agent 加载技能时把几十个文件全读一遍上下文爆炸回答反而变差。我每次回顾都提醒自己agent 读取技能包是为了知道“怎么做事”而不是“把所有知识背下来”。技能包的内容应该像操作手册的“快速开始”章节而不是整本维基百科。实操中具体压缩方法技能正文只保留高频使用的步骤和规则低频但重要的资料浓缩成摘要放进 references并在正文中明确标注“只有在处理 X 类问题时才去读 references/xx.md”示例不要超过 3 个够建立模式就行。试想一个“生成接口文档”的技能如果它附带公司全部 50 个历史接口文档作为参考agent 光是理解这些文档就要消耗大量上下文。但如果它只带 1 个标准示例和 1 份字段规范表那么剩余上下文就全部留给“怎么分析当前这个接口”了。3.3 错误恢复设计 fallback 路径和验证步骤技能包执行过程中一定会出错这没什么可回避的。脚本找不到文件、依赖没安装、用户给的路径不对、模型推理到一半发现信息不足……每一种情况都需要提前想好应对方案。我的习惯是在技能执行步骤里显式加入“异常分支”。比如在code-review的步骤 2 后面加上2. 运行 scripts/review.py。如果脚本因为缺少依赖而报错先尝试 pip install -r scripts/requirements.txt再重新运行。如果仍然失败报告错误并询问用户环境信息。同时在SKILL.md末尾固定一个“验证小节”要求 agent 在给出结果前自查是否覆盖了全部输入文件每个问题是否都能定位到具体文件行号阻塞级问题是否有明确证据是否误把建议当作必须执行的结论这个自查清单能显著减少“一本正经地胡说”。有一次我做一个数据清洗技能agent 输出了漂亮的清洗报告但内部自查时发现它根本没读取源数据文件只是根据文件名猜了结构。从那以后每个技能默认都要写验证步骤这个习惯帮我们拦下了不少低级错误。4. 调试与评估怎么知道一个 skill 是真的有用4.1 建一个回归测试集20 个用例跑一遍技能包写出来是给人用的但先得经得起测试。我给每个技能配一个tests/目录里面放一批典型的输入用例和期望输出。每次改技能就把这批用例喂给 agent 跑一遍对比输出是否仍然符合预期。这里的“期望输出”不一定是精确的文本更常见的是“必须包含的关键字”和“不能出现的内容”。比如代码审查技能的用例我可以设定输入一个带 SQL 注入漏洞的代码文件期望报告中出现“SQL 注入”和对应行号。输入一个没有问题的文件期望报告中不出现“阻塞(Blocker)”级别条目。输入一个根本不存在路径期望 agent 明确告知错误而不是自行猜测生成内容。刚开始我做测试集时只放了 5 个用例觉得已经覆盖了主要场景。后来一次技能改动把 description 写宽了导致用户随便问一句“这个功能怎么用”就触发了代码审查输出完全跑偏。测试集扩充到 20 个用例后这种回归问题基本能在提交前暴露出来。4.2 评分维度准确性、稳定性、成本、耗时跑完测试集得有一个公允的评判维度。我一般从四个维度打分每个维度满分为 10 分维度评判标准我的最低要求准确性输出是否正确、是否贴合用户原始意图9 分以上稳定性同一输入反复执行多次结果差异是否在可接受范围8 分以上成本整个执行过程消耗的 token 量与外部 API 次数是否合理与场景相关需量力耗时从触发到输出结果的时间是否满足使用场景交互场景尽量 1 分钟内重点说稳定性和成本这是最容易拖垮实际使用体验的两项。稳定性方面我会把同一个用例连跑 5 次统计输出结构是否一致。如果一个技能 5 次输出中 3 次格式都不同说明正文里的输出约束不够强需要把输出结构从“描述式”改为“模板式”甚至直接在正文里给出 markdown 结构骨架。成本方面我吃过一个大亏一个“生成会议纪要”的技能正文里附了公司全部会议模板导致 agent 每次执行都把模板全部读一遍一次任务的 token 消耗是正常情况的 5 倍。后来把模板压缩成 2 个代表样例成本立刻降下来输出质量也没变差。4.3 常见失败模式与对应修法我把调技能过程中遇到的典型问题整理成一个表遇到同类问题时可以直接对照处理失败现象可能原因修法该触发时不触发description 里触发词太少或边界描述过多加入同义触发词同时限制不使用场景不该触发时乱触发description 太宽泛缺少排除条件明确补一句“不适用于……”输出格式不稳定正文对输出结构约束不足提供输出模板要求按模板填充执行步骤被跳过步骤描述太长模型没抓住重点精简步骤把核心步骤提前脚本依赖缺失SKILL.md 没写依赖说明增加依赖清单与安装命令加载技能后废话变多references 资料过多压缩参考文件只保留摘要结果与脚本输出矛盾模型忽略脚本结果自行判断在正文中强调“以脚本输出为准”这个表看起来简单但每一条背后都是真实翻过车的。直到现在我每做一个新技能都会对照这个表过一遍先把高风险项排查掉再发布。5. 我的使用经验什么时候该写 skills什么时候该忍住5.1 五个真正适合做技能包的场景技能包不是万能的但它特别适合以下几类任务。一类是高频重复且有章可循的工作。比如周报生成、接口文档撰写、代码格式化检查、会议纪总结这些任务每次做法都差不多输入输出结构清晰做成技能包后能把“每次都重新给模型讲一遍规则”的时间省下来。第二类是规则复杂但最终可以被脚本确认的任务。比如安全扫描、依赖版本检查、日志错误分类规则哪怕有几百条只要最终判断逻辑能写成脚本技能包就能通过“脚本处理 模型解释”的方式干得漂亮。第三类是知识面窄但很深的任务。比如公司内部某个遗留系统的排障手册里面全是只有少数人知道的隐性知识把它整理成技能包其实就是把老师傅的经验沉淀下来让新手也有了处理这类问题的拐杖。第四类是需要多人共用、口径统一的任务。团队里三个人写周报三个人三种风格如果统一挂一个“周报生成”技能输出风格能被规范到同一条水平线上。这不仅仅是提效更是团队规范的一部分。第五类是单个 agent 光靠 prompt 立不住的任务。当你发现用户总是追问“你依据什么得出这个结论”时说明 prompt 里的规则对这个任务来说不够扎实需要把参考资料和判断逻辑沉淀成技能包。5.2 四个不适合的场景别为了技能而技能有些场景我也试过做技能包但最后都取消了。一个是一次性的偶发任务。比如领导让我临时分析一份 CSV 数据做完就完了为这种事写技能包是纯浪费。第二个是需要实时外部数据、且没有稳定获取通道的场景。技能包能定义做事的步骤但拿不到数据就等于巧妇难为无米之炊这时候应该先把数据通道比如 MCP 工具打通技能包才有意义。第三个是规则处于快速变化期的任务。比如某个功能的上线流程一周改三次技能包里的步骤刚写完就过时了维护成本比手写 prompt 还高。这种任务适合等流程稳定了再固化。第四个是用户个性化极强、无法标准化的任务。比如给不同客户定制营销文案每个人口味不同硬做成技能包输出的东西往往又平又泛反而丢掉了定制感。5.3 维护策略版本化、changelog 与团队共享技能包是会进化的千万别写完之后就当传家宝供着。我维护技能包有几个固定动作。每次修改目录里放一个CHANGELOG.md记录改了什么、为什么改。为什么因为技能包往往不只自己用团队里其他人也在用改完如果不说清楚别人会以为是自己用错了。版本管理上我现在把每个技能目录都看成一个独立的包在 git 里用 tag 标记版本号。发布时至少满足三个条件测试集全部通过、changelog 已更新、description 与实际行为一致。这一步做完再从主项目里引进来团队其他人拉到的就是一份可靠的模块。共享方面团队内部我用一个独立的 git 仓库存全部技能包命名规则统一SKILL.md里标注维护人和更新日期。新成员入职时先跑一遍技能清单就知道团队有哪些沉淀下来的能力比翻老员工的聊天记录高效得多。5.4 最后再说点真实的体会写过十几个技能包之后我对 agent 工程的看法变了很多。过去总想找个万能 prompt 解决所有问题现在明白了prompt 负责理解意图技能包负责提供方法两者配合好agent 才能真正从“玩具”变成“工具”。如果你开始往这个方向入手我的建议很简单——挑一个你每周至少要做三次的重复任务花半天时间把它整理成第一个技能包。不用太精致先跑起来再对着失败慢慢改。这个过程中你对“agent 怎么做才靠谱”的理解会比看任何教程都来得快。
返回列表