
最近大半年我一直在折腾AI Agent相关的东西。说实话早期做Agent有个特别头疼的问题Prompt越写越长工具函数越堆越多到最后整个系统像一团乱麻改一个功能能牵连出一串报错。后来我接触到了Agent Skills这套思路才算是找到了一个比较顺手的组织方式。这个标题“agent-skills”本质上是把“技能”作为一个独立单元来管理的一套工程实践。你可以把它理解成给Agent塞了一整套“岗位手册工具箱”而不是只丢一句“你是个助手”就完事。这篇文章我想把我自己从零搭建技能库、把一个Skill从想法变成可复用模块的完整过程捋一遍包括目录怎么组织、描述怎么写、依赖怎么处理、以及实际运行中那些文档里查不到的坑。无论是刚开始接触Agent开发的新手还是已经在做复杂多Agent系统的开发者这套思路应该都能给你一些参考。1. 为什么需要Agent Skills从一堆Prompt到一套技能体系1.1 我在Agent开发里踩过的坑最开始我做Agent的方式很简单一段系统Prompt把角色、任务、约束全塞进去再挂上几个函数。刚开始还好任务单一上下文里塞点说明就够用。但一旦功能多起来问题就变得非常明显。第一是上下文爆炸。每个工具我都要写“什么时候用、参数怎么填、返回格式是什么”这些东西全部堆在系统Prompt里一次对话要占好几千token。第二是维护成本高。Prompt里某个工具的描述更新了我得在整个长文本里找对应段落稍不留神就漏改。第三是冲突。多个工具之间的职责边界一旦模糊Agent经常选错工具明明该调A的却去调了B排查起来让人头大。这些问题不是靠“写更好的Prompt提示词”就能解决的。核心矛盾在于你把所有知识、规则、边界混在一个线性文本里Agent在推理时是逐字读取的信息一多注意力被稀释关键指令反而容易被忽略。1.2 Agent Skills到底解决什么问题Agent Skills的思路在于不再把所有说明塞进同一个上下文而是把“完成某一类任务所需的知识、指令、参考代码、示例”打包成一个独立的、可插拔的模块。Agent在运行过程中先根据用户请求判断需要哪些技能再按需加载对应的技能包而不是启动时就加载一切。用生活里的例子类比一个刚入职的运营你不可能第一天就让他背完公司所有制度手册而是给他一份“工作手册”碰到报销翻报销章节、碰到活动策划翻活动章节。Agent Skills就是这本手册的“章节”拆分机制。这套机制能带来三个直接好处。第一是上下文精简Agent每次只需要读取与当前任务相关的技能说明其余不占用token。第二是技能复用一个写好的技能包不仅可以在当前Agent里用还能复制到另一个项目里只要目录结构完整几乎是即插即用。第三是可测试性每个技能包是独立单元可以单独做输入输出验证出问题知道该改哪个包。1.3 技能、工具、提示词、工作流的边界划分这块我一开始也混淆过仔细梳理之后才理清楚。先说我理解的边界。工具是Agent执行动作的“手”负责具体的函数调用比如查天气、发邮件、读数据库。提示词是给Agent的“指令上下文”告诉它该以什么身份、按什么规则思考。工作流是多个步骤的“固定流水线”常用来编排有明确先后顺序的业务流程。而Agent Skills是一个更上层的“能力封装包”它内部可以包含工具定义、参考脚本、示例输入输出、注意事项甚至可以内嵌一小段工作流描述。举个例子写一个“周报生成技能”工具层可能只是读Git记录和读日历但Skill层会补充“周报要分几个板块、每个板块重点写什么、语气要正式、不要编造数据”这些约束。这些约束既不是纯粹的提示词也不完全属于工具逻辑它更像是一种“领域知识”。Agent Skills最大的价值就是把这类领域知识结构化、文件化、版本化。2. 技能库的整体架构设计与组织规范2.1 技能的标准目录结构与元数据规范在动手写第一个Skill之前我强烈建议先定好目录规范。好的结构应该是让人一眼就能看出“这是什么技能、怎么用、依赖什么”。目前业界比较常见的做法是把一个技能放在一个独立目录下里面至少包含以下几类内容。skills/ weekly-report/ SKILL.md reference.md examples/ example-1.md example-2.md scripts/ generate.py assets/ template.xlsx requirements.txtSKILL.md是核心文件相当于这个技能的“说明书入口”。它用YAML头信息写明技能的名称、描述、适用场景正文部分则详细说明使用步骤、注意事项。reference.md放扩展知识examples目录放典型示例scripts目录放可执行的辅助脚本。这样的好处是Agent在需要时不一定读全所有文件可以先读SKILL.md根据里面的指引决定是否继续加载其他文件。关于技能的描述信息这里有个特别关键的点描述必须写清楚“什么时候用”而不是只写“能做什么”。我之前犯过的错误是写“可以生成周报”结果Agent在用户提到整理工作内容时也去调用了它。后来我改成“当用户要求在项目结束时汇总本周工作产出、计划下周安排且需要输出结构化文档时使用”准确率明显提升。2.2 版本管理、命名规范与依赖处理技能包一旦多起来版本管理和命名规范就必须跟上。我的习惯是目录名全部小写加连字符比如weekly-report、data-visualizer不空格、不用驼峰。SKILL.md里通过version字段标注版本号每次改动至少要更新这个字段。依赖处理是另一个容易踩坑的地方。技能包里的辅助脚本往往会用到第三方Python包比如pandas、openpyxl这些依赖如果和主项目混在一起管理迟早会出问题。我目前的做法有两种轻量依赖直接写在requirements.txt里由Agent在执行前检查并安装重量依赖则建议做成独立服务通过API给Agent调用技能包里只保留调用示例和鉴权说明。后者的好处是技能包的代码逻辑和运行环境彻底解耦不会因为装不上某个包就让整个Agent挂掉这也是我在实际开发软件时最关心的稳定性问题。2.3 一次技能调用在Agent内部发生了什么为了更好理解这套架构简单说一下技能调用的完整链路。假设用户发来一句“帮我把这周的开发工作整理成周报发我邮箱”配置了技能库的Agent会做这几步首先是意图识别Agent基于当前对话内容和用户的请求结合各个技能的description判断“周报生成”这个技能是否匹配。这一步的关键是描述写得好不好描述越具体命中越准。然后是技能加载Agent读取选中技能的SKILL.md解析元数据按需加载reference和examples。接下来是执行Agent根据技能里的步骤说明调用脚本或工具完成数据拉取、内容生成。最后是结果加工Agent把脚本输出整理成用户可读的文本或附件。这四步里最耗时也最容易出问题的往往是第一步。很多技能包不被Agent使用不是因为能力不行而是description写得模棱两可。这是个纯粹的文本工程问题需要反复调优。3. 手写一个Agent Skill从零到可用的完整实操3.1 场景定义挑选第一个技能我建议第一个试水的技能一定选一个“你手头重复劳动最多”的任务。我当时选的是weekly-report周报生成因为这个任务有明确的数据源Git提交记录、有固定的输出模板、有清晰的判断逻辑哪些提交值得写进周报非常适合用来验证技能包的完整流程。挑选时有一个判断标准任务要足够“窄”。不要一上来就做“数据分析技能”太宽泛AI不知道该加载什么、调用什么。先做“从Git提交生成周报”这种具体到不能再具体的等整个流程跑通了再慢慢扩展成“数据分析技能”这类大包里面再按子任务拆分。3.2 编写SKILL.md把隐式经验变成显式指令SKILL.md是技能包的心脏也是最考验写作能力的地方。它不是给人看的文档而是给Agent看的“执行手册”。写的时候要特别注意Agent不像人一样能“凭经验发挥”所有步骤、判据、禁区都必须写明。我的一份SKILL.md正文一般包含几个部分前置条件、执行步骤、输出格式、注意事项。下面是一份精简示例。--- name: weekly-report description: 当用户要求汇总一周开发工作并生成结构化周报时使用。输入为时间范围输出为Markdown格式周报。 version: 1.2.0 --- # 周报生成 ## 前置条件 - 已安装 git - 当前目录为代码仓库根目录 ## 执行步骤 1. 使用 git log --author用户 --since开始日期 --until结束日期 --prettyformat:%h|%s|%ad 获取提交记录 2. 过滤合并提交(merge commit)只保留实际代码变更 3. 按模块归类提交信息概括为 3-5 个核心条目 4. 输出 Markdown 格式周报 ## 输出格式 - 标题YYYY-MM-DD 周报 - 结构本周完成 / 风险与阻塞 / 下周计划 - 语气客观陈述不夸大产出 ## 注意事项 - 不要虚构未出现在提交记录中的内容 - 重复提交(如 revert)需标注清楚 - 若某个提交信息含糊不清标记为“待确认”不要猜测你可能会觉得这些内容写得很“死”但事实是Agent恰恰需要这种“死”。模糊的指令只会让它在执行时随心所欲最后给你一个漂亮但不可信的结果。3.3 配套脚本与示例代码部分怎么设计SKILL.md负责告诉Agent“怎么做”scripts目录里的脚本负责“把脏活累活干了”。我在设计脚本时有一个原则脚本只做最机械、最不容出错的部分比如数据获取、格式转换至于内容的归纳、提炼这类需要理解力的工作留给Agent自己完成。拿周报技能举个例子我会写一个简单的get_git_log.py负责从Git拉取原始提交记录并输出成JSON然后由Agent读取JSON结合SKILL.md的步骤说明去整理周报。数据归数据判断归判断两者分开出错时定位起来很容易分辨。这里附一段我当时用的脚本核心逻辑做一个参考。import subprocess import json import sys from datetime import datetime def get_commits(author, start_date, end_date): cmd [ git, log, f--author{author}, f--since{start_date}, f--until{end_date}, --prettyformat:%h|||%s|||%ad, --dateshort ] result subprocess.run(cmd, capture_outputTrue, textTrue) if result.returncode ! 0: return {error: result.stderr} commits [] for line in result.stdout.strip().split(\n): if not line.strip(): continue parts line.split(|||) commits.append({ hash: parts[0], message: parts[1], date: parts[2] }) return {commits: commits} if __name__ __main__: # 期望通过命令行参数传入例如 # python get_git_log.py --authorjohndoe --start2025-01-01 --end2025-01-07 args sys.argv[1:] params {} for arg in args: key, value arg.split(, 1) params[key.strip(--)] value # 基础校验 if not all(k in params for k in (author, start, end)): print(json.dumps({error: missing parameters})) sys.exit(1) data get_commits(params[author], params[start], params[end]) print(json.dumps(data, ensure_asciiFalse, indent2))在实际运行过程中这个脚本不一定非得多复杂重要的是Agent可以通过标准输入输出轻松调用并且返回结构是稳定的JSON。稳定的结构化数据能大幅降低Agent出错概率这一点在调试时体会尤其深。3.4 技能测试与迭代不要急着上线技能包写完之后不要急着接进主流程要单独做“体检”。我的做法是准备一份测试集里面包含典型轮次。一份周报技能的测试集至少要有正常场景比如“这周提交了10条记录分布在3个模块”模糊场景比如用户只说“整理一下我的工作”没有给具体时间范围异常场景比如“这个仓库没有我的提交记录”。每个场景我都会运行一遍观察Agent是否能正确识别技能、是否正确加载文件、输出是否符合SKILL.md里定义的格式。迭代过程也有一套顺序第一步先优化description如果Agent根本没法在意图识别阶段选中技能第二步优化SKILL.md如果选中了但照着做依然出错第三步再去改脚本逻辑如果数据本身就获取错了。记住不要在第一步没做好的时候就去改第三步那是浪费时间。4. 框架选型、常见问题与排查技巧4.1 主流Skills方案对比几家的做法可以一起看目前市面上关于Agent Skills的方案不同框架各有自己的实现方式但核心思路大同小异。我把接触过的几种做法做了一个横向对比。方案核心理念优点局限Claude SkillsSKILL.md 目录化技能包通过描述匹配按需加载结构清晰官方文档完善社区范例多依赖特定运行环境迁移需做适配OpenAI Agents SDKSkills把技能拆成instructions与tools组合支持自定义工作流和函数调用生态衔接紧密灵活度高技能包规范性相对弱需要自己建体系自建Skills方案用向量库存技能描述用检索决定加载哪个包可完全定制可跨框架使用前期投入大检索效果需要调优我不太建议一上来就追求“最先进的方案”。如果你是第一次尝试选一个文档全、社区热度高的方案先跑通等理解了这个机制的本质再根据自己的场景做定制也不迟。4.2 高频问题速查与解决思路实际操作中我遇到过不少问题整理几个高频的放在这里方便对照排查。Agent总是选错技能。这一类问题的根源九成出在description写得不够具体。解决思路把description改成“触发条件任务目标输出要求”三段式多写“当...时使用”少写“可以用来”。技能加载了但Agent不按SKILL.md执行。如果Agent读了这个技能但还是“自由发挥”通常是因为SKILL.md里的步骤写得不够“硬”。这里给一个经验把步骤写成祈使句不要写成描述句。比如写“使用git log获取提交记录”不要写“应该先获取一下提交记录”前者的约束力明显更强。脚本执行报错但Agent不会处理。技能包里的脚本要考虑异常情况至少要让Agent知道“返回值里出现error字段时停下来告诉用户不要继续编造”。这个约束放在SKILL.md的注意事项里。技能包越积越多加载越来越慢。这其实是个好问题说明技能库有规模了。解决办法是按业务域拆分技能包每个域只保留当前会用到的一批技能或者在描述阶段靠RAG做预筛降低候选技能数量。4.3 几个我觉得很有用的避坑技巧这个部分算是个人经验说几个我踩过坑之后总结出来的小技巧。第一版本号更新要像对待严肃软件一样对待。技能包一旦改了SKILL.md里的步骤说明一定更新version字段。实测中如果版本不更新运行日志里根本看不出技能内容已经变化排查问题会非常痛苦。第二示例文件要比描述文件更“诱人”。Agent在没有把握的时候会倾向于仿照示例来输出。所以examples目录里的示例质量直接影响最终输出质量。我每次写好一个技能包至少配2到3个覆盖不同情况的示例并且保证示例本身完整、规范因为Agent真的会照着抄。第三把“禁区”写进注意事项。比如“不要编造数据”、“不要调用外部API”这类负向约束很多人在写Skill时只写正向步骤忘了写负向约束。但实测下来负向约束能显著降低Agent的出错率尤其是在面对一个它不太熟悉的边界场景时。第四给技能包写日志。我自己的做法是在执行类脚本里加日志输出记录收集到的数据、中间的判断结果和最终输出。不要小看这一步当技能包在真实业务里出错时有没有日志直接决定了你是花10分钟定位还是花一整天。这算是工程化改造Agent应用必做的一环。5. Agent Skills的边界与后续扩展思路5.1 什么场景不适合用Agent SkillsAgent Skills虽然好用但不是万能的。我做完两三个技能之后慢慢摸到了它的边界。如果任务本身非常简单比如“翻译一句话”“把这段文字转成JSON”不需要额外的领域知识那就直接写在系统Prompt里没必要单独抽成一个技能包先不说是否划算加载一个技能包本身就有时间开销和context开销。如果任务的执行逻辑高度动态、依赖大量实时上下文比如开放式闲聊也不适合用技能包封装。技能包强调的是“可复用、可固化”而开放式对话几乎不可能固化出一套稳定步骤。另一种不太适合的情况是“一次性的复杂任务”。如果一个任务你只会做一次根本不会有第二次复用那花时间把流程写成技能包的回报率就很低。我的建议是先做一遍完整流程如果过程中发现“这个步骤很繁琐下次肯定还会用到”再回头抽成技能也不迟。5.2 从单技能走向多技能协同当技能包数量超过10个之后会进入一个新的阶段多技能协同。简单说就是Agent在完成一个复杂任务时需要连续调用多个技能包。比如用户说“帮我把这周工作整理成周报再做成PPT发给老板”这就是周报生成技能和数据可视化技能的组合。多技能协同首先考验的是意图拆分。Agent要把用户请求拆成“生成周报”和“制作PPT”两个子任务然后依次加载对应的技能包并保持中间数据的流转。这个阶段最直接有效的优化是给相关技能之间建立“引用关系”。比如周报生成技能的SKILL.md里可以在注意事项中写“若用户同时要求制作PPT继续调用ppt-generator技能”。这种显式引用比让Agent自动推理更可靠。5.3 技能库的长期维护与进化技能库做成之后就变成一个需要长期维护的资产。我目前的做法是每个季度做一次全面盘点。盘点清单包括几个方面使用频次过低的技能再确认是否保留输出质量持续偏差的技能需要重新打磨SKILL.md依赖的第三方库有没有更新以及根据业务变化新增一些技能包。这个维护节奏不会占用太多时间但能保证技能库一直在稳定的状态里不会因为时间长了变得又乱又慢。另外技能库里的内容可以有意识沉淀成团队内部的公共资产。新人接手Agent开发时先看一遍技能库结构比看一堆设计文档更直观。我甚至觉得Agent Skills这套目录化、模块化、文档化的组织思路本身就是一份不错的“代码即文档”实践。回到最初说的那个问题Agent开发真正的瓶颈往往不是模型能力不够而是我们给它喂的知识太乱。Agent Skills恰恰提供了一套把知识结构化、工程化的方法。它让我从“一个靠提示词硬撑的助手”进化成了“一个拥有岗位手册和工具箱的员工”。如果你现在也在做Agent相关的东西我觉得可以先从一个小而具体的技能包开始试试管理上会舒服很多。