Agent Skill实战指南:从函数调用到技能编排的完整落地

发布时间:2026/10/8 16:55:18
Agent Skill实战指南:从函数调用到技能编排的完整落地 1. 项目概述先盘点一下我为什么盯上这个方向这两年做AI Agent相关项目的朋友应该都有同感模型能力卷到头之后真正决定一个Agent好不好用的已经不是脑子而是手脚了。我见过太多团队卡在同一个地方——模型选得够强提示词也精雕细琢但做出来的Agent一到真实业务场景里就露怯要么工具调用链条经常断要么技能复用性极差换个场景就得推倒重来。agent-skills这个标题说白了就是在解决这套手脚的问题。这个概念最近在Agent圈子里热度很高核心要义特别朴素把一个Agent要执行的复杂任务拆解成一个个独立、可组合、可复用的技能单元。听起来有点像函数库或者插件体系但在AI Agent的语境下它跟传统的函数封装完全是两码事。传统程序里的函数是输入-处理-输出的刚性逻辑而Agent Skill必须兼顾模型的非确定性推理得设计成让模型看得懂、调得对、用得好的样子。这篇文章我打算从一个实际做过的Agent项目切入聊清楚三件事第一Agent Skill到底是什么跟Function Calling、Workflow有啥本质区别第二从零手写一个能落地的Skill需要做哪些关键设计第三实际操作里最容易踩的坑和排查思路。目标是让看完这篇文章的人回去就能把自己手里的Agent重构出一套像样的技能体系。先说适合谁看。如果你正在用LangChain、Claude SDK或者OpenAI Assistants API做Agent开发但总觉得工具调用不顺手编排复杂场景时逻辑混乱那这篇文章就是按这个痛点写的。如果你只是听说过Agent但还没上手这篇文章里的设计思路也可以当作入门地图。我不会写太多晦涩的理论重点放在能直接抄作业的实操细节上。2. Skill的定位它凭什么不是第二个Function Calling2.1 从一次失败的项目重构说起先讲个真实的翻车经历。之前我做一个自动化运营助手用OpenAI的Function Calling做了一堆工具函数比如查库存发优惠券算折扣每个函数对应一个接口。初版跑起来很顺模型能正确调用准确率看着也不错。但业务一扩展就崩了运营同事提了个需求说帮我把滞销商品挑出来自动生成清仓文案再通过企业微信发给店主。这个需求要串三个函数查库存、生成文案、发消息。但Function Calling本身不关心顺序和组合逻辑模型得自己在一次对话里连续调用好几次而且中间任何一步出错整个链路就断了。更要命的是每个函数都是扁平的没有上下文概念——滞销商品需要先定义筛选条件发给店主需要先确定收件人这些业务规则全部散落在提示词里越堆越乱最后提示词到了八千多token改一处就崩另一处。后来我把这个需求拆成了三个Skill库存筛选Skill负责找滞销品文案生成Skill负责写清仓文案消息推送Skill负责发企业微信。每个Skill都有自己完整的输入输出Schema、失败处理逻辑和独立的提示词上下文。调用关系变成了这样库存筛选Skill跑完输出一批商品ID列表作为文案生成Skill的输入上下文文案生成Skill产出文本再作为消息推送Skill的输入。三个Skill各自独立测试、单独换版本互不干扰。这个案例就是Agent Skill和Function Calling最本质的区别Function Calling是给模型一把工具让它自己想怎么用Skill是把工具和它的使用说明书、边界条件、失败处理打包成一个整体告诉模型在什么场景下用、怎么用、用完怎么衔接。前者是函数后者是完整的工作能力。2.2 Skill、Tool与Workflow的边界到底怎么划术语混乱是目前Agent领域最大的认知障碍。很多刚接触的人一上来就问Skill和Tool是不是一回事Workflow跟Skill比哪个更高级我把这三者的边界按自己的经验理一下。Tool是最底层的能力原子。它就是一个函数、一个API接口完成一个单一动作比如查天气发短信算总价。Tool不关心业务状态不持有上下文每次调用都是独立的。Skill是Tool的封装加上使用上下文。一个Skill可以只包含一个Tool也可以包含多个Tool的组合逻辑但它与Tool的本质区别在于Skill自带什么时候用、怎么用、怎么处理异常、输出什么结构这套元信息。模型在选择Skill时看到的不是一个函数而是一整套能力说明。Workflow是更上一层的东西它编排多个Skill之间的流转关系。主干逻辑是确定的——先做A再做BA失败就做C但每个节点内部可以用Skill的灵活性。理想情况下Workflow负责走哪条路Skill负责每一段路怎么走好。这个分层我现在在实际项目中基本是这么用的项目小、交互简单直接上Tool函数就够要处理复杂业务且希望模型有自主决策空间Skill是性价比最高的粒度流程刚性、路径固定且对稳定性要求极高的场景才考虑上Workflow。三者不是替代关系是不同抽象层级。3. 核心设计思路写Skill之前先想明白这几件事3.1 输入输出的Schema设计是成败关键我见过太多Skill翻车不是逻辑有问题而是输入输出Schema设计得有歧义。模型是个语义理解器不是严格的类型系统它靠自然语言描述来理解参数含义。如果你的输入字段写的是query: string模型能猜出来大概要传什么但猜得可能跟你的预期有偏差。一个好的Skill输入输出Schema每个字段都要做到三件事字段名自解释、描述给足上下文、约束写清边界。拿我做的网页正文提取Skill举例输入字段我一开始只写了一个urlurl: string。实测下来模型在调用时会把各种各样的东西塞进来有人传的是搜索关键词有人传了一整段带HTML标签的链接。后来我把Schema改成这样url字段描述改为需要提取正文的网页完整地址必须以http://或https://开头包含域名和路径如果用户提供的是搜索语句或关键词请先使用搜索工具找到具体页面后再调用本技能同时增加了一个参数extract_type枚举值限定为article、product、list三种类型用于告诉技能按不同结构解析页面。整个调用的准确率从七成左右直接提升到九成五以上。输出Schema同样重要。我建议所有Skill的输出都遵循一个统一信封结构status表示成功失败、data是核心数据、message是给人看的说明、meta放调试信息。这样做最大的好处是多个Skill串联时下一个Skill能无脑解析上一个Skill的输出不用为每个Skill单独写一套解析逻辑。3.2 元信息配置注册表里的每个字段都有用途Skill的元信息配置很多人理解为就是给模型看的描述文本实际上它是整个技能体系运转的路由表。我习惯用一个YAML文件把元信息结构化管理每个字段都有明确用途缺一个都会在实际运行中出问题。name是整个Skill的唯一标识模型靠它精确命中要调用的技能所以必须做到全局唯一而且最好语义清晰比如webpage_extractorinventory_checker别用tool1util2这种似是而非的名字。description是最核心的字段直接决定模型在什么场景下会选择这个Skill。这个字段有两层要求一是说明能力边界——这个技能做什么、不做什么二是给出触发条件——当用户想了解某个网页的具体内容时必须调用此技能。我见过有人把description写了一百多字但全是能力描述没有触发条件模型当然不知道该什么时候用。parameters和returns就是配合Schema使用的author和version用于团队协同和版本管理tags用于分类检索。metadata字段我喜欢放一些模型不感知的系统级配置比如超时时长、幂等策略、最大重试次数。3.3 失败处理绝不能只靠提示词兜底这块是我最想强调的。很多人把Skill的容错完全寄托在模型能力上觉得我提示词里写了出错就重试出了问题让模型自我修正这在实际生产环境里是不现实的。模型的重试逻辑经常会导致同一个错误反复触发白白消耗token还会把错误状态越搞越乱。我现在的做法是每个Skill内部都要有一套确定性的失败处理机制不依赖模型临场发挥。具体分三层第一层前置校验在调用任何工具之前先检查参数是否合法、依赖状态是否就绪比如查库存Skill先确认商品ID格式和数据库连接状态不合格直接返回错误信封不进入工具调用环节第二层异常捕获工具调用过程中如果报错把原始错误信息完整记录进meta字段同时给模型一个简化的错误类别判断让上层调度能快速决定是重试还是换路第三层幂等保护凡是发消息、创建订单这类有副作用的操作必须支持幂等键机制防止模型因为超时而重复执行。这三层机制写进Skill模板后Agent的整体稳定性的提升是立竿见影的。之前那种明明已经扣了库存但因为响应超时模型又发起了一次操作请求的经典事故基本杜绝了。4. 实操过程从零开发一个可复用的邮件摘要Skill4.1 场景选定与边界定义理论说再多不如上手走一遍完整流程。我用最近做的一个邮件智能摘要与待办提取Skill作为完整案例把从设计到上线的全过程拆开讲。选这个场景是因为它包含了Agent类项目的典型复杂度需要解析非结构化文本、需要调用外部工具邮件系统、需要输出对人友好且可机读的结构化结果、还要处理异常情况邮件格式乱、权限不足等。第一步是边界定义。这个Skill只负责基于给定的邮件内容做摘要和待办提取它不负责接收邮件也不负责发送回复更不负责根据待办去执行动作。边界划清楚之后Skill的输入输出就很好设计了输入是邮件原始内容输出是摘要JSON加待办列表。关于权限和隐私在实际接入企业邮箱系统时这个Skill会读取邮件文本但不会存储原始邮件也不会将邮件内容用于任何训练同时在日志中做脱敏处理。这些设计在做真实业务时一定要提前考虑不要在项目上线后补防护措施。4.2 Skill的完整代码实现框架一个基础版本的Skill包含四个文件skill.yaml放元信息配置validate.py做输入校验run.py是核心逻辑errors.py统一定义异常。代码结构如下# skill.yaml 核心配置示例 name: email_summarizer version: 1.2.0 description: 将一封或多封邮件的全文内容转化为结构化摘要提取核心议题、关键决策与待办事项。 当用户要求总结邮件、提取邮件重点、追踪邮件待办时必须调用此技能。 此技能只处理邮件文本本身不涉及邮件收发和回复发送。 parameters: email_content: type: string description: 邮件的完整文本内容可以是纯文本或移除HTML标签后的正文。 required: true focus: type: string enum: [all, decision, todo] default: all description: 摘要侧重点all代表全面摘要decision只提取决策项todo只提取待办事项。 returns: summary: type: string description: 面向用户的自然语言摘要控制在200字以内。 todos: type: array items: type: object properties: action: { type: string } owner: { type: string } due_date: { type: string, nullable: true } decision: type: array items: { type: string }核心逻辑文件run.py我的实现方式是这样先做文本清洗去掉转发链、签名档这些噪音然后调用模型进行结构化抽取。这一步用了两轮提示第一轮让模型提炼议题第二轮提取待办和决策。用两轮而不是一轮实测下来结构化输出的稳定性能提高不少因为提炼议题和提取待办的思维方式不一样混在一起模型容易顾此失彼。4.3 调用链路的注册与调试Skill的代码写完只是第一步真正让它生效的是注册进Agent运行时的过程。我在Claude SDK和OpenAI Agents框架里都验证过这套流程原理大同小异。在Claude SDK中Agent Skill遵循Anthropic发布的开放规范它会扫描特定目录下的skill.yaml文件将元信息加载进模型上下文——不是把代码加载进去而是把配置文件和说明书交给模型理解实际执行时才回调你的函数。这种机制带来的直接好处是无论注册多少个技能模型上下文的占用是可控的。我实测过一个注册了20个Skill的项目初始化时上下文开销在两千token以内完全可以接受。调试阶段有个小技巧给每个Skill单独写一个测试脚本模拟模型视角直接调用它的入口函数验证输入校验和输出格式。这一步能过滤掉大部分低级错误别直接全链路跑到模型调试阶段再排错那是事倍功半的。这个我特别想强调一下因为真实踩过坑曾经有一个SKill在单独测试的时候完全正常但放进Agent里就偶发失败。排查了半天发现是Skill内部调用的一个公共函数与另一个工具的同名函数冲突了。从那以后所有Skill我都强制要求包含独立的命名空间公共函数一律加前缀杜绝这种灵异事件。5. 技能编排与组合单一Skill到体系化Agent的关键一跃5.1 用管道模式串联有顺序依赖的Skill实际业务里很少有单Skill能搞定的场景大多数情况下需要多个Skill配合。Skill之间的配合方式我总结下来核心就三种模式第一种是管道模式适合有明确先后顺序的任务。管道模式的实现核心是前面Skill的输出正好映射为后面Skill的输入。比如滞销品清仓助手这个场景库存筛选Skill输出一个商品ID列表直接作为文案生成Skill的上下文背景文案生成Skill输出的文案又喂给消息推送Skill的正文参数。链条清晰但每个环节都可独立替换。管道模式最大的坑出现在衔接字段上。如果你第一个Skill输出的是一个数组第二个Skill的Schema却期望的是单个对象模型在中间转换时很容易出错因为它必须凭空构造一个对象结构。所以我在设计管道模式时有个铁律链路中相邻Skill的Schema必须做到字段级对齐要么前一个Skill的输出Schema本身就是按后一个Skill的输入Schema设计的要么拆成两个独立步骤并增加一个显式的转换器。实测下来显式转换器的稳定性远大于让模型自己即兴发挥——这个“转换器”本质上是一段确定性的代码函数用规则把字段映射好不走模型的自由推理。5.2 用路由模式支持模型按需自选Skill路径第二种是路由模式模型根据用户请求的语义自主选择走哪条技能路径适合开放式的问答和决策场景。比如我的知识库Agent注册了三个技能数据库查询Skill负责结构化数据文档检索Skill负责文本型资料网页抓取Skill负责实时信息。用户提问后模型根据问题类型自动选择对应技能甚至组合调用。路由模式要想玩得转Skill的description写得必须足够精准。我给团队定的标准是description里必须包含三件事典型的使用场景例句、明确的不适用场景、以及与其他易混淆Skill的区分提示。举例来说文档检索Skill的description里会写当用户询问公司制度、操作手册、历史记录等内部文档内容时使用如果是需要实时数据的财务指标、实时股票价格等时效性强的信息不要使用此技能应选择数据库查询技能或网页抓取技能。这个细节我反复强调过很多次因为它直接影响路由准确率写得好不好差别非常大。5.3 上下文管理与动态加载策略技能数量一旦多起来上下文管理就变成了新的瓶颈。虽然Agent Skill的注册机制能控制常驻上下文大小但模型在执行过程中频繁切换技能时仍然需要把被调用技能的说明临时加载进来这个过程如果没设计好会在对话轮次拉长后逐步形成token膨胀。我的方案是引入一个技能调度层它不直接参与业务只负责维护一个当前对话可能用到的技能的候选集。调度层根据对话历史和当前输入先从技能注册表里粗筛出3到5个候选技能再把这几个候选技能的完整说明书注入模型上下文。这样一来哪怕总技能数量增长到二三十个单次对话的模型上下文里永远只有少数几个技能说明token开销稳定可控。这几个候选不是静态固定的我按“主题标签关键词直连”的方式做粗筛。比如用户提到邮件邮件摘要Skill、邮件发送Skill进入候选用户提到库存库存查询Skill、库存预警Skill进入候选。对话过程中调度层持续更新候选集旧的技能说明会被移出上下文新的会被加载。这套机制实操起来不会特别复杂但对体验提升非常明显尤其是在Agent需要长对话、多轮操作时效果突出。6. 常见问题与排查技巧实录6.1 模型老是调错Skill八成是说明书写得有问题团队里新人问我最多的一个问题是模型动不动就调错技能明明该用A技能它偏去调B技能是不是模型太笨了这个情况排查来排查去九成原因出在技能本身的description上模型只是在用你给的信息做判断它不背这个锅。排查步骤我固定按三步走。第一步查看模型实际调用时看到的是哪个description字段确认加载的是不是最新版本——我踩过配置文件缓存没刷新导致模型在读旧说明书的坑。第二步把几个易混淆技能的description并列对比看是不是长得太像如果两个技能的description都写了当用户询问天气时使用模型当然会随机调一个。第三步做单技能隔离测试只注册问题技能看模型能否在明确提示语下正确触发能触发说明技能本身没问题问题出在路由上。一个很有效的优化小技巧是差异化描述法给每个技能起一个独特的别名在description里高频使用该别名。比如邮件摘要Skill的别名是邮见——重命名成业务语义有辨识度的短语后模型对它的记忆明显更清晰。这个方法听起来玄学但实测对降低调错率确实有帮助背后逻辑可能是语义唯一性让注意力分配更集中。6.2 技能内部超时与重试陷阱在生产环境里技能执行超时是家常便饭尤其是涉及到外部API调用时。我遇到过的最典型的情况是消息推送Skill调用HTTP接口服务端处理超过十秒才返回Agent的调度层已经判定超时并触发了重试结果同一批消息被推了两次甚至三次。排查这个问题要同时看两端一端是Agent运行时的超时阈值设置另一端是技能内部的重试策略。合理的做法是把技能内部的重试次数设置为0把重试语义完整交给上层调度器由调度器基于幂等机制做统一决策。如果你把重试逻辑散落在每个Skill内部那么重试攻击面会被放大好几倍你很难全面掌控。另外我强烈建议所有有副作用的技能在设计阶段就预留幂等键字段。这个幂等键可以是业务订单号、消息ID或者事件唯一标识。判定重试请求时只要幂等键相同服务端就直接返回上一次的处理结果不再重复执行。这套机制是消息推送、转账、发券这类高敏感业务的生命线缺了它任何Agent都谈不上生产可用。6.3 技能测试的隔离与回归策略我坚持一个原则每个Skill都要有独立于Agent主工程的测试套件。很多开发者习惯改完Agent直接跑整个聊天流程做验证省事但效率特别低。调试信息被模型的随机性淹没你根本分不清是Skill本身出错还是模型编排出错。我的习惯是给每个Skill维护一个sandbox_test.py里面直接调用Skill入口函数传入固定测试用例集验证返回JSON的结构和关键字段值。跑通了再做Agent级联调。这套流程看起来多了一步但从整体研发效率来看反而是省时间的。等技能数量和版本迭代多了以后还得加上一个批量回归脚本把历史以来修过的bug场景全部纳入自动化回归集。之前修过一个邮件中的时间表达解析错误问题过了两周重构代码时又改出了同样的问题就是因为当时没有把测试用例沉淀下来。后来我把所有修过的bug都转成了回归用例这类「回魂bug」基本绝迹。7. 经验总结我做Skill体系的几条心法最后分享几条我做了多个Agent项目后沉淀下来的个人经验不成体系但每一条都是真金白银换来的尤其适合准备把项目重构到技能化体系的团队。第一Skill的粒度宁小勿大。我见过有人把处理整个订单流程做成一个Skill结果内部有十几个分支逻辑模型调用时切不中正确的子路径失败率特别高。把这种粗粒度Skill拆成校验订单计算价格确认库存发起支付几个细粒度技能之后整体效果立刻好转。粒度的判断标准很简单一个Skill能否在200字以内说清楚做什么、不做什么、什么时候用说不清楚就是粒度太大了。第二先跑通一个最核心的Skill再铺开做体系。技能体系的建设极度容易陷入设计癖把大量时间花在规划二十个技能上结果一个没跑通。我的习惯是先想清楚当前业务的黄金路径是什么找出那个最高频、最有价值的能力点把它做成第一个Skill完整跑通测试和上线流程后再复制这个模式铺开做别的。第三帮业务同事也建立技能思维。我会在需求评审阶段带着业务方把新需求拆解成技能清单一起讨论哪些技能已经存在可以复用、哪些需要新建、哪些需要改参数。这样既能减少重复建设也能让业务方清楚看到Agent的能力边界减少不切实际的预期。第四把技能相关的开发规范文档化。现在团队内部维护着一份Skill开发手册包含命名规范、Schema要求、失败处理策略、测试标准、权限与数据合规要求等硬性条目。新同学照着这份手册开发的Skill代码质量基本能保持在一个稳定的水平线上复查成本低了很多。这条路我自己走了一遍最大的感受是Agent从能跑到稳跑之间差的不是更复杂的模型而是一套像样的技能体系。花在Skill设计上的每一分钟最后都会在成倍的稳定性和开发效率上还回来。

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询