跳转至

第 23 章:退役、替换与终止使用纪律

第 VIII 部分中的章节角色

核心问题: 如何退役或替换智能体系统,同时不留下旧权限。

独特工件: 退役或替换计划。

相邻边界: 退役关闭旧的行动权。

本章不覆盖: 新的失配威胁、行为评测或遥测覆盖。

案例延续: 旧的支持工单写入路径在替换后失去行动权。

1. 为什么成熟的智能体系统必须学会“离场”

很多团队对生命周期的理解停留在这里:

  • 想出系统;
  • 把它做出来;
  • 保护它;
  • 观察它;
  • 安全地发布变更。

但任何生产系统还有一个必经阶段:它迟早要被替换、关闭或退役。

这对智能体系统尤其重要,因为它们通常会留下很长的运行尾部:

  • 记忆状态;
  • 工具访问;
  • 审批与审计轨迹;
  • 暂停运行状态(paused-run state)与后台运行状态(background-run state);
  • 能力会话状态(capability-session state)与中断血缘(interruption lineage);
  • 编排模式血缘(orchestration-pattern lineage)与工作边界决策(worker-boundary decisions);
  • 委托授权血缘(delegated authorization lineage)与撤销状态(revoke state);
  • 验证器契约血缘(verifier-contract lineage)与验证器证据保留义务(verifier evidence retention obligations);
  • 跨越上下文重置(context reset)与角色交接边界的交接工件血缘(handoff-artifact lineage);1
  • 外部集成;
  • 用户预期;
  • 依赖它的工作流。

也就是说,退役不是“删掉服务然后忘记它”,而是一个被管理的运行过程。

这也正是本章的核心承诺。它要帮助读者把退役看成整个生命周期的闭合函数,而不是交付的尾声附录:在这里,系统失去继续行动的权利,而它的记忆、证据、审批与运行血缘会被带到一个受控终点。本章的主要工件是退役计划(retirement plan):一份关闭权限、状态、证据和负责人归属的计划,而不是简单删除旧智能体。

2. 什么时候应该开始考虑退役

最好不要把退役当成遥远又尴尬的话题。

在实践里,常见触发条件包括:

  • 运行时或模型已经过时;
  • 能力契约不再被认为安全;
  • 维护成本太高;
  • 质量已经到顶,必须替换;
  • 新的平台路径正在替代旧路径;
  • 监管或治理要求发生变化;
  • 产品问题本身已经不存在。

如果团队没有明确的退役触发条件,旧的智能体系统几乎总会活得比安全和有用所允许的更久。

3. 退役和替换不是一回事

最好把这两个场景分开:

  • retirement:系统或能力直接退出运行;
  • replacement:旧系统下线之前或同时,由一个新系统接手。

这个区别很重要。

在退役里,核心问题是如何安全地下掉旧系统。

在替换里,核心问题是如何在不丢失质量、控制和历史的前提下完成受控迁移。

4. 最大的风险,是系统虽然“退役了”却仍然能行动

最糟糕的一类运行错误通常是这样发生的:

形式上系统已经“死了”,但在运行上它仍然能行动。

这对智能体特别危险,因为自主和半自主的执行路径很容易被忘掉。

贯穿案例:替换后的旧工单写入器

如果支持分诊(support-triage)v2 替换了曾经制造重复工单的旧路径,退役必须证明旧的 create_support_ticket 路径已经不能再行动。仅仅移除提示路由(prompt route)不够:团队还必须关闭工具主体、撤销网关暴露(gateway exposure)、让暂停审批(paused approvals)过期、停止后台重试,并保留审计轨迹,这样未来的重复工单才不会被归因成“来源不明”的旧智能体。

退役案例主线说明(Retirement case-spine note):每个规范案例(canonical case)都会退役一种不同的行动权(right to act)。支持分诊(Support triage)关闭已弃用写入路径(deprecated write paths)和暂停审批(paused approvals);内部知识助手(Internal knowledge assistant)退役过时语料(stale corpora)、过时嵌入(obsolete embeddings)和记忆写入规则(memory-write rules);事故协调(Incident coordination)在响应路径(response path)不再有效时关闭仅应急能力(emergency-only capabilities)、升级路由(escalation routes)和通知通道(notification channels)。只删除运行时(runtime)的退役计划(retirement plan)会把旧权限留在系统里。

5. 退役最好按层收缩

好的终止使用流程很少是一个动作完成的。通常更适合按层来做:

更稳妥的退役,更像是一步步缩小运行面

flowchart LR
    A["Freeze rollout"] --> B["Disable risky capabilities"]
    B --> C["Disable writes and background jobs"]
    C --> D["Revoke egress and principals"]
    D --> E["Archive audit and memory state"]
    E --> F["Mark system retired"]

删除会话不会释放 compute

在 OpenAI Agents API 中,删除会话既不停止自托管 compute,也不发送删除 webhook。因此,不能只凭 delete-session 成功响应就认定退役完成。

建议适配器顺序:停止新输入;在统一协调下阻止新 provisioning 并核对进行中的启动;保留非秘密引用和必要审计数据;分别删除会话、通过提供方停止 compute;确认两者结果。保留未完成清理记录,以支持重试和提供方核对。若删除请求后才创建出 compute,控制器必须发现并释放它,而不是连同映射一起遗失。停止失败意味着退役尚未完成,即使会话已删除。文件与快照保留仍是单独的策略决定,不是删除会话的隐含效果。

存储修复与清理完成是不同状态

在 Cloudflare 事件 中,恢复新块清零阻止了最初的复现方式,但没有清理已映射块。还必须退役旧磁盘并重建缓存快照。因此,修复成功发布或会话删除不能证明清理完成。

