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 有多个版本并存时,Agent 不能随便选一个,也不能总是选最新的。我把决策过程设计成四层漏斗:
第零层:兼容性硬约束(一票否决)
Agent 先检查调用方请求的 API 版本要求(如果请求中声明了)和当前 Skill 版本的兼容性范围。如果当前请求要求 >=2.0.0,而某个旧版本只支持到 1.x,该版本直接被淘汰,不进入后续评分。
第一层:稳定性标签
每个版本会带一个稳定度标签:
-
stable:生产验证稳定,绝大多数流量应该走这个。 -
beta:功能完整,但还在观察期,可承接少量灰度流量。 -
canary:金丝雀版本,仅内部测试或极低比例用户。 -
deprecated:已弃用,不再接受新请求,仅存量未完成任务可继续运行。
路由时,deprecated 版本直接被过滤;canary 版本仅对白名单用户或内测标记的请求开放。
第二层:灰度策略与流量分配
当有多个 stable 或 beta 版本时,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 的最高版本作为默认。这保证了绝大多数普通请求得到最稳定、最新的体验。