
Skill 写好了AI 还是不听话这大概是所有调 Agent 的人最容易血压升高的一幕。上周就有个朋友拿着一个写好的“会议纪要 Skill”来找我说测试的时候模型完全无视了“必须提取行动项”这条要求回答得跟普通聊天一样平淡。我把他那段 Skill 打开一看触发描述、系统提示词冲突、指令强度三个坑全踩了。其实绝大多数 Skill 失灵都不是模型“笨”而是 Skill 本身和它运行的环境之间存在几个级别的衔接问题触发链路、指令优先级、指令强度、上下文状态。这四件事按顺序查下来大部分问题都能定位到根上。这篇文章不是讲怎么从零设计 Skill而是讲一个已经写好的 Skill 为什么不生效、以及按什么顺序排查。适合正在调 Agent、写 Skill 脚本、或者往自己工作流里塞各种场景化 Skill 的朋友。我尽量不讲虚的全部用实际遇到的问题来拆。1. 先定性Skill 失灵到底是“没被触发”还是“触发了但不听话”很多人一上来就改 Skill 内容这是最浪费时间的行为。因为“没触发”和“不听话”是两条完全不同的排查路线前者是工具选择链路的问题后者是指令遵循和约束冲突的问题你混在一起改永远找不到规律。1.1 怎么判断 Skill 到底有没有被调用现在主流的大模型 Agent 架构里Skill 本质上会被包装成一个“工具”或“函数”。模型在每一轮生成的时候会先做一件事从可用工具列表里选一个然后填充参数最后再执行对应逻辑。也就是说如果模型压根没有选中你的 Skill它根本看不到你写的那一大段规范后面的表现自然跟普通聊天没区别。判断方法很简单第一步看日志或推理轨迹。大多数 Agent 框架都会记录当前轮次调用了哪个工具有没有出现tool_use、function_call、skill这类标记。如果你用的是可视化平台通常也会显示“已调用 xx 技能”。如果日志里什么都没有那基本可以判定为触发失败。第二步是“强制触发测试”。在对话里直接说一句“请使用 xxx Skill 来完成这个任务。”如果强制触发后输出立刻变得符合预期说明 Skill 内容本身没问题是自动触发环节有毛病。如果强制触发后还是老样子才需要去检查 Skill 内部的指令质量。1.2 触发成功但执行走样和完全没触发是两回事我见过很多人在群里求助“我的 Skill 明明写了输出表格为什么它输出列表”这种症状通常不是触发失败而是触发了但约束没被执行到。两者的区别看一处细节就行模型的回复里有没有出现 Skill 里定义的思路、术语或结构痕迹。比如你在 Skill 里写了三个分析维度模型回复时提到了其中一个维度但另外两个怎么都不出现这叫“部分执行”。又比如你要求它输出 Markdown 表格它却给了一段散文式总结这叫“格式约束丢失”。这两种情况说明模型已经读到了 Skill只是某些规则被它判断为“可以不遵守”。我一般会用下面这张表先做完问题定性再决定下一步动哪里症状表现更可能是哪种问题下一步动作回复内容与 Skill 完全无关连概念都不出现没触发 / 工具没被选中检查工具描述、触发条件、开关提到了 Skill 里的思路但输出格式、字段缺失触发成功指令强度不足检查指令语气和输出约束写法前两步执行得很好中间开始跑偏上下文丢失或指令被截断检查 Skill 插入位置和历史消息长度输出像是两个思路混在一起时好时坏多 Skill 冲突 / 系统提示词干扰检查优先级声明和并发激活情况定性这一步很关键因为它决定了你要不要去动那段 Skill 正文。如果问题根本在触发链路你改二十版措辞都没用。2. 第一件事查系统提示词确认没有更高优先级指令在压着你的 SkillSkill 失灵最常见、也最容易被忽略的原因是系统提示词里有规则在跟它打架。“打架”这个词用得一点不夸张因为大模型的指令遵循是有层级的系统提示词通常拥有最高解释权而 Skill 内容不管怎么注入大多数情况下都只算“对话上下文里的行为说明”优先级天然低一截。2.1 框架预设的回复风格和内容边界会先过滤掉你的要求不少 Agent 框架或者平台默认就有全局提示词比如“保持回复简洁”“语气友好”“不要输出过多列表”“不要轻易断言”等。这些约束单独看都没问题但一旦跟你 Skill 里的硬性要求产生冲突模型通常会优先满足系统层。因为它认为系统提示词是更高维度的“规则”而 Skill 只是本次任务的一次性参考。我实操中踩过的一个典型例子在某个 Agent 平台上挂了编程技能要求对每个函数给出“问题-原因-修改建议”三段式审查意见。结果系统全局提示里有一条“回复要简短避免冗余”于是模型每次只回一行“看起来没问题”我的 Skill 写得再详细也白搭。后来我把系统里那条“简短”约束单独摘掉输出立刻正常了。这种情况的坑在于你表面上看到的是“Skill 不生效”可实际上它是被系统级规则截胡了。验证方法很简单把系统提示词备份之后临时精简成一个空壳只保留安全类必要指令再跑一次。如果 Skill 立刻生效那就证明被压制了。这不是 Skill 内容的问题是运行环境的规则优先级问题。2.2 显式声明优先级并选对注入位置解决冲突不能只靠“删掉系统提示词”因为线上环境里你未必有权限改全局配置。更通用的做法是在 Skill 正文最开头加一句带“优先级宣示”的声明。比如当此 Skill 被激活时其输出格式与流程要求应优先于对话中的通用风格要求除非与安全限制冲突。这句话虽然不能保证 100% 生效但实测下来能在很大程度上改变模型的默认倾向。模型会把它理解成“这份技能规范有特殊地位”。另外一个非常有效的办法是把 Skill 的关键约束复制进系统提示词末尾。大模型对长文本开头和结尾的注意力最强Skill 内容作为系统提示词的收尾部分出现比混杂在用户消息里更容易被遵循。我把这个现象叫作“提示词的位置红利”。你写了一大段 Skill如果平台把它注入到对话历史的正中间后面跟着几十轮闲聊模型的注意力早就被稀释干净了。相反放在系统提示词尾部或者紧邻当前用户问题前执行率会明显上升。关于具体怎么验证不同模型的位置差异我后面专门有一节讲。3. 第二件事查触发条件模型的工具选择流程可能根本没认出你的 Skill如果确认系统提示词没有压制接下来就要查触发链路。很多 Skill 设计者犯的最初级错误是把 Skill 当成“一段文本”去写却忽略了它实际会被模型当作“一个工具”去选择。模型选不选这个工具完全不看你正文里写得多精彩只看工具名称和description长什么样。3.1 描述写得太“散文”模型就不知道该什么时候用工具选择本质上是一个打分排序过程。模型在每一轮会扫一遍所有可用工具的名称和描述估算“哪个工具最贴合当前用户请求”然后做出选择。如果你的描述写得含糊比如“本技能可用于生成会议纪要”“这是一份周报助手说明”模型就很难形成强关联。我推荐把描述写成一段紧凑的路由规则明确包含三个要素触发场景、典型输入信号、拒绝调用条件。举个例子一份“会议纪要 Skill”的描述可以这样写{ name: meeting_minutes_skill, description: 当用户提供会议原始记录并要求整理会议纪要时使用。若记录中出现了任务、负责人、截止时间等信息必须识别为行动项。不要用于普通闲聊或与会议记录无关的总结请求。, parameters: { type: object, properties: { source_text: { type: string, description: 用户提供的原始会议记录 } } } }而一份写得很失败的描述通常是这样的{ name: meeting_skill, description: 用来处理会议相关的东西。 }前者给模型的是一个非常明确的判定路径看到“会议原始记录整理要求”并且文本里含任务/负责人/时间就调这个看到闲聊就不调。后者等于什么都没说模型扫一眼工具列表大概率会跳到别的更具体的工具上。这就像你布置了一个新人任务只说了句“帮我把事情处理一下”他当然不知道该拎哪件事做。3.2 多个 Skill 同时存在时模型会“争抢”触发权还有一个很隐蔽的坑同一套 Agent 里挂了多个描述相似的 Skill互相争抢触发权。比如你既挂了一个“周报生成”的 Skill又挂了一个“数据分析助手”的 Skill当用户说“帮我总结一下本周数据”时模型到底该选哪个它自己也会犯迷糊。实测下来模型在这种场景下常常选错选中数据分析助手后输出的结构就跟周报 Skill 完全对不上了。处理方式有三种。一是给每个 Skill 的描述里写明边界条件比如“当用户明确要求按周报格式输出时才使用本技能若只是分析数据请不要调用”。二是在主 Skill 内部声明优先级比如写“当本技能与数据分析类技能冲突时以本技能输出结构为准”。三是运行时做减法只激活当前任务真正需要的 Skill别一次性挂十几个上去。第二种方案在多 Agent 协作的场景里尤其重要多个 Agent 各带各的 Skill如果不约定优先级和输出契约融合结果会非常不可控。顺便提一句不同平台的 Skill 启用方式不一样。一些平台要求进入插件市场安装后才能生效有些则要在模型参数里手动打开开关。遇到过好几个人跑来问“为什么我写的 Skill 不生效”最后发现是压根没启用。这种低级错误花五分钟就能排除但它在实际问题的占比里其实不小。4. 第三件事查指令强度全是“建议式措辞”等于给了模型偷懒的理由触发链路没问题、系统提示词也不冲突了接下来就要盯住 Skill 正文本身。我发现很多人的 Skill 内容写得像一份“产品介绍”而不是一份“操作合同”。词句之间的语气差异对模型执行率的影响是实打实的。4.1 从“可以”到“必须”执行率会明显变化大模型对指令的遵循并不是线性的。你把一句话分别写成“你可以尝试整理成表格”“建议整理成表格”“必须整理成表格且表头固定”模型表现出的执行力度差别非常大。原因也不神秘模型训练阶段学习了大量带有委婉语气的指令知道这是一种“低优先级请求”而“必须”“禁止”“不得”这类词汇通常对应了更严格的高优先级约束。我见过一个特别典型的例子。有人写周报 Skill第一条写的是“你可以根据本周完成情况生成一份周报如果内容太多的话尽量精简。”结果模型每次都只输出三行大意完全不展开。后来我让她改成你必须按以下流程执行先列出本周已完成事项每条不超过 20 字再列出未完成事项及原因输出 Markdown 表格表头固定为【事项 | 状态 | 负责人 | 下一步动作】原始材料中没有提到的负责人一律填“待确认”禁止自行推断。改完立刻生效。这不是玄学是模型真的把“必须序号禁止项”当成了一套强约束指令来执行。这也解释了为什么现在总有人说“要写去 AI 味的提示词”。去 AI 味本身没有错写得更像人话、更自然确实能减少模型的模板化响应。但去 AI 味不等于把语气改成“你可以试试”“不妨考虑一下”这种礼貌性措辞放进 Skill 里等于亲手把执行力度调低了一个档位。Skill 的定位本来就不是聊天是给模型立规矩规矩就得用规矩的语言写。4.2 把 Skill 当成“新员工培训手册”来写而不是“功能说明书”写完之后你可以回头读一遍自己的 Skill想象它是给一个聪明但容易犯错的新人看的操作手册。一份合格的操作手册会包含四部分职责边界、硬性流程、禁止事项、正反例。大多数 Skill 只写到了前两部分甚至只写了“你能做什么”完全没有“你不能做什么”和“做到什么程度算完成”。“完成标准”这个东西对模型特别重要。你不说清楚模型会自己定义一个“差不多”的标准。你说了它就有一个明确的自检依据。比如上面周报 Skill 里的“原始材料没有提到的负责人一律填待确认禁止自行推断”就是把完成标准精确化。没有这句话模型很可能根据你的聊天记录猜一个负责人填上去看着合理其实是幻觉产生的。反例也值得写。你可以直接在 Skill 末尾加一段“错误示范”告诉模型“下面这种输出形态不合格”因为大模型对反例的敏感度往往比对抽象规则还要高。我的习惯是每个 Skill 固定配一个正确示例和一个错误示例这个习惯从我做了十几个 Agent 项目之后一直保留到现在效果非常稳定。5. 第四件事查上下文状态Skill 被埋没了或正在被另一个 Skill 干扰即使上面三件事查完都能排除Skill 依然有可能失效那就是上下文状态出问题了。我这里是泛泛说的“上下文状态”其实包含两个独立问题一是 Skill 内容太长或位置太差被模型遗忘了二是多个 Skill 同时激活时互相污染。5.1 长上下文的“中间丢失”效应Skill 被塞在最没存在感的地方大模型对长文本中间部分的信息记忆力是偏弱的。这不是我随口说的业内早已把这种现象叫作“Lost in the Middle”。翻译成白话就是一段文本前面和结尾的内容最容易被严格遵循中间的内容容易被稀里糊涂地忽略掉。所以 Skill 内容是放在 System Prompt 末尾、紧邻用户请求、还是埋在几十条历史消息中间执行率完全不一样。如果你的平台允许调整注入位置优先放在 System Prompt 末尾或者紧挨当前用户问题的提示句里。如果不允许就做一个“锚点提示”的小技巧在用户问题后面自动附加一句“注意当前任务必须按上方 Skill 规范输出”这句话足以把模型对 Skill 内容的注意力重新拉回来。另外Skill 本身不要太长。有一些新手作者喜欢把各种细节、背景、使用场景全部堆进去一个 Skill 动辄三千字。模型的注意力是有限的你把所有内容堆满它抓不住重点效果反而不如一个 300 到 600 字、职责单一、结构紧凑的 Skill。我自己的经验是一份 Skill 如果不能在一页之内讲完就该考虑拆分成两份了。5.2 多个 Agent 协作时Skill 的命名空间和输出契约会成为新瓶颈现在很多人开始玩多 Agent 协作让多个 AI 各自负责一个环节每个 Agent 又挂了自己的 Skill。这个架构最大的风险就是 Skill 之间的隐性覆盖。举个例子A Agent 负责数据提取B Agent 负责报告生成两者的 Skill 里都定义了summary这个字段。当数据提取 Agent 把结果传给报告生成 Agent 时B 的 Skill 仍然读到了 A 的输出它可能把 A 的字段误当成自己的结果输出的报告结构一团糟。这种问题不是靠“写清楚指令”能根治的你得做两件工程化的事一是给 Skill 里的参数加前缀命名空间比如source_、output_避免字段语义混在一起二是在 Skill 出口处定义好输出契约明确谁生产、谁消费、字段类型是什么。本质上你是在给多个 AI 之间制定 API 协议而不是单纯写提示词。还有一个更直接的坑就是模型的上下文窗口本身不够用。长对话进行到后半段早期 Skill 内容可能已经被系统裁剪掉了。当你发现 Skill 在前面几轮很正常、后面越来越失常先别急着改 Skill去查一下历史消息是不是已经顶爆了上下文窗口或者平台有没有做“摘要压缩”导致技能内容被当作早期记忆清掉了。这个问题在长会话任务里非常常见。6. 按顺序实操一套半小时定位问题的排查清单理论说再多不如给一套能直接照着做的操作顺序。我现在每接到一个“Skill 不生效”的问题都会固定走下面这套流程多数问题半小时内能定位。先抛结论排查顺序是强制触发测试、系统提示词检查、触发描述检查、指令强度强化、上下文精简。不要跳步不要一次改两个变量。步骤检查项验证方法通过标准1触发链路看日志里的工具调用记录用“请使用 xx Skill 执行”强制触发强制触发后输出明显变化2系统提示词临时精简系统提示词后再测精简后 Skill 恢复执行3工具描述检查 name 和 description 是否包含触发信号自动触发也能稳定选中4指令强度把“可以/建议”改成“必须/禁止”补完成标准输出格式和字段完全符合定义5上下文状态调整注入位置、压缩 Skill 长度、处理并发冲突长对话后半段执行率不衰减这套清单我打印出来贴在工位上过。每次排查的时候最忌讳的就是“顺手改一句”加上“顺手再改一句”最后问题确实可能消失了但你根本不知道是哪个改动起的作用。以后同样的坑还得再踩一遍。我说一个真实的案例复盘。某个同事写了一个周报生成 Skill第一版测试时 AI 完全不理会回复像普通聊天。我查了日志发现模型压根没有选中这个工具问题出在描述写得太泛只有一句“用于生成周报”。我把 description 改成“当用户询问本周工作汇总、需要按周报格式输出时调用本工具如果只是闲聊日常事务不要调用”触发立刻恢复。第二版测试时触发了但输出只有一段话没有表格。查系统提示词发现框架预设了“回复应简洁友好”跟 Skill 的表格输出要求直接冲突。我在 Skill 开头加了优先级声明并把关键约束复制到系统提示词尾部输出恢复正常。第三版又一个新问题模型把过去两个月的任务全部列进了周报没有时间范围概念。我在 Skill 里补了一句“只提取截止时间是本周内的任务未标明时间的不纳入本周周报”才算彻底消停。整个过程看下来每一步都是我在前面反复强调的那几件事触发、优先级、指令强度、上下文边界。踩过这么多坑之后我现在的习惯是写任何一个 Skill 时先写好触发路由描述再写硬性指令再配一个错误示例最后确认插入位置。整套东西本质上就是给模型写一份带验收标准的合同。Skill 不是写出来就完事的静态文本它和运行环境、系统提示词、其他工具之间的关系才是决定它好不好用的关键。下次再遇到 Skill 写好了却不执行先别急着骂模型把这四件事从头查一遍思路会清楚很多。