资讯动态

Agent开发实战:SKILL渐进式披露机制与编写指南

发布时间:2026/10/8 4:18:02 来源:尧图企业网站定制
1. 从一次踩坑说起为什么SKILL值得单独拿出来讲去年年底我接手了一个内部工具链的改造项目核心诉求是让团队里的Agent能稳定完成一套固定的代码审查流程。一开始我的做法很粗暴——把所有规则、示例、边界条件全部塞进一个超长的系统提示词里。结果呢模型在前几轮表现还行一旦对话轮次拉长它就开始忘事前面强调过的命名规范到后面就抛到脑后了。更头疼的是每次微调一条规则整个提示词都要重新测一遍回归成本高得离谱。后来我接触到Anthropic官方提出的SKILL概念才意识到问题的根源不在于模型能力而在于我把知识和指令混在了一起没有做分层。SKILL这套东西本质上解决的就是如何把领域知识、操作流程、工具调用规范打包成一个可复用、可渐进加载的模块。它不是一个新模型也不是一个插件市场而是一种组织Agent能力的工程范式。这篇文章我想聊三件事SKILL到底是什么、它的渐进式披露机制为什么重要、以及怎么写一个真正能打的SKILL。适合正在做Agent应用开发、提示词工程、或者想把团队经验沉淀成可复用资产的同行参考。不管你是刚接触这个概念还是已经写过几个SKILL但总觉得效果不稳定下面这些内容应该都能对上你的痛点。2. SKILL到底是什么拆开看它的核心结构2.1 一句话定义与它要解决的问题如果只用一句话概括SKILL是一份用Markdown写的、带有元数据的操作说明书告诉Agent在特定场景下该怎么做、该调用什么工具、该遵循什么约束。它的载体通常是一个SKILL.md文件放在一个独立目录里目录下还可以附带脚本、模板、参考文档等资源。听起来好像跟普通的提示词模板差不多差别在于三个关键点。第一SKILL有明确的触发条件不是所有对话都加载而是当任务匹配时才被激活。第二SKILL支持渐进式披露也就是分层加载——先加载最核心的摘要需要细节时再逐层展开。第三SKILL是可组合的一个复杂任务可以挂载多个SKILL各司其职。我打个比方。传统的长提示词就像把整本员工手册一次性拍在新员工桌上他可能翻两页就晕了。而SKILL更像是一个带目录的活页夹封面写着这是处理退款流程的第一页是三步概要翻到第二页才有具体的字段校验规则再往后才是异常情况的处理分支。Agent在需要的时候才去翻对应的页上下文窗口的占用被压到了最低。2.2 SKILL.md的典型结构长什么样一个规范的SKILL.md通常包含两大部分前置元数据frontmatter和正文内容。前置元数据用YAML格式写在文件顶部声明这个SKILL的名字、描述、适用场景等。正文则是具体的操作指引。我拿一个实际项目里用过的结构举例这是一个代码审查SKILL的骨架--- name: code-review description: 对提交的代码进行规范性审查检查命名、注释、异常处理和测试覆盖 trigger: 当用户请求审查代码、检查PR或提到代码质量时激活 version: 1.2 --- ## 概述 本SKILL用于对代码变更进行结构化审查输出问题清单和改进建议。 ## 审查维度 1. 命名规范变量、函数、类名是否符合项目约定 2. 注释完整性公共接口是否有文档注释 3. 异常处理是否有未捕获的异常路径 4. 测试覆盖新增逻辑是否有对应测试 ## 输出格式 按严重程度分级阻塞、警告、建议。 ## 详细规则 此处省略按需加载注意最后那行按需加载——这就是渐进式披露的入口。核心的审查维度和输出格式放在主文件里而每个维度的详细规则、正反例、边界情况可以拆到单独的参考文件里只有当Agent真的需要判断某个具体问题时才去读取。2.3 SKILL和提示词、工具调用、RAG的区别很多人第一次接触会把它和几个已有概念搞混我列个表对比一下这个对比是我自己在选型时整理的实测很有用维度普通提示词工具调用RAG检索SKILL核心作用设定角色和语气执行外部动作补充事实知识封装操作流程加载方式全程常驻按需调用按查询检索渐进式分层加载内容形态自然语言指令函数签名文档片段结构化操作手册复用粒度整个对话单个函数单条知识完整任务模块典型场景角色扮演查天气、发邮件问答、客服多步骤复杂流程关键区别在于工具调用解决的是能不能做RAG解决的是知不知道而SKILL解决的是怎么做才对。一个Agent可以同时挂载工具、接入RAG、加载SKILL三者是互补关系不是替代关系。3. 渐进式披露SKILL最容易被忽视的设计精髓3.1 为什么不能把所有内容一次性塞进去上下文窗口是稀缺资源这一点做过Agent开发的人都深有体会。假设你有一个包含50条规则的SKILL每条规则平均200字全量加载就是1万字。如果这个Agent同时挂了5个SKILL光SKILL就吃掉5万字的上下文留给实际对话的空间被严重挤压而且模型在超长上下文里的注意力会稀释规则遵守率反而下降。渐进式披露的核心思想是把必须知道和可能需要知道分开。主文件只放最核心的框架——这个SKILL是干什么的、分几个步骤、每步的产出是什么。具体的判断细则、边界案例、参考数据全部拆到子文件里用明确的引用路径指向它们。Agent在执行到某一步时如果遇到需要细节的情况才去读取对应的子文件。我实测过一个对比同一个代码审查任务全量加载版本在对话进行到第8轮时开始出现规则遗漏而渐进式披露版本到第15轮仍然稳定。原因很简单前者从一开始就占满了上下文后者在大部分轮次里只占用主文件的几百字。3.2 三层结构的划分逻辑根据我的实践一个设计良好的SKILL通常分三层第一层是入口层也就是SKILL.md的主文件。这一层回答这个SKILL解决什么问题、什么时候用、大致流程是什么。字数控制在500到1500字之间超过这个范围就说明该拆了。第二层是规则层通常是一个或多个rules.md或reference.md文件。这一层回答具体每一步的判断标准是什么、有哪些约束条件。比如代码审查里命名规范的具体要求就放在这一层。第三层是资源层包括示例代码、模板文件、测试用例、脚本工具等。这一层回答有没有现成的例子可以参照、有没有工具可以直接调用。这一层的内容通常不是文本而是实际可执行或可复制的资产。划分的依据是使用频率和依赖顺序。高频使用的放上层低频的放下层前置依赖的放上层后续补充的放下层。这个逻辑跟写代码时拆分模块是一样的道理。3.3 触发条件的写法与常见误区触发条件写得好不好直接决定SKILL会不会在该激活的时候激活、不该激活的时候乱激活。我见过最常见的两个极端一是触发条件写得太宽泛比如当用户提到代码时激活结果用户只是随口问一句这段代码什么意思也把整个审查SKILL加载了二是写得太窄比如精确匹配某个句式用户换个说法就触发不了。我的经验是触发条件应该描述任务意图而不是关键词。比如当用户请求对代码进行质量评估、规范检查或改进建议时激活这比罗列一堆关键词要稳健得多。同时要写清楚排除条件比如仅当用户提供了具体代码片段或文件路径时激活纯概念讨论不激活。另外提醒一点触发条件的描述本身也会占用上下文所以不要写得太长。我一般控制在两三句话以内把什么时候用和什么时候不用都说清楚就够了。4. 手把手写一个能打的SKILL从零到可用4.1 第一步明确边界别贪多新手写SKILL最容易犯的错就是贪多想用一个SKILL解决一整条业务线的问题。我踩过这个坑——曾经写过一个全流程数据处理SKILL涵盖数据清洗、特征工程、模型训练、结果评估结果每个环节都写得很浅Agent执行起来到处卡壳。正确的做法是一个SKILL只解决一类任务。判断标准很简单如果你没法用一句话说清楚这个SKILL的输入和输出那就说明它太大了该拆。比如对CSV文件做缺失值填充和异常值检测就是一个合适的粒度数据预处理就太宽了。拆的时候按任务阶段拆不要按技术栈拆。比如一个完整的机器学习项目可以拆成数据探查SKILL特征处理SKILL模型训练SKILL结果解读SKILL每个都有明确的输入输出。这样Agent在每一步只需要加载当前阶段的SKILL上下文干净执行也稳定。4.2 第二步写清楚输入输出契约这一步很多人会跳过但它恰恰是SKILL能不能被稳定调用的关键。所谓输入输出契约就是明确告诉Agent这个SKILL需要什么前置信息、产出什么格式的结果。输入方面要写清楚需要用户提供什么、需要其他SKILL或工具提供什么、哪些是必需的哪些是可选的。比如一个生成周报的SKILL输入契约可能是需要本周的提交记录必需、本周的会议纪要可选、上周的周报可选用于对比。输出方面要写清楚产出的格式Markdown表格、JSON、纯文本、产出的结构分几个部分、每部分包含什么字段、产出的质量标准比如每个问题必须附带具体的代码行号。我习惯在SKILL里直接给一个输出模板Agent照着填就行比纯文字描述靠谱得多。4.3 第三步用示例锚定行为光有规则描述Agent的理解可能会有偏差。最有效的办法是给正例和反例。正例告诉它这样做是对的反例告诉它这样做是错的一正一反边界就清晰了。举个例子在代码注释这个规则下我会这样写### 正例 def calculate_tax(income, rate): 根据收入和税率计算应缴税额。 Args: income: 税前收入正数 rate: 税率0到1之间的小数 Returns: 应缴税额保留两位小数 ### 反例 def calculate_tax(income, rate): # 算税 return income * rate反例不需要多每个规则配一到两个就够。关键是反例要典型是实际工作中真实会出现的错误写法而不是为了凑数编出来的。4.4 第四步把工具调用写进流程如果SKILL涉及调用外部工具一定要在流程里明确标注在哪一步、调用什么工具、传什么参数、拿到结果后怎么处理。不要假设Agent会自己判断该调什么工具它可能会漏调也可能会调错。我的写法是在流程步骤里直接嵌入工具调用说明### 步骤3获取文件列表 调用 list_files 工具参数 path 设为用户指定的目录 recursive 设为 true。拿到返回的文件列表后 过滤掉扩展名不在 [.py, .js, .ts] 中的文件。这样写的好处是Agent执行到这一步时不需要再做决策照着做就行。决策点越少执行越稳定。4.5 第五步版本管理与迭代SKILL不是写完就完事的它需要迭代。我在每个SKILL的frontmatter里都会加version字段并且维护一个简单的变更记录。每次修改后我会用一组固定的测试用例跑一遍确认没有引入回归。测试用例怎么来就是从实际使用中积累。每次发现Agent执行出错就把那个场景记下来作为回归测试的输入。时间长了你就有了一个覆盖各种边界情况的测试集改SKILL的时候心里有底。5. 实操现场一个完整SKILL的落地记录5.1 需求背景与初始方案前面讲的都是方法论这一节我把一个真实项目的落地过程完整还原一遍。需求是给团队的代码仓库做一个自动化的提交前检查SKILL在开发者提交代码前Agent自动检查几个关键项是否有调试代码残留、是否有硬编码的敏感信息、提交信息是否符合规范、是否有明显的性能问题。初始方案我写了一个单文件SKILL把所有检查项和规则都塞在一起大概3000字。测试下来发现两个问题一是加载慢每次对话都要吃掉3000字上下文二是规则之间互相干扰比如检查硬编码的规则偶尔会被误用到提交信息检查上。5.2 重构为渐进式结构重构后我把它拆成了四层主文件SKILL.md只保留检查项清单和输出格式约400字。每个检查项对应一个子文件比如check-debug.md、check-secrets.md、check-message.md、check-performance.md每个子文件约500到800字包含具体的判断规则和正反例。Agent的工作流变成先读主文件了解有哪几项检查然后逐项读取子文件执行检查每检查完一项就释放对应的上下文。实测上下文占用从3000字降到了平均800字左右而且规则之间的干扰问题消失了。5.3 关键参数与配置细节这里说几个具体的配置细节都是踩坑踩出来的。子文件的引用路径要写绝对路径或明确的相对路径。我一开始写的是参见check-debug.mdAgent有时候找不到文件。后来改成参见 ./checks/check-debug.md就稳定了。每个子文件的开头要有一句话摘要。这样Agent在决定是否读取这个文件时可以先看摘要判断相关性避免无谓的读取。摘要格式我统一用本文件用于检查XXX适用于XXX场景。主文件里要写明检查顺序。有些检查有依赖关系比如必须先确认没有敏感信息泄露才能进行后续检查。顺序写清楚Agent就不会乱序执行。输出格式要固定。我定义了一个统一的输出模板每个检查项的输出都按这个模板来最后汇总成一张表。这样不管是人看还是程序解析都很方便。5.4 效果对比与数据记录重构前后我做了对比测试用同一组20个测试提交跑指标重构前重构后平均上下文占用约3200字约850字检查项遗漏率12%2%误报率8%3%平均执行轮次6.2轮4.1轮规则冲突次数5次/20次0次/20次数据不一定适用于所有场景但趋势是明确的渐进式披露结构在稳定性和效率上都有明显优势。尤其是规则冲突这一项从有到无说明分层确实解决了规则互相干扰的问题。6. 常见问题与排查技巧实录6.1 SKILL不触发或误触发怎么办这是最高频的问题。排查思路分三步走。第一步检查触发条件的描述是否过于依赖关键词。如果写的是当用户提到review时激活那用户说帮我看看这段代码就不会触发。改成描述意图当用户请求对代码进行质量评估或改进建议时激活。第二步检查是否有其他SKILL的触发条件覆盖了它。多个SKILL的触发条件如果有重叠Agent可能会优先加载其中一个。解决办法是在触发条件里写明优先级或者把重叠的部分合并到一个SKILL里。第三步检查主文件的摘要是否足够清晰。Agent在决定加载哪个SKILL时主要看的是description字段。如果description写得太模糊比如处理代码相关任务Agent就不知道该不该加载。description要具体到任务类型和产出物。6.2 子文件读取失败怎么排查渐进式披露依赖子文件的正确读取读不到就退化成单文件了。常见原因有三个。路径问题最常见。相对路径的基准目录不明确Agent可能从不同的工作目录去解析。我的做法是统一用相对于SKILL.md所在目录的路径并且在主文件里明确写出基准目录。文件名大小写问题也遇到过。有些系统对大小写敏感Check-Debug.md和check-debug.md是两个文件。统一用小写加连字符避免麻烦。权限问题偶尔出现。如果SKILL目录是只读挂载的子文件可能读不到。确认一下文件权限确保Agent进程有读取权限。6.3 规则冲突与优先级处理当多个SKILL同时激活或者一个SKILL内部有多条规则时冲突是难免的。我的处理原则是显式声明优先级不要让Agent自己猜。在SKILL的frontmatter里加一个priority字段数值越小优先级越高。当两个SKILL的规则冲突时高优先级的覆盖低优先级的。在SKILL内部如果两条规则可能冲突就在规则描述里写明当与XXX规则冲突时以本条为准。还有一个技巧是把互斥的规则放到不同的SKILL里通过触发条件来隔离。比如严格模式和宽松模式的检查规则做成两个SKILL用户选择哪个就加载哪个从根上避免冲突。6.4 常见问题速查表问题现象可能原因排查动作解决方向SKILL不激活触发条件太窄检查description和trigger字段改为描述任务意图SKILL误激活触发条件太宽查看是否有排除条件补充排除条件子文件读不到路径或权限问题确认路径基准和文件权限统一用相对路径规则执行不全上下文被挤占检查主文件字数拆分到子文件输出格式不稳定缺少输出模板查看是否有固定模板补充输出模板多SKILL冲突优先级未声明检查priority字段显式声明优先级迭代后回归缺少测试用例回顾变更记录建立回归测试集6.5 几个我踩过的坑第一个坑是在SKILL里写太长的背景介绍。我一开始觉得多写点背景有助于Agent理解结果发现背景部分占了大半篇幅真正的操作规则被淹没了。后来我把背景压缩到两三句话把篇幅留给规则和示例。第二个坑是用自然语言描述本该用表格描述的内容。比如检查项的对照关系用文字写要写一大段用表格三行就清楚了。Agent对表格的解析能力其实很强该用表格就用表格。第三个坑是忽略了SKILL之间的依赖关系。有一次我写了两个SKILL一个负责数据读取一个负责数据分析但没写明依赖顺序。结果Agent有时候先加载分析SKILL发现没有数据又回头加载读取SKILL多绕了一圈。后来我在分析SKILL的触发条件里写明需在数据读取SKILL之后激活就顺畅了。第四个坑是版本更新后没有同步更新description。SKILL的功能扩展了但description还是旧的导致触发条件不匹配。现在我每次改SKILL第一件事就是检查description是否还准确。7. 关于SKILL设计的一些个人体会写SKILL这件事说到底是在做知识的工程化封装。它跟写文档、写代码都有相似之处但又不完全一样。文档是给人看的可以容忍一定的模糊性代码是给机器执行的要求精确而SKILL是给Agent看的既要精确到能执行又要保留一定的灵活性来应对变化。我的体会是一个好的SKILL应该像一个经验丰富的老师傅带徒弟先告诉徒弟这个活儿是干什么的然后示范一遍标准流程再指出几个容易出错的地方最后说遇到搞不定的再来问我。它不会把所有的知识一次性倒给徒弟而是在徒弟需要的时候提供对应的指导。渐进式披露的精髓就在这里。另外一点SKILL的质量不取决于写得多详细而取决于边界划得多清楚。什么该做、什么不该做、做到什么程度算完成这些边界越清晰Agent执行越稳定。我见过很多SKILL写得很长很全但边界模糊Agent执行起来反而犹豫不决。宁可写短一点把边界写死也不要写长而模糊。最后分享一个实用的小技巧如果你不确定一个SKILL该怎么拆就先按最粗的粒度写一版然后在实际使用中观察Agent在哪里卡壳。卡壳的地方就是需要拆分的信号。用着用着结构自然就清晰了。这比一开始就追求完美结构要高效得多。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