skill规范翻译
skill规范的官方文档::https://agentskills.io/home支持skill的智能体:https://agentskills.io/clientsclaude官方skill:https://github.com/anthropics/skills其他参考文章:claude官方skill解析:claude官方skill解析skill的编写实践解读:https://zhuanlan.zhihu.com/p/2022392731603837461skill基本结构skill就是一个目录结果:skill-name/── SKILL.md # Required: metadata + instructions── scripts/ # Optional: executable code── references/ # Optional: documentation── assets/ # Optional: templates, resources── ... # Any additional files or directoriesskill.md文件分为两部分:顶部yaml给是的元素。这里必须按照规范写,包括:name:必须有,且和目录名要保持一样,最大64字符。description:必须有,最大1024字符。这部分license:非必选,许可证说明compatibility:非必选:环境要求说明,最大500字符metada:非必选,kv结构的其他任何自定义元数据,官方建议将作者和版本放到这个metadata里allowd-tools:非必选,空格课改的允许使用的工具列表后续markdow格式的正文。这部分没有任何要求,可以随意编写的,这里的内容是为了帮助大模型更好完成任务的,官方建议内容包括如下:步骤化的命令输入/输入示例一些边界场景。script目录:这里放一些可执行的脚本,这里支持的脚本语言类型,可能不同的智能体会有不一样,通常python、shell、JavaScript都会支持,但是这里的脚本编写的时候,官方建议:脚本要求能够独立运行,或者清晰描述出脚本的外部依赖。对于错误处理,需要包含清晰明确的错误提示。需要处理好边界casereference目录完成当前任务需要的一些额外的文档,当只能判断需要的时候,会自动加载,通常包含如下部分:reference.md:完成当前任务的技术参考文档,这里可以详细说明一些技术实现细节。forms.md:结构化的数据(或者表单数据)其他文档xxx.md:其他任何可能需要的文档,比如法律条文等注意:这个目录是相对路径,保持reference目录在和skill.md目录,而且尽量reference下不要有嵌套太深的路径了,一层就够了。assets目录放一些静态资源,比如一些模板数据:比如文档模板、配置模板等,用于文档和配置的模板说明图片/图表:比如图表、图片示例等。数据文件:比如查找表和数据架构文件可以使用如下命令来验证编写的skill是否符合规范skills-ref validate ./my-skillskill内容加载说到底,使用llm的时候,大模型能够获得的数据都只有两部分:模型数据:通过训练获得,训练后就不能再更新了,除非重新训练。微调就是在改变模型本身通过提示词:即在使用的时候通过提示词给到模型。模型本身的数据一旦训练完成,修改模型的代价是相对比较大的,不可能做到实时更新,而且基础模型训练的时候也拿不到某个特定行业的内部数据,所以模型训练的数据一定有其触及不到的信息,那么对于特定行业的大模型该怎么办呢?在基础模型上进行微调再训练:即将自己领域的数据作为训练数据,进行微调再训练,得到一个自己领域相关的模型。这个就是很多垂类大模型的做法,但是这个也需要比较大的代价的。通过提示词在使用的时候将领域数据传递给大模型,这种方式相对来说是实现成本是最低的,现在比较流行的RAG、提示工程、包括这里的skill,其实都是在干这个事情,甚至大模型的记忆功能也是通过将历史信息通过提示词再次给到后续的和大模型交互中来实现的。所以这里的所有技术都是在干一件事:帮助如何通过提示词的方式,让大模型更好的输出内容。但是这中方式有一个短板:大模型收费是按token收费的(输入+输出),输入越多越消耗token,那就收费越贵。输入的提示词是有大小限制的。不同模型限制不一样。所以为了节约token,这里的skill的内容也不是一下子将所有的skill都放到输入中,而是按需逐步加载:回话开始时,加载所有.claude/skills目录下的所有skill.md中的元数据部分,将这部分给到大模型。大模型会根据元数据中的description来判断,当前任务是否需要用到什么skill。如果大模型根据skill中的description判断,需要用到当前这个skill,那么就会加载skill.md中的指令部分(就是markdow格式的部分):将这里的数据给到大模型,大模型就会根据这里的描述来判断:是否需要调用外部工具、是否需要加载其他资源、是否需要执行脚本等等如果大模型判断需要其他文档就会自动取加载reference下的内容,再次给到大模型,大模型会叠加reference的内容再次输出;如果需要一些资源文件,那就加载asssets中的内容;如果根据上面这些信息大模型判断需要执行脚本,那么就会让agent直接调用scripts下的脚本来进行执行。从这个加载过程可以看出,写skill的时候,也不是随便乱写的skill.md中的元数据部分,控制在100 token内skill.md中的指令部分,控制在5k token内而整个skill.md一般建议不要超过500行。skill编写实践最贱实践一:基于实际领域只是编写skill的一个常见误区就是让通用大模型去生成一个skill,而没有提供特定领域的上下文,这种生成的skill往往空泛、笼统,缺少实际可后自行细节,不具备执行知道,往往效果并不是很好。更好的方式是在让大模型来生成skill的时候,要提供领域特定的只是、api调用方式,边界case、项目规范等等最佳实践二:从实践中提炼skill其实是将一个特定的任务执行的经验等固化下来,以便在相似场景的时候,agent能够按照沉淀下来的经验去完成相似的任务,这样对于相似任务的完成会更加的高效,且正确。所以实际的skill,应该是从实际的时间中提炼出沉淀出来的可复用的模式,让智能体能够重复使用这些可复用的经验。所以,从和大模型的实际对话中,提炼总结出来一个可复用的skill,在skill中一般可包含:分步骤引导:列出每一步需要做什么事情。易错点明确:在步骤中明确易错点,比如明确让agent使用工具A,而不是工具B;明确让大模型要注意便捷场景XXX输入/输出的格式明确:输入/输出的格式要求要明确,甚至可以分别给出示例上下文:明确当前任务执行的上线文,比如有哪些约束、哪些领域特定知识等,总之将当前任务执行时候大模型可能不知道的数据,都需要在skill里进行明确。总之,高质量的技能来自于真实的实践过程,需要记录任务执行中的关键细节和纠正点,而不仅仅是最终的指令。最佳实践三:从现有工程中提炼如果是现有的项目,可以尝试将现有的项目直接喂给通用大模型,让大模型来提炼总结出一个skill。这样大模型从现有实际项目提炼总结出来的skill,一般来说一定比基于通用大模型直接生成的skill要有效得多,因为从实际项目中,大模型会会总结现有项目的架构模式、故障处理、以及故障恢复处理等。说白了,从现有项目中总结,就会包含项目相关的资料,而非一些通用的信息。项目中易邮柜的资料一般包括:内部文档、运行手册白皮书、项目整体风格等。api描述文档、api的定义规范、配置文件到呢改代码CR的评论、cr提出问题的追踪(cr的评论、issure的追踪往往包含了重复出现的问题,以及代码review的要求)版本历史,特别是一些历史问题的修复真实的异常场景,以及对这些异常场景的处理最佳实践四:通过实际执行进行优化第一版本的skill执行效果并不一定理想,所以往往需要根据实际执行的效果进行调整skill。在使用大模型进行生成skill的后,根据实际任务来使用skill,并将执行的结果反向作为生成skill大模型的提示词,来进一步优化生成的skill,包括执行是所有结果(不仅仅是失败的结果)。如果遇到了失败,就需要看是什么原因导致了这个失败结果、是有什么被遗漏了么?是有什么可以被删除掉?往往将执行结果反向给到生成skill生成提示词,哪怕是只有做了一次这样的skill优化,往往skill的效果提升都比较显著。当然对于一些复杂的领域,可能会经历多次这样的:执行--反馈--修整skill--再执行注意:在实际执行的时候,不要仅仅只关心最终的输出,对于agent的执行过程也要仔细阅读,从agnet的执行过程中,我们可能会发现agnet可能浪费在了一些无效的步骤上。这些无效的步骤的产生往往可能是因为:skill的描述中,指令过于模糊导致agent尝试了多张方法多条路径才找到一个可行的方案指令并不适用当前任务,但因为在skill中有描述,所以agent也去照做了指令提供了太多的选项,但都没有默认值,就会导致agent去尝试各种各样的选项最佳实践五:skill内容要精简,简明扼要一旦大模型根据description决定要使用这个skill的时候,那么就会将整个skill.md文档进行加载,放到后面和大模型对话的提示词中,但是大模型的提示词的上下文窗口是有限的,而现在大模型的记忆(历史会话)、一些系统提示词、还有可能其他的skill都是通过提示词给到大模型的,那么如果skill描述的比较宽泛,内容比较多,就比较消耗这个context。所以在编写 Skill 时,内容要尽量精简、精准。因为 Agent 的上下文窗口空间有限,如果每个 Skill 都写得很啰嗦,就会挤占对话历史或其他关键指令的空间,导致 Agent “顾此失彼”,忘记原本的任务。最佳实践六:skill中只编写大模型不知道的,省略大模型已有的知识现在大模型的训练几乎都包含了所有公开的资源,比如github、开源软件库、编程语言sdk、各大知识网站等等,这些都是大模型已经有的知识了,在编写skill的时候,这些内容就不要出现在skill里。而大模型缺少的是你当前从事的特定领域、你当前工程项目的知识,比如当前你项目的特有的规范、你当前领域特有的术语概念特有流程等、当前领域里的一些特殊的边界case、以及当前项目需要使用的特殊工具、调用的特殊api等。所以在skill编写的时候,重点 就放在当前任务执行的领域特色信息、当前工程特殊要求这些信息。完全不用再kill里解释什么事pdf文档、http的执行过程等这些大模型很明显已经有的知识了一个例子:!-- Too verbose — the agent already knows what PDFs are -- ## Extract PDF text PDF (Portable Document Format) files are a common file format that contains text, images, and other content. To extract text from a PDF, you'll need to use a library. pdfplumber is recommended because it handles most cases well. !-- Better — jumps straight to what the agent wouldn't know on its own -- ## Extract PDF text Use pdfplumber for text extraction. For scanned documents, fall back to pdf2image with pytesseract. ```python import pdfplumber with pdfplumber.open("file.pdf") as pdf: text = pdf.pages[0].extract_text() ```编写到skill.md中的指令,都可以自我范文一下:如果没有这条指令,大模型是否会将整个任务搞砸如果答案是不会,那就不要这个指令如果不确定,那就保留后,测试一下,然后根据执行结果修正另外,如果 Agent 在没有这个 Skill 的情况下已经能很好地处理整个任务,那么这个 Skill 可能并没有带来实际价值,那这个skill都是非必要的。最佳实践七:单一职责(连贯的逻辑单元)在编写skill的时候,这个skill到底应该完成什么样的职责,就像变成函数定义一样,需要决策这个函数到底应该完成什么样的内容,函数的定义一般遵循单一职责,我们希望这个函数封装的是一个连贯的逻辑单元,并且能够与其他函数进行组合调用。 skill的定义也是一样的,需要这样的权衡一个skill到底应该包含什么样的内容。一个skill的职责过窄,那么在完成一个任务的时候就可能需要加载多个skill,从而导致更大的开销,设置可能出现使用的skill中各个指令存在冲突职责钉的过于宽泛,那么大模型有比较难以精确判断,是否应该使用这个skill比如查询数据库,并将结果按照指定格式进行输出是一个连贯单一的逻辑单元,但是在这之上叠加数据库管理的,那么就显得职责有点过多了最贱实践八:保留适度的细节过于详尽的 Skill 往往弊大于利:Agent 会难以从中提取相关信息,甚至可能因为那些不适用于当前任务的指令而误入歧途。相比于面面俱到的文档,简洁、分步骤的指导加上一个可运行的示例,通常效果会更好。当你发现自己试图覆盖每一个边缘情况时,不妨考虑一下:其中大部分是否交给 Agent 自行判断处理会更合适。最佳实践九:利用渐进式披露来组织大型 Skillagent skill的规范建议,将skill.md文件控制在500行、5k个token以内。在skill.md文件里只保留agent 每次运行所需的核心指令。如果一个skill确实需要更多内容时,应将详细的参考资料移至references/或类似的独立目录文件中。但是需要注意,在skill.md中需要告诉agnet什么时候加载什么样的文件,不要给一个笼统的"详见 references/"。比如“如果 API 返回非 200 状态码,请阅读references/api-errors.md”这样能让 Agent 按需加载上下文,而不是一开始就全部加载,这正是渐进式披露的设计初衷。最佳实践十:校准控制力度skill中并不是每个部分都需要同等程度的规约,不同指令可以不一样会不一样。最佳实践十一:Match specificity to fragility(根据脆弱性匹配具体程度)当完成任务的方法多种多样时,不用太死板的指定指令,而是在skill中解释指令背后的为什么,让agentg去理解背后的真实目的,然后大模型根据上下文可以做出更贴切的决策,自行决策实现方法,这往往是更有效的。比如一个做code review的skill,与其在skill中告诉agent第一步需要检查什么、第二步需要检查什么,还不如直接告诉大模型code review的要求,至于到底是先检查哪个、后检查哪个,agent自行来决定,比如:检查所有db查询sql的sql注入风险(必须使用参数化的查询)每个操作入口的权限校验在并发代码路径上,检查竞锁条件确认对外错误信息不回泄露内部信息但是如果你的任务执行顺序非常重要,一致性要求非常高,否则会导致代码的执行变得很脆弱,那么就应该描述清楚步骤,以及每一步骤执行的内容,比如如下的数据迁移skill:必须是先备份、再迁移,且迁移过程中不能修改,这就需要明确的告诉大模型## Database migration Run exactly this sequence: ```bash python scripts/migrate.py --verify --backup ``` Do not modify the command or add additional flags.大多数的任务场景,其实没有这么明显的区分,都是两种情况混合的,所以就需要根据任务情况,来确定什么时候描述要求,具体执行方式让agent自主决策;什么时候需要明确指明步骤,且每一步执行的指令。最佳实践十二:有多种选择的时候,提供默认值当完成任务有多种工具或方法可选时,请一定给一个默认方式。并且简明清晰的告诉agent什么时候替换默认方式。错误示范:!-- Too many options -- You can use pypdf, pdfplumber, PyMuPDF, or pdf2image...更好的方式是!-- Clear default with escape hatch -- Use pdfplumber for text extraction: ```python import pdfplumber ``` For scanned PDFs requiring OCR, use pdf2image with pytesseract instead.最佳实践十三:优先使用流程性描述,而非声明性描述一个skill是告诉agent某一类的问题改如何处理,而不是针对某一个具体的实例应该如何处理。反面示例:!-- Specific answer — only useful for this exact task -- Join the `orders` table to `customers` on `customer_id`, filter where `region = 'EMEA'`, and sum the `amount` column.这其实就是直接在告诉agent,联表查询orders和customer表,联表条件都写好了。其实这就是非常具体点问题,他就只能联表查表orders和表customer,要换个别的表就不行了更好的表达:!-- Reusable method — works for any analytical query -- 1. Read the schema from `references/schema.yaml` to find relevant tables 2. Join tables using the `_id` foreign key convention 3. Apply any filters from the user's request as WHERE clauses 4. Aggregate numeric columns as needed and format as a markdown table这就就是一个链表查询的茶镜。但也要注意,这并不意味着 Skill 不能包含具体执行细节、以及输出格式模板。比如skill里包含严禁输出个人身份信息是非常合理的。以及在skill里注明调用特定工具的指令,往往都是合理的方式,这里的关键在于度:哪怕是有个个别细节是必要的,但整个skill应该是解决的是一类问题,有一定的通用性。最佳实践十四:高效的指令模式各种各样的写skill的技巧,并不是每个skill都需要这些技巧,根基你实际的任务来决定使用什么样的skill写作技巧最佳实践十五:skill中包含陷阱提示在许多skill中,有的时候包含一份“陷阱提示”,是非常有必要的。比如对于一些违背常理的假设、对于特定环境的要求等。这些闲情提示,不能是一个笼统的,比如请妥善处理错误,这种提示并不是高效的。更好的做法是,如果不告诉agent这些提示,agent遇到这种情况的时候就会犯错,把这些情况给列简明清晰的列举。比如:user表使用的是软删除,查询的时候必须带条件WHERE deleted_at IS NULL,否则查询结果就会包含已经删除的用户用户id的表达,在表里是user_id,在授权服务里字段是uid、在账单接口里是accountId,这三个字段都表示用户id。/health接口,当且仅当服务器正常运行的时候返回200,哪怕数据库的连接关闭了/health也返回200。要检查整个服务是否正常,使用/ready如上这些提示,如果不告诉anget,当agent遇到这些情况的时候,他就可能犯错的。在skill.md文件中编写陷阱提示的时候,根据按需加载的逻辑,要确保agent在执行过程中,遇到这些陷阱情况之前,能够读到这些陷阱提示。当然,如果如果你能明确告知 Agent 何时加载,使用单独的参考文件来保存陷阱提示也是可行的。只是说在编写skill.md的时候要明确告知agent,在什么情况要去读取哪个文件。但这个也要注意但对于那些不明显的潜在问题,Agent 可能无法识别出触发时机。当在agnet使用当前skill执行任务的时候,从执行结果中,你发现agent犯了错,而这个错需要我们人肉来纠正,那么就请将这个case作为陷阱提示,写到skill.md中。也也是前面将的通过实际执行结果来优化skill最直接的方法。最佳实践十六:指定输出格式模板如果需要agent输出特定的格式,那么在skill中就指定输出格式模板。给出输出格式模板比使用文字描述输出格式要求,更加有效,因为agent更擅长更具具体的结构进行模式匹配。,简短的模板可以直接放在SKILL.md中;对于较长的模板,或者仅在某些特定情况下才需要的模板,建议将它们存储在assets/目录中,并在SKILL.md中引用它们,这样就可以仅在需要时才加载输出格式模板。举个例子:## Report structure Use this template, adapting sections as needed for the specific analysis: ```markdown # [Analysis Title] ## Executive summary [One-paragraph overview of key findings] ## Key findings - Finding 1 with supporting data - Finding 2 with supporting data ## Recommendations 1. Specific actionable recommendation 2. Specific actionable recommendation ```最佳实践十七:对于任务是多步骤的工作流时,提供check list当任务是多步骤执行的一个工作流的时候,在skill中,明确一个check list,可以帮助agnet来追踪工作流的精度,避免跳过步骤,特别是工作流中的步骤之间有依赖关系时,更应该指定check list## Form processing workflow Progress: - [ ] Step 1: Analyze the form (run `scripts/analyze_form.py`) - [ ] Step 2: Create field mapping (edit `fields.json`) - [ ] Step 3: Validate mapping (run `scripts/validate_fields.py`) - [ ] Step 4: Fill the form (run `scripts/fill_form.py`) - [ ] Step 5: Verify output (run `scripts/verify_output.py`)