2. 特征版本管理核心概念:版本号规范、特征血缘关系、特征生命周期管理

版本管理这件事,说白了就是给每个特征一个「身份证」。我见过太多团队,一开始觉得版本号随便写写就行,结果上线后出了问题,连哪个版本的特征在跑都搞不清楚。嗯,今天我们就来聊聊这三个核心概念。

2.1 版本号规范:给特征一个清晰的身份证

版本号不是随便写的。我个人习惯用 语义化版本号,格式是 MAJOR.MINOR.PATCH。举个例子:v2.3.1。

  • MAJOR:不兼容的改动。比如特征逻辑完全重写,或者输出格式变了。
  • MINOR:向下兼容的新功能。比如加了一个新的参数,但旧逻辑还能跑。
  • PATCH:向下兼容的 bug 修复。比如修了一个计算精度问题。

我在项目中遇到过一种情况:团队里有人把 bug 修复也标成了 MINOR 版本号。结果下游依赖方以为有新功能,白白浪费了测试时间。所以,版本号一定要严格对齐改动类型。

版本号规范示例

版本号 改动类型 示例说明
v1.0.0 初始版本 特征首次上线
v1.1.0 MINOR 新增一个可选参数
v1.1.1 PATCH 修复空指针异常
v2.0.0 MAJOR 特征逻辑重构,输出格式变更

你想想看,如果版本号乱标,下游依赖方怎么知道该不该升级?我曾经见过一个项目,因为版本号不规范,导致两个团队同时依赖同一个特征的不同「v1.0.0」版本,结果线上数据对不上。排查了整整两天。

我的建议:在版本号后面加上构建元数据,比如 v1.2.3+build.20250315。这样既能看清语义,又能追溯构建时间。

2.2 特征血缘关系:谁生谁,谁依赖谁

特征不是孤立存在的。一个特征可能依赖上游的原始数据,也可能被下游的模型消费。这就是特征血缘关系。说白了,就是一张「特征家族树」。

我记得有一次排查线上问题,发现一个推荐模型的 AUC 突然下降。查了半天,才发现是上游的一个特征版本被悄悄替换了。如果当时有血缘关系图,一眼就能定位到问题。

特征血缘关系通常包含三种节点:

  • 数据源:原始数据表、日志、API 等。
  • 特征:经过加工后的特征。
  • 模型/应用:消费特征的最终产品。

下面这张图展示了特征血缘关系的典型结构:

特征血缘关系图 数据源:用户行为日志 数据源:商品信息表 特征:用户活跃度 v1.2 特征:商品类目 v2.0 特征:用户-商品交叉 v1.0 模型:推荐模型 v3.1 说明:箭头方向表示数据流向,从数据源到特征再到模型

为什么要维护血缘关系?原因有三:

  1. 问题排查:模型效果变差时,能快速定位是哪个特征出了问题。
  2. 影响分析:某个特征要下线,能提前知道会影响哪些模型。
  3. 版本回溯:需要回滚时,能清楚知道要回滚哪些特征版本。

注意:血缘关系不是画一次就完事了。特征版本每次变更,血缘关系都要同步更新。我曾经见过一个团队,血缘关系图还是半年前的,结果排查问题时完全对不上。

2.3 特征生命周期管理:从生到死

每个特征都有生命周期。从创建到废弃,中间要经历多个阶段。我个人习惯把生命周期分为五个阶段:

阶段 状态 说明
1 开发中 特征正在开发,仅供测试使用
2 灰度中 小流量验证,观察效果
3 已上线 全量发布,正式使用
4 已废弃 不再维护,但数据仍可查询
5 已删除 彻底清理,数据不可恢复

你可能会问:为什么要有「已废弃」和「已删除」两个阶段?

嗯,这里要注意。废弃是给下游一个缓冲期。比如某个特征要下线,先标记为「已废弃」,通知所有依赖方在 30 天内迁移。30 天后,再执行「已删除」。我曾经在项目中跳过废弃阶段,直接删了一个特征,结果下游模型第二天就报错了。从那以后,我再也不敢省略废弃阶段。

避坑指南:废弃阶段一定要设置一个明确的截止日期。我建议在特征元数据中加上 deprecated_at 和 removed_at 字段,方便自动化检查。

特征生命周期管理的核心,其实就是一句话:让每个特征的状态可追溯、可控制。版本号规范保证你能说清楚「这个特征是什么」,血缘关系保证你能说清楚「这个特征从哪里来、到哪里去」,生命周期管理保证你能说清楚「这个特征现在能不能用」。

这三个概念,缺一个都不行。