首页
/ Nacos AI 资源生命周期管理规范深度解析:从草稿到在线的版本状态机与发布流水线

Nacos AI 资源生命周期管理规范深度解析:从草稿到在线的版本状态机与发布流水线

2026-09-09 12:05:52作者:郦嵘贵Just

导读

本文围绕 AI 资源生命周期规范 展开,系统讲解 Nacos AI 注册中心(AI Registry)中版本化 AI 资源(Agent、AgentSpec、Skill、Prompt、MCP Server 等)的通用生命周期规则:从 draft 草稿、reviewing 审核、reviewed 待发布到 online 在线,再到 offline 下线的完整状态机。文章不仅完整继承规范中的状态定义、标准流程与操作约束,还结合 ai 模块 的源码实现(CAS 指针管理、流水线结果归一化、latest 标签服务端托管、删除时的存储清理顺序、审计追踪)进行逐层印证。读完本文,你将掌握 Nacos AI 资源的生命周期 API 契约、发布流水线的交互语义,以及如何在源码层面定位每个状态迁移的具体实现。

1. 为什么需要统一的 AI 资源生命周期

在 Nacos 的 AI 云原生架构中,Agent、AgentSpec、Skill、Prompt、MCP Server 等 AI 资源都具有"版本化"的共性需求:内容需要反复编辑、经过审核后发布、按标签路由、支持下线与回滚。若每种资源各自实现一套版本逻辑,必然导致行为不一致、维护成本飙升。

因此 Nacos 在 AI Registry 之上定义了一套跨类型的通用生命周期规则,即本规范。各类型专属规范(如 Agent 管理规范MCP Server 规范)只在此基础上做细化,不得随意打破通用语义。例如,Agent 类型只为兼容旧的 A2A 直连上线门面做了例外,MCP 类型也只为其历史 API 版本保留了一个受审计的兼容通道——这些例外都被显式声明,而不是悄悄改规则。

2. 状态模型:元数据状态与版本状态的双层设计

生命周期规范将状态分为两层:元数据(Metadata)状态版本(Version)状态。二者职责完全不同,一个描述"资源整体是否可用",一个描述"某个具体版本处于什么阶段"。

2.1 元数据状态

状态 含义
enable 资源可见且至少存在一个可查询版本时,该资源可用。
disable 资源在元数据层面被禁用;具体查询行为由类型规范定义。

在源码中,这两个常量定义于 AiResourceConstants.java

public static final String META_STATUS_ENABLE = "enable";
public static final String META_STATUS_DISABLE = "disable";

元数据启用/禁用操作通过 CAS 更新元数据行,且不触碰版本信息,见 AiResourceManager.javametaEnableDisable 的实现:冲突刷新回调只保留 descbizTagsext 字段,明确排除 versionInfo

2.2 版本状态

状态 含义
draft 正在编辑、尚未提交的版本。
reviewing 已提交,正在等待发布流水线(publish pipeline)审核。
reviewed 流水线审核已完成,等待显式的 publish、force-publish、redraft 或重新 submit。
online 已发布,可被查询。
offline 已从常规运行时路由中移除的既有版本。

对应常量同样集中在 AiResourceConstants.javaVERSION_STATUS_ONLINEVERSION_STATUS_DRAFTVERSION_STATUS_REVIEWINGVERSION_STATUS_REVIEWEDVERSION_STATUS_OFFLINE。状态判定工具方法(isDraftVersionisReviewingVersionisReviewedVersion)位于 AiResourceManager.java

3. 标准生命周期流程

规范的完整标准流程如下:

create/upload draft
  -> update draft
  -> submit
  -> reviewing
  -> reviewed
  -> publish
  -> online
  -> offline/online toggle or delete

关键点在于 submitpublish 是两个分离的动作:

  • submit 把版本送入审核流程(进入 reviewing);
  • publish 把已审核版本真正发布为 online

无流水线直发:如果未启用发布流水线,或流水线中没有匹配该资源类型的节点,则根据类型实现,submit 可能直接完成发布。这一语义为小型部署(无需人工审核)保留了轻量路径。

force-publish(强制发布):绕过流水线校验,必须作为管理操作保留。它只接受 draftreviewingreviewed 三种状态的版本;对 onlineoffline 版本必须拒绝。

