Skill 的版本管理如何设计?当多个版本的同一 Skill 并存时,Agent 如何选择?

面试官:“Skill 的版本管理你是怎么设计的?当同一 Skill 有多个版本并存时,Agent 怎么决定用哪个?”

候选人:

“Skill 的版本管理本质上解决的是安全迭代与平滑过渡的矛盾。我的设计思路分两块:版本号的规范定义,以及多版本共存时的路由选择策略。前者保证‘谁是谁’一目了然,后者保证‘谁该被用’智能决策。


一、版本号设计 —— 语义化版本 + 内部修订

我采用标准的语义化版本号(SemVer),格式为 主版本.次版本.修订号,并在此基础上扩展兼容性声明。

版本号规则:

  • 主版本(Major):不兼容的 API 修改。比如参数 schema 大改,旧调用方式完全失效。

  • 次版本(Minor):向下兼容的功能新增。比如加了可选参数、新增了一个辅助方法,所有旧调用方式依旧有效。

  • 修订号(Patch):向下兼容的问题修复。比如修复了某类邮件的编码错误,接口和行为不变。

此外,Skill 元信息里还要显式声明兼容性范围,比如:

{
  "version": "2.1.0",
  "compatibility": {
    "min_api_version": "2.0.0",
    "max_api_version": "2.x.x",
    "breaking_changes": ["参数 'template_id' 改为 'template_code'"]
  }
}

这让 Agent 在路由时不仅看版本号,更能理解版本之间的替代关系。


漫画Skill版本解析 (1).png

二、多版本选择策略 —— 分级决策漏斗

当同一个 Skill 有多个版本并存时,Agent 不能随便选一个,也不能总是选最新的。我把决策过程设计成四层漏斗:

第零层:兼容性硬约束(一票否决) Agent 先检查调用方请求的 API 版本要求(如果请求中声明了)和当前 Skill 版本的兼容性范围。如果当前请求要求 >=2.0.0,而某个旧版本只支持到 1.x,该版本直接被淘汰,不进入后续评分。

第一层:稳定性标签

每个版本会带一个稳定度标签:

  • stable:生产验证稳定,绝大多数流量应该走这个。

  • beta:功能完整,但还在观察期,可承接少量灰度流量。

  • canary:金丝雀版本,仅内部测试或极低比例用户。

  • deprecated:已弃用,不再接受新请求,仅存量未完成任务可继续运行。

路由时,deprecated 版本直接被过滤;canary 版本仅对白名单用户或内测标记的请求开放。

第二层:灰度策略与流量分配 当有多个 stablebeta 版本时,Agent 根据预设的流量分配权重来决定。例如:

{
  "versions": [
    { "version": "1.3.0", "label": "stable", "weight": 80 },
    { "version": "2.0.0", "label": "beta", "weight": 20 }
  ]
}

Agent 路由层会对请求做哈希(如按 userId 取模),落到 0-79 区间走 1.3,80-99 走 2.0。这样同一个用户不会被新旧版本来回切,体验一致。

第三层:请求特征与版本能力匹配

如果灰度权重不能区分,Agent 会进一步分析请求特征:

  • 请求中是否使用了某个新增的可选参数?如果有,自动优先匹配支持该参数的次版本。

  • 用户是否为高级会员?VIP 用户优先走最新稳定版,普通用户走老稳定版,减少风险。

  • 调用耗时要求?如果某个版本平均耗时低 30%,时间敏感的请求优先路由到它。

第四层:默认兜底 如果以上所有维度都无法做出显著区分,Agent 选择当前标记为 stable 的最高版本作为默认。这保证了绝大多数普通请求得到最稳定、最新的体验。