云选科普

AI 工作流的 OSS 文件怎么清理:标签、生命周期与版本控制

面向使用 AI 工作流的开发者和小团队,梳理 OSS 临时文件、审核版本与正式结果的保留边界,给出标签、生命周期、Dry Run、版本控制和权限设计方法。

AI 工作流里的文件通常不是“用完即删”的临时数据。一次任务可能同时产生上传原件、解析中间文件、提示词快照、模型草稿、审核版本和最终结果。若只按对象年龄设置统一删除规则,容易把仍被任务引用的输入、需要追溯的版本一起清掉。

更稳妥的做法是把“业务上是否还要保留”与“存储层要执行什么动作”分开:应用记录对象状态和引用关系,OSS 通过前缀、对象标签和生命周期规则执行过期或存储类型转换。这样清理策略可以被审计、预演,也能随业务状态变化调整。

先把对象分成可解释的状态

建议至少区分四类状态:

  • temporary:可重新生成、没有业务引用的中间产物;
  • review:等待人工或下游审核,仍可能被再次读取;
  • published:已经对外使用的结果,需要保留来源和版本;
  • hold:争议、审计或合规要求暂时禁止自动处理。

状态不是存储动作。temporary 可能进入过期候选,review 可能转入低频存储,published 由内容制度决定保留时间,hold 则必须排除自动删除。未知状态应默认保留,不能把缺少标签当成“可以清理”。

对象目录可以作为稳定边界,例如 ai-workflow/input/working/output/;对象标签再表达会变化的业务状态,例如 stage=reviewretention=hold。前缀负责分区,标签负责状态,两者组合比单独依赖目录更容易迁移和审计。

同时维护一份对象清单,至少包含:

任务 ID、对象 Key、版本 ID、产物类型、状态、引用任务、创建时间、保留策略、锁定原因

任务结束不代表所有关联对象都能删除。最终结果可能仍需追溯输入,审核记录可能要长期保留,而解析缓存才适合较短周期。

用生命周期规则执行,而不是每天遍历删除

OSS 生命周期规则可以按前缀、对象标签等条件筛选对象,并执行过期删除或存储类型转换。应用负责把对象标记为正确状态,OSS 负责按规则执行存储动作。生命周期任务是周期性处理,不应被当作精确到秒的定时器;业务状态需要单独记录“已进入清理候选”,再由存储检查确认实际结果。

一个可读的规则模型如下:

范围:ai-workflow/
条件:stage=temporary
动作:达到保留期限后过期

范围:ai-workflow/
条件:stage=review
动作:达到审核期限后转低频存储

配置多条规则时,要从“一个对象会命中哪些规则”反向检查。前缀、标签和排除条件叠加后,原本想保留的对象可能仍被另一条规则命中。hold 对象可以使用独立前缀,也可以通过排除条件隔离;不管采用哪种方式,都应在测试对象上验证命中结果。

通过 API 或 SDK 更新 Bucket 生命周期时,先读取现有完整配置,再做差异比较。阿里云 OSS 的生命周期更新接口采用整体配置语义,只提交新规则可能覆盖原有规则。上线流程应保存规则 ID、变更原因和生效时间,提交后再次读取确认,而不是只依赖控制台提示成功。

删除前必须经过 Dry Run

生命周期删除可能不可逆,先做候选清单比直接试删更重要。Dry Run 不访问真实删除接口,只根据对象清单计算计划动作:

@dataclass(frozen=True)
class ObjectRecord:
    key: str
    stage: str
    age_days: int
    referenced_by: tuple[str, ...] = ()
    hold: bool = False
    version_id: str | None = None

def decide(item: ObjectRecord) -> str:
    if item.hold or item.referenced_by:
        return "retain_manual_review"
    if item.stage == "temporary" and item.age_days >= 7:
        return "expire_candidate"
    if item.stage == "review" and item.age_days >= 30:
        return "archive_candidate"
    return "keep"

示例中的 7 天和 30 天只是演示参数,不是通用建议。真实期限应由数据敏感性、任务重跑成本、审核周期和合规要求共同决定。候选报告应带上对象 Key、版本 ID、状态、引用关系、计划动作和原因,并抽查以下对象:正在运行的任务、已发布内容的输入、标签缺失对象、历史版本以及处于争议或审计中的文件。

先在隔离前缀和少量测试对象上观察规则命中,再逐步扩大范围。业务数据库中的 retention_decision 与存储侧 storage_status 分开记录,只有确认对象已过期或完成存储转换,才把状态更新为最终结果。

版本控制与分片上传要单独设计

开启版本控制后,删除当前版本和清理历史版本是两件事。生命周期可能先为当前版本添加删除标记,历史版本仍然占用空间;要释放历史版本,还需要单独配置非当前版本的过期策略。因此 Dry Run 必须包含 version_id、是否为当前版本和删除标记信息,不能只按对象 Key 统计。

大文件常用分片上传。网络中断或进程退出后,未完成的 Part 不会自动等同于一个可见对象,也可能持续占用空间。应为未完成分片设置独立的清理规则,并把它和对象过期的监控分开,便于确认清理的是上传残片而不是有效文件。

审核文件转归档类存储前,还要确认下游是否需要即时读取、恢复等待时间是否可接受、取回费用和最短存储时长是否符合预算。存储类型和计费规则会随地域与产品能力变化,正式配置前应以当前 OSS 文档和控制台为准。

权限、发布与回滚边界

标签本身会影响生命周期命中,修改标签的权限不能与普通处理函数混用。可以按职责拆分:上传函数只能创建 temporary 对象;审核流程负责变更为 review;发布流程在确认后变更为 published;保留管理员单独设置或解除 hold。普通生成任务不应拥有解除保留锁定或批量删除对象的权限。

推荐采用下面的上线顺序:

  1. 先定义状态、引用关系和默认保留策略;
  2. 在应用侧写入标签并保留状态变更审计记录;
  3. 以只读方式生成 Dry Run 报告;
  4. 在测试前缀配置生命周期并回读完整规则;
  5. 观察实际过期、归档、历史版本和分片清理结果;
  6. 逐步扩大前缀范围,并为异常命中保留回滚方案。

一份适合小团队的检查清单

  • 未知状态是否默认保留;
  • 运行中任务和正式结果的引用是否可查询;
  • 前缀、标签和排除条件是否经过组合测试;
  • 删除候选是否先经过 Dry Run 和人工抽查;
  • 生命周期更新是否采用读取、合并、完整提交、回读流程;
  • 版本控制下是否同时处理历史版本和删除标记;
  • 未完成分片是否单独清理;
  • 归档后的读取时延与取回成本是否明确;
  • 标签、保留锁定和删除权限是否最小化;
  • 是否能观测“规则命中、实际执行、异常回滚”三个阶段。

AI 文件治理的目标不是让 Bucket 尽快变空,而是让每一次保留、归档和删除都有业务依据。先用状态和引用关系表达保留意图,再让 OSS 生命周期按条件执行,配合 Dry Run、版本策略和最小权限,才能在控制存储成本的同时保住可追溯性与恢复能力。

继续浏览

还想继续看,可以再看这些文章

适合想继续在同一主题下横向阅读、对比不同切入角度的用户。