在源码中,直接发布(绕过流水线)由 directPublishVersion 实现(AiResourceManager.java),其原子化地完成四件事:

  1. 将版本行状态更新为 online
  2. 清空指向该版本的 editingVersion / reviewingVersion 指针;
  3. onlineCnt 自增(为 null 时初始化为 1);
  4. 在标签映射中写入 latest 指向该版本。
public void directPublishVersion(String namespaceId, AiResource meta, ResourceVersionInfo info,
    String version, boolean updateLatestLabel) throws NacosException {
    // 1. 版本行置为 online
    aiResourceVersionPersistService.updateStatus(namespaceId, name, type, version,
        AiResourceConstants.VERSION_STATUS_ONLINE);
    // 2-4. CAS 更新版本信息:清指针、onlineCnt++、latest 标签
    updateVersionInfoCas(namespaceId, meta, info, latestInfo -> {
        if (StringUtils.equals(latestInfo.getEditingVersion(), version)) {
            latestInfo.setEditingVersion(null);
        }
        if (StringUtils.equals(latestInfo.getReviewingVersion(), version)) {
            latestInfo.setReviewingVersion(null);
        }
        Integer cnt = latestInfo.getOnlineCnt();
        latestInfo.setOnlineCnt(cnt == null ? 1 : (cnt + 1));
        if (latestInfo.getLabels() == null) {
            latestInfo.setLabels(new HashMap<>(4));
        }
        latestInfo.getLabels().put(AiResourceConstants.LABEL_LATEST, version);
        return latestInfo;
    });
}

updateLatestLabel 参数被注释为"为兼容而保留并忽略,latest 始终更新"——这与规范中"该参数已废弃,新客户端不得发送"的要求一致。

4. 草稿规则:一个资源至多一个工作草稿

草稿是版本生命周期的起点,规范规定了以下行为:

  • 一个资源最多应有一个工作草稿,除非类型规范定义了覆盖(overwrite)或多草稿行为;
  • 创建草稿可以新建一条元数据行,也可以从某个 online 版本 fork 出来;
  • 草稿更新只能修改当前草稿版本,不能误改其他版本;
  • 删除草稿会清空元数据中的 editingVersion 指针,并删除草稿版本行及其存储内容;
  • 上传(upload)操作可能因类型而异,但除非是显式的 bootstrap/import 操作,否则也应产生草稿版本

editingVersion 指针与 reviewingVersiononlineCntlabels 一起构成资源版本信息的核心结构,定义在 ResourceVersionInfo.java

public class ResourceVersionInfo {
    private String editingVersion;      // 当前工作草稿指针
    private String reviewingVersion;    // 正在审核的版本指针
    private Integer onlineCnt;          // 累计在线版本数
    private Map<String, String> labels; // 版本标签映射
}

创建草稿时通过 markEditingVersionCasAiResourceManager.java)以 CAS 方式写入 editingVersion:冲突重试时会重新读取最新版本信息并再次校验"未出现工作版本",从而保证并发生命周期/标签更新不会被过期版本信息覆盖。

requireDraftVersionAiResourceManager.java)则强制要求目标版本处于 draft 状态,否则抛出 INVALID_PARAM 级别的 NacosApiException,错误信息为 "Current editing version is not draft: " + version

5. 审核与发布规则:最复杂的状态迁移语义

这是整个规范的核心章节,包含了提交、重提、幂等、latest 标签、兼容投影等大量细节。

5.1 Submit 的目标解析与合法性

  • Submit 解析目标版本的顺序为:显式指定的版本 → 当前 editingVersionreviewingreviewed 状态下的 reviewingVersion
  • 无 draft、reviewing 或 reviewed 目标时必须失败
  • Submit 接受 draftreviewingreviewed 三种状态的目标:
    • draft / reviewed 目标进入审核/直发流程;
    • reviewed 目标视为重新提交(resubmission),必须经过流水线,不得绕过流水线直接进入发布流程
    • reviewing 目标是幂等空操作,直接返回当前版本,不重复启动流水线;
  • onlineoffline 版本调用 submit 必须返回 INVALID_PARAM,且不得变更版本状态或元数据指针

