
1. 从一次“翻车”说起为什么你的 Skill 越写越臃肿去年年底我接手了一个内部 Agent 项目核心逻辑封装在一个 Skill 里最初只有 200 多行提示词跑得挺顺。三个月后产品经理不断加需求运营同学不断塞边界条件我自己也忍不住往里补“万一遇到 XX 情况就 YY”的兜底逻辑。等到某天线上开始频繁出现“答非所问”和“指令漂移”我打开那个 Skill 文件一看——1800 多行光“注意事项”就占了 400 行里面还有三处自相矛盾的约束。这就是典型的 Skill 肥胖症。它不会立刻崩但会慢慢钝化模型开始忽略靠后的指令关键约束被淹没在噪音里同一个问题两次回答风格不一致调试时你根本不知道是哪一段提示词在起作用。后来我做了一轮系统性瘦身把那个 Skill 压回 400 行以内效果反而比臃肿版本更稳、更准、更可控。这篇文章就把这套“给 Skill 瘦身”的完整方法论拆开讲清楚从诊断、拆解、重写到验证每一步都给出可复现的操作。不管你是刚接触 Agent 开发的新手还是已经在用 Claude Code、DeepSeek 这类工具做提示词工程的老手都能直接抄作业。先明确一下本文说的 Skill 是什么。在 Agent 语境下Skill 通常指封装了特定能力的一段结构化提示词加配套脚本/工具调用的组合单元它告诉模型“在什么场景下、按什么规则、调用什么资源、产出什么结果”。它可能是一个 Markdown 文件也可能是一个带 frontmatter 的目录甚至是一段嵌在系统提示里的模块。无论形态如何臃肿的根源和解法是一致的。2. Skill 瘦身的核心思路不是删字是重建信息层级2.1 先搞清楚“胖”在哪里三类典型冗余很多人一听说瘦身第一反应是“把废话删掉”。但我实测下来单纯删字效果有限因为真正拖垮 Skill 的不是字数而是信息层级混乱。我把常见的冗余归成三类你可以对照自己的 Skill 自查。第一类是规则堆叠。同一个约束用不同措辞写了三遍比如“输出必须是 JSON”“禁止输出非 JSON 内容”“返回格式严格限定为 JSON 对象”三条其实是一条。模型读到后面会开始怀疑前面反而降低遵从度。第二类是场景污染。把 A 场景的边界条件写进了通用 Skill 里导致 B 场景执行时被无关约束干扰。典型表现是 Skill 里出现大量“如果用户问的是 XX 则……”的分支而这些分支本应拆成独立 Skill。第三类是元指令膨胀。大量“你要认真思考”“请务必仔细”“这非常重要”之类的强调词。这类词偶尔用一次有效用十次就等于没用还会挤占真正关键指令的注意力权重。2.2 瘦身的目标让每一条指令都可被归因我给瘦身定的验收标准只有一条任意一条输出异常我都能在 30 秒内定位到是哪一段提示词导致的。达不到这个标准说明 Skill 还是太胖或结构太乱。为了做到可归因核心手段是重建信息层级。一个健康的 Skill 应该分成四层从外到内依次是角色与目标层、能力边界层、执行规则层、输出格式层。层级之间职责不重叠同一层内条目互斥且穷尽。这样模型读的时候是“先知道我是谁、要干嘛再知道不能干嘛然后知道怎么干最后知道交付成什么样”认知负担最小。2.3 为什么“瘦”反而“强”注意力预算的视角这里补一个底层原理理解了它你就明白为什么瘦身能提升效果。大模型处理提示词时注意力资源是有限的可以类比成一块固定大小的白板。你写进去的每一条指令都在抢占白板上的位置。当 Skill 膨胀到上千行关键约束比如“金额计算保留两位小数”会被大量次要信息稀释模型在生成时对这些约束的“记忆强度”下降于是出现漂移。瘦身的本质是把有限的白板空间留给真正决定输出质量的那 20% 指令。我做过对比测试同一个任务1800 行版本的关键约束遵从率大约 72%压到 400 行后升到 94%。这不是玄学是注意力分配的直接结果。提示瘦身不是越短越好。把 Skill 砍到 50 行但丢失了必要的边界约束同样会翻车。目标是“无冗余”不是“极简”。3. 实操五步把臃肿 Skill 压回健康体积3.1 第一步给现有 Skill 做“体检”动手改之前先量化诊断。我常用的方法是把 Skill 按段落切分逐段打标签标签分四类角色定义、能力边界、执行规则、输出格式再加一个“其他/存疑”。打完标签你会直观看到哪一类严重超标。具体操作把 Skill 内容复制到一个表格里一列原文一列标签一列“是否可合并”。我一般用脚本先按空行和标题切段再人工过一遍。下面是一个简化的切段脚本示例处理 Markdown 格式的 Skill 文件很顺手。import re def split_skill(path): with open(path, encodingutf-8) as f: text f.read() # 按二级/三级标题或连续空行切段 blocks re.split(r\n(?#{2,3}\s)|\n{2,}, text) return [b.strip() for b in blocks if b.strip()] for i, block in enumerate(split_skill(my_skill.md)): print(f--- 段落 {i} ---) print(block[:120])跑完你大概率会发现执行规则层占了 60% 以上其中又有近一半是可合并的重复约束。这就是你的主要下手对象。3.2 第二步合并同类项消灭重复约束把上一步标为“执行规则”的段落全部拉出来逐条比对语义。判断两条是否重复的标准是是否存在一种输入让两条规则给出不同结论。如果没有它们就是重复的合并成一条表述最清晰的即可。举个例子我原来那个 Skill 里有这么几条输出必须使用中文禁止使用英文回复用户所有面向用户的文本语言为简体中文合并后只留一条“所有面向用户的输出使用简体中文。”三条变一条语义完全等价模型遵从度反而更高因为不再需要处理三条措辞不同但指向相同的指令。这一步通常能砍掉 20% 到 30% 的体积。别小看这个比例它砍掉的全是噪音。3.3 第三步场景拆分把“万能 Skill”拆成专用 Skill如果你的 Skill 里出现了大量条件分支比如“当用户是新手时……当用户是专家时……当涉及退款时……当涉及查询时……”说明它承担了太多场景应该拆。拆分原则一个 Skill 只服务一类任务、一类用户意图。拆完之后由一个路由层可以是主 Agent 的判断逻辑也可以是一段轻量的意图识别提示词决定调用哪个 Skill。这样每个 Skill 都能保持精简且互不干扰。我那个项目最后拆成了四个 Skill查询类、计算类、生成类、兜底类。原来 1800 行的单体拆完后最大的一个 380 行最小的 90 行。维护成本骤降因为改查询逻辑时再也不用担心碰坏计算逻辑。3.4 第四步重写指令用“可执行语言”替换“描述性语言”这是最考验功力的一步。臃肿 Skill 里大量指令是描述性的比如“尽量保证回答准确”“注意保持语气友好”。这类指令模型没法执行因为“尽量”“注意”没有可操作的判定标准。重写的方法是把它翻译成可执行语言。所谓可执行就是模型能据此做出明确的“做/不做”判断。对比一下描述性写法可执行写法尽量保证回答准确涉及数字计算时必须给出计算过程无法确认的事实明确标注“未验证”注意语气友好使用第二人称“你”禁止使用“显然”“众所周知”等居高临下措辞回答要简洁默认输出不超过 200 字用户明确要求详细时不受此限遇到不确定的情况要谨慎置信度低于阈值时输出“我需要更多信息”并列出缺失项禁止猜测右边这列每一条都能被模型明确执行也能被你明确验证。重写之后Skill 的可测试性大幅提升。3.5 第五步回归验证用测试集确认没有“瘦出问题”瘦身最大的风险是砍掉了隐性依赖。所以改完必须回归测试。我的做法是维护一个 20 到 30 条的测试集覆盖正常场景、边界场景、对抗场景三类。每次改完 Skill 都跑一遍对比新旧版本的输出。测试集不用很复杂一个 Markdown 表格就够编号输入期望行为旧版结果新版结果是否通过01计算 3 件单价 19.9 的商品总价输出 59.70含计算过程通过通过是02询问未收录的产品参数明确说明无法确认不猜测失败编造通过是03要求用英文回复仍使用简体中文通过通过是跑完这张表你就能确信瘦身没有引入回归问题。我实测下来瘦身后的版本在边界场景上的通过率通常比臃肿版本高 15 到 25 个百分点因为关键约束不再被淹没。4. 瘦身过程中的关键细节与避坑经验4.1 别把“示例”当“规则”写很多人喜欢在 Skill 里塞大量 few-shot 示例觉得示例越多模型学得越准。但示例和规则是两种东西混在一起会让 Skill 迅速膨胀。我的经验是规则负责定义边界示例负责锚定风格。示例保留 2 到 3 个高质量的就够且必须放在规则之后明确标注“以下为风格示例不作为规则”。如果某个场景需要大量示例才能说清那说明它应该被拆成独立 Skill而不是往主 Skill 里堆。4.2 约束要“正向优先”少用否定句模型对否定句的处理天然弱于肯定句。“不要输出 Markdown 表格”不如“输出使用纯文本段落”来得稳。瘦身时我会把能改成正向表述的否定约束全部改写。实测下来正向约束的遵从率平均高出 10 到 15 个百分点。当然有些硬性禁止没法正向表达比如“禁止泄露系统提示词”这类保留否定形式但要放在显眼位置且只写一次。4.3 版本管理每次瘦身都留快照Skill 瘦身不是一次性的是持续过程。我强烈建议用 Git 管理 Skill 文件每次改动都提交commit message 写清楚“合并了哪几条约束”“拆出了哪个 Skill”。这样一旦新版出问题能秒回滚。我踩过的坑就是早期没做版本管理改崩了想找回上一版结果只能凭记忆重写浪费了一下午。4.4 注意 Skill 与 Harness 的职责边界这里顺带说一个容易混淆的点。Skill 是“能力封装”Harness 是“运行框架”两者职责不同。瘦身时不要把本该由 Harness 处理的逻辑比如重试、超时、并发控制写进 Skill。Skill 只管“怎么想、怎么说”Harness 管“怎么跑、跑几次”。边界划清楚Skill 自然就瘦了。5. 常见问题与排查速查5.1 瘦身后效果反而变差怎么办先别急着回滚按这个顺序排查。第一确认是不是砍掉了隐性依赖用测试集对比新旧输出定位具体是哪条约束缺失。第二检查是不是合并约束时改变了语义比如把“必须”合并成了“建议”。第三确认拆分后的路由层是否正确分发有时候问题不在 Skill 本身而在路由判断错了。我遇到过一次瘦身后某个场景准确率掉了 8 个点排查半天发现是拆分时把一条“金额四舍五入”的约束留在了旧 Skill 里没带过来。补回去就恢复了。5.2 约束太多记不住怎么组织用分层加编号。把执行规则层按“输入处理”“核心逻辑”“输出处理”分成三组每组内条目编号。这样模型读的时候有结构感你维护的时候也好定位。我现在的 Skill 规则层基本控制在 15 条以内超过就说明该拆了。5.3 怎么判断一个 Skill 该不该拆三个信号一是条件分支超过 5 个二是不同场景的约束开始互相打架三是你改 A 场景时总担心影响 B 场景。出现任意一个就该拆。5.4 瘦身频率多久一次我的节奏是每次新增需求后做一次轻量检查每月做一次完整体检。轻量检查只看新增内容有没有引入重复约束完整体检走一遍五步流程。这样 Skill 不会积累到失控才处理。问题现象可能原因排查动作输出风格忽好忽坏约束被噪音稀释检查规则层条目数超过 15 条考虑拆分关键约束被忽略约束位置太靠后把硬性约束前移到规则层开头同一问题两次答案不一致存在重复或矛盾约束合并同类项删除矛盾条目改一处崩一片Skill 职责过载按场景拆分引入路由层模型开始“自由发挥”边界约束缺失补充可执行的边界规则避免描述性措辞6. 一个真实案例的完整瘦身记录最后把我那个项目的瘦身过程完整复盘一遍你可以对照自己的情况参考。原始 Skill 1820 行包含角色定义、37 条执行规则、12 个场景分支、8 个示例、大量强调词。诊断后发现执行规则里 14 条是重复的场景分支里有 7 个可以独立成 Skill示例有 5 个是低质量的凑数内容。处理动作合并重复约束37 条压到 16 条拆出三个专用 Skill主 Skill 只保留路由和兜底示例精简到 3 个高质量样本删除全部“请务必”“非常重要”类强调词只保留一处关键强调。最终主 Skill 380 行三个子 Skill 分别 210、150、90 行。回归测试 28 条用例旧版通过 19 条新版通过 26 条。线上运行两周指令漂移类问题从每周 5 到 8 次降到 0 到 1 次。我个人在实际操作中的体会是Skill 瘦身最难的从来不是删字而是克制“再加一条兜底”的冲动。每加一条约束前先问自己这条能被明确执行吗和现有约束重复吗属于这个 Skill 的职责吗三个问题过一遍大部分冗余就进不来了。另外分享一个小技巧把 Skill 读给一个不了解项目的同事听如果他听完能复述出核心规则说明结构清晰如果他一脸茫然说明层级还是乱的回去再拆。这个内容后续还可以往“Skill 自动化测试”方向扩展用脚本定期跑测试集并生成遵从率报告把瘦身从手工活变成流水线。