AI Agent Skill 越多越笨?上下文膨胀与路由混乱的工程解法
Skill 不是装得越多越好。不少开发者在 Claude Code、Cursor、Codex 这类编码 Agent 里一口气塞了二十几个 Skill结果发现 Agent 的响应开始变得“犹豫”该调接口的时候不调不该用工具的时候乱用推理速度也明显下降。这不是模型变弱了而是 Skill 的管理方式出了问题。这篇文章不聊“Skill 该怎么写”这种单点教程而是看一个更核心的工程问题当 AI Agent Skill 数量膨胀之后系统为什么会变“笨”我会从加载机制、上下文占用、技能路由三个层面拆原因再给出一套“减负”和排查的实操方法。如果你正在给 Agent 堆技能或者已经在维护一个越来越乱的 Skill 目录这篇可以直接收藏。1. 核心现象速览观察项说明核心现象Skill 数量增加后Agent 出现误选工具、上下文被稀释、回复质量下降、响应变慢本质原因技能全部加载进提示词后上下文被无关内容挤占路由判断出现歧义主要触发条件把所有 Skill 塞进 System Prompt、技能描述不清晰、技能与技能职责重叠受影响场景编码 Agent、个人知识库助手、批量自动化任务、多工具 API 聚合场景常见平台Claude Code、Cursor、Codex、OpenCode以及各类自研 Agent 框架与 MCP 关系Skill 影响的是“怎么想”MCP 解决的是“能调什么”两者不能互相替代最直接的对策精简技能数量按需加载给技能写清晰的触发条件用日志和评估集验证命中率这张表是全文的结论也是我给大多数团队做 Agent 工程优化时的判断框架问题往往不是模型不行而是提示词和工具的组织方式超出了模型的有效决策范围。2. 这个问题的适用场景与边界先说清楚不是所有 Agent 都会“技能越多越笨”。如果你只是把 3 到 5 个 Skill 放在固定的工作流里每个技能描述写得很清晰且任务之间没有交叉那么多一个 Skill 通常影响不大。问题容易出在以下三种场景通用型 Agent同一个 Agent 既要写代码又要查资料还要处理文档、发邮件、分析数据。技能之间的边界模糊模型很难在任务一开始就确定正确路径。编码 AgentClaude Code、Cursor、Codex 这类工具允许用户把开发规范、测试框架、部署流程都做成 Skill一旦数量超过十几条Agent 在文件读写时容易把无关技能也带入推理过程。批量任务系统Agent 需要根据输入自动路由到不同 Skill。技能描述相似度越高路由失败的概率越大。不适合用“堆技能”解决的问题也要讲清楚当任务本身依赖外部数据源或工具时比如读取数据库、调用第三方 API应该优先考虑 MCP 或独立工具服务而不是把这些操作强行包装成“技能”。Skill 适合解决“怎么做”的问题不适合解决“能连什么”的问题。涉及版权、隐私和数据安全的内容也要注意如果 Skill 里包含公司内部代码规范、客户数据字段或隐私策略部署到云端 Agent 前必须确认服务商的权限隔离和加密策略如果你把 Skill 分享到公开仓库先检查里面是否暴露了密钥、内部域名或敏感路径。3. 先看 Skill 的加载方式三种典型机制要理解“技能越多越笨”先要知道 Skill 是怎么进入模型视野的。目前主流 Agent 框架的 Skill 加载方式大致有三种3.1 全部注入 System Prompt这是最简单的实现启动服务时读取 Skill 目录下的所有 Markdown 文件把它们的名称、描述、指令全部拼进 System Prompt。模型每一次请求都能看到完整的技能列表。优点是实现简单、可控性强缺点是上下文占用随技能数量线性增长。假设每个 Skill 的描述平均 500 token50 个 Skill 就会额外消耗 25000 token这条路径同时挤占了用户输入、历史对话和模型输出的空间。常见表现是Agent 开始丢三落四早期任务要求被遗忘。3.2 目录扫描加动态检索这类实现只在需要时把相关技能片段拉到上下文里典型的做法是“技能描述 嵌入检索”。系统把所有技能的描述生成向量请求进来后先做相似度检索只把 Top-K 个技能注入上下文。这个方案在技能数量较多时明显更省 Token但引入了一个新问题检索本身可能出错。如果两个技能的描述都包含“处理日志”模型或者检索器就分不清到底该用日志分析技能还是日志清洗技能。结果就是技能越多检索结果越不稳定。3.3 通过 MCP 工具注册MCPModel Context Protocol把外部能力暴露成标准工具Agent 通过工具调用的形式使用。Skill 在这里更像“人在回路中的提示词资产”MCP 工具本身不参与技能选择但 Agent 需要结合工具列表和 Skill 描述一起规划任务。这种模式下技能膨胀不会直接压低推理质量但会增加 Agent 在“到底该调用哪个工具”这个问题上的决策成本。从工程角度看前两种加载方式最容易出现“越装越笨”第三种更多表现为“工具列表太长导致选择困难”。但不管哪种方式只要技能数量超过模型在这种任务上的判断上限性能都会下降。4. Skill 过载具体“笨”在哪里下面拆开讲五个具体表现你可以对照自己的项目排查。4.1 上下文被无关技能稀释假设一个 Agent 的任务是“读取 PDF提取表格导出 Markdown”。如果系统里还有“OCR 图片识别”“批量压缩图片”“生成海报文案”这些无关技能它们在上下文里占据了大量 token模型在处理 PDF 时也可能把“图片识别”的手段混进来。这种稀释的直接影响是核心指令在 token 中的相对占比下降模型更容易“忘掉”用户的精确要求。你可能会看到 Agent 明明指定了“表格导出 CSV”它却输出成 Markdown。4.2 路由选择困难当你有 20 个技能时模型必须在每次任务开始时推断“应该调用哪个技能”。这本质上是一个分类问题技能描述越模糊、数量越多分类准确率越低。典型例子是“阅读”类技能 “阅读 PDF”“阅读网页”“阅读文档”三个技能如果描述高度相似Agent 很可能选了 PDF 阅读技能却读不了网页内容然后开始瞎猜或报错。4.3 技能冲突与顺序覆盖技能 A 说“遇到代码错误先分析日志”技能 B 说“遇到代码错误直接尝试修复”。两个 Skill 同时存在时Agent 可能反复横跳行为不稳定。更麻烦的是配置覆盖有些 Agent 框架会按目录顺序加载技能后加载的技能可能覆盖同名字段导致你写的规则没生效而你自己并不知情。4.4 基本行为退化Skill 过多之后的另一个典型现象是 Agent 的“常识行为”被削弱。原本一个不挂任何 Skill 的 Agent 面对“读取 config.yaml 并输出 JSON”能直接完成但挂了 30 个技能后它可能先调用“配置文件解析专家”技能再尝试“代码评审”技能把简单问题复杂化。这是因为模型把过多的技能当作决策依据过度依赖“技能卡片”反而遮盖了自身的推理能力。你可以把这种现象理解为 Agent 的“能力恐慌”技能范式太强模型默认走技能流程不再按通用能力处理问题。4.5 性能与成本上升技能全部加载时每次请求的输入 token 都会增加直接带来两个后果响应变慢推理成本上升。在自部署场景里显存和算力消耗也会增加在 API 调用场景里Token 费用线性增长。这一点在长对话里尤其明显。假设一次会话有 20 轮每轮多消耗 10000 token 的重复技能描述总增量就是 20 万 token成本完全不可忽视。5. 怎么判断你的 Agent 已经“Skill 过载”不要靠感觉判断。给一套可操作的检查方法。5.1 观察清单先回答下面四个问题每次系统提示词里注入的技能描述是否超过 10 个技能列表里是否存在超过两个职责重叠的技能同一个任务在重复执行 10 次时模型选择技能的结果是否稳定去掉部分技能后任务正确率是否反而上升如果四个问题有两个答案是“是”大概率已经过载。5.2 用日志记录技能命中率在 Agent 框架里加一个简单的日志记录每次请求命中了哪些技能、实际调用了哪些工具、输出是否正确。有了数据再决定删哪些技能。import json import time from collections import defaultdict # 简单技能命中统计实际使用中可替换成项目内的日志系统 skill_hit defaultdict(int) skill_fail defaultdict(int) def log_skill_usage(skill_name: str, success: bool, extra: dict None): record { skill: skill_name, success: success, ts: time.time(), extra: extra or {}, } # 输出可被日志采集的 JSON 行 print(json.dumps(record, ensure_asciiFalse)) if success: skill_hit[skill_name] 1 else: skill_fail[skill_name] 1 def report(): for skill in set(skill_hit) | set(skill_fail): hit skill_hit[skill] fail skill_fail[skill] print(f{skill}: hit{hit}, fail{fail}, rate{hit / max(hit fail, 1):.1%})把这个统计表跑一周优先删除“零命中”和“高调用但低成功率”的技能。5.3 做最小对比实验更严谨的方式是控制变量准备 20 个标准测试用例分别用“全量技能”和“精简技能”跑一遍对比正确率与平均响应时间。如果你的 A/B 测试显示精简后正确率上升那就不是玄学是工程结论。6. Skill 与 MCP 的区别别再混着堆很多人把 Skill 和 MCP 混在一起处理这是技能目录混乱的原因之一。Skill 本质上是一段结构化的指令包它告诉模型“遇到哪类问题时按照哪些步骤来思考”它不会直接调用外部系统。MCP 则是一个协议它把文件系统、数据库、API、浏览器等外部资源封装成标准可调用工具。两者的关系是Skill 负责设计问题求解策略MCP 负责提供执行能力。可以在自己的 Agent 里这样分化维度SkillMCP核心作用提示词层面的方法论工具能力接入是否消耗上下文会需按量控制会工具描述也会进入模型典型文件形式SKILL.md / prompt 文件server 配置 / 可执行服务排错思路检查描述、触发条件检查服务端口、鉴权、响应格式合理的数量越少越好按任务域收敛按真实能力需求宁缺毋滥这意味着你在做“技能瘦身”时不要简单地把一堆 MCP 工具改写成 SKILL.md。那样只是把“工具列表过长”换成了“技能列表过长”问题并没有消失。7. 优化实操把 20 个 Skill 缩到 5 个下面给一套可落地的优化流程目标是把技能目录收敛到“够用、干净、可维护”。7.1 按任务域合并先列出当前技能实际对应的任务类型合并成五个左右的大类。举例编码代码生成、代码审查、Debug、重构、测试编写统一为一个“编码助手”技能。文档PDF 解析、Word 转换、Markdown 格式化统一为“文档处理”技能。数据分析日志分析、JSON 提取、表格统计统一为“数据处理”技能。内容产出周报、摘要、文案生成统一为“内容生成”技能。运维命令检查、服务器状态、部署说明统一为“运维助手”技能。合并后每个技能里用“分支指令”区分具体场景而不是一个场景单独一个技能。7.2 给每个 Skill 写清楚触发条件模糊的 description 是 Agent 误路由的元凶。写 SKILL.md 时重点不是把操作步骤写多细而是写清楚“什么情况触发”和“什么情况不要触发”。--- name: code-review description: | 用于代码评审任务。当用户要求检查代码质量、发现潜在 bug、 给出重构建议时使用本技能。 不适用于解释代码逻辑、生成新功能的场景这类场景请使用 code-generation。 triggers: - 检查代码 - 代码评审 - code review - 找 bug - 重构建议 ---注意把“什么时候不触发”也写进去这一步能有效降低相似技能之间的路由冲突。7.3 把大技能拆成“入口 子流程”合并不是把内容堆成一个巨型 Markdown。更好的做法是保留一个入口文件子流程按步骤编号或按参数分支调用。# Document Processing Skill ## 触发条件 - 用户需要读取或转换 PDF、Word、Markdown 文件 - 用户要求提取表格、导出结构化内容 ## 处理流程 1. 判断输入文件类型 2. 如果是 PDF使用 pdf-parse 提取文本 3. 如果是 Word使用 pandoc 转换为 Markdown 4. 如果包含表格按用户指定格式输出CSV / Markdown 5. 输出前检查字段是否完整这样既合并了数量又保留了每个分支的可执行细节。7.4 只保留经过验证的规则很多技能里写的是“我认为应该这样做”的规则而不是“验证过有效”的规则。要定期清理那些没有实际执行过的指令。可以用前面提到的命中率统计一段时间内零调用的技能直接下线调用多但成功率低的技能重写它的触发条件。7.5 用评估集防回退优化完技能后维护一个 20 到 50 条的标准任务集。每次改技能都跑一遍防止“优化”变成“回归”。评估集不需要自动化得很复杂手动截图记录也可以关键是稳定可重复。EVAL_CASES [ {task: 读取 a.pdf 提取表格并导出 csv, expect: 输出 csv 文件且表格字段完整}, {task: 解释这段 Python 代码的异常处理逻辑, expect: 不调用任何代码生成技能}, {task: 总结这篇文章为 5 条要点, expect: 不调用编码技能}, ] def evaluate(agent_run_func): passed 0 for case in EVAL_CASES: result agent_run_func(case[task]) ok judge(result, case[expect]) passed int(ok) print(f{case[task][:20]}... {PASS if ok else FAIL}) print(ftotal: {passed}/{len(EVAL_CASES)})注意评估时要同时看“任务完成度”和“技能选择是否合理”因为 Agent 的“笨”很多时候体现在错误技能选对了结果这种假成功同样要拦截。8. 常见问题与排查方法问题现象可能原因排查方式解决方案Agent 经常选错技能技能描述模糊或职责重叠打印每次请求的命中技能日志重写 description增加“不触发”条件响应速度明显变慢技能全部注入上下文token 膨胀查看每次请求的 prompt token 数改为按需加载或精简技能数量输出质量不稳定同一任务结果忽好忽坏存在技能冲突或覆盖检查加载顺序看是否有同名配置统一目录加载规则保留唯一入口去掉部分技能后运行反而更稳定技能过载导致路由混乱做 A/B 对比测试保留核心技能维持最小化原则MCP 工具描述太长Agent 调用异常工具列表超长决策成本过高检查工具注册数量精简 MCP server合并工具参数技能更新后旧任务失败新技能规则覆盖了旧行为用评估集回归测试先跑评估集再上线批量任务卡在某个技能调用上技能内部指令死循环或缺少退出条件查看日志中的调用链给技能增加最大重试次数和失败出口技能里包含敏感信息外发到云端 API权限与合规隐患扫描 SKILL 目录中的密钥和内部路径删除敏感信息使用环境变量引用9. 最佳实践与工程化建议把技能从“放进去就能用”升级成“一套可持续维护的提示词资产系统”建议从下面几点入手。9.1 目录结构标准化不要把所有技能文件平铺在一个目录里。建议按领域分目录skills/ ├── coding/ │ ├── SKILL.md │ └── examples/ ├── document/ │ ├── SKILL.md │ └── templates/ ├── data/ │ └── SKILL.md ├── content/ │ └── SKILL.md └── ops/ └── SKILL.md这样 Agent 框架可以按目录做检索也方便后续按模块做权限控制。9.2 把技能当作代码来管理技能文件要进 Git要有变更记录要有人 Review。技能描述和提示词属于“可运行资产”改坏了会影响全部下游任务。更新技能时遵守先写评估用例再改技能跑评估通过后才合入。9.3 控制加载粒度尽量不要做到“全量加载”。在框架支持的情况下优先用“技能检索 按需注入”的方式。如果检索方案不稳定可以先维护一份人工映射表把常见任务和技能绑定减小模型自行分类的压力。9.4 重视日志与可观测性记录每个任务的技能调用链、模型决策过程、输出质量才能定位“变笨”的根因。没有日志的 Agent 优化基本等同盲调。9.5 合规与安全边界Skill 目录里不要出现明文 API Key、Token、内部服务器地址。涉及人脸、声音、私人文档处理时必须先获得授权并在部署环境做访问限制。把 Skill 分享到公开平台前检查是否包含公司内部规范或个人隐私数据。在批量任务中如果技能调用第三方服务要注意输出内容的版权归属。10. 总结与下一步“Skill 越多Agent 越笨”这个现象的核心原因不是模型变笨而是你把过多决策压力放到了模型身上。技能的价值在于提供精确的方法论而不是堆积数量。每增加一个 Skill实际是在增加一次路由决策、增加一段上下文占用、增加一次冲突可能。最值得做的三件事把当前技能目录按任务域合并给每个技能写清楚触发和排除条件然后跑日志统计看命中率。最容易踩的坑是“技能不够就再加一个”——这只会让问题在数量层面继续累积。如果你现在维护的 Agent 已经出现选错技能、输出不稳定、响应变慢的现象先不要换更大的模型先检查你的 Skill 目录这通常比换模型省成本也更直接。后续可以继续探索的方向包括基于向量检索的技能路由、技能自动评估集、多 Agent 分工替换超大技能包以及 Skill 与 MCP 工具链的职责再划分。
上一篇/下一篇内容由系统自动关联
返回资讯列表 →