resolveSubmitTarget 的实现(AiResourceManager.java)严格遵循上述解析顺序,找不到目标时抛出 NOT_FOUND

public String resolveSubmitTarget(ResourceVersionInfo info, String version, String type,
    String name) throws NacosException {
    String target = version;
    if (StringUtils.isBlank(target)) {
        target = info.getEditingVersion();
    }
    if (StringUtils.isBlank(target)) {
        target = info.getReviewingVersion();
    }
    if (StringUtils.isBlank(target)) {
        throw new NacosApiException(NacosException.NOT_FOUND, ErrorCode.RESOURCE_NOT_FOUND,
            "No draft, reviewing, or reviewed version to submit for " + type + ": " + name);
    }
    return target;
}

requireSubmitVersionAiResourceManager.java)负责合法性校验:只允许 draftreviewingreviewed 三种状态被提交。

5.2 中断完成迁移的归一化与历史流水线结果

规范处理了一个易被忽视的边界情况:

  • 停留在 reviewing 版本上的当前终态流水线结果(APPROVEDREJECTED),被视为一次"被中断的完成迁移"(即流水线已落库结果但未完成状态迁移),在重新提交前归一化为 reviewed
  • 标记为 historical=true 的结果属于上一轮审核周期,不得用于完成当前审核,此时 submit 保持幂等。

这一定义与 PublishPipelineInfo.java 中的 historical 字段一一对应——该字段的 Javadoc 明确写道:"为 true 时,流水线结果不得用于 draft 版本的 force-publish 资格判定":

public class PublishPipelineInfo {
    private String executionId;
    private PipelineExecutionStatus status;   // IN_PROGRESS / APPROVED / REJECTED 等
    private List<PipelineNodeResult> pipeline;
    private Boolean historical;               // 是否属于上一轮审核周期
}

prepareSubmitVersionAiResourceManager.java)实现了归一化逻辑:仅当版本处于 reviewing、流水线信息非空且非 historical、状态为终态的 APPROVEDREJECTED 时,才把版本行更新为 reviewed

5.3 审核中的指针与流水线状态落库

  • 处于审核中的版本必须在元数据中记录为 reviewingVersion
  • 流水线执行状态可写入 publishPipelineInfopipeline_execution
  • 审核通过与拒绝的结果都会把版本迁移到 reviewed;被拒绝后如需继续编辑,用户必须显式 redraft 该版本。

moveToReviewingAiResourceManager.java)在把版本置为 reviewing 的同时,通过 CAS 确保没有其他工作版本存在,将 editingVersion 清空并写入 reviewingVersion,最后发出 SUBMIT_REVIEW 追踪事件。流水线启动时则调用 writePipelineInfoInProgressAiResourceManager.java)写入 IN_PROGRESS 状态的执行记录;流水线不可用的边界情况由 clearPipelineInfo 清空流水线信息。

5.4 Publish 的状态迁移与 latest 标签管理

发布操作将版本置为 online、清空工作指针、按需递增 onlineCnt,并由服务端根据资源类型规范管理 latest 标签。规范对 latest 的默认规则是:

  • 除非类型规范定义了确定性细化,成功发布或上线后目标版本即成为 latest
  • 当当前 latest 版本被删除或下线时,默认替换为剩余版本号最大的在线版本;若无在线版本,服务端移除 latest
  • 类型细化仍必须保持 latest 由服务端管理、指向在线版本,并定义删除/下线回退。

从源码看,doPublishAiResourceManager.java)与 directPublishVersion 均以 CAS 方式统一维护 latest 标签,服务端托管语义贯穿始终。updateLatestLabel 仅为历史兼容保留,新客户端不应发送。

5.5 兼容性投影与收敛失败重试

规范针对"独立兼容性服务投影"(separate compatibility serving projection)给出了强一致约束:

  • 生命周期行是持久化的期望状态(durable desired state)
  • 投影收敛跟随生命周期变更,投影校验通过后操作才报告成功
  • 收敛失败时保留生命周期行,以便幂等重试或 reconciler 完成投影。

这一"先留行、后清理、失败可重试"的锚点思想,同样贯穿第 6 节的删除规则。

