一、背景:为何要打造组件复用 Skill
这个组件复用Skill的诞生,初衷极为简单且现实:在日常功能开发中,开发者常常“顺手就新建一个组件”,而非优先去库中查找现成方案。久而久之,组件库如同滚雪球般越积越大,而这种习惯带来的伤害是复利式的:

- 重复组件日益增多,维护成本持续攀升;
- UI与交互的一致性不断下降;
- 连AI生成代码时,也更容易陷入混乱循环。
因此,这个Skill的目标并非简单的“帮AI搜一下组件”,而是将“复用优先”的思考过程固化为一套标准流程。让AI在真正动手写代码之前,先严格执行“查索引—判断是否复用—实在不行再新建”的完整路径。
二、想解决的不是搜索问题,而是“思考顺序”问题
起初,很容易把问题想得过于简单:“给AI做一个组件搜索工具不就解决了?”但实际落地后才明白,问题根本不在于工具有没有,而在于:
- AI会不会主动使用?
- 它在什么时机触发?
- 用完以后能否回到项目上下文中?
- 整个流程能否稳定一致地执行?
这恰好印证了Vercel在Agent评测中观察到的现象:Skills本身并非无用,但Agent往往不会稳定触发。而将基础知识放入AGENTS.md这类“被动上下文”后,稳定性显著提升。Vercel的实验显示,默认的Skill触发并未提高通过率,加入显式指令后才有明显改善,而AGENTS.md文档索引方案表现更为稳健。
这为我们指明了关键设计方向:先解决AI的“决策点”问题,再解决AI的“执行能力”问题。
三、核心设计思路:AGENTS.md + Hook + Skill(三层结构)
基于上述思考,最终采用了三层结构的设计方案。
AGENTS.md:承载基础上下文(常驻)
AGENTS.md的职责是存放基础上下文,并且是常驻的。它将“组件复用优先”的规则、组件索引入口、以及扫描后需要执行的操作,全部写入文档中。目的并非填满文档,而是让AI在每轮会话中都能知晓:
- 当前仓库拥有组件复用机制;
- 默认应优先查询可复用组件;
- 查不到时再考虑新建;
- 扫描后还需完成描述补全流程。
这一层解决的核心问题是:AI根本不知道有这套机制。如果不在上下文中明确写明,AI主动调用Skill的概率确实极低——这一点已有不少前车之鉴。
Hook:进行路由增强(提高触发概率)
如果运行环境支持hooks,便可增加一层“意图路由增强”。当用户提及“组件复用”、“是否有现成组件”、“封装组件”、“查组件”等语义时,向AI注入提示,引导其优先走组件复用流程。这一层解决的是:AI知道有Skill,但未必能想起来用。
Skill:提供流程与工具(真正执行)
Skill不仅仅是说明文档,它需要提供:明确的调用入口、稳定的输出格式、可执行的脚本,以及失败时的兜底逻辑。这一层解决的是:AI想用,但执行过程不稳定。
四、这套Skill在源码中如何落地
下面分享本次组件复用Skill的几个关键实现点。
先把“入口”收敛为一个:find-component.js
SKILL.md中明确写明:Agent必须调用统一入口find-component.js。原因很简单:避免AI在多个脚本之间犹豫,避免AI遗漏前置步骤,避免调用路径不一致导致结果不稳定。
这个统一入口完成了以下几项工作:接收查询词(query)、仓库根路径(repoRoot)、当前聚焦路径(startDir)。若components.csv缺失,内部自动触发扫描;调用resolve-scope计算当前应用与允许搜索范围;调用match-component进行匹配排序;命中时记录使用情况;最后按固定JSON协议返回结果。
这一步的本质,是将分散的逻辑聚合为一个“业务动作”:“查一下有没有可复用组件”,而非“先算scope,再查CSV,再排序,再补扫,再记usage”。这对AI的执行稳定性至关重要。
不是“全仓库乱搜”,而是“当前应用 + 根级共享”优先
在monorepo场景里,组件复用容易踩两个坑:一是只搜当前app,漏掉根级共享组件;二是全局乱搜,结果太多太噪。因此resolve-scope.js实现了一套工程化的范围解析策略:
- 读取
pnpm-workspace.yaml解析workspace包; - 根据当前聚焦文件/目录反推
currentAppRoot; - 结合
root_scope_patterns构建允许范围; - 最终形成搜索集合:当前应用 + 根作用域共享包。
如果没有聚焦子项目,则切换为全量scope。这个设计很像人类工程师的查找策略:先看“我的业务应用里有没有”,再看“全局共享有没有”,而不是在整个monorepo中大海捞针。
匹配不依赖纯关键字:多因素加权是核心
组件匹配若只做字符串包含,很快会变成垃圾召回器。match-component.js与fuzzy-match.js实现了一套组合评分机制,核心因素包括:名称精确/包含匹配、模糊匹配(编辑距离)、Token重叠、首字母缩写匹配(如dlp匹配DateLinkPicker)、当前应用加权、使用频率加权、来源质量加权、存在性校验、记录类型权重等。
这里的目标并非追求“算法先进”,而是让排序更贴合团队的真实使用习惯:“更可能被复用的组件排在前面”。此外还设定了低分阈值:若最高分太低,则视为噪音命中,可触发一次扫描后再查;仍为低分则按“无匹配”返回,避免将劣质候选结果传给AI。
把“索引构建”做成可复用流水线,而非一次性脚本
很多类似方案停留在“扫一遍生成CSV”,随后便过时。本次将扫描架构设计为run-scan.js、index-manager、enrich的流水线,核心考量是持续维护。
run-scan.js负责编排流程:resolve-scope、updateIndex、自动触发autoEnrich。index-manager.js负责索引更新策略:保留历史记录并合并、根据source_hash跳过未变化组件、记录last-scan-changed-ids.json、支持并行扫描、对缺失文件标记exists=0。
扫描后进入Agent富化流程:读取agent-enrich-prompts.json,找出summary占位符项,按id回到components.csv,读取源码或README,生成summary与keywords,再通过update-component-summary.js写回。更关键的是配置中启用了agent_mode_no_fallback = true,在Agent模式下不走规则引擎降级,要求Agent必须完成这一步——这即是“流程化思考”的精髓:不是建议,而是纳入主流程。
让Skill不只是“搜索器”,还是“反馈回路”
一个容易被忽视的点是:查找命中后,还记录了使用行为(usage-tracker)。这意味着系统并非静态,它会逐步学习团队偏好:哪些组件频繁复用,哪些组件在某个app中更常出现,哪些结果应在排序中更靠前。这是一种非常轻量但极其实用的反馈机制——无需复杂训练,也能提升AI下一次的推荐质量。
五、本次实现中总结出“让AI流程化”的3条原则
这也是最想分享的部分。
原则1:将基础上下文放进AGENTS.md(或用Hook注入)
若不这样做,AI主动使用Skill的概率会极低。原因不是AI笨,而是Agent的执行存在“决策成本”:它需要先意识到有Skill,再判断是否该用,再决定何时用。而将基础上下文放入AGENTS.md或通过Hook提前注入,本质上是在减少决策点。
原则2:Skill需要直接提供工具函数供AI调用
只写一堆说明文档远远不够。AI在工程任务中最需要的是:一个可直接执行的入口、明确的参数、稳定的返回结构。因此find-component.js被设计为统一入口,并定义了固定JSON输出,这能明显提升AI的执行稳定性。
原则3:显式告诉AI调用哪些函数,并将分散逻辑聚合到一个入口
这是最容易被忽略、也是最影响稳定性的一点。如果给AI暴露一堆脚本,它理论上能拼起来,但实践中很容易漏步骤、顺序错、参数错。所以在Skill中显式规定:查找时用find-component.js,构建时用run-scan.js,更新描述时用update-component-summary.js。将复杂系统收敛为几个明确入口,AI才容易稳定执行。
六、本次实践中的一个重要认知转变
原本以为“写skill”是在给AI增加能力。现在更像是在做:给AI增加“默认工作方式”。换句话说,skill不仅是能力包,更是流程控制器。
AGENTS.md负责“告诉AI世界观”;- Hook负责“提醒AI当前该用哪套流程”;
- Skill负责“把动作做完,并且做得稳定”;
- 日志/CSV/usage负责“让系统可观测、可迭代”。
这套思路不仅适用于组件复用,未来还可迁移到任务优化闭环、日志分析标准化、策略诊断流程、代码规范治理等场景。
七、这套方案当前的价值
- AI开发前先查询可复用组件,而非直接新建;
- 在monorepo下按“当前应用 + 共享组件”范围检索;
- 索引缺失时自动扫描;
- 组件描述富化进入主流程;
- 匹配质量具备加权与反馈回路;
- 整体流程拥有明确入口和输出协议。
八、结语:让AI少一点“即兴发挥”,多一点“工程纪律”
本次组件复用Skill的开发过程,最大的启发并非“AI能帮我写多少代码”,而是:AI其实非常适合被放入一套清晰流程中工作。只要把以下三件事做好——基础上下文、可执行入口、明确流程边界——AI就不会只是一个“会说话的代码补全器”,而会更像一个遵守团队规范的工程协作者。而这,正是我们在这里真正想要的结果。
