过去半年,GitHub上以"agent-skills"命名的仓库数量涨得飞快,各家Agent平台也纷纷上线所谓的"技能市场"。我一开始以为这只是RAG或者提示词工程的又一次换皮,直到自己动手把一套技能库塞进生产环境的Agent里,才意识到它解决的问题跟前面几代方案完全不在一个层次上。这篇东西就当是给想入局的人画一张尽量完整的地图,把我踩过的坑、验证过的做法、以及现在主流skill体系的内部结构一次说清楚。
如果你已经在做LLM Agent相关的工作,或者正在纠结"Agent怎么才能稳定复现一个复杂任务",这篇文章会很对胃口。如果你只是听说过agent-skills这个词,那更建议看完前两章,理解它跟工具调用、微调、RAG的根本区别——这决定了你后面的技术选型会不会跑偏。
1. 为什么"技能库"正在取代提示词模板:Agent Skills要解决的三个核心问题
先给个朴素定义。Agent Skills(智能体技能)指的是把某一类任务的可复用执行能力,封装成一组带元数据、前置条件、执行步骤和验证逻辑的文件,让Agent在运行时按需发现、加载、执行、退出。它不是一个函数,也不是一段prompt,而是一整套"任务执行的最小知识包"。
这套东西爆火,是因为前面几代方案都卡在了同一个地方:长尾任务不可控。
1.1 从"会对话"到"会干活":能力封装方式的演进
早期我们给Agent加能力,靠的是把操作步骤写进system prompt。这种方式对两三步的任务有效,一旦任务变成二十步,prompt就开始失控——模型会在某个中间步骤偏离指令,或者因为上下文挤占而遗忘了后面的步骤。后来大家用function calling把能力切成函数,解决了"动作原子化"的问题,但函数只负责执行单个调用,不负责"如何组织一串调用去完成一个完整目标"。
真正卡住的是两个点。第一,复杂任务的执行路径需要大量情境知识,比如"处理这份财务报表时,如果出现负数余额,要先检查上一期的结转而不是直接报错",这类隐性规则塞不进一个函数签名。第二,这些知识如果用RAG捞出来塞进上下文,你无法控制捞出来的内容是不是恰好覆盖当前任务阶段,经常出现检索命中率高但执行效果差的尴尬情况。
Agent Skills的思路是把"情境知识+操作步骤+验证规则"绑在一起,作为一个整体让Agent按需加载。这等于给模型配了一套标准作业流程手册,而不是让它每次临场发挥。
1.2 Token效率:被遗忘的上下文窗口
很多团队忽略了一个现实:把技能知识全部塞进上下文是不可持续的。一套完整的技能库可能有几百个技能,每个技能的详细文档动辄几千token,全量加载直接撑爆窗口。而且模型在长上下文里对中后段内容的注意力会显著衰减,哪怕没超限,塞得越多,执行质量反而越差。
所以现在主流做法是渐进式披露:先只给Agent每个技能的短描述,让它根据当前目标判断需要哪个技能,再按需加载该技能的完整文件和资源。这就像你进图书馆只需要看书籍索引,而不是把整馆的书全背在身上。token消耗从几百K降到了几K到几十K,成本和质量同时受益。
1.3 可复现性与跨团队复用
还有一个容易被忽视的价值:技能文件本质上是纯文本资产,可以进Git、走Code Review、做版本回滚。这意味着Agent的行为不再是黑盒里的随机涌现,而是变成了一等公民的工程资产。A团队写好一个"销售线索清洗"技能,B团队可以直接复用或者基于它改巴改巴出"客服工单清洗"技能,而不需要重新调prompt、重新试错。
这一点在实际协作里比什么技术优势都重要。我见过太多团队因为"这次Agent表现好但没人知道为什么"导致上线后不敢迭代。技能库把Agent做成可审计、可实验、可回滚的系统之后,迭代节奏才真正快得起来。
2. 拆解一个Skill的最小可用结构:从SKILL.md到验证脚本
弄清楚了为什么要有技能,接下来最实际的问题就是:一个技能文件里到底该放什么?现在社区里已经形成了一套比较成熟的文件约定,虽然各家命名略有出入,但骨架基本一致。我以现在用得最多的SKILL.md为基准讲,你看完任何一家平台的技能包结构,基本都能对上号。
2.1 核心清单:描述、主体与示例
一个最小可用的技能至少包含三个部分:技能描述(写在元数据区)、执行步骤(正文)、以及参考示例(可选但强烈建议)。
技能描述是整个技能包的门面,也是Agent决定"当前这个任务我要不要用这个技能"的唯一依据。写得好的描述会包含:任务触发条件、适用数据形态、不适用场景、以及大致的预期输出。我在下面给一个SKILL.md的真实骨架,你直接照着改就能用:
--- name: sales_leads_deduplication description: 对销售线索表格按公司名+联系人邮箱做去重合并。 仅适用于包含company/email列的CSV或XLSX文件。 若数据源来自API,请先调用export_to_csv技能导出后再执行本技能。 Output: 一个去重后的CSV文件,并生成dedupe_report.md说明合并规则。 --- # 销售线索去重流程 ## 输入要求 - 表头必须包含 company 和 email 字段 - 编码统一为UTF-8 ## 执行步骤 1. 读取文件,用pandas加载并统一列名。 2. 以company为第一匹配键,email为第二匹配键做分组。 3. 同组内保留最早创建的一行,其余行合并进deleted_rows_log。 4. 输出文件到 output/ 目录,写去重报告。 ## 示例 输入: company: Acme Inc, email: ops@acme.com company: Acme Inc, email: ops@acme.com (重复) 输出:保留一行,日志记录操作。注意这个文件里没有多余的东西。我不写"请使用Python"这种废话,因为那不是流程的一部分。每一步都是Agent能直接照做的指令,而且写明了输入边界和输出产物。这套文件养活了很多Agent平台,它之所以有效,是因为它把"判断"压缩到了加载前的一瞬间,把"执行"变成了清单式的跟随。
2.2 PROGRESS.md:状态跟踪为什么必不可少
执行复杂任务时,Agent最需要的是记住"我现在走到哪一步了"。这看起来简单,但实际上是最容易翻车的地方。Agent一旦开始调用外部API或者操作文件,就会产生大量中间状态,如果这些状态没有落盘,Agent的注意力一分散,后面的步骤就全乱套了。
所以我在每个技能包里都会放一个PROGRESS.md,让Agent在执行过程中持续更新当前进度、已完成清单、未决问题。这个文件的妙处在于两件事:第一,它让Agent中途被打断后能恢复执行;第二,它给人类留了检查点——你可以随时打开这个文件看到Agent干到哪了,而不是面对一个黑盒干瞪眼。
2.3 参考资料分层加载:渐进式披露的实操
技能包里经常需要带参考资料,比如政策条文、产品手册、全套模板。这些材料直接塞进SKILL.md会把主流程淹没,我通常的做法是放一个references/目录,在里面放多个独立文档,然后只在SKILL.md的步骤里按需引用。
例如,在"处理退款请求"技能里,我会把不同退款原因对应的处理规则拆成refunds_policy.md、chargeback_manual.md等文件,主文件只写"判断退款原因->读取对应规则文件->执行对应流程"。这样Agent只在走到那一步时才去加载对应文件,完全不浪费token。这就是前面提到的渐进式披露在文件结构层面的落地。
还有一个实际建议:不要在技能里塞超过3层的目录嵌套,否则检索和路径解析都容易出问题,Agent经常会迷路。扁平化一点,宁可多建几个技能,也不要把一个技能搞得过于庞大。
3. 从零搭建一个Agent技能库的完整流程
到这里,原理说得差不多了,直接进入搭建实操。下面这套流程我跑过好几轮,也帮朋友团队搭过,可以负责任地说,按这个顺序做,你大概率一遍过。
3.1 先定边界:一个技能只做一件完整的事
我见过最典型的错误是"没想好边界就开写"。有人把一个技能写成"数据分析",结果里面包含了数据清洗、可视化、生成报告、推送消息四件事,最后Agent执行的时候要么只做了一半,要么把不相干的步骤也做了。
正确的切法是一个技能只做一件完整的、有明确产出物的事。判断标准很简单:你能不能给它写出一条"任务结束"条件?比如"去重完成后输出文件并生成报告",这就结束了。凡是你需要列"如果……就继续做……"的推理分支太多,就说明这个技能应该拆成多个。
3.2 技能的目录组织与命名规范
技能库的物理组织方式直接决定检索效率。我建议的目录结构是这样的:
skills/ sales_leads_deduplication/ SKILL.md PROGRESS.md references/ export_api_guide.md company_merge_rules.md scripts/ dedupe.py verify_output.py tests/ test_sample1.csv refund_handling/ SKILL.md PROGRESS.md references/ refunds_policy.md ...命名规范我坚持用snake_case的动词开头的动宾短语,如extract_invoices、verify_identity,不做层级编号。这样Agent在看到"提取发票信息"这个意图时,检索系统能直接命中。命名长度控制在30个字符以内,太长的名字在日志里看着费劲,也容易被截断。
3.3 技能检索与动态加载的工程实现
搭建技能库不只是一堆文件,你需要一个运行时加载机制。目前主流实现是:把每个技能的SKILL.md的description字段抽出来,建一个技能索引,Agent在任务开始前先检索这个索引,选出技能ID,然后加载对应技能包。
索引可以极其简单,直接用文本相似度匹配就行,不需要一开始就上向量数据库。我自己是先用关键词+embedding双路召回,再对候选技能做重排,第一版用的就是几十行的Python脚本,实测召回准确率在常见任务里已经能到九成以上。只有当技能数超过500个时,我才会考虑引入专门的管理平台。
动态加载的细节里有个容易被忽略的问题:Agent加载了技能之后,执行完要不要主动"退出并释放"?我在代码里写的是执行完直接关闭相关上下文,把PROGRESS.md写回技能库存档,避免下一个任务被上一个任务的残留信息污染。
3.4 版本管理与权限控制
技能文件的迭代频率其实比业务代码还高,因为Agent的执行效果会直接影响技能内容的修改。我强烈建议技能库独立成仓,每个技能的改动走MR。文件里最好带上版本号和行为风格变更记录,这样出了问题能直接回滚到上一个可用版本。
权限上需要分两层看:技能的读取和执行权限不一定要一致。有些技能可以被所有Agent检索到,但只有特定角色能执行,比如"删除生产环境数据"这类技能默认只允许管理员权限的Agent调用。这个权限模型跟工具调用的RBAC是同一套思路,别偷懒省略,否则后方出事的时候你想追责都追不到。
还有一个插曲:技能包内如果带scripts脚本,执行环境要固定。我遇到过线上Python版本不一致,导致某个技能里的脚本跑挂的情况。后来统一用Docker镜像承载技能运行环境,问题彻底解决。这个经验可以省你不少排障时间。
4. 技能质量的度量:SKILL-Bench评估思路与离线验证
技能写完不是终点,你怎么知道它真的让Agent变强了?不能靠"看着感觉好多了"。这块社区现在拿SKILL-Bench这类基准测试做标准化验证,思路非常实用,可以迁移到任何技能上。
4.1 评估维度的选择
SKILL-Bench的核心思路是围绕"技能提升"程度来衡量:拿同一个基座模型,分别跑"不加载技能"和"加载技能"两种模式,在同一批任务上对比几个指标。我实际用的指标有四个:
- 任务完成率:Agent正确走完流程并产出预期产物的比例。
- 步骤遵循度:按PROGRESS.md记录的步骤核对,看Agent有没有跳过、乱序或额外插入步骤。
- 输入多样性鲁棒性:把同一技能的输入数据做成多个变体(如DA类型表、金额列用不同格式),看技能是否还能稳定执行。
- 平均token消耗:加载技能前后所有阶段的token用量对比,确保技能带来的不是单纯靠堆上下文获得的效果。
这四个维度落地之后,我会把每个技能做成一张评分卡,低于及格线的技能不允许合入主干。
4.2 离线仿真环境搭建
评估Agent技能最忌讳的是直接上生产环境试错,所以我强烈建议搭一个离线仿真层。这个仿真层其实不复杂:把技能会接触到的外部依赖(API、数据库、文件系统)全部替换成mock版本,把真实业务数据脱敏后制作一套固定样本集。
我搭建的测试台就是一个Docker容器,内部预装了mock_server、样本CSV库和结果校验脚本。跑评估的时候,让Agent在容器里加载技能并处理样本,跑完自动比对输出文件。整个过程可以全部脚本化,CI里每天定时跑一遍,技能库有任何改动都能立刻发现问题。我见过太多团队跳过这一步,结果技能上线第一天就把生产库的字段写错了,教训相当惨痛。
4.3 回归测试与持续集成
因为技能库是文本资产,天然适合进CI。我在技能仓库里挂了两个流水线:一个是PR时跑的快速冒烟测试,挑每个技能的代表性样本各跑一次,确保主路径通;另一个是每日凌晨跑的完整回归,跑全量样本和指标对比,生成趋势报告。趋势报告特别有用,你会发现某些技能随着基座模型升级,完成率会突然下降——这不是你的代码坏了,而是模型行为变了,需要更新技能描述来适配。
这里有个经验之谈:技能内容超过三个月不碰,基本可以判定它在腐烂。不是因为代码过期,而是你的业务也在变。定一个维护节奏,比如每周五下午轮流review两个技能,让技能库保持"活着"的状态,比写更多新技能重要得多。
5. 实际踩坑记录:Agent技能落地时的五个典型问题
最后这部分全是实战里淌出来的坑,每个我都交过学费。你要是在实施过程中遇到类似症状,可以直接对着排查。
5.1 技能过载,决策时间暴涨
技能库一开始只有5个技能,一切顺滑。等我加到50个技能时,发现Agent决策变慢了很多,因为它在每次任务前都会对全部技能做检索和排序,检索结果里的干扰项一多,模型要花额外的精力做排除。
这个问题的解法有两层:第一,把每个技能描述写得像路标一样明确,尤其是"不适用场景"一定要写进负面描述,比如"本技能不适用于PDF格式",让检索阶段直接过滤掉;第二,把技能做分组索引,按业务域划分,Agent先定位业务域,再在组内检索,把单次检索的候选范围从全库缩小到十几个。我现在线上一个Agent挂了80多个技能,决策延迟和5个技能时基本持平。
5.2 描述文本与执行内容脱节
这是最隐蔽也最贵的坑。有时候你更新了SKILL.md里的执行步骤,但description里的行为描述忘了同步更新,结果Agent按照旧描述检索命中了技能,加载进来却发现步骤不对,白白浪费一轮调用。
解决手段是强制建立一致性检查:在CI里加一个diff脚本,检测description中的关键词与正文步骤中的高亮产物名是否匹配,不匹配就拦下PR。另一个办法是让技能包自带自检脚本,加载后先跑一个前置校验,校验不通过直接向Agent报"技能已过期,请使用同类技能",宁可快速失败也不要硬着头皮往下做。
5.3 技能间的依赖与混淆
技能设计得不够正交时,Agent会遇到"两个技能看起来都能干这件事"的纠结。比如"导出数据"和"数据备份"在行为上有重叠,Agent选错了,输出的文件和日志格式都会对不上下游技能。
我的做法是在设计阶段画一张技能依赖关系表(不需要画图,写表格就够了),明确每个技能的前置技能和后续技能,并把前置逻辑写进description。例如在"导出数据"的description里直接注明"如需导出后做备份,应调用backup_to_oss技能",让Agent拿到正确的调用链条。依赖关系表要随技能库一起review,不能只写一次就再也不管。
5.4 安全与数据访问边界
技能执行时通常需要访问文件、数据库、第三方API,这里的安全边界比单一工具调用复杂得多。你写的技能是按照"正常输入"设计的,但Agent的输入是不可控的,恶意或异常的输入可能在技能执行里被放大。
我现在的安全基线是:技能内所有涉及写外部系统的操作,必须经过一层独立于技能逻辑的鉴权服务;凡是删除、修改、批量发送类操作,默认要求二次确认。另外,技能读取的数据如果是敏感字段,技能包内不允许明文记录字段映射,必须走变量注入。这套基线看起来增加了一点工作量,但Agent事故里最贵的就是数据操作事故,省什么都别省这块。
5.5 维护成本失控:技能坟场
最后一个坑是技能越写越多,很多技能上线三个月后连作者自己都想不起来它是干什么的。团队里如果有人离职,他维护的那几个技能就彻底变成僵尸技能,检索系统还会不停把它们送进候选列表。
我现在的维护策略是每季度做一次技能体检:按调用次数和评估通过率排序,三个月调用次数为零的技能标记为deprecated;评估通过率长期低于阈值的技能限期整改,整改不了就下架。别舍不得,技能作为工程资产,跟代码一样需要治理,不然你早晚会被自己写的技能库拖垮。
我个人现在最深刻的体会是,Agent技能本质上就是数字化版本的标准作业流程,它的战斗力来自"极简的接口描述+严格的执行流程+可控的动态加载",而不是内容越多越好。如果你正准备踏上这条船,建议从三五个真正高频、流程清晰的任务开刀,跑通评估闭环之后再逐步扩库。等你哪天发现新同事接手你的技能库居然不用过来问你细节的时候,这套设计就算是成了。