5.6 类型规范的两处兼容例外

规范明确了两类类型的兼容性门面,均为审计过的例外,不得扩散到标准 API:

  • Agent 类型:仅在其遗留 A2A 直连上线门面上,setAsLatest=false 可保留当前有效指针;标准 Agent 发布/上线仍移动 latest,删除或下线当前指针时选择剩余最大的在线 Agent 版本。详见 Agent 管理规范A2A Agent 规范
  • MCP 类型:历史 API 的 Version 会立即变为 online,其遗留 latest 标志可保留当前有效指针;历史更新门面还可能覆盖已存在的精确 Version(受审计的例外),但规范的 draft/lifecycle API 绝不复用这一放宽。标准 MCP 发布、强制发布、上线仍移动 latest;latest 回退优先级为:最大 SemVer → 最大数字 vN → 最大稳定大小写敏感字符串。详见 MCP Server 规范

流水线的扩展行为由 AI 发布流水线插件规范 定义,本域规范只负责说明 AI 资源生命周期如何响应流水线结果。

6. 标签(Labels)规则

  • latest保留的默认标签,指向最新发布版本;
  • latest服务端管理:手动标签更新请求可出于兼容性包含 latest,但服务端必须忽略客户端提供的 latest,并把当前服务端管理的 latest 值合并回有效标签映射;
  • 标签映射到版本字符串,不得指向 draftreviewing 版本
  • 修改标签本身不改变版本内容或版本状态;
  • 按标签的运行时查询必须在请求时实时解析标签

常量 LABEL_LATEST = "latest" 定义于 AiResourceConstants.java。标签语义与版本信息中的 labels 字段(ResourceVersionInfo.java)配合,所有标签变更都发生在 draft/reviewing 之外的安全边界上。

7. 删除规则:先清存储,后删元数据

删除是生命周期中风险最高的操作,规范给出的顺序约束非常严格:

  1. 删除版本:应移除该版本行与类型持有的该版本存储;
  2. 删除资源:应移除元数据、全部版本行与全部类型持有的存储;
  3. 删除资源前必须加载每个 Version 的存储描述符,存储清理必须路由到每个描述符中持久化的 provider,并尝试清理所有被引用的内容对象;
  4. 加载完所有描述符后,类型可先把 Resource 及其 Versions 移到非服务生命周期状态,再收敛外部兼容投影、开始物理清理;保留的行是清理完成前的持久化重试锚点
  5. 元数据与 Version 行只有在所有被引用存储内容成功清理后才能删除;任何清理失败都必须报告失败并保留可重试的行与描述符;
  6. 删除操作仅在公共 API 契约声明"资源缺失即成功"时才是幂等的
  7. 删除在线版本时,若类型实现支持,应更新 onlineCnt 或标签;
  8. 类型持有的物理清理必须参与类型存储删除回调,并在元数据行移除前完成。特别地,MCP 持有的 Direct Naming 清理与 MCP Version Config 清理遵循同样的"行保留"规则:任一失败都将删除报告为未完成,并保留 Resource/Version 行与描述符供重试。普通被引用的 Service 与客户端持有的 Runtime 状态不是类型持有的清理目标。

AiResourceManager.java 中可以看到 deleteVersiondeleteVersionsByNameAndTypedeleteMeta 三个删除入口的并列设计,印证了"版本级删除 / 批量版本删除 / 元数据删除"三种粒度各自独立、按序执行的架构。

8. 追踪与计数器:全操作审计

8.1 应追踪的操作清单

AI 资源操作应为以下动作发出 trace/audit 事件:

创建草稿(create draft)、更新草稿(update draft)、提交(submit)、审核通过/拒绝(review approved/rejected)、发布(publish)、强制发布(force publish)、上线/下线(online/offline)、删除(delete)、标签更新(label update)、描述更新(description update)、作用域更新(scope update)以及下载(download)。

