AI Agent Skill越多越笨?从上下文干扰到工程治理的排查指南

AI Agent Skill越多越笨?从上下文干扰到工程治理的排查指南 AI Agent 的 Skill 越多Agent 反而越笨这个判断听起来很反直觉但我在实际项目里确实反复踩到过。很多开发者在给 Agent 加技能包时习惯把一个能力拆成一个 Skill结果装了十几个之后模型不但没有变强反而开始频繁选错工具、重复调用、输出格式越来越不稳定。问题并不在 Skill 本身而在于 Skill 被加载进上下文之后模型要在大量互相干扰的指令里做决策。如果你是做 AI Agent 开发或者在维护自己的 Skill 库这篇文章可以帮你省掉不少排查时间。我会先解释为什么会出现“越装越笨”再给一套诊断方法和组织规范最后落到一个能直接执行的排查顺序。1. 先搞清楚Agent 的 Skill 到底在改变什么1.1 Skill 和 Prompt、插件、MCP 的边界Skill 在 AI Agent 里通常不是独立程序而是一组描述“什么时候用、怎么用、按什么步骤做、输出什么格式”的指令可能包含文本说明、示例、代码片段或外部工具的调用入口。你可以把它理解成给 Agent 的“岗位手册”它不直接提供能力而是告诉模型如何调用现成能力或者用什么样的思考路径完成任务。很多人会把 Skill 和 MCP 混在一起。MCP 解决的是 Agent 与外部系统的连接协议比如通过 API 读取数据库、操作文件、调用浏览器Skill 更多解决的是“接到任务后怎么组织行为”比如“分析日志时先按时间排序再按错误码聚合”。两者可以配合但不是一个东西。还有一个容易混淆的概念是 Prompt。Prompt 是一次对话的上下文Skill 通常是可以复用的模块被动态加载到 Prompt 里。也就是说Skill 最终会变成 Prompt 的一部分但它的价值在于“可以按规则插入或不插入”。明白了这个边界你就会发现加 Skill 本质是在增加输入给模型的文本约束。每加一个 Skill模型每次生成时都要处理更多指令和示例。如果这些指令彼此独立、目标明确Agent 会更稳如果只是把一堆文档塞进去模型反而要花时间去理解“当前到底适用于哪一个”。1.2 Skill 的加载方式决定“多”和“乱”的起点不同框架对 Skill 的加载方式不一样。有的框架把所有 Skill 描述一次性放进系统提示词有的框架先用一个路由或选择模型根据用户请求挑选相关 Skill再把命中内容注入主模型还有的框架要求用户手动指定。同一个框架的不同版本也可能有动态 Skill 选择逻辑。最容易出问题的是第一种全量加载。如果只有 3 个 Skill全量加载通常没事但到 20 个、50 个之后模型每次都要在所有 Skill 描述里做判断。上下文窗口虽然能装下不代表注意力能覆盖好。第二种动态选择看起来更聪明但也会引入新错误路由模型可能选错 Skill可能一次选中多个 Skill甚至一个都没选中。这时的表现就是明明 Skill 很多Agent 却像没装一样或者频繁调用无关工具。所以讨论“Skill 越多越笨”之前先要确认自己的加载机制。如果框架支持按需加载那就应该把精力放在触发规则上如果框架是全量加载那么 Skill 总数就是一个必须控制的核心参数。2. 为什么 Skill 数量增长Agent 表现反而下降2.1 上下文被无关内容占满关键指令容易被稀释大模型在做决策时会综合考虑输入中的所有 token。上下文窗口越来越宽确实能接收更多信息但模型并不会像数据库一样精确检索。多个 Skill 同时存在时即使描述之间没有矛盾它们也会分散注意力。比如模型正在处理一个把 CSV 转成 JSON 的任务系统提示里却还带着“写邮件要用正式语气”“做 PPT 要注意配色”“调用数据库前必须检查连接池”等 Skill 描述。这些内容不一定有害但它们占据了注意力让模型更容易遗漏当前任务里的关键约束。更隐蔽的是 token 消耗。Skill 越多每次请求传输的 token 越多接口延迟和运行成本都会上升。你可能觉得几个 Skill 的文本没多少但一个 Skill 如果包含详细示例、使用限制、输出格式很容易达到一两千 token。十个 Skill 就是一两万 token这在批量任务里非常明显。跑 Agent 测试时不能只看功能是否成功还要监控输入 token 涨幅和响应耗时。2.2 工具选择准确率下降候选越多决策越难Agent 的决策本质是一种选择问题。系统提示里有多个 Skill 时模型需要先判断当前任务是否命中了某个 Skill再做工具调用。Skill 数量增加会让候选集合变大如果 Skill 名称不清楚、描述词重叠模型就很容易在相近的 Skill 之间犹豫或选错。我见过一个比较典型的案例有人给 Agent 写了“读取数据库”“查询销售数据”“生成报表”三个 Skill。表面看都是独立功能但实际任务经常是“读取销售数据库并生成报表”这时模型可能要连续调用两三个 Skill。如果 Skill 之间的输入输出没有衔接好Agent 会在中间环节卡住甚至把查询数据和生成报表当成互斥选项。最后的结果就是Agent 看起来会很多技能但完成一个完整流程时总在转换环节出错。这种问题不是模型变笨了而是选择空间变大之后每一步都有概率出错。单步选错概率假设是 5%三步链路成功率是 85.7%看起来还行但五步链路成功率为 77.4%。如果 Skill 数量从 5 个增到 30 个选择概率还会进一步下降。所以不要只看单次调用是否成功要看多步链路的目标完成率。2.3 冲突和重叠同一个任务被多个 Skill 覆盖当多个 Skill 对同一个任务给出不同处理规则时问题会更严重。这是最常见也最难排查的情况。比如一个 Skill 说“数据清洗前先统一缺失值为 0”另一个 Skill 说“缺失值应该直接剔除”模型加载到两个规则后可能每次执行都不一致。另一个重叠点是输出格式。有的 Skill 要求输出 JSON有的 Skill 要求输出 Markdown 表格如果 Agent 需要把结果串起来前一个 Skill 的输出可能不符合后一个 Skill 的输入要求。这种冲突不会直接报错但会导致重复格式化、字段丢失、解析失败。解决冲突并不是把所有 Skill 合并成一个。更稳妥的做法是给每个 Skill 定义清晰的适用范围并且在描述里写“如果任务不满足以下条件不要使用本 Skill”。这相当于给模型一个排除法减少同时命中多个 Skill 的机会。3. 怎么判断你的 Agent 是不是“被 Skill 拖笨了”3.1 先看日志有没有频繁切换或先调错 Skill判断 Agent 是否被 Skill 拖累不用急着改代码先看日志。大多数 Agent 框架会输出任务流程包括模型思考过程、工具调用记录、每一步的输入输出。打开最近几十条失败或低质量任务观察几个信号。第一个信号是“先调错 Skill”比如任务要导出 ExcelAgent 先去调了读取 CSV 的工具任务要写 Python 脚本Agent 先调用代码审查的 Skill。这说明排序和路由出了问题。第二个信号是“频繁切换”同一个任务里Agent 在不同 Skill 之间反复横跳调了 A 又调 B发现不对再调 A。第三个信号是“忽略核心 Skill”明明某个 Skill 最适合当前任务但模型从头到尾没有提到它或者主动绕过了它。如果日志里频繁出现这三类信号基本可以判断是 Skill 管理问题而不是模型本身能力问题。3.2 跑一组固定任务记录成功率、延迟和 token 消耗只看日志还不够要建立一组固定任务来做对照。选 10 到 20 个真实业务场景覆盖 Agent 的核心能力每个任务设置明确的输入、期望输出和验收标准。然后在同一模型、同一参数下分别记录带全部 Skill 和只带核心 Skill 的表现。建议记录四个指标指标记录方式如果 Skill 过多通常会看到任务成功率最终结果是否符合验收标准下降平均步数单次任务里 Agent 调用工具或 Skill 的次数变多响应延迟从发起请求到最终输出完成的时间变高token 消耗每次任务平均消耗的输入和输出 token明显上涨这组数据会告诉你真相。如果带全部 Skill 后成功率下降、步数变多、token 上涨那说明 Skill 数量正在拖后腿。如果只是 token 上涨但成功率和步数都没变说明影响还没到需要大改的程度。3.3 做一次最小化对照只保留核心 Skill最值得做的是“最小化对照”实验。把当前所有 Skill 分成两类一类是 Agent 日常核心任务必须的另一类是“可能有用”的。先删掉所有“可能有用”的 Skill只保留 3 到 5 个核心 Skill然后跑同一组固定任务。这个实验不需要改模型也不需要重新训练只要调整加载列表即可。很多情况下你会发现成功率反而上升了。原因很简单模型可以把注意力集中在少数几套规则上不再需要花额外判断去过滤无关 Skill。等最小集跑稳定后再逐个加回 Skill每加一个跑一遍固定任务观察指标是否变差。这样就能定位是哪个 Skill 在拖累全局。4. 真正有效的 Skill 组织方式按场景隔离不按总数堆叠4.1 按任务域拆分而不是按功能点拆很多人的 Skill 是按“功能点”拆的比如“读取 Excel”“合并表格”“生成图表”“写邮件”每一个都独立。这样拆的问题在于真实任务往往是多个功能点组合模型必须在多个 Skill 之间串联每一步都有代价。更推荐按“任务域”拆分也就是面向一类完整任务去定义 Skill。比如“月度数据汇总”“客户邮件回复”“代码仓库分析”这三个 Skill每个内部包含输入要求、处理步骤、输出格式以及可能需要调用的底层工具。这样模型接到的不是散装功能而是一套完整工作流。按任务域拆分之后Skill 总数通常会下降。一个任务域少则一个多则两三个不会出现几十个功能点全部堆在系统提示里的情况。对新人也更好理解看到某个任务直接判断它属于哪个任务域再调用对应的 Skill。4.2 为 Skill 写清触发条件和禁用条件Skill 描述里不能只写“这个 Skill 能做什么”还要写清楚“什么情况下才用”和“什么情况下不要用”。这听起来像废话但实际维护的 Skill 里很少有人认真写禁用条件。一个好的触发描述应该包含适用任务类型解决什么问题。适用输入格式接受什么参数、文件、数据格式。不适用条件哪些场景不要调用。前置依赖是否需要先完成其他步骤。输出约定返回什么结构。可以给一个简单的示例name: sales-report trigger: - 用户要求生成销售日报 - 输入中包含订单明细或销售数据 ignore: - 用户只问销售趋势不需要生成报表 steps: - 读取输入数据 - 按日期聚合 - 生成 Markdown 表格 output: format: markdown-table fields: [date, revenue, orders]这个示例不是固定格式具体要以你的框架为准。但思路很明确模型拿到 Skill 后第一件事是判断是否触发、是否要忽略而不是直接把所有步骤执行一遍。4.3 把常用参数、输出格式放进 Skill减少模型自由发挥模型在自由决定的场景里容易不一致。比如输出格式没有写清楚时第一次返回 JSON第二次返回带代码块的 JSON第三次可能直接给文字。为了避免这种波动Skill 内部要尽可能定义稳定的执行模板。具体做法包括固定输出字段、固定分隔符、固定报错措辞如果某个环节需要调用外部工具写明工具名称和参数如果有默认值直接写进 Skill比如“日期格式统一为 YYYY-MM-DD”“金额保留两位小数”。这些看似琐碎但对 Agent 稳定性影响很大。当然也不是把所有细节都写进去。Skill 如果过长一样会稀释注意力。核心原则是把容易出错的细节模板化把不重要的余地留给模型。每个 Skill 尽量控制在几百到一两千字以内避免像文档仓库一样长。5. 从单 Agent 到多 AgentSkill 越多越需要治理5.1 给 Skill 加版本和来源标注Skill 一旦多起来就成了需要治理的资产。最简单的做法是给每个 Skill 加元信息包括名称、版本、作者、来源、更新日期、关联测试用例。这样当某个 Skill 导致问题时可以快速定位。这里的“作者”并不是让个人署名而是在团队里标明维护人。一个 Skill 如果长期没有人维护规则可能已经过时和新的 Agent 框架不兼容。版本号最好显式写在描述里比如 v1.2这样排查时能确认当前加载的是不是旧版本。如果你把 Skill 放在 Git 仓库里可以顺手记录每次变更内容。没有版本管理的话至少保留一份变更日志。很多人不重视这一步等到 Agent 行为失控时只能在几十个 Skill 里盲猜非常浪费精力。5.2 建立 Skill 的准入和淘汰机制Skill 不能只增不减。我建议按季度或项目迭代周期做一次 Skill 清理。清理的方法很简单看日志里的调用频率和成功率。调用频率低且成功率也不高的 Skill优先考虑删掉调用频率高但成功率低的 Skill需要优化描述或拆细调用频率高且成功率高的 Skill就是核心资产要重点保护。准入机制更重要。新增 Skill 之前先问三个问题这个 Skill 是否覆盖了一个完整任务是否和现有 Skill 重叠能不能用当前能力加几步提示替代如果两个 Skill 重叠超过 30%就不要新增而是改造现有 Skill。不要因为看到一个热门 Skill 就安装很多 Skill 在别人的场景里有效放在你的 Agent 里只会增加噪音。5.3 用编排层控制 Skill 调用权限到多 Agent 阶段不建议让每个 Agent 都能访问所有 Skill。更好的做法是在编排层配置访问范围数据分析 Agent 只加载数据处理类 Skill内容生成 Agent 只加载写作类 Skill客服 Agent 只加载问答和工单类 Skill。这样每个子 Agent 的上下文里 Skill 数量始终可控整体系统也不会因为某个 Agent 加载过多 Skill 而性能下降。编排层还可以做统一的调用日志、超时保护、失败回退。即使某个 Skill 出问题也只影响一个子 Agent而不是拖垮所有任务。如果项目还没到多 Agent也可以提前按这个思路做“分组加载”。把 Skill 分到不同目录根据任务类型动态选择目录而不是一次性注入所有 Skill。等到需要扩展时改造成本就很小。6. 我建议的落地步骤和排查顺序6.1 从最小可运行 Skill 开始不要一上来就管理一堆 Skill。先从一个最小可运行的 Skill 开始比如“把用户输入整理成 JSON 输出”。给它写清楚触发条件、输入字段、输出格式和一段示例。然后跑一条任务确认它能稳定工作。这个 Skill 可以作为所有后续 Skill 的模板。你后面每加一个新 Skill都按同样的结构去写触发、忽略、步骤、输入、输出、示例。不要某些 Skill 写得像 Prompt某些 Skill 写成纯脚本那样模型很难统一理解。结构一致性能明显减少 Agent 在多个 Skill 之间切换时的混乱。6.2 先单条任务验证再批量验证拿到一个新 Skill不要直接放进生产环境。先在测试环境里跑 10 到 20 条覆盖不同场景的任务观察成功率。等单条任务稳定后再做批量验证。批量验证要特别注意几个点输出文件命名是否冲突、失败任务有没有正确重试、日志是否容易按任务 ID 检索。很多时候单条任务没问题批量跑的时候 Skill 才出现“变笨”现象就是因为批量任务里模型要连续处理大量上下文注意力分配更容易被无关 Skill 干扰。如果批量成功率下降优先减少同时加载的 Skill 数量然后再看模型参数。6.3 遇到副作用时按顺序排查如果 Agent 出现变笨、乱调、输出不稳定建议按这个顺序排查先看现象是成功率为零还是偶发失败还是输出格式乱。再看输入当前任务的输入格式、文件路径、参数是否完整。再看加载逻辑当前请求到底加载了哪些 Skill是不是把无关 Skill 也带进来了。再看 Skill 内容触发条件、禁用条件、输出约定是否清晰是否存在冲突。最后看模型和框架版本同一个 Skill 在不同模型上的表现可能差很多不要盲目调 Skill。按这个顺序排查大部分问题会在第 3 步和第 4 步暴露。不要一上来就怀疑模型太笨先把 Skill 的上下文噪音降下来再说。我个人更建议把“Skill 数量”当成 Agent 性能指标之一。每加一个 Skill都要同时记录它对成功率、步数、token 和延迟的影响。真正让 Agent 变强的永远是那些在关键时刻能被准确选中、并且能把规则执行到底的 Skill而不是系统里躺着的一大堆备用技能。