前几年大家聊AI Agent聊得最多的还是“怎么让模型记住上下文”“怎么把工作流串起来”。模型能力上来之后这些基础问题慢慢有了标准解法新的瓶颈反而转移到了更底层的地方Agent到底会做什么它手里的“手艺”从哪来这就是“agent-skills”这个方向真正让人兴奋的地方。它不像一个大模型那么玄学也不像一个RAG框架那么通用它更像是在给Agent装配“职业技能证书”——你希望它成为数据分析师就给它装SQL技能包你希望它当运维助手就给它配K8s排查工具集。技能的边界就是Agent能力的边界。这篇文章我想从一个实操者的角度聊聊我理解的agent-skills究竟是什么、怎么设计、怎么落地以及我在自己项目里踩过哪些坑。不搬运论文不讲玄虚架构尽量说人话给能直接用的东西。1. 技能到底是什么从“模型知道”到“模型会做”1.1 先厘清一个最容易被混淆的概念很多人第一次看到agent-skills会下意识把它等同于“工具调用”或者“Function Calling”。这个理解不算错但不够。工具调用只是技能的执行层技能本身是一个更完整的封装——它包含触发条件、执行逻辑、参数规则、输出格式、前置条件和后置校验。我打个比方。工具像是你给实习生一把螺丝刀他拿到之后得自己琢磨怎么拧而技能是一套完整的“操作手册训练记录”什么场景用螺丝刀、怎么握、拧几圈、拧完怎么检查、出问题了怎么处理。Agent有了技能不是“能用某个工具”而是“会干某类活”。在agent-skills体系里一个标准技能通常由四部分组成元信息技能名字、描述、版本、作者、适用场景这部分主要用于技能检索和路由让Agent知道“什么时候该调用它”调用合约入参、出参、错误码、超时策略这层是给解析层用的保证Agent按规范调用执行体具体干活的动作序列可以是一段代码、一组Prompt模板、一个脚本、甚至是人工审批流程校验器判断技能执行结果是否有效的规则避免Agent“做了但做错了”还不自知这个四件套缺一不可。我见过不少项目把技能直接定义成一个Python函数Agent能调但什么时候调、调完怎么判断结果对不对全都靠模型“临场发挥”。短期看没问题任务稍微复杂一点就露馅该用技能的时候没用用完之后把错误结果当正确答案接着往下跑。1.2 技能库解决的核心痛点为什么现在大家开始专门做技能库因为经验沉淀变成了瓶颈。同样是让Agent写一份行业分析报告业务专家脑子里那套“先拉数据、再对指标、最后找异常”的方法论是很难通过一两句System Prompt交给模型的。而把这些流程固化成技能的每一步价值就完全不同。技能库的另一个价值是能力隔离。Agent系统跑久了各种工具、提示词、业务逻辑会越摞越多全塞在一个上下文里模型决策质量会明显下降。把技能拆出去让模型只在需要的时候“加载”对应技能就像做菜的时候只拿当前这道菜需要的调料而不是把所有瓶子全摆上桌。我还想强调一点技能不是死的。它需要能在实际使用中不断更新。Agent每次调用技能之后的反馈最好都能沉淀下来用来修正技能本身的缺陷。这就是一个“技能进化”的过程——这个思路做扎实了Agent系统会越跑越顺同一个技能的失败率会持续下降。1.3 什么人需要关注agent-skills如果你正在做下面这几类事情agent-skills这个思路非常值得参考做垂直领域Agent比如客服、运维、数据分析助手需要大量领域专业技能做多Agent协作系统希望不同Agent共享一套成熟的执行能力做Agent平台的要给上层应用提供“技能市场”或“插件机制”或者你只是单纯觉得现在的Agent“不太听话”让其做复杂任务总在关键步骤掉链子这个方向比起调Prompt、调模型参数收益要确定得多。模型能力是底座底座再强没有好用的技能模块Agent也无法真正落地到具体业务里。2. 技能库的整体设计规模、分层与组织方式2.1 技能不是越多越好别把库做成杂货铺我最早做技能库的时候犯过一个特别蠢的错误想穷举所有场景拼命往库里加技能。数据分析来一个、邮件代写来一个、周报生成来一个……最后库里有几十个技能模型反而懵了——检索时经常挑错甚至互相干扰。后来我想明白了一件事技能库的设计目标和推荐系统类似核心是“精准命中”不是“海量覆盖”。多数业务场景真正高频使用的技能其实只有十几个。与其做一百个“能用”的技能不如把二十个核心技能打磨到“好用”。判断技能是否需要入库我一般用三个标准这个任务是不是高频一周用不到一次的任务先不急着做成技能这个任务的执行路径是不是相对固定如果每次处理逻辑都完全不一样说明这个任务还在探索期不适合固化这个任务的失败代价大不大涉及资金、法务、客户沟通类的操作就算频率低也值得做成技能用强校验兜底按这个标准筛过之后技能库规模基本能控制在二三十个以内。这个量级无论是做检索还是维护成本都可控。2.2 分层设计把“知道做什么”和“知道怎么做”分开技能库一旦超过一定规模就需要分层。我常用的分层方式是这样的基础技能层通用能力比如HTTP请求、文件读写、数据库查询、发送邮件。这层不绑定业务哪里都能用领域技能层绑定具体业务领域的复合能力比如“查询订单状态”“生成对账单”“排查服务异常”。这层会调用基础技能但做了业务封装对上层屏蔽细节业务流层多个技能按特定顺序组合成的完整流程比如“处理客户投诉”可能需要调用用户信息查询、历史订单检索、工单创建、话术生成等多个技能这个分层带来的最大好处是复用。换一个业务场景基础技能层完全不用动只需要重新编排领域技能和业务流。我在两个完全不同的项目里都用了这套结构从第一个项目迁移到第二个项目时底层那批技能直接就搬过去用了省了非常大的力气。2.3 技能的组织形态文件、代码库还是数据库技能存储和组织方式我做过三种尝试第一种纯代码库。每个技能是一个Python包优点是灵活缺点是模型调用的入口不统一而且非技术成员没法参与维护。第二种结构化文件YAML/JSON。把技能的元信息、参数、执行体写在一个个文件里统一放在一个目录下。上线速度快、可读性好缺点是技能逻辑复杂时需要外挂脚本文件之间容易产生依赖混乱。第三种数据库存储。技能元数据存表执行体以代码或DSL的形式存字段支持版本管理、权限控制和动态更新。这算是比较成熟的做法但前期的建表、接口设计成本也最高。我个人推荐路径是起步阶段用结构化文件先把核心技能的SOP跑通等技能数量上来或者多人协作了再迁到数据库方案。拿一个配置仓库直接起步不会错。还有一点很多人忽略技能仓库本身要做版本管理。技能和代码一样改出Bug是常态。没有版本记录出了问题想回滚都无从下手。我所有技能定义都放Git仓库里管理每次更新走MR评审这个习惯救了我很多次。3. 核心细节拆解一个技能的前世今生3.1 技能元信息让模型在正确的时候想起你技能能否被正确调用很大程度上取决于元信息写得好不好。这里说的“好”不是文采好而是能被模型准确理解。最容易被忽视的字段是description。很多人写技能描述随便来一句“查询用户订单”结果模型在需要“查用户最近一笔订单的支付状态”时宁可自己胡写SQL也没想起来调用这个技能。为什么因为描述不够精确模型匹配不上。我总结的一个经验是技能的description里要尽量包含触发场景、核心功能和边界约束三要素。举个例子我之前做过一个“轮班助手”技能描述是这样写的name: shift_schedule_helper description: | 当用户询问班次安排、换班申请、排班表调整等排班相关问题时使用。 能够帮助查看当前排班、提交换班请求、统计工时。 注意不处理请假审批请假请走专属审批流程。最后那句“不处理什么”特别关键。模型看到之后就不会在这个技能和请假流程之间反复横跳。技能描述的边界信息和能力信息同样重要这一点是我踩坑才悟出来的。3.2 执行体技能干活的方式选择执行体是一段代码还是一个Prompt模板取决于这个技能的性质。偏向确定性流程的我倾向直接用代码写死逻辑。比如“计算两个日期之间的工作日天数”这类操作逻辑明确、结果可预期没必要让模型生成代码再执行风险大还慢。直接用函数输入输出干干净净。偏向开放式生成的则需要用Prompt模板比如“根据指标数据生成解读报告”。这类任务没有唯一正确输出模板的价值在于给模型一个合理的思考框架让输出的结构相对稳定。还有一种混合形态技能内部先用代码做数据准备再调用Prompt模板做内容生成最后再用代码做格式校验。这种复合技能是我目前最常用的形态也是最能体现“技能”威力的一种。它不再是一个孤立的工具而是一个完整的“岗位能力”。3.3 校验器别让Agent带着错误结果继续跑技能执行完之后怎么判断结果靠不靠谱这个环节非常关键但也是很多技能库设计里最薄弱的一环。最简单的校验是Schema校验检查返回的字段类型、必填项是否齐全。再进一步是规则校验比如查出来的数据是否在合理区间、是否为空、数量级是否正常。更高级的做法是对接业务系统比如是否成功创建了工单、是否完成扣款等可以用业务系统返回的状态码做最终确认。我的经验是校验器不要搞得太重够用就行。工业界有句话叫“宁可错杀不可放行”在Agent场景下如果你不确定结果是否正确应该默认不接受触发重试或交给人工而不是赌一把让它继续跑。尤其是涉及用户资金、隐私、外部系统操作时这个原则不能妥协。4. 实操从零搭一个可用的技能库4.1 最小可用目录结构咱们不看大厂那套复杂的平台设计直接看一个单机单库的最小落地案例。假设我们要给一个客服Agent搭技能库目录结构这样组织就很清晰skills/ ├── base/ │ ├── http_get.yaml │ ├── db_query.yaml │ └── send_email.yaml ├── domain/ │ ├── order_status.yaml │ ├── refund_process.yaml │ └── complaint_handle.yaml ├── workflows/ │ ├── handle_refund.json │ └── escalate_issue.json └── registry.yamlbase目录放基础技能domain目录放领域技能workflows放跨技能的流程编排最外层的registry.yaml是整个技能库的索引——记录每个技能的位置、版本号、启用状态。模型在启动时加载registry需要某个技能时按图索骥去取对应定义。4.2 一个领域技能长什么样拿最常用的“订单状态查询”举例。完整定义大概长这样name: order_status_query version: 1.2.0 description: | 当用户询问订单物流进度、支付状态、发货状态时使用。 支持按订单号查询也支持按用户ID查最近订单。 此技能只用于查询不处理修改订单、退款、投诉。 trigger: keywords: [订单, 物流, 发货, 快递] semantic: 用户询问任何与订单当前状态相关的信息 parameters: - name: order_id type: string required: false description: 订单号格式如ORD20250101XXXX - name: user_id type: string required: false description: 用户ID当未提供订单号时使用 execution: type: code entry: impl/order_status.py run: OrderStatusService.query validation: - type: schema rule: 返回字段包含status、timestamp、detail - type: range rule: status与订单状态枚举匹配 - type: non_empty rule: detail字段不能为空 error_handler: retry: 2 fallback: escalate_issue message: 订单查询失败已转人工处理注意几个细节。trigger这层描述是为了帮模型做“要不要用这个技能”的预判断。execution.type有好几种这里用的是直接调函数的方式简单直接。validation是校验层保证返回数据是符合预期的。error_handler则规定了失败后怎么办——重试两次再不行就走升级流程。这套字段设计不算标准答案但它覆盖了一个技能从触发到执行到校验到兜底的全流程缺一不可。4.3 技能调用链从用户问题到技能执行光有定义还不够还得有运行时机制。技能库落地时至少要打通这么一条调用链用户问题输入 → 意图判断 → 技能检索 → 参数抽取 → 技能执行 → 结果校验 → 输出整合其中“技能检索”和“参数抽取”是技术含量最高的两个环节。技能检索有两条路。轻量级做法是给所有技能建一个向量索引把用户的意图描述和技能的description做相似度匹配选出TopK再做精排。更可控的做法是用规则路由先按关键词、业务线、用户类型等条件做硬过滤再把候选集交给模型选择。我建议先用规则做粗筛——尤其是技能库规模不大时规则路由的准确率远高于纯向量召回还不用维护embedding模型。参数抽取也一样可以纯靠模型抽也可以结合规则。涉及用户ID、订单号这类高价值参数建议用正则、PII脱敏服务先兜一层底模型抽完了再用规则校验一遍两个都通过才继续。4.4 失败兜底技能也不是万能的技能一定会失败。参数不齐、底层服务挂了、模型抽错了参数、校验不通过……失败的原因五花八门。我处理失败时有一条很朴素的策略技能调用失败 ≠ 系统报错它只是当前路径走不通换条路还是有机会完成的。所以我会为每个技能预设一个“备选路径”主技能失败后尝试用更基础的技能组合来替代比如查询复杂报表失败退化成先查明细再本地聚合组合也解决不了就降级为给出部分结果 明确告诉用户“这里查不到完整数据”最后兜底才是转人工这套降级策略让我服务的准确率和用户体验都稳了很多。系统出错不可怕可怕的是没有任何预案。5. 常见问题与排查技巧实战排坑实录5.1 问题模型明明有技能该用的时候就是不用这是最让人抓狂的问题。技能库里摆着现成的能力模型偏要绕一大圈自己想办法最后结果还错了。排查顺序我建议这样先看技能描述是否写得足够精确。很多时候不是模型不想用是它没有意识到“当前任务 某个技能的触发场景”再看意图识别环节。如果上游把用户意图判错了模型根本不会走到技能检索那一步最后看上下文信息。有些Agent会在上下文里塞太多无关内容模型决策被干扰技能检索结果被淹没我自己的排查经验是八成这类问题出在技能描述质量上不是模型问题。把描述里“什么时候用”写清楚这类“调用率过低”的情况能缓解一大半。5.2 问题技能调了但参数抽得一塌糊涂参数抽取是技能执行的入口抽不准后面执行全白搭。比较典型的坑有用户说的是“帮我查一下上周五的订单”模型生成参数时把时间格式写成了2025-01-10但技能要求的是20250110用户说“查我自己最近一笔充值记录”但Agent上下文里根本没有用户标识参数缺失模型把同音字、错别字也原样填进参数导致查询失败我的解法是给参数加“归一化层”。在这一层里把时间、金额、手机号、单号等常见类型统一用规则做格式转换和合法性校验。模型抽完参先过这一层不过就反馈给模型要求重新抽取。这样能在最大程度上避免因为低级格式问题导致的执行失败。5.3 问题多个技能长得很像模型总是选错技能库大了以后难免出现几个技能描述相近的情况。比如“订单查询”和“售后进度查询”从用户视角来看区别没那么明显。解决思路有两个方向。一个是把技能合并。如果两个技能在语义上高度重合、执行逻辑也差不多那它们本来就不该是两个技能合并成一个用参数来区分不同场景。另一个是加路由规则。在技能检索层加一条硬规则比如“只有用户明确提到退货/换货才走售后进度查询否则默认走订单查询”。规则写得越清晰模型越不容易选错。5.4 问题技能执行时间太长用户等得不耐烦技能里如果有同步调外部接口的操作很容易出现几秒到十几秒的等待。这在和用户实时对话的场景里体验是很差的。我常用的优化手段是把技能执行拆成“同步预检查”和“异步任务”两段。预检查只做最快能确认的事情——参数有没有、服务通不通、预估执行时长。确认没问题之后直接给用户一个“好的马上帮您处理”的反馈同时把真正的任务丢到异步任务队列里跑完后再通知用户结果。这个交互设计上的变化相比硬等接口返回体感上好了很多。用户不是不能等而是不能“不知道要等多久”地等。5.5 问题技能用着用着就“不灵了”这里的“不灵”说的不是技术故障而是业务规则变了技能还在按老逻辑执行。比如退款规则更新了原来的技能里还写着老流程Agent照着执行自然就出错。这个问题只能靠“技能治理”来解决。每次业务规则变更都需要同步审视技能库里受影响的技能。我在项目里要求所有技能必须有版本号变更必须发新版本同时维护一个“技能—业务规则”的映射表每次业务规则变更时对照映射表逐一检查技能是否需要更新。这个维护成本看起來是额外负担但如果不做技能库会随着时间推移慢慢腐烂——一个过时技能造成的信任损害远比维护成本更大。6. 一些关于后续的思考技能这个方向往深了发展我觉得至少有两条线值得长期投入。一条是技能共享生态。不同团队、不同公司之间完全可以沉淀一套通用的基础技能——比如HTTP请求、数据库操作、消息推送——然后贡献到共享库里。领域技能可以自己维护但基础技能没必要重复造轮子。技能描述、校验规则、错误处理这些设计模式也值得像开源软件一样互相借鉴。另一条是技能自动生成。把一段操作日志、一份业务SOP自动转化成可复用的技能定义这个方向潜力极大。哪怕现在只能实现“半自动”先把标准化的流程模板变成技能雏形再人工打磨细节效率也比从零手写高很多。技能库的定位其实很像“积木”。单个技能是积木块嵌入在Agent中的技能库是一整套积木玩具。积木块的质量决定能搭多稳但能把它们拼成什么东西还看搭积木的人。我在实际项目里最大的体会就是Agent的能力天花板很大程度上由我们愿意为它沉淀多少“手艺”决定。模型负责聪明而技能系统负责专业。聪明是天赋专业则是积累出来的。希望这篇文章能帮你少走一些弯路在技能库的设计上做出真正适合自己业务的方案。