AiResourceTraceService.java 中,这些操作被一一映射为字符串常量:OP_CREATE_DRAFTOP_UPDATE_DRAFTOP_DELETE_DRAFTOP_UPLOADOP_SUBMIT_REVIEWOP_REVIEW_APPROVEDOP_REVIEW_REJECTEDOP_REVIEW_FORCE_SKIPOP_REDRAFTOP_PUBLISHOP_FORCE_PUBLISHOP_OFFLINE_VERSIONOP_ONLINE_VERSIONOP_DELETE_VERSIONOP_DELETE_RESOURCEOP_SET_LABELOP_REMOVE_LABELOP_UPDATE_LABELSOP_UPDATE_SCOPEOP_UPDATE_DESCRIPTIONOP_UPDATE_BIZ_TAGSOP_UPDATE_RESOURCEOP_ENABLEOP_DISABLE 等。

8.2 追踪事件与默认落盘

AI 资源追踪使用 AiResourceTraceEvent。该事件类定义于 common 模块,字段包括:

public class AiResourceTraceEvent extends TraceEvent {
    private final String operator;      // 操作者
    private final String resourceType;  // 资源类型
    private final String resourceId;    // 资源 ID
    private final String version;       // 版本
    private final String operation;     // 操作
    private final String status;        // 状态
    private final String clientIp;      // 客户端 IP
    private final String ext;           // 扩展信息
}

默认的 AI 资源追踪插件将 JSON 行审计日志写入 ai-resource-trace.log,同时允许外部追踪订阅者消费同一事件流。日志滚动配置在 distribution/conf/nacos-logback.xml 中,输出文件为 ${LOG_HOME}/ai-resource-trace.log,按天与序号滚动(ai-resource-trace.log.%d{yyyy-MM-dd}.%i)。典型日志行格式如下(来自 AiResourceTraceService.java 的 Javadoc 示例):

{"timestamp":"2026-03-30T10:15:30Z","operator":"admin","resource_type":"skill",
 "resource_id":"my-skill","version":"v1.0","operation":"PUBLISH",
 "status":"SUCCESS","ip":"192.168.1.1"}

该 JSON 行格式专为 ELK/Loki 等日志采集链路设计。追踪插件的扩展行为由 追踪插件规范 定义。计数器仅用于诊断,不得用于定义授权或生命周期状态——这是规范划出的一条硬边界:审计与指标永远只是观察者,不能反过来成为状态机的输入。

9. 演进说明:状态机的未来扩展

规范在结尾明确指出,随着 AI 发布工作流成熟,生命周期状态可能扩展,例如支持:

  • 审批链(approval chains)
  • 分阶段发布(staged rollout)
  • 策略评估(policy evaluation)
  • 签名(signing)
  • 制品扫描(artifact scanning)

所有新状态都必须定义与既有 draftreviewingreviewedonlineoffline 行为的兼容性。这意味着现有状态机是一个"可演进的核心",任何扩展都不能破坏既有 API 契约与存量资源的状态迁移路径。

10. 实践要点小结

  • 两态分离enable/disable 管资源可用性,五个版本状态管版本阶段,二者互不干扰;
  • 提交与发布分离submit 进流水线,publish 真正上线;无流水线时 submit 可直接直发;
  • reviewed 是"待命"态:审核通过/拒绝后版本停在 reviewed,用户必须显式触发发布、强制发布、redraft 或重新提交;
  • reviewing 提交是幂等的:重复 submit 不会重复启动流水线;历史流水线结果(historical=true)不会完成当前审核;
  • latest 永远服务端托管:客户端提供的 latest 值一律被忽略,删除/下线时的回退规则由服务端统一执行;
  • 删除先清存储后删行:所有版本存储描述符加载完毕、物理清理成功之后,才允许删除元数据与版本行,失败即保留行以待重试;
  • 全操作审计:从创建草稿到下载的每个动作都产出 AiResourceTraceEvent,默认落到 ai-resource-trace.log,便于审计与可观测性接入。

如需进一步深入,可继续阅读 Agent 管理规范MCP Server 规范AI 发布流水线插件规范,或直接研读 AiResourceManager.java 中从 markEditingVersionCasdoPublish 的完整状态机实现。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.14 K
2.75 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
860
1.35 K
docsdocs
暂无描述
Markdown
899
5.83 K
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
924
1.85 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.84 K
1.02 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
533
599
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.03 K
525
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.37 K
1.46 K
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
548
394