1. 从“会聊天”到“能干活”agent-skills 到底在解决什么问题大模型刚火起来那阵子大家最兴奋的是“它能陪我聊天”。但真把它丢进业务里问题马上就来了你问它“帮我处理一下这个月的报销单”它能给你洋洋洒洒写一篇报销流程说明却没法真的打开表格、核对金额、填好字段、发出去。这就是典型的“会说不会做”。agent-skills这个项目本质上就是在补这块短板。它要解决的核心问题只有一个让智能体Agent从“对话工具”变成“能执行任务的执行体”。所谓 skills你可以理解成给智能体装上的“技能包”——每一个 skill 就是一套封装好的能力包含触发条件、执行逻辑、依赖工具和输出规范。智能体不再靠一句句提示词去猜该干什么而是根据任务自动匹配并调用对应的 skill。这套东西适合谁三类人最该关注。第一类是应用开发者你手里有业务系统想让 AI 真正接进去干活而不是只做个问答窗口第二类是自动化流程设计者你已经在用各种脚本和工具串联工作流现在想让大模型来做“调度大脑”第三类是产品与运营同学你不写底层代码但需要理解智能体能力的边界才能设计出靠谱的 AI 功能。我接触过不少团队一上来就想搞“全能智能体”结果做出来的东西什么都能聊、什么都干不成。agent-skills的思路恰恰相反先把能力拆成一个个可复用、可测试、可组合的技能单元再让智能体去编排它们。这个思路听起来朴素但它是目前让 AI 真正落地干活的少数靠谱路径之一。下面我就把这套东西从设计思路到实操细节一层层拆开讲。2. 整体设计思路为什么是“技能”而不是“提示词”2.1 提示词工程的三个死穴先说清楚为什么不能只靠提示词。很多人做智能体第一反应是写一个超长的系统提示词把能想到的规则全塞进去。我早期也这么干过踩了三个坑。第一个坑是上下文膨胀。你每加一个能力提示词就长一截。加到十几个能力之后光系统提示就几千字模型注意力被稀释原本会做的事也开始出错。这就像给一个员工塞了一本越来越厚的操作手册翻到后面他早忘了前面。第二个坑是能力冲突。提示词里写“遇到 A 情况做 X遇到 B 情况做 Y”但现实任务往往是 A 和 B 混在一起。模型在长提示词里做判断边界模糊经常选错分支。你还没法调试因为提示词是个黑盒。第三个坑是无法测试。提示词改一个字整体行为可能全变。你想单独验证“处理报销单”这个能力做不到因为它和别的规则纠缠在一起。工程上没法做单元测试就没法保证质量。2.2 技能化拆解的核心逻辑agent-skills的设计逻辑用一句话概括把“怎么做”从提示词里抽出来变成独立的、有明确输入输出的技能模块。具体来说一个 skill 通常包含四个部分。元信息描述这个技能叫什么、干什么用、什么时候该触发输入规范定义它需要哪些参数格式是什么执行逻辑是真正干活的部分可以调用外部工具、API、脚本输出规范定义它返回什么成功和失败分别怎么表示。这样拆的好处非常直接。技能之间互不干扰你可以单独开发、单独测试、单独替换。智能体面对任务时先做的是“技能匹配”——判断这个任务该用哪个或哪几个技能而不是在一大段文字里找规则。匹配这件事本身可以交给模型也可以交给规则引擎甚至可以混合。提示技能粒度是这套方案成败的关键。太粗一个技能干太多事又回到提示词老路太细技能数量爆炸匹配成本飙升。我的经验是一个技能对应“一个可独立完成的动作”比如“查询订单状态”“生成对账单”“发送通知”而不是“处理订单”这种大而全的。2.3 与常见方案的本质区别市面上做智能体的方案大致三类。一类是纯提示词编排靠模型自己规划一类是硬编码工作流用代码把步骤写死agent-skills属于第三类技能库加动态编排。纯提示词方案灵活但不可控硬编码方案可控但不灵活。技能库方案取中间技能本身是确定性的、可测试的编排层是灵活的、由模型驱动的。这就好比一家餐厅菜谱技能是固定的、标准化的但今天客人点什么、按什么顺序上菜编排是动态决定的。这个区别在真实业务里非常关键。比如一个客服智能体用户说“我上周买的那个东西还没到帮我看看顺便把地址改一下”。这句话里其实有两个任务查物流、改地址。纯提示词方案容易漏掉一个硬编码方案处理不了这种自由组合而技能库方案可以匹配到“查询物流”和“修改地址”两个技能依次执行。3. 核心细节解析一个技能到底长什么样3.1 技能描述文件的结构技能描述文件是整个体系的基石。它通常是一个结构化文件比如 JSON 或 YAML。我拿一个“查询物流”的技能举例把关键字段拆开讲。name: query_logistics description: 根据订单号查询当前物流状态和预计送达时间 trigger: keywords: [物流, 快递, 到哪了, 什么时候到, 发货] intent: 查询配送进度 input: order_id: type: string required: true description: 订单编号 output: status: type: string enum: [已发货, 运输中, 已签收, 异常] estimated_arrival: type: string format: date tracking_events: type: array handler: type: http method: GET endpoint: /api/logistics/{order_id}这里每个字段都有讲究。trigger里的关键词和意图是给匹配层用的。关键词是快速召回意图是精确判断。两者结合能大幅降低误触发。input里明确标了required这样智能体在调用前就知道缺参数要追问用户而不是硬着头皮调用然后报错。output里的enum和format是给下游用的。如果输出状态只有这四种编排层就能针对不同状态走不同分支比如“异常”状态自动触发人工介入技能。这种强类型约束是技能可靠性的保障。3.2 触发匹配的两种策略技能怎么被选中是核心环节。我实测下来关键词召回加语义匹配的两段式最稳。第一段用关键词做粗筛。用户输入里出现“物流”“快递”这类词就把query_logistics放进候选集。这一步快成本低能过滤掉大部分无关技能。第二段用语义相似度做精排。把用户意图和候选技能的description做向量比对选相似度最高的。如果最高分低于阈值就不触发任何技能转而走兜底回复。为什么不直接上语义匹配因为技能多了以后向量检索有误召回。比如“我要退货”和“我要查物流”语义上都有“订单相关”的味道纯语义容易混。加上关键词这一层准确率明显提升。注意关键词表要定期维护。用户表达方式会变新词、缩写、错别字层出不穷。我一般会记录所有未匹配成功的输入每周复盘一次把高频新词补进关键词表。这个习惯能让匹配率持续爬升。3.3 参数提取与追问机制技能匹配上了不代表参数齐全。用户说“帮我查下物流”没给订单号。这时候不能直接调用得追问。参数提取我推荐模型抽取加规则校验的组合。先用模型从对话历史里抽order_id抽到了就校验格式比如是不是纯数字、长度对不对。校验不过或者没抽到就触发追问。追问话术也要设计好不能干巴巴问“请提供订单号”而是“为了帮您查询物流麻烦提供一下订单编号一般在订单详情页可以看到”。这里有个容易忽略的点追问要有次数上限。我见过有的智能体陷入死循环用户答非所问它就一直追问同一个参数。正确做法是设一个上限比如追问两次还没拿到就转人工或结束当前技能避免体验崩坏。3.4 执行层的隔离与超时技能执行必须做隔离。每个技能调用外部服务时都要有独立的超时和重试策略。查询类技能超时可以短一点比如 3 秒写入类技能要谨慎重试避免重复下单这种事故。我踩过的一个坑是某个技能调用的接口偶发慢拖垮了整个对话响应。后来给每个技能加了超时熔断慢接口直接返回“暂时查询不到请稍后再试”用户体验反而更稳定。技能之间不能互相拖累这是执行层设计的第一原则。4. 实操过程从零搭一个可用的技能体系4.1 环境与依赖准备动手之前先把基础环境理清楚。这套体系通常需要三块东西一个技能注册中心用来存放和管理所有技能描述一个编排引擎负责匹配、参数提取、调用和结果处理一个执行沙箱让技能的实际操作在受控环境里跑。注册中心用文件系统起步完全够用一个目录放所有 YAML 文件启动时加载进内存。编排引擎可以自己写也可以用现成的智能体框架。执行沙箱这块如果技能只是调 HTTP 接口那不需要额外隔离如果技能要跑本地脚本建议用容器或子进程隔离防止一个技能把主进程搞崩。依赖方面向量检索需要一个嵌入模型本地跑一个小模型就够不必上大模型。HTTP 调用用标准库即可。整体依赖很轻一台普通开发机就能跑起来。4.2 定义第一批技能新手最容易犯的错是一上来定义几十个技能。我的建议是从三个技能起步覆盖“查、改、通知”三类动作。比如查订单、改地址、发通知。这三个技能能把主流程跑通也能暴露大部分设计问题。定义技能时description要写得像给同事交代任务一样清楚。不要写“处理订单相关操作”要写“根据订单号查询订单的当前状态包括是否发货、物流进度和预计送达时间”。描述越具体语义匹配越准。输入参数尽量用基础类型字符串、数字、布尔值。复杂结构能拆就拆。输出也一样能用枚举就别用自由文本。这些约束看起来麻烦但能省掉后面大量的调试时间。4.3 编排引擎的核心流程编排引擎跑起来是这样一个循环。收到用户输入后先做技能匹配得到候选技能列表。如果列表为空走兜底回复。如果有候选取最匹配的那个进入参数检查。参数齐全就执行不齐全就追问。执行完拿到结果判断是成功还是失败成功就组织语言回复用户失败就根据错误类型决定是重试、换技能还是报错。这个循环里状态管理是难点。多轮对话中当前在哪个技能、已经收集了哪些参数、上一步结果是什么都要记清楚。我一般用一个会话状态对象来存每轮更新。状态对象要能序列化方便持久化和恢复。session_state { current_skill: query_logistics, collected_params: {order_id: 123456}, missing_params: [], last_result: None, retry_count: 0 }这个结构简单但够用。retry_count用来控制重试和追问次数防止死循环。4.4 联调与验证技能体系搭好后别急着接真实用户。先做离线验证。准备一批测试用例每条包含用户输入和期望触发的技能。跑一遍看匹配准确率。低于 90% 就回去调关键词和描述。然后做端到端验证。模拟完整对话从用户提问到技能执行到回复走通全流程。重点看参数提取准不准、追问话术自不自然、异常处理到不到位。这一步能发现很多单测发现不了的问题。最后做压力验证。并发跑几十路对话看编排引擎会不会串状态、执行沙箱会不会资源耗尽。我遇到过并发下会话状态互相覆盖的问题排查了半天最后发现是状态对象用了全局变量。这种坑只有压测才能暴露。5. 常见问题与排查技巧实录5.1 技能匹配不准怎么办匹配不准通常有三种表现。该触发没触发多半是关键词覆盖不够或者描述写得太抽象。不该触发乱触发多半是关键词太宽泛比如“订单”这个词几乎所有订单相关技能都命中。触发错了技能多半是两个技能描述太像语义区分度不够。排查时先把失败案例收集起来按这三种分类。关键词问题就补词或收窄词描述问题就重写突出技能之间的差异点。我一般会在描述里加一句“本技能不处理 XXXX 请用另一个技能”这种负向说明对区分度帮助很大。5.2 参数提取总出错参数提取出错先看是抽不到还是抽错了。抽不到可能是用户表达太口语化模型没理解。这时候可以在技能里加几个参数别名比如order_id同时接受“订单号”“单号”“编号”。抽错了多半是上下文里有多个相似值模型选错。解决办法是在追问时明确格式减少歧义。还有一个隐蔽问题多轮对话中参数被覆盖。用户第一轮给了订单号第二轮说了别的话模型可能把订单号冲掉了。这就要靠会话状态来兜底已收集的参数除非用户明确修改否则不清空。5.3 技能执行超时或失败执行失败分两类。可重试的比如网络抖动、服务临时不可用这类可以自动重试一到两次。不可重试的比如参数错误、权限不足重试也没用直接报错并给出解决建议。超时处理要区分技能类型。查询类超时可以短快速失败写入类超时要长一点但必须有上限避免用户干等。我一般给查询类设 3 秒写入类设 10 秒。超过就中断返回友好提示。下面这张表是我整理的常见问题速查可以直接拿去对照排查。问题现象可能原因排查方向解决建议技能不触发关键词缺失检查用户输入与关键词表补充同义词、口语表达技能误触发关键词过宽检查关键词是否太通用收窄关键词增加意图校验参数抽不到表达太口语查看对话历史增加参数别名优化追问参数抽错上下文歧义检查是否有多个候选值追问时明确格式要求执行超时下游服务慢查看接口响应时间设置超时熔断降级返回状态串扰并发共享状态检查状态对象作用域改为会话级独立状态5.4 独家避坑经验说几个文档里不会写、但实际一定会遇到的坑。第一个坑技能描述里的示例会误导匹配。很多人喜欢在描述里加“例如用户说……”本意是帮助理解结果模型把示例当成了触发条件用户说别的话反而不触发。我的做法是示例只放在文档里不放进技能描述。第二个坑追问话术太机械。默认的“请提供参数 X”听起来像机器人。我一般会为每个必填参数写一句自然的话术放在技能定义里。这样追问时直接取用体验好很多。第三个坑技能版本管理缺失。技能改了线上还在跑旧版新旧行为不一致。后来我给每个技能加了版本号注册中心支持多版本共存编排时指定版本。改技能先发新版本灰度验证后再切流量。第四个坑忽略空结果。技能执行成功但返回空比如查物流查不到记录。这种情况不能当成功处理要单独定义“空结果”状态走不同的回复逻辑。否则用户会收到一条莫名其妙的空消息。6. 技能体系的扩展与长期维护6.1 技能组合与嵌套单个技能跑通后自然会想组合。比如“退货”这个任务其实包含“查订单”“判断是否可退”“生成退货单”“发通知”四个技能。组合方式有两种串行编排和技能内嵌套。串行编排由编排引擎按顺序调用适合步骤清晰、每步都要和用户交互的场景。技能内嵌套是把子技能封装进一个父技能对外只暴露一个入口适合步骤固定、不需要中途交互的场景。我一般优先用串行编排因为它更透明出问题好定位。6.2 技能质量监控技能上线不是终点。要持续监控几个指标触发率看哪些技能从没被触发过可能是描述有问题成功率看哪些技能经常失败可能是下游不稳定追问率看哪些技能总在追问参数可能是参数设计不合理用户满意度看技能执行后的反馈。这些指标我一般做成一个简单看板每周过一遍。发现异常就深入排查。技能体系是个活的东西不维护就会慢慢腐烂。6.3 从技能到能力平台技能攒到几十个之后就该考虑平台化了。核心是两件事技能市场和权限体系。技能市场让不同团队能共享技能避免重复造轮子。权限体系控制谁能用哪些技能尤其是写入类技能必须严格管控。平台化之后技能的开发、测试、发布、下线就有了标准流程。新技能先进测试环境跑通验证用例再灰度发布观察指标正常后全量。这套流程和普通软件发布没本质区别只是对象从代码变成了技能。我个人在实际操作中的体会是agent-skills这套东西最大的价值不在于技术多先进而在于它把“让 AI 干活”这件事从玄学变成了工程。你不再需要祈祷提示词生效而是可以像搭积木一样一块块把能力拼起来每块都能测、能换、能复用。刚开始搭的时候会觉得麻烦但技能数量上去之后这种结构化的优势会越来越明显。最后分享一个小技巧每次新增技能先问自己“这个技能能不能被单独测试”如果答案是否定的说明粒度还是太粗继续拆。