
这两年做大模型应用一个很明显的感受是纯靠System Prompt堆提示词的时代正在过去大家开始认真琢磨怎么让Agent真正具备可复用、可维护、可扩展的能力。而这一切的抓手恰恰就是技能Skills。不管是Claude的Agent Skills、OpenAI的Custom Instructions还是自己从零搭的技能编排系统核心思路都是一样的——把大模型从什么都知道一点但什么都不精的状态变成在特定任务上真的能干、干得稳的状态。这篇文章我准备从工程落地的角度完整拆解一下agent-skills到底是什么、怎么做、坑在哪里。不是概念科普是那种你拿回去就能照着搭一套的实战记录。1. 技能不是工具调用从Function Calling到Skill的跃迁1.1 Function Calling的本质缺陷很多人第一次接触Agent都是从Function Calling函数调用开始的。模型在对话过程中识别出用户意图然后输出一个结构化的JSON告诉系统我需要调用某个函数参数是什么。系统拿到这个JSON去执行对应的代码把结果返回给模型模型再组织语言回答用户。这套机制本身没毛病小规模场景下完全够用。但做到后面你会发现几个很别扭的问题。第一Function Calling是一次性的。每次调用都要在请求里把函数定义带上模型靠函数描述去理解这个工具是干什么的。如果你的Agent有三十个工具每个工具的description写得稍微模棱两可一点模型就开始蒙了选错工具、传错参数的情况会频繁出现。第二Function Calling是无状态的。函数就是函数它不记得上一次调用发生了什么也没有中间产物的概念。但真实任务往往是多步骤的先查资料再写代码再跑测试最后汇总报告。每一步之间是有依赖关系的光靠函数调用很难把这些中间结果组织起来。第三Function Calling的边界太窄。它本质上还是在对话的框架里做事情适合的是用户问一句、Agent调一个工具、返回一个结果这种交互模式。但很多实际任务根本不是问答式的而是帮我处理完这一整个流程——这需要的是一连串有组织、有顺序、有依赖关系的行为序列。1.2 Skill到底解决了什么问题Skill技能的定义可以很朴素它是让Agent具备完成某一类任务能力的完整单元包含行为逻辑、知识上下文、工具调用规则和输出规范。和Function Calling相比Skill的关键区别在于完整性和复用性。完整性指的是技能不再是单一的函数声明而是一整套指令集。以写一个代码审查技能为例它不只是调用一个review函数而是告诉Agent你拿到代码后要分哪几个维度去检查、检查的深度是什么、怎么输出问题清单、遇到疑似严重问题要不要停下来确认。这些行为逻辑、质量标准、输出格式全部固化在技能定义里。复用性指的是技能可以被挂载到不同的Agent上。我这个项目里做了个代码审查Agent后来又做了一个Code Review Bot集成到GitLab流水线里技能文件几乎没动直接复用。这才是工程上真正的价值——你积累的是能力资产不是一次性脚本。所以我的理解是Function Calling解决的是模型如何触发代码Skill解决的是模型如何完成一项任务。后者的粒度更粗、封装更完整、更接近人的能力概念。1.3 和Prompt Engineering、Workflow的边界要理解skill的定位还得把它跟另外两个概念做区分。Prompt Engineering是教模型怎么说所有的行为引导都写在System Prompt里。问题在于Prompt的承载量有限塞太多东西模型会遗忘、会混淆而且不同任务的知识混在一起互相干扰。Workflow是把流程写死在代码里每一步做什么由代码控制模型只是在每个节点上做一次判断或生成。优点是稳定缺点是僵化——流程稍有变化就要改代码。Skill恰好是中间态它把任务怎么拆解的流程逻辑和每一步怎么执行的行为规范封装在一起但又不把所有细节固定死给模型留出推理和决策的空间。现实中我会这样用流程非常固定、不允许出错的比如发送HTTP请求、读写数据库写成Workflow或者普通函数。需要模型理解语义、拿捏分寸的比如撰写报告、审查代码、拆解需求做成Skill。Prompt里只留最基础的Agent人设和全局规则业务能力全部通过技能加载。这样分层之后Prompt不会失控代码不会臃肿模型的灵活性和稳定性也都能保住。2. AI Agent技能工程化的四层实践框架2.1 第一层Agent的核心配置做技能系统第一件事不是写技能而是把Agent本身的结构想清楚。我给Agent配置了四个要素身份目标role、决策模型brain、感知输入perception、行为输出action。身份目标回答你是谁、要达成什么目标这是Agent行为的牵引力。决策模型回答面对多步任务时怎么判断下一步做什么通常靠ReAct模式或Plan-and-Execute。感知输入是Agent接收信息的渠道包括用户消息、工具返回值、环境状态。行为输出是Agent经过推理后要采取的动作也就是调用技能或直接生成文本。这个框架的好处在于技能的定位在整体结构中是清晰的。技能既不在感知层也不在决策层它是行为的载体。Agent的决策模型决定什么时候用什么技能技能本身则专注于这个任务怎么干完。两层解耦之后系统的可维护性会好很多。2.2 第二层技能的选择策略技能是给Agent用的所以技能的设计策略要围绕Agent的使用场景来定。我整理了一个判断清单这个技能是否会被反复使用一次性的任务不值得做成技能。这个技能是否完整覆盖了一个任务的闭环如果没有闭环Agent做完一半还要人工接力那就没达到技能的目的。这个技能的任务边界是否清晰边界模糊的技能会让Agent在用不用它之间犹豫反而降低效率。实际操作中我给一个Agent挂的技能数量一般控制在5到10个。太少Agent很多事做不了太多Agent的选择负担会增大而且技能描述和技能描述之间可能互相干扰。2.3 第三层技能文件的SKILL.md结构设计一个skill在Git仓库里就是一个目录目录下包含SKILL.md技能说明文件、脚本、参考文档、测试用例等。这里最关键的是SKILL.md的结构设计它决定了大模型对技能的理解质量。经过多次调试我总结出了一套比较稳定的SKILL.md模板--- name: skill名称 description: 技能功能的一句话说明 version: 1.0.0 --- # 技能名称 ## 适用场景 什么情况下应该调用此技能什么问题用此技能解决。 ## 技能目标 技能执行完成后应该达成的结果状态。 ## 工作流程 1. 第一步做什么怎么判断是否完成 2. 第二步做什么关键节点怎么检查 3. 第三步做什么输出什么文件 ## 技术规范 - 使用的工具/API/命令 - 需要遵循的编码规范或设计规范 ## 输出格式 最终交付物的格式要求如文件类型、目录结构、文档模板。 ## 注意事项 常见边界情况、易错点、禁止行为。这个模板的核心思路是从何时用、用了干什么、怎么干、干完输出什么四个维度把模型需要的决策信息补齐。我踩过一个典型的坑一开始SKILL.md写得太抽象比如进行代码审查。模型调用技能后完全不知道该从哪下手审查结果泛泛而谈。后来我把审查维度明确为安全性、性能、可读性、边界条件、依赖合理性五个维度每个维度又给了具体的检查点模型的输出质量立刻上了一个台阶。2.4 第四层技能的发布与加载机制技能做好了要在Agent里真正跑起来就涉及到加载机制。我的实现方式是配置驱动的agent: name: code-reviewer model: claude-sonnet-4-20250514 skills: - code-review-security - code-review-performance - commit-analysis - changelog-generator启动Agent时系统读取这份配置把对应技能目录的SKILL.md内容拼接到应用上下文里同时把技能引用的脚本路径注册成可调用工具。我建议把技能存放在独立的Git仓库中和Agent代码分开管理。这个做法的好处是技能可以被多个Agent引用同一个技能仓库可以打tag发版Agent可以锁版本避免技能在不知情的情况下被改动。3. 让技能真正可落地几个实践细节3.1 技能与知识库的搭桥一个容易被忽略的问题技能是否需要知识库配合。很多时候完成一项任务不仅需要怎么做的执行步骤还需要用什么做的知识背景。比如代码审查技能如果只告诉Agent审查维度但Agent不了解你这个项目的编码规范审出来的结果可能不符合你们团队的标准。我的解决方案是在技能目录下放一个docs文件夹把项目规范、术语表、参考实现都放进去。技能说明中明确写了执行前先查阅docs/CODE_STYLE.md模型在执行任务时会把技能文档和参考文档结合起来理解效果比单靠技能说明要好得多。这个设计背后其实是能力和认知的分离技能提供的是完整的执行框架文档提供的是执行时需要的参考知识。两者合在一起技能的覆盖面才能撑得住。3.2 技能的版本管理策略技能和代码一样需要版本管理。但技能也有它的特殊性你无法像单元测试一样全面验证一个技能的行为。大模型的输出天然是概率性的同一个技能定义模型这次表现很好下次可能因为上下文干扰而失准。所以我不追求一次改对而是用小步迭代的方式做技能维护每次只改一个维度避免多变量同时变化不然你根本不知道是哪个改动起了作用。每个版本的SKILL.md保留变更记录方便回溯。一个技能上线后先小流量试用跑出几个真实case看看效果再逐步放量。技能的质量不是写出来的是调出来的。第一次写成的技能能跑到70分的水平就已经算不错了剩下的30分要靠真实业务的反馈来补。3.3 技能内部脚本的参数传递当技能涉及脚本调用时参数传递这块经常出问题。我把参数分成两类一类是模型已知的常量比如技能涉及的目录路径、默认阈值。这类参数我建议直接写在技能配置里不放对话上下文避免模型在每次对话中重复生成可能不一致的参数。另一类是每次执行时需要动态确定的参数比如审查的代码路径、需要生成报告的标题。这类参数需要模型在推理过程中自行提取。为了稳定我在SKILL.md的定义中做了清晰的说明让模型能正确完成参数提取而不是给一个空字符串或默认值。举个例子我的技能脚本用Python的argparse定义参数并约定允许模型用命令行方式调用。这个约定的好处是模型在生成命令时参数名和Naming convention天然对齐少了参数映射的中间层。4. 实测下来的效果一个完整的技能话术示例这里贴一个我实际投入使用的技能定义供大家参考。这是一个Git仓库变更分析器职责是分析两个分支之间的差异生成结构化的变更总结。SKILL.md缩略版--- name: git-diff-analyzer description: 分析Git分支间的变更生成结构化变更报告 version: 1.2.0 --- # Git变更分析技能 ## 适用场景 当用户要求分析两个Git分支、两次提交、或者一个PR的变更内容时使用本技能。 ## 技能目标 产出一份结构清晰的变更报告包含变更统计、核心变更点、潜在影响范围。 ## 工作流程 1. 调用 git diff --stat 获取变更文件清单和统计信息 2. 用 git diff --name-status 判断文件变更类型新增/修改/删除/重命名 3. 对核心代码文件逐一查看具体diff内容 4. 聚合所有信息输出结构化报告 ## 技术规范 - 必须使用 -u 参数保证diff包含上下文 - 对binary文件只记录文件名不看内容 ## 输出格式 变更报告格式 ### 变更概览 - 涉及文件数、新增行数、删除行数 ### 核心变更点 - 按模块列出变更原因和对应改动 ### 潜在风险 - 对涉及核心链路、数据库结构、公共接口的变更列出影响面这个技能的效果说实话超出了我的预期。以前让模型直接分析代码差异经常抓到一堆无关紧要的细节然后拼凑出逻辑混乱的总结。接上这个技能后输出的结构稳定性明显提升着——不是说内容一定百分百精确而是结构、层次、侧重点都对了人工审核的负担大幅下降。我给工程团队用了两周后的反馈是大家担心的不是模型不会用技能而是技能定义本身的质量决定了Agent能力的上限。这话我特别认同。模型只要读得懂SKILL.md它就干得好读不懂或者定义含糊再聪明的模型也会拉胯。5. 踩坑记录技能定义里那些版本史和注意到的细节5.1 问题一技能说明里用了太多负面清单一开始我写技能定义有个坏习惯怕模型乱来于是事无巨细地写不要做什么。例如不要修改源文件不要跳过错误不要使用网络请求。我把这些写成了一大段结果模型反而变得畏手畏脚该做的判断不敢做天天来问我是否继续。后来我意识到负面清单不是不能用而是要搭配足够强的正面指引。模型需要知道的是应该怎么做而不是被一堆不要束缚。我现在写技能说明的原则是正面指示优先负面约束只留最关键的红线比如禁止删除用户数据这种。5.2 问题二技能粒度太细引起Agent选择困难有个阶段我把技能拆得特别细查单个文件的技能、查整个目录的技能、查两个分支差异的技能分得清清楚楚。结果Agent反而经常选错——因为它面对这么多选择时判断用哪个的成本变高了。后来我把这些细粒度技能合并成一个代码库分析技能内部用不同的模式参数区分任务类型。效果立竿见影Agent需要做的决策从选哪个工具降级为进入技能后选哪个模式路径短了失误自然就少了。5.3 问题三技能文档的上下文开销每个技能挂载到Agent上都有上下文成本。SKILL.md、附带文档、脚本说明加起来动辄几千token。如果Agent挂了十来个技能光技能定义就能占掉一大块上下文窗口。我的应对策略是分场景加载不是所有技能都常驻而是根据Agent当前任务的性质动态加载相关技能。比如代码审查Agent只有拿到PR信息后才加载变更分析和代码审查技能在闲聊阶段这些技能完全不占上下文。实现方式也不复杂Agent框架先做意图判断再决定加载哪些技能。判断用轻量级模型或直接规则匹配都行关键是别让技能常驻的上下文开销拖垮了Agent的推理能力。5.4 问题四任务描述与技能描述的关键字匹配倒腾了几个月后我悟到一个核心问题Agent能不能选对技能很大程度上取决于技能描述里的关键词和用户任务描述的重合度。如果用户说帮我分析一下这个仓库的代码质量而技能的description写的是对代码进行多维度代码评审两者语义虽然有重叠但字面上没有任何公共关键词模型可能就匹配不上。我现在的写法是description里把常见的用户表达列全比如代码质量分析代码评审Code Review代码审查代码问题排查都写进去。这样做虽然看起来有点笨拙但在真实场景中确实能显著提高选择的准确率。6. 从技能到技能系统一点深层体会最后说点可能比怎么实现更重要的体会。做了一段时间技能工程之后我越来越觉得agent-skills表面上是一套技术方案本质上是一种思维方式——把复杂任务拆成有边界的、可测试的、能组合的单元然后让模型在这些单元之上做推理和规划。这个思路的好处在于系统的稳定性不再依赖模型随机应变的能力而是依赖你对任务的拆解是否合理、对技能的定义是否清晰。前者是概率问题你控制不了后者是工程问题你可以通过迭代不断逼近最优。当然这套工程化的做法也有它的代价。维护技能库的成本不低每个技能的说明文档都需要持续迭代而且要在大模型更新之后重新验证行为是否符合预期。如果你的项目场景是那种一次性探索或者任务范围糊到根本没法拆解那直接让模型自由发挥可能反而更快。但如果你做的Agent是要长期跑在生产环境里、要被多个团队复用、要产生可积累的能力资产那我强烈建议你在这个方向上投入。技能工程可能不是大模型应用里最酷的部分但它绝对是最值得打磨的部分。我自己踩过不少坑试了很多版本才渐渐稳定下来。这个领域的变化速度非常快模型能力在涨框架在成熟大家的实践也在迭代。如果你正在做Agent技能相关的事情欢迎在实际调试中把这套框架再往前推一步。毕竟这个方向的价值不是靠人写代码堆出来的而是靠一次次的真实任务跑出来的。