把低频 Skill 变成可检索冷存储让 Agent 按需找回能力省上下文也更稳。原文链接AI小老六导语Agent 的能力越来越像一个小型操作系统它能读文件、调接口、写代码、查日历也能按团队经验执行一套固定流程。Skill 就是把这些经验沉淀下来的常见方式。问题也随之出现。Skill 少的时候把所有 Skill 的名字和描述塞进上下文模型大概率还能挑对。Skill 一多这套办法开始变形上下文预算被占掉description 被截断语义相近的 Skill 互相干扰低频 Skill 明明一个月才用一次却每天都在消耗常驻 token。更麻烦的是很多团队在写 Skill 时天然倾向于“多拆一点”。一个 OpenAPI 一个 Skill一个业务流程一个 Skill一个文档模板一个 Skill。短期看很灵活长期看就会把 Agent 的路由入口堆成一片噪声。我最近在想的不是“再训练一个更准的 Skill 分类器”而是另一个问题Skill 能不能像知识库一样被 Agent 主动检索常用能力保持在手边长尾能力先放进冷存储需要时Agent 自己搜索、检查证据、确认选择再把对应 Skill 拉回来执行。这其实就是 ​Agentic Search 在 Skill 管理里的一个变体​。Skill listing 的真实成本不是 token 数字那么简单图高频 Skill 留在工作台长尾能力进入可检索冷存储Skill 的一个核心设计是渐进式加载。默认只把 metadata 放进上下文真正的操作步骤、示例、脚本和参考资料等到触发后再读。这比把完整插件说明常驻上下文要合理得多。但 ​metadata 也不是免费的​。常见 Skill 文件大概长这样skills/ lark-doc/ SKILL.md # metadata body references/ scripts/ lark-mail/ SKILL.md code-review/ SKILL.mdSKILL.md通常分成两层frontmatter / metadataname、description、tags、适用场景默认参与路由。body完整流程、注意事项、命令示例、错误处理命中后再读。这套结构在几十个 Skill 时很好用。到了几百个甚至几千个 Skill麻烦开始出现。第一宿主通常会给 Skill listing 设置固定预算。预算超了怎么办只能截断 description甚至只保留 name。一个本来写得很清楚的“飞书文档读取、更新、图片插入与权限处理”被截成“飞书文档读…”路由质量自然会掉。第二Skill 数量越多语义相似项越多。lark-doc、lark-wiki、lark-drive、lark-sheets都和“飞书文件”有关stock-analysis、china-stock-analysis、us-stock-analysis都和股票有关。模型看到一堆短描述时很容易被表面词拉走。第三常驻 listing 会让低频 Skill 持续占预算。一个一年用三次的 Skill只要 enabled就和每天都会用的 Skill 站在同一个上下文入口里。这对个人环境还能忍对团队级 Skill 目录就不太现实了。所以Skill 管理的核心矛盾不是“怎么把所有 Skill 介绍得更短”而是哪些 Skill 应该常驻哪些 Skill 应该退出上下文但仍然能被找回被动 Top-K 路由为什么不够一个自然反应是做检索。把 Skill 的 name、description、body 建索引用户请求来了embedding 召回 Top-K再交给 reranker 或 LLM 选一个。这条路当然能做而且很多场景有效。但它有两个工程代价。先说模型依赖。embedding、reranker、向量库、索引刷新、版本兼容这些东西对平台团队不是大问题对本地 Agent 用户和小团队就是额外负担。Skill 本来是为了降低使用门槛最后又引入一套检索基础设施味道有点不对。再说交互形态。传统 Top-K 本质上是一次性函数调用用户 query 进去候选列表出来Agent 只能消费结果。如果第一轮 query 抽错了词或者候选里两个 Skill 很接近Agent 很难像人一样“换个词再搜一下”“打开两个候选看看证据”“不确定就不要选”。这就是被动检索的限制。它把 Agent 放在消费者位置而不是​搜索过程的操作者​。Agentic Search 的关键变化让模型控制检索过程Agentic Search 不神秘。它只是把搜索从“一次返回答案”改成“多步收集证据”。一个更适合 Agent 的检索接口至少要允许它做四件事从当前任务里抽关键词而不是原样拿用户句子去搜。看见候选为什么被召回包括命中的字段、片段、分数和是否截断。对少量候选做进一步检查但不要一下子把全文全倒出来。在证据足够时选择在证据不足时停止或继续搜索。这和近两年 Agentic RAG、Direct Corpus Interaction、grep-style harness 的讨论是一条线检索器不再只是黑盒排序器而是 Agent 可以操作的外部环境。放到 Skill 管理里思路会变成这样图Agent 在 enabled Skill 与 metadata corpus 之间按证据路由这里有一个边界很重要​select 之前只看 metadata不读被禁用 Skill 的 body​。这不是洁癖而是上下文控制。搜索阶段如果每个候选都打开完整说明Skill router 很快会退化成另一个上下文黑洞。metadata 足够时就选metadata 不够时最多检查少量候选仍然不够就承认低置信而不是硬选一个看起来顺眼的。​禁用不是删除​低频 Skill 应该进入冷存储Skill 管理里最容易被误解的是 disable。很多人听到禁用会以为能力消失了。更合理的理解是禁用只是让它退出常驻 listing。文件还在metadata 还在路径还在使用记录也可以继续记录。它只是从“每天站在上下文门口”变成“需要时可以被查到”。这有点像内存和磁盘的关系。高频、基础、系统级 Skill 留在内存里长尾 Skill 放到磁盘上。Agent 不应该每次启动都把整块磁盘读进上下文它应该有一套索引和读取协议。一个可维护的 Skill 冷存储至少需要这些东西组件作用需要避免的问题metadata corpus保存 disabled Skill 的可检索字段例如 name、description、aliases、tags、tools、domains、intents、examplesdescription 太短、字段缺失、同质 Skill 没有区分度stable ref用稳定引用指向候选而不是直接把本地路径暴露给模型路径泄露、路径变化、候选不可复现inspect 接口允许 Agent 对少量候选查看更多 metadata一次性输出过多重新制造上下文压力select 记录把“为什么选它”写成可审计事件路由不可追踪后续无法优化restore 机制能把 disabled Skill 恢复为 enabled禁用变成破坏性操作这样处理后Skill 数量增长带来的压力就不再线性压到上下文里。上下文里常驻的是少量高频 Skill加一个 router 入口长尾 Skill 通过 metadata corpus 被按需找回。三个 primitivesearch、inspect、select图Agent 通过 search、inspect、select 逐步收集路由证据我更倾向于把 Skill 路由拆成三个小工具而不是做一个“一步到位”的routeSkill(query)。corpus search低成本召回search 接收 Agent 抽出来的关键词返回一组候选。这里最好区分 must terms 和 probe terms。比如用户说“读取飞书 docx 并提取第一章”must terms 可以是lark、docxprobe terms 可以是document、fetch、extract。search 返回的不是最终答案而是候选证据ref、score、matched terms、description snippets、totalMatches、returned、truncated。truncated这个字段很有用。它告诉 Agent当前 query 太宽了候选被截断了需要换词或加约束。没有这个信号模型会误以为返回列表就是全部世界。corpus inspect只检查少量候选inspect 用来处理“几个候选都像”的情况。它可以返回更完整的 metadata例如 aliases、tags、tools、domains、intents、examples但仍然不读 body。这一步的重点是有界。不要让 Agent 一口气 inspect 50 个候选。通常 2-5 个就够了。Skill 路由不是信息检索比赛它只是要帮当前任务找到一个能执行的能力入口。corpus select把选择变成记录select 是闭环动作。Agent 必须给出 ref/id、原始 query、confidence 和 reason。CLI 再把 ref 解析成真实 disabled Skill记录一次 routed use最后返回selected.skillMdPath。这样做有两个好处。第一模型不能直接拿搜索结果里的路径乱读。第二所有选择都有审计记录。以后你想知道哪些 disabled Skill 其实经常被找回哪些从来没有被选中过就有数据可看。一个典型调用流程可以设计成这样agentic-skill-router skills corpus search\--alllark\--anydocx\--anydocument\--anyextract\--limit30\--jsonagentic-skill-router skills corpus inspect corpus-xxx corpus-yyy--jsonagentic-skill-router skills corpusselectcorpus-xxx\--query读取飞书 docx 并输出第一章\--confidencehigh\--reasonmetadata covers Lark docx fetching and document content extraction\--json这个接口不炫但边界清楚。Agent 负责判断CLI 负责索引、分页、ref、JSON schema、缓存和选择记录。Bash 直接搜文件为什么不适合作为默认产品边界如果只看研究验证直接让 Agent 用 shell 搜本地 Skill 目录很诱人。find、grep、sed、awk足够强模型也能临场组合很多策略。中小规模目录里这种 DCI 风格的做法甚至会非常准。但它不适合当默认产品形态。原因不是 bash 不强而是太自由。今天模型写grep -R明天写find | xargs后天又加head -20。路径里有空格怎么办文件太多触发 ARG_MAX 怎么办候选被head截掉怎么办输出太长撑爆上下文怎么办这些问题最后都会落到 prompt 里prompt 越写越像一段脆弱的 shell 教程。Tool-wrapped 的优势就在这里。把容易犯错的部分收到 CLI路径枚举、缓存、索引、分页、截断提示、候选引用、schema 校验。Agent 还在做主动搜索但它不必每次临场写一段不稳定的 pipeline。换句话说bash 适合调试 failure case适合做研究对照默认路径最好还是稳定 primitive。Metadata-first 的边界领域词会欺骗路由只看 metadata 也有上限。最典型的失败来自“业务领域词”和“底层执行工具”打架。用户说“分析 supply shock 的经济影响并生成表格”metadata-only router 可能被economics、shock analysis、timeseries这些领域词吸走。但真正要完成任务可能需要的是 spreadsheet / Excel Skill因为交付物是读取表格、写公式、生成文件。这类 query 不能简单按语义最相近来选。要加一条 tie-break当任务明确要求操作 xlsx、csv、单元格、公式、透视表或表格产物时底层 substrate Skill 的优先级应该高于领域分析 Skill。除非领域 Skill 明确声明自己也能完成文件读写和表格输出。所以​metadata-first 更像第一层过滤不是最终真理​。候选接近时可以引入 body-on-tie只读取少量候选的 body确认谁真的具备执行能力。这个动作必须少量、低频、可记录否则又会回到全文倒灌的问题。从理论到一个可用实现我找到的 agentic-skill-router前面讲的是设计原则。按这些原则找实现时我看到一个比较贴近这套思路的项目agentic-skill-router。它的定位不是再做一个推荐系统而是把低频 Skill 从常驻 listing 里移出去同时保留可检索 metadata。Agent 没有明显命中 enabled Skill 时再通过 router Skill 进入 search / inspect / select 工作流。项目地址GitHubhttps://github.com/legendtkl/agentic-skill-routerWeb 页面https://legendtkl.github.io/agentic-skill-router/我觉得它有几个设计点值得单独看。第一disable 的实现很轻。它通过重命名SKILL.md为SKILL.md.agentic-skill-router-disabled之类的方式让 Skill 退出宿主扫描但文件本身仍然可恢复。这符合“禁用不是删除”的思路。第二检索阶段坚持 metadata-only。router 在 select 前不读取 disabled Skill body只暴露可路由字段和候选证据。这个边界能避免路由过程自己变成上下文膨胀源。第三候选使用 stable corpus ref。Agent 看到的是corpus-...这类引用而不是本地绝对路径。最终必须通过 select 才能拿到selected.skillMdPath。这让路径暴露、幻觉路径、绕过审计的问题少很多。第四select 会记录 routed use。这个细节很工程化路由不是一次性行为它会反过来影响后续管理。一个长期被找回的 disabled Skill可能应该重新 enabled一个从不被选中的 Skill可能 metadata 写得不好也可能确实该清理。基本安装和初始化很直接npminstall-gagentic-skill-router agentic-skill-router init如果需要指定宿主和作用域可以显式写agentic-skill-router init codex project agentic-skill-router init codex global agentic-skill-router init claude-code project agentic-skill-router init claude-code global日常管理大概是这些动作agentic-skill-router list agentic-skill-router suggest--jsonagentic-skill-router disableskill-id--yesagentic-skill-routerenableskill-idagentic-skill-router status如果在 Codex 或 Claude Code 里用也可以通过对应宿主的 Skill 触发方式调用。这里不把它当成主角更准确地说它是 Agentic Skill Routing 这套设计的一个可运行样本​低频能力冷存储、metadata corpus、Agent 主动检索、选择后再读取 body​。更长期的形态本地 router 加服务化 registry本地 Skill 管理能解决一部分问题但它不该承担全部治理职责。Skill 一旦在团队内扩散新的问题会冒出来哪个版本最新哪个版本废弃了谁发布的有没有签名有没有组织推荐版本当前宿主是否兼容本地目录扫描很难回答这些问题。更合理的分工可能是图本地 Skill Router 与远端 Registry 的分工本地继续负责低延迟、隐私、缓存和最终执行。服务端负责目录、版本、信任、策略和反馈闭环。这个 registry 不需要把所有 Skill body 都服务化也不应该替 Agent 做最终选择。它更像一个控制平面告诉本地 router 有哪些 Skill、哪个版本可信、哪些已经 deprecated、哪些适合当前组织、包的 digest 是什么、发布者是谁。一个完整流程可以是开发者发布 Skillregistry 校验 schema、metadata、权限声明和签名组织把它标成 recommended、experimental、deprecated 或 blocked本地 router 同步 metadata 和 lockfileAgent 请求到来时先查本地 enabled Skill未命中再查 cache / registry选中后才按需拉取或 materialize 对应 Skill。这比“每台机器各装各的 Skill然后靠目录扫描自我管理”可靠得多。收束Skill 规模化之后真正难的不是写更多 Skill而是让 Agent 在正确的时间看见正确的 Skill。把所有 Skill 常驻上下文简单但不耐扩展。把路由完全交给一次性 Top-K省事但会削弱 Agent 的主动判断。更稳的方向是 Agentic Skill Routing高频 Skill 常驻长尾 Skill 进入 metadata corpusAgent 通过 search、inspect、select 多步找回能力证据不足就继续查或停止不强行命中。这套方法的价值不在于某个 ranker 分数多高而在于边界清楚metadata 先行、候选有界、选择可审计、body 按需读取、禁用可恢复。等 Skill 再往团队级、组织级扩张本地 router 还可以自然接上服务化 registry把发现、版本和信任治理从个人机器里搬出来。​Agent 的上下文窗口不应该变成 Skill 目录的垃圾桶​。它更像工作台只放当前要用的工具。其他工具可以在仓库里但得有一套靠谱的查找和取用办法。推荐阅读平台智能化到了分水岭为什么配置代码化才是 AI Coding 的下一代接口业务 Agent 搭建指南别急着重造 Agent用知识、工具与评测跑通闭环Dynamic Workflows 深度解析Claude Code 为什么把多 Agent 编排写进可执行代码Codex Context Compaction 真相Agent 为什么压缩后还能接着干活