ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Agent Skills 实战:把大型系统提示词拆成可复用技能包

Agent Skills 实战:把大型系统提示词拆成可复用技能包 1. 为什么我最后把 Agent 的能力拆成了一堆小技能包第一次接触agent-skills这个概念的时候我的反应是又来个新名词。当时我手上正维护着一个单文件两千多行的系统提示词里面塞了二十多种任务的处理逻辑每次改一个分支都像在雷区里走钢丝。直到我把这套东西按技能拆开重写了一遍才真正明白它解决的到底是什么问题。简单讲agent-skills 是把一个 Agent 的能力拆成一个个独立、可复用、按需加载的能力单元。每个单元就是一坨自包含的文件夹里面有说明、有脚本、有模板Agent 在需要的时候才把它读进上下文不需要的时候它连一个字都不占。它能解决的问题非常具体上下文被无关指令撑爆、一个 prompt 改到后面谁也不敢动、同一种能力在不同 Agent 之间没法搬运、以及最要命的——你没法知道到底是哪条指令在起作用。这套思路适合谁我建议这几类人重点看正在维护大型系统提示词的工程师、要给多个 Agent 复用同一批能力的团队、以及被改一处崩三处折磨过的独立开发者。如果你只是写个几十行的玩具 Agent那确实用不上拆技能反而是负担。但只要你的指令规模开始超过单个文件能舒服管理的程度技能化基本是迟早要走的路。我下面会把整个拆解过程、目录设计、触发调优、踩坑记录都摊开讲尽量给到能直接抄的结构和参数。2. 动手之前先想清楚技能化的收益到底从哪来2.1 单体式提示词的四个致命伤先说我为什么下定决心重构。那个两千行的提示词问题主要集中在四个地方。第一是上下文浪费。用户只是问了一句帮我把这个表格转成 CSV但我的提示词里关于图像生成、邮件撰写、日程安排的规则全都被塞进了上下文。这些规则一个字都没用上却实实在在占着 token还稀释了模型对真正相关指令的注意力。实测下来指令越杂模型越容易看漏关键的那几条。第二是修改风险。二十多个分支写在一个文件里A 分支的规则和 B 分支的措辞高度相似改 A 的时候手抖碰到 B线上跑一周才发现。这种问题在结构上就是无解的因为你没有物理隔离。第三是复用困难。我另一个 Agent 也需要解析 PDF 表单这个能力但我没法直接搬因为那段逻辑跟主提示词里的变量约定、输出格式、错误处理全缠在一起。只能复制粘贴再手动改改完两个版本又开始漂移。第四是定位困难。某个任务表现不好我根本不知道该改哪。是触发描述写得不够准是步骤顺序有问题还是某个工具调用的参数给错了全糊在一起只能靠猜。2.2 技能化之后这些痛点分别被谁接走了拆成技能之后这四个问题各自找到了对应解法。上下文浪费靠渐进式披露解决。技能的元数据名字加描述常驻占几十个 token技能的正文只在被选中时加载技能附带的脚本和参考文档只在正文里明确需要读的时候才加载。三层结构越往里越重越往里越少用。这样一来二十个技能同时在册实际占用的上下文可能还不到原来的三分之一。修改风险靠物理隔离解决。每个技能一个文件夹改 A 技能不可能碰到 B 技能因为它们在磁盘上就是两棵不相交的子树。改坏了直接回滚那个文件夹就行。复用困难靠自包含解决。技能把它的脚本、模板、参考文档全带在文件夹里换个项目直接拷过去。只要运行环境里有对应的依赖它就能跑。定位困难靠边界清晰解决。任务表现差我先看触发描述有没有命中再看技能正文的步骤最后看脚本执行日志。三段式排查每次只需要盯一个环节。2.3 什么情况下我反而不建议拆拆技能不是没有成本。每个技能都要写描述、定契约、测触发这些都是实打实的工作量。我的经验是下面几种情况先别拆。技能数量少于五个、每个技能的逻辑不超过三十行的时候拆了管理成本大于收益。技能的调用链特别长、中间状态必须共享的场景拆成独立技能反而要来回传参不如写成一个整体。还有就是探索阶段需求天天变这时候把东西钉死在技能结构里改起来比改一段 prompt 还慢。说白了技能化是给已经稳定下来、需要长期维护和复用的能力准备的。你还在找方向就别急着上结构。3. 一个 Agent Skill 到底由哪几块构成3.1 元数据层决定这个技能会不会被选中元数据是技能的门面也是最容易被低估的部分。一个典型的技能描述文件长这样前面用 frontmatter 放元数据--- name: pdf-form-filler description: 填写和提取 PDF 表单数据。当用户需要把结构化数据填入 PDF 表单、或从已有 PDF 表单中读取字段时使用。支持 AcroForm 和 XFA 两种表单格式。 --- 下面是技能正文name要短、要唯一、用连字符分词。description是重点它实际上是写给模型看的使用说明书模型靠它判断当前任务该不该激活这个技能。我踩过的坑是一开始把描述写成了功能罗列比如这是一个 PDF 处理工具支持填写、提取、合并、拆分结果模型经常在纯合并 PDF 的任务上误触发它。后来我把描述改成了做什么 什么时候用的结构并且明确写出不覆盖哪些场景误触发率明显下降。描述里出现用户可能说的原话很关键比如用户会说把这份表单填一下那描述里就带上填写表单这种说法。3.2 指令层渐进式披露的主战场技能正文就是指令层它是整个技能被激活后加载的第二层内容。这里有个设计原则我一直坚持正文只写怎么做的决策逻辑不写大段的数据和细节。举个例子处理客户反馈这个技能正文里应该写的是先判断反馈类型是投诉还是建议投诉走 A 流程建议走 B 流程判断依据看是否涉及已有订单。而具体的投诉话术模板、各类建议的分类标准这些东西应该丢到references/目录下的文件里正文里只留一句分类标准见 references/taxonomy.md。为什么要这么切因为正文是每次激活都要完整加载的它有硬性的大小压力。而参考文档只在真正需要处理某个分类时才读读的时候也只是读那一小段。我见过有人把两千行的分类规则全塞进技能正文结果每次激活都吃掉一大块上下文等于没做渐进式披露。正文的另一个写法要点是用祈使句给明确的判断依据不要写你可以考虑……这种软绵绵的表述。模型对明确指令的服从度比对建议性措辞高得多。3.3 资源层脚本、模板、参考资料怎么放资源层是技能自包含的关键。我的目录习惯是这样的pdf-form-filler/ ├── SKILL.md ├── scripts/ │ ├── fill_form.py │ └── extract_fields.py ├── references/ │ ├── acroform-notes.md │ └── xfa-quirks.md └── assets/ └── field-mapping-template.jsonscripts/放可执行脚本。这里有个重要判断能写成脚本的确定性逻辑就别让模型去推理。比如解析 PDF 表单字段这活儿用代码干是百分之百准确的让模型去看图说话既慢又容易错。脚本的价值就是把确定性任务从模型手里拿走。references/放需要时再查的知识。判断标准是这段内容是不是只在特定分支才用到是的话就放这儿。assets/放模板、映射表、示例文件这类会被直接引用或复制的静态资源。3.4 输入输出契约技能之间怎么接力单个技能好用不代表一套技能好用。多个技能串起来跑的时候最容易出问题的地方就是技能之间传数据。我的做法是给每个技能都定义清楚的输入和输出。输入方面明确它需要哪些字段、哪些是必填哪些可选、格式是什么。输出方面规定它必须返回一个固定结构的对象而不是一段自由文本。比如抽取类技能统一返回{items: [...], confidence: ...}这种结构下游技能就不用去解析自然语言了。这一步看起来多余实则是省大麻烦。我之前有个流程A 技能输出一段描述性的文字B 技能再去理解这段文字中间信息一丢B 就开始胡编。改成结构化输出后整条链的稳定性上了一个台阶。4. 手把手搭一套能跑起来的技能体系4.1 目录结构从顶层怎么摆先说顶层怎么组织。我一般会在项目里开一个skills/目录底下每个技能一个子目录project/ ├── skills/ │ ├── pdf-form-filler/ │ ├──>--- name:>## 处理流程 1. 先用 scripts/profile.py 跑一遍数据画像看行数、列数、缺失率、重复率。 2. 行数小于 1 万直接在内存里处理按下面的规则逐列清洗。 3. 行数超过 1 万走分块路径参考 references/large-data.md。 4. 缺失值处理优先级数值列用中位数填补类别列用众数超过 60% 缺失的列直接标记待用户确认不要擅自填。 5. 重复行按全字段完全一致判定保留第一条。 6. 清洗完成后必须输出清洗前后的对比摘要包含处理了多少行、多少列、各类操作各影响多少条记录。 ## 详细规则 字段类型识别、异常值判定阈值这些细节见 references/cleaning-rules.md。第四步写脚本。profile.py负责数据画像纯确定性逻辑不让模型碰。第五步测触发。我准备了十条测试问句五条该触发的、五条不该触发的跑一遍看命中情况。这一步不能省描述写完自己看着挺好实际跑起来经常不触发或者乱触发。5. 技能路由让 Agent 在对的时候挑对的技能5.1 描述即路由这是最反直觉的一点很多人以为路由是靠代码写的判断逻辑其实在那个清单注入的架构里路由完全由描述文字驱动。模型读清单自己判断该用哪个。这意味着调试路由本质上是在调试文案。我一开始不信这个邪试图在系统提示词里加各种如果用户说 X 就用 Y的硬规则结果技能一多规则之间互相打架还不如把描述写好来得干净。所以遇到技能不触发第一反应应该是去改描述而不是去加规则。5.2 把触发率从六成拉到九成我做了这几件事第一件把用户原话塞进描述。用户会说帮我把这个表清一下那描述里就写清洗表格。用户的表达习惯要猜测到位。第二件加负向排除。相邻技能最容易互相误触发。>[ {input: 帮我把这个表里的空值补一下, expect: true}, {input: 这个 CSV 里重复行好多清一下, expect: true}, {input: 帮我画个销售趋势图, expect: false}, {input: 分析下这批数据的分布, expect: false} ]每次改完描述把这几条跑一遍。别小看这十几条它拦住过我至少三次把技能改废的操作。6.2 埋点看什么指标光看对错还不够我会记录三个指标。触发率该触发的任务里实际触发了多少。低于九成说明描述不够准。误触发率不该触发的任务里误触发了多少。超过一成说明边界没划清。内部成功率技能触发之后任务真正完成的比例。这个指标低问题就不在路由而在技能正文或者脚本。这三个指标分开看非常关键因为它们的修法完全不同。触发率低去改描述成功率低去改正文和脚本混在一起看就会瞎改。我个人的体会是技能体系真正的价值不在于让 Agent 变聪明而在于让它的能力变得可维护。从前改一个 prompt 是玄学改完不知道会不会崩现在改一个技能我有描述、有正文、有脚本、有用例每一步都能验证。这套结构带来的确定性比它省下的那点 token 值钱得多。最后分享一个小技巧新写一个技能的时候先只写元数据和一个空正文跑一遍触发测试确认路由没问题了再往里填内容。反过来做——先埋头写完一大篇正文再测触发——一旦发现触发不准你会舍不得删那篇正文然后就开始打补丁越补越乱。这个顺序我踩过坑希望你别再踩一遍。
返回列表