建议的关闭流程是:确定受影响存储池、磁盘、快照和派生缓存;禁止分配及恢复未经验证的代次;协调停止或迁移负载;重建或清理受影响产物;将实际清单与预期覆盖范围核对;由基础设施负责人确认结果。清理还应协调并发创建和克隆,否则旧镜像层可能在过程中重新出现。保留 remediation_version、受影响资源范围、产物代次、清理状态、非秘密证据引用、验证者及未解决例外。这些是建议的记录字段,不是现有运行时模式。

缺少确认、主机不可达或仍有残留缓存,都意味着对应范围清理未完成,即使新分配测试已通过。未知状态不能变成可安全重用。若因调查或保留策略必须保存副本,应隔离它、禁止向新租户分配,并记录负责人和期限:“受限访问下保留”不等于“已清理”。应用级删除日志只能证明该操作,不能证明所有底层副本均已物理擦除。案例与合成检查展示了如何区分这些条件。

6. 记忆与审计数据需要单独的纪律

一旦系统退役,一个不舒服的问题就出现了:积累下来的状态该怎么办?

团队通常需要分别决定:

所以退役影响的不只是正在运行的系统,还包括整段历史运行足迹。

7. 替换应该分阶段,而不是二元切换

当旧系统被新系统替换时,最自然的冲动是:“直接切换过去,然后继续前进。”

对智能体系统来说,这通常太冒险。

更安全的是分阶段替换:

这也是替换和上线纪律最接近的地方,只不过替换还多了一个问题:如何在新旧系统之间保持连续性。

8. 老的能力和模式应该被正式废弃

最好不仅有已批准清单(approved inventory),还要有已废弃清单(deprecated inventory)。

例如:

这很重要,因为退役几乎总是从“明确宣布这条路不再是正常路径”开始,而不是从突然关机开始。

9. 面向用户的过渡也是生命周期的一部分

如果智能体系统影响到用户或内部工作流,那么终止使用不能只在平台层内部完成。

最好单独想清楚:

  • 需要通知谁;
  • 哪些流程会变化;
  • 哪些预期需要重新设置;
  • 会有哪些回退路径;
  • 老的集成还要支持多久。

这对内部智能体系统尤其重要,因为它们很快就会长进团队的真实工作习惯里。

10. 一个退役策略示例

下面这个骨架很实用:

retirement:
  triggers:
    - deprecated_runtime
    - unsafe_capability_pattern
    - maintenance_cost_exceeded
    - replacement_ready
  required_steps:
    - freeze_rollout
    - disable_risky_capabilities
    - stop_memory_write
    - expire_paused_runs
    - stop_background_routes
    - freeze_reinitialization
    - disable_deprecated_patterns
    - revoke_worker_capability_exposure
    - retire_verifier_contracts
    - revoke_egress
    - archive_audit_state
    - set_retired_status

它的价值不在于 YAML 本身,而在于把退役变成了明确的运行契约。

11. 一个替换就绪检查示例

下面这个代码片段展示的是正确的门禁形态:

from dataclasses import dataclass


@dataclass
class ReplacementState:
    shadow_eval_passed: bool
    migration_plan_ready: bool
    risky_capabilities_disabled: bool
    archive_plan_ready: bool
    paused_runs_drained: bool
    capability_sessions_resolved: bool


def ready_for_replacement(state: ReplacementState) -> bool:
    return (
        state.shadow_eval_passed
        and state.migration_plan_ready
        and state.risky_capabilities_disabled
        and state.archive_plan_ready
        and state.paused_runs_drained
        and state.capability_sessions_resolved
    )

重点很简单:替换也应该有门禁,而不是“凭感觉切换”。

12. 终止使用纪律最常坏在哪里

这些问题非常常见:

正是这些小细节,会把一个“几乎完整”的生命周期重新变成事故来源。

13. 给终止使用纪律做一次快速成熟度测试

团队不应该只因为会把流量切走、再把系统标成 deprecated,就觉得自己已经会做退役。

更高的标准应该是:

  • 系统会在被宣布 retired 之前先失去行动能力;
  • 主体(principals)、连接器(connectors)、记忆写入(memory writes)、暂停运行(paused runs)、能力会话(capability sessions)、编排模式(orchestration patterns)与后台任务(background jobs)会被有意识地逐层收缩;
  • 替换是分阶段的,而不是二元切换(cutover);
  • 已废弃的审批模式(approval schemas)与运行时控制模式(runtime-control schemas)会被真正关闭,而不是作为隐藏兼容路径长期残留;
  • 归档状态有负责人,也有保留决策;
  • 已废弃模式会变成真正被阻断的路径,而不只是警告(warnings)。

如果这些条件大多不成立,那团队也许已经有一些关闭机制,但还没有真正的终止使用纪律。

14. 实用检查清单

如果你想快速检查自己的终止使用纪律,可以问:

  • 系统是否有明确的退役触发条件?
  • 能力能否按阶段关闭,而不是只能“一键全关”?
  • 关闭后记忆、追踪、审批、暂停运行状态(paused-run state)和能力会话状态(capability-session state)怎么处理,是否清楚?
  • 是否有分阶段替换计划?
  • 主体、连接器、出口访问、暂停审批(paused approvals)、能力会话重新初始化(capability-session re-init)和后台路由(background routes)能否快速撤销或排空?
  • 已归档工件和历史状态的负责人是否明确?

如果连续几个问题的答案都是“否”,那你的生命周期其实还停留在发布,而不是完整运营。

15. 接下来读什么

这章把 Part VIII 真正闭合成一个完整的运行闭环:

  • SDLC→ADLC;
  • 变更管理;
  • 保障闭环;
  • 工件治理;
  • 退役与替换。

现在这一部分已经不仅能解释架构,还能作为生产级智能体系统的生命周期手册使用。

16. 值得配套阅读的参考页