Agent技能管理体系:从散装Prompt到结构化技能文件 说实话第一次在调试记录里看到agent-skills这个命名的时候我愣了一下。等我把手头那个频繁精神分裂的Agent项目拆开重做之后才反应过来真正卡住我们大半年的根本不是模型能力不够而是我们从来没给Agent建立过一套正经的技能管理体系。这篇内容不聊大模型原理也不搬论文。纯粹从一个写代码的人视角聊聊我围绕agent-skills这个思路把原来一堆散装Prompt整理成结构化技能文件之后系统行为发生了哪些肉眼可见的变化踩了哪些坑以及现在回看哪些设计是最关键的。1. 为什么我把注意力从堆Prompt转向了Skills体系1.1 散装Prompt最大的问题是不可预期早先做Agent我的习惯是这样的把任务背景、角色设定、工具清单、注意事项全部塞进一个超长的System Prompt里。需求一多就接着往后面追加最后那个Prompt文件比我毕业论文还长改一个业务细节要全局搜一遍关键词生怕动了哪句话导致别的场景崩掉。但真正让我破防的不是维护成本而是行为不可控。同样一个Agent上午跑流程还很规矩下午换了模型版本之后开始自作主张跳过步骤明明只让它查天气它把上下文里所有历史对话当成背景信息写了一大段综合研判报告。这类问题的根源是什么是我们的指令全部混在一坨文本里模型根本分不清什么时候该做什么。agent-skills这种设计思路解决的就是这个问题不是给Agent写一篇全能说明书而是把它的能力拆成一个一个独立封装的技能文件每个技能只负责一件具体的事包含触发条件、执行步骤、输出格式、边界限制。Agent在某个节点该调用哪个技能由路由逻辑决定而不是让模型在一团乱麻里自己猜。1.2 技能文件和Prompt的本质区别很多人觉得这不就是把Prompt拆成几个文件嘛本质上没区别。最开始我也这么想等实际做完对比实验才发现差得远。一张表格就能说明白维度传统长Prompt技能文件Skills触发机制全靠模型在上下文里自行判断显式的技能描述路由逻辑内容组织所有能力平铺混排按职责拆封每个文件独立可测试性改一句影响全局难以定位单技能独立验证回归方便复用性换个项目基本重写跨项目复制改参数即用上下文占用超长Prompt持续占据token按需加载不用的技能不进上下文行为一致性依赖模型当时的心情尽量把不确定性约束在技能内部关键差异在最后一条agent-skills的核心逻辑是把能力外置Agent本身只做规划和路由具体怎么执行一件事交给确定的技能文件来约束。这相当于你把一个实习生的工作手册从一段模糊的口头交代变成了一套标准作业程序。模型漂移的影响被限制在理解任务并选对技能这个层面而不是在3000字指令里找出对的那一句。2. Skills的物理形态从SKILL.md到技能目录的整体设计2.1 一个技能文件该长什么样这个体系落地的时候我参考了社区里比较常见的做法按一个目录代表一个技能的规范来组织。每个技能目录里必须有一个技能定义文件一般习惯命名为SKILL.md其余根据需求放示例脚本、参考文档、模板文件。整体结构长这样skills/ ├── meeting-minutes/ # 会议纪要技能 │ ├── SKILL.md # 技能定义必选 │ ├── templates/ │ │ └── minutes.md # 输出模板 │ └── examples/ │ └── example_input.md ├── code-review/ # 代码审查技能 │ ├── SKILL.md │ └── checklists/ │ └── python.md └──>--- name: meeting-minutes description: 用于将会议录音转写文本整理为结构化会议纪要输出包含结论、分歧点、待办事项。 when_to_use: 当输入包含会议参与人对话记录且需要产出会议纪要文档时使用。 ---注意when_to_use这个字段。我一开始没写它结果Agent在用户单纯描述今天开会讨论了XX的时候也会触发会议纪要技能生成了大量无用输出。后来我把什么场景下该用和什么场景下不该用写清楚误触发率立刻降下来了。2.2 技能内容的分段设计逻辑SKILL.md元信息下面就是正文。这一部分不要写成长篇大论而是写清楚做这件事的步骤和标准。我现在固定用三段式执行步骤用有序列表写明从输入到输出的处理阶段每个阶段一句话即可避免让模型自由发挥。输出规范明确最终产物的格式比如使用Markdown表格列出待办事项每条结论必须注明对应发言人。边界与禁区写清楚哪些动作不允许做比如不得修改用户原始输入不生成会议中未讨论内容的决策。以前写Prompt总想着把话说全生怕模型听不懂。实践下来恰恰相反技能文件写得越克制命中率越高。原因也简单模型对结构化短指令的遵循度远高于长篇大论的温言劝导。你把步骤压缩到 5 条以内它照着做的概率极高你把每步都展开成 300 字它反而开始理解性发挥。2.3 技能目录统一放在项目根的skills/下没有硬性规范说技能必须集中放但我的习惯是所有技能统一塞进项目根目录的skills/文件夹。这样做的直接好处有三个第一路径清晰任何人接手项目打开根目录就知道Agent有哪些能力第二加载逻辑简单初始化Agent时遍历目录即可不需要维护复杂的索引表第三方便后续做版本管理整个skills/目录可以单独打包共享也可以挂在远端仓库作为公共技能库。跨项目迁移的时候直接把整个skills/目录拷贝过去顺手把技能依赖的脚本路径改一下一个Agent就拥有了另一套完整能力集。这件事在传统Prompt模式下基本没法想象每一个新项目都要重新调Prompt跟调教新员工似的。3. 手写一个可复用的技能文件结构、参数与流程3.1 从零定义一个技能以代码审查为例拿我这个项目里每天都在用的代码审查技能举例。以前我让Agent做代码审查直接在System Prompt里写请审查提交的代码关注bug、性能和可维护性并给出修改建议结果就是每次输出的审查报告风格完全不同有时候给表格有时候给长文甚至有一次把代码直接重写了一遍搞得人很头大。改成技能文件之后我先定义清楚了代码审查这个技能的边界--- name: code-review description: 针对使用者提交的代码变更做静态审查输出问题列表与修改建议。 when_to_use: 当输入包含代码片段或diff内容且用户明确要求进行代码审查时。 when_not_to_use: 用户未要求审查时不得主动评论代码质量用户要求重构或改写代码时不应调用本技能应直接修改。 --- ## 执行步骤 1. 识别输入中的代码片段或diff确定涉及的编程语言。 2. 按优先级依次检查正确性缺陷空指针、越界、逻辑反转、安全隐患SQL注入、硬编码密钥、性能问题N1查询、重复计算、可维护性命名、魔法数字、重复代码。 3. 将问题按严重程度分级P0必须修复、P1建议修复、P2可选优化。 ## 输出规范 - 使用Markdown表格输出列为严重级别、文件行号、问题描述、修改建议。 - 每个问题必须附带可读性良好的代码示例示例放在表格下方。 - 不得直接重写用户代码除非用户明确要求。 ## 边界 - 只审查输入范围内的代码不推测未提供文件中的问题。 - 不执行自动修复只提供建议。这个文件写完之后Agent的审查行为稳定了很多。输出格式不同的问题彻底消失了审查深度也基本稳定在一个可接受的水平。后面我又在这个技能目录里加了一个checklists/文件夹放各种语言的检查清单让模型按需参考。比如Python项目的审查可以额外读取checklists/python.md里面列明常见反模式和对应的排查方式。这一步把领域经验也沉淀进了技能里而不是只依赖模型的通用知识。3.2 参数传递让技能和你的业务数据解耦技能不能是封闭的。它必须接收外部的输入否则每个场景都要复制一份技能文件那就谈不上复用了。我的做法是技能文件的说明中明确约定输入字段由Agent从对话上下文中提取并填充。以会议纪要技能为例我约定的输入格式是## 输入约定 调用本技能时请从对话中提取以下字段 - 参会人员: 通过上下文或用户明确指定获取 - 会议主题: 通常为用户第一句话点明的内容 - 对话记录: 用户提供的全部文本这样设计之后技能本身只依赖字段值的输入结构不关心这些值来自哪个渠道。用户可能直接粘贴记录也可能让Agent从某个附件里读取字段层面完全复用。遇到字段缺失技能文件中还要写明兜底策略参会人员缺失时默认写未知会议主题缺失时根据第一条消息推断并加注推断。3.3 技能内嵌脚本把算法逻辑从模型手里拿走纯文本技能文件能做很多事情但遇到需要精确计算或数据处理的场景让模型心算就不靠谱了。比如数据分析技能我让模型自己算数据集的四分位数和异常值它每次算出来的结果都不一样而且从不告诉用户它用的是哪种方法。后来我改了方案把这种确定性逻辑写成Python脚本放进技能目录的scripts/文件夹技能文件里写清楚当需要计算异常值时执行scripts/outliers.py并将输出作为依据。模型负责判断什么时候该跑脚本、解释脚本输出但纯粹的数值计算交给真正的代码。这套设计思路后来被我推广到好多技能里能交给代码的绝不留给模型自由发挥。模型擅长的是理解需求和组织语言不擅长的是精确计算和稳定复现。一个技能文件里动的操作越多执行结果就越稳定。4. 技能质量的核心边界感与渐进式披露4.1 边界感是单技能稳定的基石我在很多技能文件里反复强调什么时候不该用它刚开始身边同事不理解觉得写这些限制是画蛇添足技能本来就是干这个的还写什么不让干。到项目跑起来之后大家才意识到边界描述能救多少场。以会议纪要技能为例我在when_not_to_use里写了用户仅询问如何组织会议时不调用本技能。如果不写这条Agent会在用户问开会应该注意什么的时候直接生成一份随机会议的纪要答非所问等于无效回答还浪费大量token。边界写得具体Agent的选择就是一路坦途。我建议每个技能文件里都加一个当用户表达内容与技能目的相关但并非要求执行时的处理条目。这个边界成本极低收益是肉眼可见的稳定性提升。我自己在后来的技能模板里把它列为必填项了。4.2 渐进式披露不要让模型一口气读完所有细节技能文件最忌讳写成百科全书。一个技能的完整执行细节可能有两三千字如果全部塞进模型上下文不仅浪费token还会稀释核心指令的权重。渐进式披露Progressive Disclosure的做法是SKILL.md主文件只写核心步骤、输出规范和不能做的事控制在500字以内那些进阶技巧特殊场景处理之类的内容放在同目录下的参考文档里主文件中写一句如处理××场景参考references/xxx.md。模型只有在遇到对应场景时才会按需读取那个文档。实际效果差异非常大。两个技能一个全量塞入一个按需加载前者在长任务中目标丢失的周期明显更短后者在连续执行多轮任务时准确率几乎不衰减。这和人的工作记忆一个道理不管能力多强你在某一时刻能全神贯注处理的信息量是有限的。让Agent先记住核心步骤是保障长链路稳定的关键。4.3 技能描述会被模型阅读理解meta信息要下功夫既然技能是按描述被路由的那description字段才是模型决定到底用不用你的第一道关卡。描述写得不准确后面所有细节都白搭。我踩过的坑是把描述写得太宽泛。比如用于处理数据分析相关问题结果分析需求来了模型看了半天觉得这个描述太笼统宁可自己发挥也不用技能我又回到之前的混乱状态。后来我把描述改成输入包含表格或结构化数据集合且需要探索数据分布、检测异常值或提取统计指标时使用。指向性瞬间清晰命中率从六成左右稳定提升到九成以上在线上的对话日志里测了好几轮效果非常显著。写作时的技巧是把自己放在Agent视角它的上下文里有一堆技能描述每个描述只有一两行它必须判断当前用户需求由哪个技能来承接。如果你自己是模型看了这段描述能秒懂它的使用场景吗按这个标准去写基本不会差到哪去。5. 调优与实测技能冲突、误触发和收敛策略5.1 技能多了就会互相打架层级与优先级设计技能数量一多新的问题冒出来了多个技能描述看起来都沾边模型选了错误的那一个。最典型的例子我同时建了内容总结和会议纪要两个技能。有次用户发了一段会议对话说帮我总结一下模型去调了内容总结输出的是摘要而用户其实想要的是带待办事项的纪要。这类问题的本质是技能之间没有明确的优先级关系。我的方案分两种触发条件收窄在会议纪要的description里明确要求当输入内容属于多人同步交流记录且输出需要包含待办事项时优先使用把场景区分度拉大。引入路由前置判断在Agent的规划提示里写一句涉及多个技能时优先选择执行步骤更具体、更贴近用户原始意图的那个拿不准时向用户确认不要自行猜测。其实这个问题还可以做得再彻底一点给技能元信息加一个priority场数字精确匹配路由时按最高优先级的技能优先加载。不过跑了几周我发现收敛触发条件之后基本用不上这么重的机制。先把描述写清楚大多数冲突自己就消失了。5.2 单技能回归测试一个人的质量保障agent-skills体系最大的隐性红利是每个技能都可以独立测试不用再开一个完整Agent跑端到端流程。我日常调优的手法是写一个test_inputs/目录每个技能文件夹下放5到10条标记过的输入用例有一部分是该触发的有一部分是故意为难它不该触发的。跑完看两个指标召回率该触发的有没有漏和误报率不该触发的有没有乱出。有一次我调整了会议纪要技能的描述把多人交流记录改成会议或多人对话的转写文本结果误报率立刻上升了两个百分点。回滚之后我又把描述改成包含发言人与对话轮次的文本误报率才降回去。没有这套测试集这类细微的语义漂移根本不可能是能隔夜发现的。技能仓库里跑测试成了我后面发布技能之前的固定动作。5.3 上下文污染技能一旦加载就会留在上下文里还有一个细节容易忽略技能文件被加载之后它的内容会残留在上下文中。就算这次任务已经结束后续几轮对话里模型仍受它影响。最典型的场景是用户调用会议纪要技能生成了一份纪要。然后接着问帮我把这封邮件翻译成英文。按理说这跟会议纪要没有半点关系但因为技能文件还在上下文模型可能把邮件翻译整成把会议纪要用英文重新排版输出。解决思路有两个方向。一是系统层面做上下文清理在每个任务的结尾标记技能上下文结束强迫模型把后续内容当成新任务对待二是技能文件本身加提示完成输出后如用户新提出的要求与当前技能无关则忽略技能中的格式与步骤约束。第二个方案实施起来更简单实测也确实有效。我通常是两个一起做一个从外部压制一个从内部提醒双管齐下。6. 多Agent协作下的技能编排与共享6.1 技能作为Agent的可复制能力单元项目做到后期已经不是一个Agent在干活了。我拆了三个角色一个负责日常问答一个负责代码相关任务一个负责数据分析。它们的能力有一部分是重叠的比如都要求能读文件、能写摘要。如果每个Agent各自维护一套Prompt改一处要同步三遍迟早出不一致。技能的引入让这件事变得很轻松公共技能放进共享目录各Agent按需加载。负责代码审查的Agent不会去读会议纪要技能但代码审查技能内部又会引用文件读取这种公共技能。能力成了模块Agent变成了组装模块的壳子比起单一Agent包揽所有任务可维护性提升得不止一个量级。6.2 技能共享仓库改一处处处生效技能共享之后版本更新就成了大家关心的头等大事。我目前用的是最原始但最可靠的方案技能目录用Git管理所有变更走提交记录技能文件头部备注最后修改人和修改原因。Agent加载技能时读的是当前工作分支的内容改完直接同步到所有用到该技能的Agent上无缝衔接新逻辑。当然这是一把双刃剑。如果某个Agent依赖旧版技能的行为共享技能的更新就可能让它行为突变。我的折中方案是一个技能目录下可以放SKILL.md当前版本和SKILL.v1.md旧版本需要锁定行为的Agent在配置里指明使用SKILL.v1.md。这样既享受了共享的便利又不用怕公共技能改挂了自己的流程。6.3 跨项目克隆一套技能体系的隐性收益最后说一个隐性收益技能的跨项目复用能力比想象中大得多。我在A项目里写的会议纪要技能原封不动拷到B项目几乎不用改就能正常工作。因为技能文件描述的是如何把输入转为输出它与具体业务解耦得足够彻底。沿着这个思路我已经在内部攒了几十个通用技能内容覆盖代码审查、文档生成、数据分析、信息抽取、报告规范化等高频场景。新项目启动时不再是从零开始调教Agent而是从技能库里挑合适的直接组装一个新Agent上场。原来一个Agent从搭建到稳定需要两周现在选好技能、跑一遍单技能测试两天就能用在真实业务里。这也是agent-skills让我最受触动的一点Agent的能力不再是一锤子买卖它变成了一笔可以跨项目积累的资产。每打磨一个技能等于给未来的所有项目都做了一次升级。说回项目本身我回头看这轮重构印象最深的反而不是某个具体技能写得多好而是把Agent的能力当作工程资产来管理这件事。技能文件让能力有了边界有了版本有了测试也有了跨项目复用的可能。那些曾经让我头疼的模型不听话问题从根源上被改变了我不再期待模型自己变聪明而是给它一套足够清晰的规则让它没有机会乱来。如果你现在也在跟Agent的行为反复作斗争我建议别急着加Prompt了。花点时间把能力拆成一个个独立的技能文件配上清晰的边界描述和触发条件先跑一周看看。也许你会发现问题比我说的还顽固但方向大概率是对的Agent的进化下一步不是模型再变大而是技能体系变得更好用。