从“会聊天”到“会办事”Agent Skills 才是智能体的分水岭做 Agent 开发这几年我最大的感触是模型本身的聪明程度确实重要但真正让一个智能体从“什么都懂一点”变成“能把事办成”的往往是它手里的那套技能——也就是标题里这个“agent-skills”。你可能也遇到过这种情况同一个大模型有人用它搭出来的助手只会陪聊有人却能做出一套能查库存、改订单、写周报的多面手。差别在哪就在技能体系的设计和积累上。Agent Skills 不是某个工具的新名词而是一套让智能体具备“可复用、可编排、可成长”能力的方法论。这篇文章不聊那些虚的概念我直接用自己实操过的分层设计、技能注册、编排调度和评估迭代经验把它拆开讲清楚。无论你是在做个人效率助手还是企业级智能体平台这套思路都能直接落地。1. Agent Skills 的本质先搞清楚技能在智能体里扮演什么角色1.1 从一次对话说起技能是怎么参与工作的先看一个最简单的场景。用户对智能体说“帮我把这周五的项目周报整理出来顺便提醒团队三位同学。”这个请求看起来不复杂但背后至少涉及三类能力一是理解文档内容、提炼要点的文本处理能力二是根据人选查找通讯录、发送消息的对接能力三是维护一个待办清单、在周五触发的调度能力。如果智能体只是把这段话丢给大模型去“自由发挥”结果大概率是周报格式漂移、提醒对象搞错、时间节点丢失。有了技能体系之后就不一样了。智能体会先把用户请求拆解成“写周报”“查通讯录”“建提醒”三个子任务然后分别匹配到对应的技能模块。每个技能模块像一个封装好的函数输入“原始会议记录和本周数据”输出“一份格式规范的周报”输入“人名”输出“通讯录中的联系方式和 IM 地址”。大模型在这里扮演的是“调度员翻译官”而不是“每一行代码都要自己写的苦力”。换句话说Agent Skills 的本质是把智能体需要具备的专业能力从模型参数中剥离出来放进一个可维护、可复用、可独立更新的能力层。这个能力层既可以承载确定性逻辑查数据库、算金额也可以承载模型自身的推理能力总结、分类、生成还可以关联外部工具链发消息、调接口、跑脚本。1.2 技能、工具、提示词三者的区别和关联很多刚开始接触技能体系的同学会把 Agent Skills 和“提示词”或者“工具调用”混为一谈。我自己的理解是这样的。提示词是“怎么引导模型说话”的模板它是静态的每一次调用都需要重新组织上下文工具是一段独立的 API 或脚本它是确定性的输入和输出都很严格而技能介于两者之间是一个“完整的工作单元”它包含触发条件、输入参数、执行逻辑、输出格式、异常兜底甚至还可以包含一小段专门针对这个任务的提示词。你可以在一个工具上面套一层技能。比如“查询天气”是一个工具但“为出行计划提供天气建议”是一个技能——它不仅要查天气还要结合出行时间、目的地的场景做整合。你也可以在一个技能里面编排多个工具。比如“生成项目周报”这个技能可能要调用“读取周会议记录”“读取代码提交统计”“调用大模型生成摘要”“格式化输出”四个工具。所以我的经验是提示词是技能的一部分工具是技能的一种底层资源而技能是对两者以及更多元素的有机组合。想明白了这一层你设计技能体系时才不会跑偏。1.3 技能类型全景原子技能、组合技能、软技能把技能按功能边界分个类开发和维护的心态都会清楚很多。原子技能是最小可执行单元通常对应单个工具或单个逻辑块。比如“获取文件元数据”“发送钉钉消息”“计算两个日期之差”。这类技能的特点是职责单一、测试容易、几乎不需要大模型参与推理。组合技能则是在原子技能之上编排出来的、有明确流程的能力。比如“处理客户退款”它可能要依次调用“核对订单状态”“计算可退金额”“执行退款接口”“发送通知”。组合技能可以有自己的状态机也允许在中途根据结果分支跳转。还有一类容易被忽视的是“软技能”。它不直接对接工具而是承载一种思考方式或表达规范。比如“会议纪要写作风格”“代码风格审查”“安全合规检查”。这类技能的核心是一段高质量的提示词和一系列规则约束。看起来不硬核但在实际产品中软技能往往决定了用户体验的专业度。我一般建议二八原则体系里百分之八十是原子技能百分之十五是组合技能百分之五是软技能。比例失衡的时候要么系统散成一地碎片要么变成了一个大而笨重的“超级提示词”这两种状态维护起来都痛苦。2. 技能体系怎么设计分层、粒度与注册机制2.1 三层技能栈通用层、业务层、专用层设计技能体系的第一步不是急着写技能而是先把目录结构定下来。我习惯把技能仓库分成三个层级。通用层放的是与具体业务无关的能力比如“基地语言翻译”“长文本摘要”“表格转 Markdown”“意图识别”。这一层可以在不同项目里直接复用相当于自己攒的基础工具库。业务层服务于特定领域但相对稳定。比如做客服智能体业务层会有“订单查询”“物流轨迹解析”“售后工单创建”做内容创作助手业务层则有“选题推荐”“文章结构化”“多平台适配改写”。专用层是面向具体场景和活动定制的往往需要频繁调整。比如“某次营销活动的用户反馈分类”“某版本更新后的 Bug 报告摘要”。这些技能生命周期短、变化快建议和长期技能做隔离这样你在更新时不会影响主链路。我踩过一个大坑一开始图省事把所有技能堆在一个命名空间里后来技能数量超过一百个的时候检索和更新都变得非常痛苦。强制分层之后哪怕技能数量再多定位一个技能只需要“层名业务域动作”三段式路径效率提升非常明显。2.2 技能颗粒度的取舍太粗还是太细技能设计中最难拿捏的往往是粒度问题。技能太粗比如把一个“全自动报告生成器”做成一个技能输入几十个参数、输出几十种格式表面上很省事实际上一旦报错或者需要修改整个人都会陷进去。而且这种粗粒度技能对模型来很难被准确触发你根本说不清楚它到底能干什么边际案例一多模型选择技能的正确率会断崖式下降。技能太细也有问题。比如把“计算两个日期之差”拆成“计算天数之差”“计算小时之差”“计算工作日之差”三个技能看似职责清晰实际上调用链变长、匹配次数变多每次都要多做一遍技能选择的推理既慢又容易错。我常用的判断标准很简单如果这个技能的描述可以在 20 个字以内说清楚它“什么时候被调用、输入是什么、输出是什么”那它的粒度基本合适。另外还有一个经验如果两个技能经常被同一个请求同时触发那就考虑把它们合并成一个组合技能如果某个技能内部的步骤经常被单独替换那就考虑把它拆开。技能不是越多越好而是“该拆的拆、该合的合”。2.3 技能描述与注册让智能体“看见”技能这里必须单独提一下技能描述的重要性。很多技能没被正确触发不是模型不行而是描述写得太抽象了。我之前接手过一个项目里面有个技能描述写的是“处理数据问题”。结果这个技能要么被错误地用于一切与数据沾边的任务要么被模型完全忽略。后来我改成“当用户提出 Excel 表格中存在重复行、空值、格式错误等问题需要清洗和标准化数据集时执行此技能”命中率立刻上来了。写技能描述的原则我总结为一句话写触发场景不写能力概述。你要告诉模型“什么情况下用”而不是“这个技能有多厉害”。另外技能的输入参数说明也要具体最好带上示例值。比如“format: 可选参数支持 md、html、txt默认 md”这比“输出格式”四个字好用得多。注册机制方面凡是需要被模型动态选择的技能都应该有一个统一的路由表。每次新增技能时先登记再上线不要把技能散落在各种配置文件和代码库里。我已经养成习惯技能仓库里维护一个索引文件每个技能有自己的 ID、名称、描述、入参、出参、权限标记和版本号。这一步看起来繁琐但它保证了后续的评估和排障有据可依。3. 技能编排与调用链路的实操从一个真实场景说起3.1 技能调用格式与参数设计确定了技能清单之后下一步就是把技能的接口设计出来。我采用的是类似 JSON-RPC 的风格每个技能一个skill_id调用时传入一个参数对象返回一个标准结构的结果。{ skill_id: weekly_report.generate, params: { project: 某跨平台系统, week_start: 2025-05-12, week_end: 2025-05-16, include: [会议记录, 代码提交, 风险项] }, trace_id: req_8f3a2b... }返回也好统一包一层业务逻辑层永远不去猜“这个技能到底返回了啥”{ status: success, data: { report: ......, sections: [summary, progress, risk] }, meta: { duration_ms: 820, model_calls: 3 } }参数设计上我有一条铁律能传结构化的就不要传自然语言。比如你要让技能“按日期过滤记录”直接传{start_date: ..., end_date: ...}而不要传一句“把最近五天到昨天的数据弄出来”。结构化参数既方便缓存和校验也便于将来做并行调度和重放测试。技能的幂等性也值得提前考虑。凡是会改数据的技能比如发消息、写文件、创建工单我都在参数里加一个idempotency_key避免重试的时候产生重复操作。这个设计可能在原型阶段看不出来但一旦接入真实业务几乎一定会用得上。3.2 多技能协同一个完整的编排样例看一个具体的编排例子。假设我们正在做一个“客户周报自动生成”的智能体收到的原始请求是这样的“本周华北区客户的活跃度有明显下降帮我整理一份包含使用趋势、可能原因和建议动作的周报发给项目经理。”这个请求会被拆成这样的技能调用链第一步调用profile.customer_filters技能把“华北区客户”解析成具体的客户列表第二步调用metrics.usage_trend查询这些客户近四周的登录次数、模块使用时长等指标第三步调用analytics.change_detector识别活跃度下降最明显的客户子集和时间拐点第四步调用insight.reason_candidate让大模型基于数据给出可能的下降原因第五步调用report.finalize把以上结果整合成符合内部模板的周报最后一步调用message.im_notify把报告发送给项目经理。这个链路里前三步偏确定性执行第四步需要大模型推理第五步又回到模板化输出。技能编排的核心就在这把确定性和非确定性穿插组合而不是让模型一步到位地“记起”所有数据。模型不擅长精确计算但它很擅长在你准备好的分析材料上做归纳。编排时的错误处理策略也要提前定好。我的经验是组合技能里每一个子步骤都要有超时上限并且在超时后走“降级路径”。比如analytics.change_detector失败了可以降级为用metrics.usage_trend的原始数据加insight.reason_candidate的粗略分析顶上保证最终的报告仍然能产出只是精度可能低一些。3.3 技能回调与结果校验技能执行完之后不要急着把它当成“不可质疑的真理”。尤其涉及真实业务数据的场景校验是必须的。我在每个组合技能的末尾都会接一个validator子技能它的工作分三层一是检查完整性确认返回结果中的关键字段是否存在二是检查一致性比如周报里的数据是否和源查询结果一致有没有出现凭空多出来的指标三是检查可读性比如日期格式、数量单位、专有名词是否统一。这个验证步骤看似多花一次模型调用实际上能帮你省掉大量返工。我经历过一次线上事故生成的周报里把“下降 12%”写成了“上升 12%”底层数据是对的但模型在生成叙述时把正负号给反转了。从那以后涉及到关键指标的技能返回我都会强制加一轮“数据叙述对照”校验。宁可慢几百毫秒也不能带错发布。提示校验技能不要用生产环境的真实数据跑随机测试最好建立一个独立的“黄金数据集”里面包含几十条典型历史场景以及正确的预期输出。每次技能版本更新先在黄金数据集上跑回归再放量。4. 技能评估与持续迭代怎么让技能越用越准4.1 别偷懒给每个技能建一个“及格线”很多团队做完技能就上线上线后全靠用户反馈来发现问题。这种做法太被动了。我自己会在技能上线之前给每个技能定义三层评估指标。第一层是触发准确率。针对一组真实历史请求计算“该触发的时候触发了、不该触发的时候没触发”的占比。我一般要求不低于 85%。如果某个技能经常被误触发我会优先调整它的描述和触发条件。第二层是执行成功率。技能跑完且结果通过校验的比例。这里要注意模型调用失败算失败工具接口返回错误算失败输出格式不对也算失败。最好把失败原因打点分类否则很难定位问题在哪一层。第三层是端到端体验分。这个偏主观我会抽一批典型任务让一个评估小助手按照固定的问答基准给结果打分。虽然每个团队的打分标准不一样但分数本身能不能稳定复现才是重点——如果同一批任务两次评估的分数波动很大说明你的评估流程还不够规范。4.2 从失败日志反推技能缺口快速定位与修复技能上线后出现问题是必然的。关键是你从失败里能不能快速找到规律。我这里有一个常用的排查思路。先把所有失败请求按“故障类型”分组是技能没被触发、技能被触发后参数缺失、技能调用过程中依赖的工具报错、还是返回结果校验没通过这四个方向定位路径完全不同。技能没被触发去看请求上下文与技能描述的相关性多半是描述语义覆盖不够或模型在多个相似技能之间产生了混淆。参数缺失回看请求原文看模型抽取入参时是否缺少必要的实体信息必要时在技能描述里补充抽取示例或在调用达到一定条件时主动反问用户。工具报错检查依赖的接口是否变更、权限是否缺失、服务是否降级这类问题往往是生产环境波动导致的。校验不通过看校验器列出的具体错误类型是数据完整性还是可读性问题这类问题往往需要调整技能内部的输出模板或后处理逻辑。我还会定期做一次“未命中请求复盘”从日志里找到所有没有匹配到任何技能的合法请求把它们聚成主题。如果某个主题反复出现那说明你缺一个新技能或在某个现有技能的描述里漏掉了这个使用场景。技能体系不是一个静态仓库它是在真实请求的“喂养”下慢慢长出来的。4.3 技能的版本管理与灰度发布从哪一步开始技能改起来比普通代码容易但也正因为容易出问题的范围也容易被放大。我现在的习惯是对任何一个“组合技能”级别以上的技能都做版本管理并且在发布流程上分三步走。先在隔离环境跑黄金数据集回归确保改动没有破坏历史场景。然后让新版本技能以一定比例在真实流量上生效同时对比新旧版本的触发准确率和执行成功率。最后根据对比结果决定是全量切换还是回滚。这里有一个容易忽略的细节版本管理不要只记录技能代码要连技能的描述文本、依赖的工具版本甚至模型版本一起记录。因为技能的行为是“代码提示词模型”共同决定的某天模型厂商升级了底层能力同一个技能的表现可能会明显变化没有配套版本记录你根本没法解释为什么突然变好了或者变差了。注意灰度期间要确保同一个会话或同一个用户始终使用固定版本的技能避免用户前后两次操作得到不一致的结果。我一般会按trace_id后缀或user_id哈希来路由而不是简单按请求量百分比。5. 常见问题与排查技巧实录那些年我踩过的坑5.1 技能没有被正确触发怎么办这是使用频率最高、也最让人抓狂的问题。排查方向我总结成三步。第一步检查技能描述。把技能描述拿出来和真实请求逐字对照很多时候是描述里用了太多抽象词汇比如“处理”“分析”而用户通常说的是具体场景比如“把这堆聊天记录里客户抱怨最多的功能点挑出来”。把抽象词改成场景化的触发词效果立竿见影。第二步检查是不是存在相似技能。当两个技能描述在语义上重叠达到一定程度时模型就会开始随机选择。解决办法是明确区分边界在描述里主动写明“本技能不负责……场景”。没错负向描述同样重要。第三步检查路由策略。如果你在代码里对某些技能加了显式优先级或者黑名单先确认是不是因为路由规则把正确技能拦掉了。这类问题从日志里很好定位别一开始就怀疑模型能力。5.2 技能返回格式不稳定怎么兜底模型生成的结果天生就带有不确定性即便你把输出模板写得再细也挡不住它在边界场景里“自由发挥”。我的兜底策略是两条腿走路。一方面加强强约束生成。能通过 JSON Schema 约束的内容就尽量约束必要时会对模型输出做一次结构化校验自动重试超过两次重试再走兜底分支。这样可以显著降低格式异常的概率。另一方面做后处理清洗。无论模型的输出是什么形态先统一转成文本再用轻量的脚本做规则修补。比如把“百分之十二”替换成“12%”把日期中的“2025/5/16”统一为“2025-05-16”。这套清洗逻辑独立于技能内部逻辑可以复用到所有技能上。5.3 多技能同时匹配上了冲突怎么解决请求“帮我把这个文档翻译成英语并整理摘要”很容易让“翻译技能”和“摘要技能”同时被触发。真正的问题不在于两者都触发了而在于它们的执行顺序。我在技能路由表里加了一个priority字段同时对有依赖关系的技能在描述里显式声明前置条件。比如摘要技能的描述里写明“如果用户同时要求翻译请先翻译后摘要”。此外还有一种更稳妥的做法不让模型一次决定多个技能的执行顺序而是让它先选主技能主技能内部再串起其他子技能。5.4 独家避坑清单五条我用真金白银换来的教训技能描述千万别写成“能力介绍”要写成“触发场景说明”。组合技能的中间结果一定要落盘或打点否则出问题的时候根本没有依据排查。新增技能之前先搜索一下现有技能很多时候你不需要新建只需要扩展现有的描述。不要在一个技能里塞超过五个工具调用链路越长越容易断尽量用组合子技能代替串行硬编码。定期清理长期未触发访问的技能它们要么是废技能要么是描述已经失效了。在我实际接触的大量智能体项目里真正拉开体验差距的从来不是某一个模型有多强而是背后那套技能体系是否足够清晰、可扩展、能排错。把 Agent Skills 当作一个需要长期耕耘的产品来经营你会看到智能体的能力天花板被一次次抬高。希望这篇基于实操经验的拆解能帮你少走一些弯路。