← 返回文章列表
011 — AI · #Skill 设计 #Prompt 工程 #逆向工程 · 2026-08-19 · 8 MIN READ

从专用到通用:Skill 的技术栈中立化改造

一套 skill 的两次生命

最初版本的七个 skill 是为一个项目量身定制的:前端认定 Vue2,组件库认定 element-ui,接口封装认定 api/*.js,数据访问认定 MyBatis 的 XML,数据库认定 PostgreSQL。规则写得又细又顺,产出的文档质量很高,一切美好的前提是——下一个项目长得一模一样。

第二个项目进门时现实揭晓:Python 脚本群加 OCR,没有 Vue;再下一个,ExtJS 加 jqGrid 加 Hibernate,没有 element-ui 也没有 MyBatis。专用 skill 在新栈上开始输出荒唐的结果:给 Python 脚本找 Controller,把 jqGrid 的列当成表格装饰略过不提。

复盘发现所有失效的规则都犯了同一个错误:把「这个项目的做法」写成了「必须这么做」。改造的方向随之确定——把项目习惯从规则里剥离出去,换成技术栈中立的表述,技术栈差异用识别加路由消化。剥离沿着四个维度展开。

维度一:功能点来源

专用版的规则句式是「找 el-button 的 click 事件」。这个句式在 Vue2 项目里精确,出了这个门就是零召回。中立化后的句式改成「找用户的动作入口」,再按栈给出具体形态:

形态实例
模板事件绑定Vue 的 @click、JSP 的 onclick
编程式事件绑定ExtJS 的 grid.onbutton.on
组件定义即功能jqGrid 的 colModel、导航栏按钮配置
后端入口Controller 的 @RequestMapping
脚本入口Python 主函数、__main__、主流程方法
时间入口@Scheduled、Quartz 任务、crontab

关键转变是抽象层级:规则描述的是「入口」这个概念,各栈的写法只是概念的实例。模型先理解找什么,再按栈的形态表对号入座。表格里没有的栈,模型也能沿着「用户动作入口」的定义去找,比死记 el-button 泛化得多。

维度二:链路追踪路径

专用版只有一条链:.vue -> api/*.js -> Controller -> Service -> ServiceImpl -> Mapper -> XML -> PG 表。中立化后一条链变成六张模板,覆盖三类 Java 栈、一个纯前端调用、一个 Python 栈、一个定时批处理栈。

模板化时最费琢磨的是粒度。模板太细,每来一个变体就要新增一张,维护不过来;太粗,路由过去等于没路由。最后定下的颗粒度是「数据访问风格」这一层:MyBatis 的 XML 一种,Hibernate 的 DAO 一种,注解 SQL 一种,原生 SQL 一种——这个切分刚好决定链路图的最后三层长什么样。至于 Service 有没有接口、包名怎么起,各项目自由,模板不约束。

另一个统一动作是外部依赖的标注。专用版里 SAP 调用是清账平台的特例,通用版把它升格为一级概念:任何跨出当前代码库的调用都用 External: 前缀统一标注。特例一旦成为概念,第三个项目接进来时 OSS、OCR、第三方接口自动有了位置。

维度三:输出字段来源

输出字段的三级优先级——展示层列定义、SQL 别名、实体属性——这个框架本身是中立的,不中立的是各层在每种栈里的具体形态:

优先级层RuoYi 栈的形态其他栈的新增形态
展示层列定义el-table 的 prop 和 labelExtJS 的 columns 配置、jqGrid 的 label、返回 JSON 的 key
数据访问层MyBatis XML 的 SELECT 别名Hibernate 的 HQL 投影、注解 SQL、原生 SQL
实体属性兜底Java 实体类字段Python 字典 key、表格结构定义

改造前最典型的漏案是 jqGrid:colModel 里明晃晃写着每个业务字段的中文名,专用规则不认识它,模型退到 SQL 里硬啃别名。改造后 label 优先,输出字段直接拿到业务命名,列名列序与页面严格一致反而更轻松。这个案例说明泛化不只是兼容更多栈,中立规则的提取本身会让原栈的提取质量变得更好。

维度四:数据库方言

专用版认定 PostgreSQL,注释读写只有一套语法。中立化后按四种方言各配一套:PostgreSQL 的 COMMENT ON、Oracle 的行内注释、MySQL 的建表内 COMMENT、SQL Server 的扩展属性。识别靠系统表结构信号,注释脚本严格按识别出的方言生成。

方言维度还有个容易被忽略的收益:数据字典的三级注释优先级(业务产物、DDL COMMENT、命名直译)是方言无关的,真正随方言变的只有读写语法薄薄一层。把变的和不变的分开,四种方言的成本只增加在语法层,精修逻辑、占位注释识别、待确认兜底全部原样复用。

技术栈识别器

四个维度都指向同一个前提:先知道是什么栈。识别器用三重信号:文件扩展名给出第一判断,目录结构给出交叉验证,框架特征词给出最终确认。三重信号一致才下结论,冲突时报告待人工确认,宁可慢一步,不许猜错栈——栈认错,后面所有模板全部路由错误。

识别的结论写进 function-list JSON 的 技术栈 字段,一次识别全程消费,这是全流水线的固定分工:识别集中在一处,下游全部消费。如果每个 skill 各自识别,同一个项目可能在不同步骤被认成不同栈,中间产物对不上账。

参数与原则的分界

中立化过程中最清醒的一个决定,是区分「做成参数的」和「固化成原则的」:

做成参数固化为原则
模块结构(business.json 按项目配置)零合并原则,任何栈不许合并字段
技术栈模板表(可增删栈)先读后写,任何栈不许凭想象写码
注释方言语法完成标志协议,跨项目统一
归类关键词(按业务领域调整)质量门禁数字与重试降级
技术底座说明(每项目一份)业务语言禁令清单

分界线画在「会不会随项目变」上:模块叫什么名字、用哪种数据库,每个项目都不同,这类做成配置,改起来不动规则。零合并、先读后写、N=M 校验这类,是文档工程的底座规律,跨栈跨项目不变,固化在 skill 里谁也不许改。

没有这条分界线的 skill 有两种下场:把参数写死,每个新项目都要改 skill 本体;把原则做成参数,某个项目图省事把零合并关掉,文档质量静默崩塌。分界线让 skill 在「换项目改配置」和「换项目不改底线」之间各得其所。

中立化的代价

通用不是免费的。第一笔账是规则密度:识别表从一张变成七张,链路模板从一张变成六张,skill 文档的篇幅翻了近倍,模型每次执行要处理的指令更长。第二笔账是维护成本:新栈进来要审四维度全部改点,漏改一处就是隐性失败。第三笔账最隐蔽——通用规则的表述天然不如专用规则精确,「找用户动作入口」不如「找 @click」直接,靠形态实例表补回来的精确度,对表格覆盖不到的边角栈是打折的。

这笔账算下来依然划算,因为三个项目的实战证明:定制的成本集中在识别和模板两张表上,是一次性的;而下游占大头的业务翻译、文档组织步骤零改动复用。通用化的收益随项目数线性增长,成本近似常数。

相关阅读:功能点提取一篇有七类入口特征表的完整清单;几百张表、几十个功能点的活怎么拆给一群子代理,见子代理并行的分治实践

Comments