Agent 部署策略:金丝雀发布、蓝绿部署与渐进式上线

30秒要点

  • 核心问题:传统软件部署假设"相同输入→相同输出"——Agent 不成立。模型更新引入非确定性的行为漂移,工具 API 变化导致接口断裂,模型升级可能导致单任务 Token 消耗翻倍。这三种风险是任何 Agent 系统走向生产时必须面对的系统性挑战。
  • 三层部署策略:金丝雀发布(5-10%流量验证语义正确性)→ 蓝绿部署(零停机环境切换,保护会话状态和工具注册表)→ 渐进式上线(10%→25%→50%→100% 流量阶梯,每阶段由语义评分、成本退化检测和延迟回归三项指标守住)。三者不是互斥选项——它们是同一套部署体系中的三道防线。
  • Agent 特有的部署门槛:通用 DevOps 部署关心的指标是 HTTP 状态码和 CPU 占用率。Agent 部署的门槛完全不同——输出语义质量评分是否下滑、工具调用成功率是否降低、per-task Token 消耗是否增长超过 15%、模型产出速率是否下降。这些是 Agent 部署的真正健康指标。
  • 读完能做什么:为你的 Agent 系统设计从金丝雀到全量部署的完整流水线——包含语义评分评估器、工具调用烟雾测试、成本回归检测器、和自动回滚触发器。每个策略都配有可直接参考的 YAML 配置模板。

§1 引言:AI Agent 为何需要专属部署策略

2026 年 4 月的一个深夜,某电商平台的客服 Agent 从 gpt-4-turbo 迁移到 gpt-4o。部署团队按照标准的 Kubernetes 滚动更新流程完成了上线——所有 Pod 的健康检查通过,HTTP 探针全部返回 200,CPU 和内存指标正常。30 分钟后,运营团队收到大量投诉:Agent 开始拒绝处理退货申请,理由是"您的订单中未找到符合退货条件的商品"——而实际上这些订单完全符合退货政策。

问题出在哪里?新模型对退货政策的推理逻辑与旧模型有细微差异:旧模型在计算退货窗口时使用"签收日期 + 7 天",新模型错误地使用了"下单日期 + 7 天"——这一差异在传统的 HTTP 健康检查中完全不可见。所有请求都返回了 200 OK,响应时间甚至更快了,但语义正确性已经坍塌。这是 Agent 部署的核心困境:传统软件部署假设"相同输入→相同输出",Agent 不成立。

部署方程的变化:传统软件:deploy(new_version) → 验证(HTTP 200, CPU < 80%, latency < 500ms) → 成功。Agent 系统:deploy(new_model/tool/system_prompt) → 验证(HTTP 200 语义评分 ≥ 0.95 工具调用成功率 ≥ 99% per-task Token 增长 < 15% 模型输出速率 ≥ baseline) → 成功。后者的验证维度比前者多出 3-4 个轴,且每个轴的测量都需要专门的评估基础设施。

Agent 部署面临的三种独特风险

传统软件的部署风险主要集中在一个维度——代码回归:新版本是否引入了 Bug?回滚是否简单?但 Agent 系统在代码之上叠加了模型推理、工具执行和 Token 经济三个新维度,每种维度都引入了传统部署流程无法覆盖的风险:

  1. 行为漂移(Behavior Drift):模型更新——即使只是 Provider 的无公告小版本更新——可能改变 Agent 的推理路径。同一个 Prompt,同一个温度参数,从 claude-sonnet-20250219claude-sonnet-20250601,模型处理同一份退货政策的"理解"可能发生微妙但致命的偏移。这种漂移不像代码 Bug 那样有明确的错误日志——它静默地发生,只有在语义层面的对比评估中才能被捕获。
  2. 接口断裂(Tool API Incompatibility):Agent 不只是一个 HTTP 服务——它是一个由 LLM 推理引擎 + 工具注册表 + 提示词模板 + 上下文管理策略组成的复合系统。新版本的 Agent 可能使用新的工具定义、更新的函数签名、或不同的参数 Schema。如果新 Agent 调用了 search_documents(query, top_k=10) 而旧版本的工具端只接受 search(query, limit),Agent 的 function_call 会返回一个格式正确的 JSON——然后被工具端点以 400 Bad Request 拒绝。Agent 会进入重试循环,每次重试都在消耗 Token,直到上下文窗口被错误信息撑爆。
  3. 成本退化(Cost Regression):这是 Agent 部署特有的风险类别。新模型可能"更好"——输出质量更高、推理更准确——但同时消耗更多的 Token。如果从 gpt-4o-mini 迁移到 gpt-4o 使每个客服对话的平均 Token 从 1200 涨到 3800,在一个日均 5000 次对话的系统中,月度 API 费用可能从 $5,000 暴增到 $16,000。成本退化不会触发任何传统监控告警——没有错误日志、没有延迟飙升、没有崩溃——只有月底的账单。

三层部署策略:金丝雀 → 蓝绿 → 渐进式

这三种风险不能通过单一部署模式来应对。行为漂移需要小流量语义验证(用小比例的真实流量来测试 Agent 的实际推理质量)——这正是金丝雀发布的设计目标。接口断裂需要完整的并行环境对比(在同一组工具上同时运行新旧两个版本并比较输出)——蓝绿部署提供了这个能力。成本退化需要渐进式的流量放大和持续的指标观察——渐进式上线是专门为此设计的流量阶梯。

以下表格总结了三种策略与三种风险的对应关系:

部署策略 核心防护 流量比例 决策时机
金丝雀发布 行为漂移检测 5–10% 语义评分未达标 → 自动回滚
蓝绿部署 接口断裂防护 + 状态一致性 0%→100%(切换) 环境烟雾测试通过 → 路由切换
渐进式上线 成本退化 + 性能退化监控 10%→25%→50%→100% 每个阶段的指标阈值守住 → 进入下一阶段

这三种策略不是互斥的——它们构成一个由紧到松的部署安全网。金丝雀在最前沿,用最小流量检测最危险的语义退化;蓝绿部署在中间,确保新版本的完整环境在任何时间点都可以被验证和回退;渐进式上线在最后一环,通过阶梯式放大来检测只有足够量级才会暴露的成本和性能问题。关于部署失败后的回滚机制设计,参见 Agent 回滚设计——本文聚焦于回滚之前的部署防护。

§2 金丝雀发布:Agent 行为验证的最小化测试

金丝雀发布(Canary Deployment)的名字来源于煤矿工人带金丝雀下井的传统——金丝雀对瓦斯气体更敏感,比人类更早表现出中毒症状,给矿工争取撤离时间。在 Agent 部署中,金丝雀的"瓦斯气体"是语义退化——将 5-10% 的真实流量引导到新版 Agent,用这些流量作为早期预警系统,在新版 Agent 的推理质量全面崩溃之前检测到信号。

Agent 金丝雀发布与微服务金丝雀发布的关键区别在于验证对象:微服务验证的是"返回的 JSON 结构是否正确",Agent 验证的是"返回的 JSON 内容在语义上是否正确"。前者是结构验证,后者是语义评估——结构验证可以在 1 毫秒内完成,语义评估需要调用评估模型进行成对对比,耗时可能达到秒级。

金丝雀 ≠ 灰度发布:灰度发布是按用户维度逐步扩大范围("先让 10% 的用户看到新版"),金丝雀发布是按请求维度抽样("随机抽取 10% 的请求路由到新版")。在 Agent 场景中,金丝雀更适合做行为一致性验证——同一用户在短时间内发出的连续请求会被分配到新旧两个版本,输出差异可以被直接对比。灰度发布更适合做用户体验验证——同一用户始终看到同一个版本,体验更一致。本文的金丝雀发布指前者。

金丝雀发布的 Agent 专属验证维度

传统金丝雀的验证只需要三个指标:HTTP 错误率、延迟、和资源使用。Agent 金丝雀需要在这些基础指标之上增加至少五个 Agent 专属维度:

  1. 输出语义质量(Output Semantic Quality):金丝雀流量中,每个请求同时发送到旧版 Agent(baseline)和新版 Agent(canary)。两组输出被送入一个评估模型(evaluator),返回 0-1 的语义等价分数。这个分数不是简单的字符串相似度——它需要理解 Agent 的输出是否达成了相同的意图。例如,"您的订单预计 3 月 15 日送达"和"包裹将在 2026-03-15 配送到您手中"在字符串层面相似度只有 40%,但在语义意图层面是等价的。评估模型必须识别这种等价。
  2. 工具调用一致性(Tool Call Consistency):同一个用户请求,旧版 Agent 和新版 Agent 是否调用了相同的工具?参数是否一致?如果旧版调用了 get_order(order_id=38291) 而新版调用了 search_orders(query="38291"),虽然最终可能得到相同结果,但工具的变更意味着推理路径发生了实质改变——这在金丝雀阶段就应该被标记。
  3. 推理步骤数量(Reasoning Step Count):Agent 的推理步骤数(LLM 调用次数 + 工具调用次数)是成本的主要驱动因素。如果新版 Agent 的推理步骤从基线 3.2 步增长到 5.7 步,即使输出质量保持不变,单次任务的成本几乎翻倍——金丝雀阶段就应该阻止它进入更大的流量。
  4. 幻觉率(Hallucination Rate):新版模型是否比旧模型更容易产生幻觉?幻觉率的测量需要专门的评估——在已知答案的测试集中,检查 Agent 的输出是否包含了不存在于上下文中的信息。金丝雀流量可以通过采样 + 人工抽查或自动评估来估算幻觉率的相对变化。
  5. Token 产出速率(Token Throughput):模型产出 Token 的速度直接影响用户体验。如果新版 Agent 的平均 Token 产出速率从 45 Token/s 下降到 18 Token/s,用户会感到明显的"卡顿"——即使最终输出是正确的。

这五个维度中,语义质量和工具调用一致性是必须通过的硬性门槛(不通过即回滚),推理步骤数、幻觉率和 Token 产出速率是退化预警(超过阈值则标记为警告,由人工判断是否继续)。

金丝雀发布的 YAML 配置模板

以下是一份完整的金丝雀发布配置模板,涵盖了流量控制、语义评估、回滚条件三个核心模块:

# canary_deploy.yaml — Agent 金丝雀发布配置
# 作用:将 8% 的流量路由到新版 Agent,通过语义评估和工具调用对比
# 来验证新版本的行为一致性,不通过则在 15 分钟内自动回滚。

deployment:
  name: "customer-service-agent-v2.3-canary"
  pipeline_id: "agent-deploy-20260724-001"
  timestamp: "2026-07-24T14:30:00Z"

# ─── 金丝雀流量控制 ───
canary_traffic:
  routing_strategy: "request_sampling"     # request_sampling | user_hash | session_sticky
  canary_ratio: 0.08                       # 8% 流量进入新版 Agent
  baseline_ratio: 0.92                     # 92% 流量保持在旧版
  sampling_seed: 20260724                  # 确定性采样种子,保证同一请求可复现
  max_canary_duration_minutes: 60          # 金丝雀最大持续时间,超时自动终止
  shadow_traffic: true                     # 额外发送 5% 流量到新版但不返回结果(对比用)

# ─── 新版 Agent 配置 ───
canary_version:
  model: "gpt-4o-2024-05-13"
  model_temperature: 0.3
  system_prompt_version: "v2.3"
  tool_registry_version: "tools-v4.1"
  context_window_max_tokens: 128000
  agent_config_uri: "s3://agent-configs/customer-service/v2.3.0.yaml"

# ─── 旧版 Agent 配置(基线)───
baseline_version:
  model: "gpt-4-turbo-2024-04-09"
  model_temperature: 0.3
  system_prompt_version: "v2.2"
  tool_registry_version: "tools-v4.0"
  context_window_max_tokens: 128000

# ─── 语义评估配置 ───
evaluation:
  evaluator_model: "claude-sonnet-20250601"  # 独立评估模型,不是被评估的模型之一
  semantic_equivalence_threshold: 0.95       # 语义等价分数 ≥ 0.95 才算通过
  tool_call_match_threshold: 0.99            # 工具调用一致性 ≥ 99%
  hallucination_delta_threshold: 0.02        # 幻觉率增长 ≤ 2 个百分点
  reasoning_steps_ratio_max: 1.25            # 推理步骤数增加 ≤ 25%
  token_throughput_ratio_min: 0.70           # Token 产出速率下降 ≤ 30%

  # 语义评分的具体实现:对每个金丝雀请求,同时发给新旧版本,
  # 然后用 evaluator 模型按以下标准进行成对评分。
  eval_prompt: |
    You are evaluating two agent responses for semantic equivalence.
    Score from 0.0 (completely different outcome) to 1.0 (identical outcome).

    User Request: {user_request}
    Baseline Response (old): {baseline_output}
    Canary Response (new): {canary_output}

    Scoring criteria:
    - 1.0: Same conclusion, same reasoning, same tool calls
    - 0.8-0.9: Same conclusion, slightly different reasoning or wording
    - 0.5-0.7: Similar direction but different details or tool usage
    - 0.2-0.4: Different approach, possibly different outcome
    - 0.0-0.1: Contradictory conclusions or completely different outcome

    Return ONLY a JSON object: {"score": float, "reason": "string"}

# ─── 回滚条件 ───
rollback:
  auto_rollback: true
  # 硬性条件:满足任一即触发自动回滚
  hard_conditions:
    - metric: "semantic_equivalence_score"
      threshold: 0.95
      operator: "lt"                         # less than — 语义评分 < 0.95
      min_samples: 50                        # 至少 50 个金丝雀样本才触发
      window_minutes: 5                      # 滚动时间窗口

    - metric: "tool_call_match_rate"
      threshold: 0.99
      operator: "lt"
      min_samples: 50

    - metric: "http_error_rate"
      threshold: 0.01                        # HTTP 错误率 > 1%
      operator: "gt"

    - metric: "hallucination_rate_delta"
      threshold: 0.02                        # 幻觉率增长 > 2 个百分点
      operator: "gt"
      min_samples: 30

  # 软性条件:满足时发出告警,但暂不回滚
  soft_conditions:
    - metric: "avg_reasoning_steps_ratio"
      threshold: 1.25                        # 推理步骤增加 > 25%
      operator: "gt"
      action: "alert_oncall"

    - metric: "token_throughput_ratio"
      threshold: 0.70                        # Token 产出速率下降 > 30%
      operator: "lt"
      action: "alert_oncall"

  # 回滚执行:将流量 100% 切回旧版 Agent
  rollback_action:
    type: "traffic_switch"
    target: "baseline_version"
    drain_canary_connections: true
    notification_channels:
      - "slack:#agent-deploy-alerts"
      - "pagerduty:agent-oncall"

# ─── 观察期与数据收集 ───
observation:
  metrics_export:
    - type: "prometheus"
      endpoint: "pushgateway.agent.internal:9091"
    - type: "s3_log"
      bucket: "agent-canary-logs"
      prefix: "canary-20260724-001/"

  sampling:
    request_log_sample_rate: 1.0             # 金丝雀请求 100% 记录
    response_log_sample_rate: 1.0
    max_stored_samples: 10000

这个配置的核心思想是:金丝雀发布不是"放一点流量出去看看"——它是一套完整的实验,有明确的假设(新版 Agent 的语义行为与旧版一致)、有量化的成功标准(语义评分 ≥ 0.95、工具调用一致性 ≥ 99%)、有预设的终止条件(任何一个硬性指标跌破阈值即自动回滚)。

语义评分器的工作原理

语义评分器(Semantic Evaluator)是金丝雀发布中最关键的组件。它的工作方式如下:

  1. 每一个被路由到金丝雀的请求,同时发送到 baseline_versioncanary_version 两个 Agent 实例。两个实例使用各自的模型、系统提示词和工具注册表,独立完成推理。
  2. 两个输出被送入 evaluator_model(注意:评估模型必须是独立于新旧版本的第三个模型——如果评估模型与新旧版本之一重合,评估结果会有偏见)。评估模型按 eval_prompt 中定义的标准给出 0-1 的语义等价分数。
  3. 所有评分在 5 分钟的滚动窗口中聚合。如果 50+ 个样本的平均语义等价分数低于 0.95,触发自动回滚。
  4. 评分日志被写入 Prometheus 和 S3,用于事后分析。每一次回滚都附带了完整的评分历史——什么请求导致了评分下降、下降的模式是什么、是系统性的(所有请求都下降)还是局部性的(特定类型的请求下降)。

为什么是 0.95 而不是 0.99?在实际生产环境中,新旧 Agent 的输出不可能完全一致。即使是模型的无公告小版本更新(Provider 侧的模型热更新)也可能引入 1-3% 的微小漂移。将阈值设为 0.99 会导致几乎所有金丝雀都触发误报回滚。0.95 是一个经过验证的实用阈值——它容忍微小的措辞差异,但会捕获实质性的推理变化。对于安全敏感的 Agent(如金融交易、医疗诊断),可以将阈值提高到 0.98;对于低风险的信息查询 Agent,0.92 也是一个可行的选择。

金丝雀发布的故障模式与韧性配合

金丝雀发布本身也可能出现故障——评估模型不可用、金丝雀 Agent 实例因为新模型对资源的更高要求而 OOM、金丝雀流量在抽样时引入了样本偏差。这些故障模式需要一个与之配合的韧性层。在 Agent 韧性模式的整体框架中,金丝雀发布的评估管道应该受熔断器保护(当评估模型连续失败时停止评分,而不是让金丝雀在不设防的情况下继续),金丝雀 Agent 实例应该受 Bulkhead 隔离(避免金丝雀的 OOM 影响生产流量)。关于这些韧性模式的完整设计,参见 Agent 韧性模式

当金丝雀的语义评分跌破阈值触发自动回滚后,问题并没有结束——你还需要理解为什么会失败。是模型本身的问题、系统提示词的变更、还是工具注册表的差异?回滚只是止血,根因分析需要回滚设计中的审计和诊断能力。关于回滚后的诊断和根因追踪,参见 Agent 回滚设计

§3 蓝绿部署:Agent 版本的零停机切换

金丝雀发布解决了"新版本的行为是否与旧版本一致"的问题,但它没有解决另一个关键问题:当新版本 Agent 需要在所有流量上替换旧版本时,如何确保切换过程本身不引入故障?这就是蓝绿部署(Blue-Green Deployment)的设计目标——维护两套完整的 Agent 环境(蓝环境为当前生产环境,绿环境为待上线的新版本),通过一次路由变更完成切换,实现零停机、零会话中断的版本过渡。

在传统微服务中,蓝绿部署相对简单:蓝环境和绿环境各自运行一套独立的 Pod 集合,切换时更新负载均衡器的后端池即可。但在 Agent 系统中,两套环境的定义远比"一组 Pod"复杂——每套 Agent 环境包含:

  • LLM Provider 连接池:指向特定模型版本的 API 密钥、速率限制配置、回退 Provider 列表。
  • 工具注册表:工具定义、函数签名、端点 URL、认证凭据、超时配置的完整集合。工具注册表的版本号(如 tools-v4.1)决定了 Agent 可以调用哪些工具以及如何调用。
  • 提示词模板库:系统提示词、任务模板、Few-shot 示例的版本化集合。
  • 记忆与状态存储:用户会话历史、长期记忆向量库、对话摘要缓存。
  • 评估与监控管道:语义评分器配置、指标导出端点、告警规则。

如果蓝绿切换只变更了路由而不同步这些组件,切换后的环境会处于一个"半蓝半绿"的不一致状态——这对 Agent 是致命的。例如,绿环境的 Agent 使用了新的系统提示词 system-prompt-v3,但工具注册表仍然是旧的 tools-v4.0——新提示词中引用了一个 tools-v4.1 才有的函数名,Agent 在第一次工具调用时就会失败并陷入重试循环。

Agent 蓝绿部署的三阶段流程

以下将 Agent 的蓝绿部署拆解为三个阶段:环境准备 → 烟雾测试 → 流量切换。每个阶段都针对 Agent 特有的风险设定了检查点。

阶段一:绿环境完整启动

绿环境不是简单地"启动一组新 Pod"——它是一个完整的 Agent 运行环境的独立实例化。启动序列必须包含:

# blue_green_deploy.yaml — Agent 蓝绿部署配置

deployment:
  name: "customer-service-agent-blue-green"
  strategy: "blue_green"

environments:
  # ─── 蓝环境(当前生产)───
  blue:
    label: "production-current"
    model: "gpt-4-turbo-2024-04-09"
    system_prompt_version: "v2.2"
    tool_registry_version: "tools-v4.0"
    memory_store: "redis-cluster-blue.internal"
    vector_store: "pinecone-index-blue"
    metrics_namespace: "agent/blue"
    health_endpoint: "/healthz"

  # ─── 绿环境(待上线)───
  green:
    label: "production-next"
    model: "gpt-4o-2024-05-13"
    system_prompt_version: "v2.3"
    tool_registry_version: "tools-v4.1"
    memory_store: "redis-cluster-green.internal"    # 独立 Redis 实例
    vector_store: "pinecone-index-green"             # 独立向量索引
    metrics_namespace: "agent/green"
    health_endpoint: "/healthz"

    # 绿环境启动时必须完成的检查项
    startup_checks:
      - name: "llm_connectivity"
        type: "api_call"
        endpoint: "/v1/chat/completions"
        expected_status: 200
        timeout_seconds: 10

      - name: "tool_registry_load"
        type: "config_validation"
        # 验证所有工具端点可达且 Schema 一致
        tools_to_validate: ["get_order", "search_knowledge_base",
                            "send_email", "create_ticket", "cancel_order"]

      - name: "memory_store_ping"
        type: "redis_ping"
        target: "redis-cluster-green.internal"

      - name: "vector_store_connectivity"
        type: "pinecone_check"
        index: "pinecone-index-green"

      - name: "prompt_template_compile"
        type: "template_check"
        # 验证所有提示词模板的变量占位符一致
        templates: ["system_prompt_v2.3", "greeting_v3", "escalation_v3"]

# ─── 配置 Schema 版本化 ───
config_versioning:
  schema_version: "2.3.0"
  compatible_schema_versions: ["2.2.0", "2.3.0"]
  # 如果绿环境的 schema_version 与蓝环境不兼容,拒绝切换
  enforce_schema_compatibility: true

配置 Schema 版本化是关键:Agent 的配置结构会随着系统演进发生变化——新的工具添加、旧的工具弃用、提示词模板的变量重命名。蓝绿环境之间的配置 Schema 必须标记版本号。如果绿环境使用了 schema_version: 3.0 而蓝环境使用的是 schema_version: 2.0,并且两者不兼容,那么蓝绿切换后,如果触发了回滚(切换回蓝环境),历史请求中积累的 v3.0 格式数据可能无法被蓝环境的 v2.0 Schema 正确解析。版本兼容性检查是蓝绿部署中防止"回不去了"的最后一道防线。

对于独立环境的隔离安全性——包括蓝绿环境之间的网络策略分离、资源配额隔离和凭据独立管理——需要配合运行时的安全隔离设计。关于 Agent 运行时环境隔离的完整设计,参见 Agent 运行时安全隔离

阶段二:蓝绿烟雾测试(Agent Blue-Green Smoke Test)

绿环境启动完成后,在切换任何生产流量之前,必须执行一套专门的 Agent 烟雾测试。这套测试与传统烟雾测试的根本区别在于:它不只是验证绿环境是否"能跑",而是验证绿环境与蓝环境在处理同一组请求时是否产生一致的结果。

烟雾测试分为三个层级:

层级 测试内容 样本量 通过标准
L1 — 端点连通性 LLM API、工具端点、记忆存储、向量库均可达 每个端点 1 次 100% 成功
L2 — 工具调用一致性 同一组输入,蓝绿环境的工具调用序列一致 50 个预定义测试用例 ≥ 98% 工具调用匹配率
L3 — 端到端语义一致性 蓝绿环境对同一请求的最终输出语义等价 50 个预定义测试用例 语义评分 ≥ 0.95
# smoke_test.yaml — 蓝绿部署烟雾测试配置
smoke_test:
  enabled: true
  test_suite: "agent-blue-green-smoke-v2"
  timeout_minutes: 10

  layers:
    l1_connectivity:
      parallel: true
      checks:
        - target: "green.llm_endpoint"
          method: "POST"
          payload: {"model": "gpt-4o-2024-05-13", "messages": [{"role": "user", "content": "ping"}], "max_tokens": 5}
          expect: {"status": 200}
        - target: "green.tools.get_order"
          method: "GET"
          path: "/api/v1/orders/health"
          expect: {"status": 200}

    l2_tool_call_consistency:
      test_cases_source: "s3://agent-test-cases/smoke-v2/l2-tool-calls.jsonl"
      sample_count: 50
      match_criteria:
        tool_name_match: true         # 调用的工具名必须匹配
        argument_structure_match: true # 参数结构必须匹配(值可容忍微小差异)
      pass_threshold: 0.98            # 至少 98% 的测试用例工具调用匹配

    l3_semantic_equivalence:
      test_cases_source: "s3://agent-test-cases/smoke-v2/l3-end-to-end.jsonl"
      sample_count: 50
      evaluator_model: "claude-sonnet-20250601"
      semantic_threshold: 0.95
      pass_threshold: 0.90            # 至少 90% 的测试用例语义评分 ≥ 0.95

  # 烟雾测试失败时的行为
  on_failure: "abort_deployment"      # 中止部署,不切换流量
  on_success: "proceed_to_traffic_switch"

L2 工具调用一致性测试是蓝绿部署中最容易被低估但最关键的一环。Agent 对同一问题的回答可能措辞不同但语义等价(L3 容错),但工具调用的差异意味着推理路径的改变——即使最终结果相同,工具路径的改变可能意味着性能变化(多调用了一个慢速外部 API)、成本变化(多消耗了一轮 LLM 推理 Token)、或权限变化(调用了原本不该调用的工具)。工具调用的可靠性直接影响 Agent 的成本和安全性。

阶段三:流量切换与状态迁移

前两个阶段通过后,执行流量切换——将负载均衡器从蓝环境指向绿环境。在 Agent 系统中,这个切换包含三个并行的动作:

  1. 请求路由切换:所有新的 Agent 请求被导向绿环境。这一步与传统蓝绿部署相同。
  2. 会话状态迁移:已经在蓝环境中进行中的用户会话(活跃会话)有两种处理策略:
    • 排空策略(Drain):蓝环境继续处理已有的活跃会话直到它们自然结束,新会话全部进入绿环境。适用于会话平均时长较短(< 2 分钟)的场景。
    • 迁移策略(Migrate):活跃会话的状态(对话历史、上下文摘要、中间工具调用结果)从蓝环境的记忆存储迁移到绿环境的记忆存储。适用于会话平均时长较长(5 分钟以上)的场景,但需要蓝绿环境之间记忆存储 Schema 兼容。
  3. 工具注册表热切换:如果绿环境使用了新版本的工具注册表(tools-v4.1),需要确保旧版本工具端点在被排空的蓝环境会话中仍然可用,直到蓝环境流量完全归零。不能因为切换了路由就立即关闭蓝环境的工具端点——那会当场杀死所有还在排空中的蓝环境会话。
# traffic_switch.yaml — 流量切换配置
traffic_switch:
  strategy: "instantaneous"           # instantaneous | gradual_drain
  connection_draining_seconds: 300    # 蓝环境活跃连接最大存活 5 分钟

  session_state_handling:
    mode: "drain"                     # drain | migrate
    max_drain_duration_seconds: 600   # 排空最长等待 10 分钟
    # 如果需要迁移模式:
    # mode: migrate
    # migration_batch_size: 100       # 每批迁移 100 个会话
    # migration_source: "redis-cluster-blue.internal"
    # migration_target: "redis-cluster-green.internal"
    # schema_version_check: true      # 迁移前检查 Schema 兼容性

  tool_endpoint_lifecycle:
    # 工具端点必须在蓝环境流量完全归零后才能关闭
    blue_tool_drain_policy: "wait_for_zero_connections"
    blue_tool_max_keepalive_seconds: 900   # 最长保持 15 分钟
    green_tool_warmup_seconds: 30          # 绿环境工具预热 30 秒

  rollback_trigger:
    # 切换后 5 分钟内如果出现以下情况,自动切回蓝环境
    observation_window_minutes: 5
    auto_rollback_on:
      - metric: "http_error_rate"
        threshold: 0.05               # 错误率 > 5%
      - metric: "tool_call_failure_rate"
        threshold: 0.03               # 工具调用失败率 > 3%
      - metric: "session_abandon_rate"
        threshold: 0.10               # 会话放弃率 > 10%

  notifications:
    on_switch_start: ["slack:#agent-deploy-info"]
    on_switch_complete: ["slack:#agent-deploy-info"]
    on_rollback: ["slack:#agent-deploy-alerts", "pagerduty:agent-oncall"]

§4 渐进式上线:基于性能与成本的流量阶梯

金丝雀发布用 5-10% 的流量验证了语义正确性。蓝绿部署确保了环境的完整性和可回退性。但还有一个问题没有被回答:某些 Agent 退化只在大流量下暴露。成本退化、延迟回归、和长尾语义错误——这些不会在金丝雀的 50 个样本或蓝绿的 50 个烟雾测试中显现,它们需要持续数小时、处理数千个真实请求后才会浮出水面。

渐进式上线(Progressive Rollout)就是为这类退化设计的流量阶梯。它将全量部署拆解为 10%→25%→50%→100% 四个阶段,每个阶段之间有预设的观察窗口(通常 30 分钟到 2 小时),只有当上一阶段的全部指标达标时,流量才进入下一阶梯。

渐进式上线的三个核心触发指标

与传统服务的渐进式上线(只看延迟和错误率)不同,Agent 的渐进式上线需要三个正交的评估轴:

轴一:语义质量维持(Semantic Quality Sustainment)

金丝雀的语义评分基于 50+ 个样本,置信区间较宽。渐进式上线的每个阶段会积累更大的样本量(10% → 约 500 样本/小时,25% → 约 1250 样本/小时),更精确地测量语义质量。关键是:语义质量必须在大流量下保持稳定——不能随着样本量增大而"均值回归"到一个更低的水平。如果金丝雀阶段(50 样本)的语义评分是 0.96,但 10% 流量阶段(500 样本)降到了 0.91,说明金丝雀的样本存在选择偏差(金丝雀随机抽样碰巧抽到了"简单"的请求)。此时应该中止渐进式上线并回滚。

轴二:成本退化检测(Cost Regression Detection)

这是 Agent 渐进式上线中最独特的一环。成本退化不是简单的"总费用增加"——它需要精确到 per-task Token 消耗。以下指标构成了成本退化的检测矩阵:

  • per-task Token 增长:将单次 Agent 任务的完整 Token 消耗(包括 LLM 推理 Token + 工具调用 Token + 评估 Token)按任务类型分组统计。如果新版 Agent 的客服查询类任务的平均 Token 从 1200 涨到 1700(增长 41.7%),即使输出质量更好,这也是一个需要决策的成本退化。阈值建议设为人均 Token 增长 ≤ 15%。
  • LLM 调用次数 per task:新版 Agent 是否比旧版多执行了额外的 LLM 调用?每一次额外的 LLM 调用意味着更多的 Token 消耗和更多的延迟。如果平均调用次数从 3.2 增长到 5.1,即使每次调用的 Token 消耗不变,总成本也增长了约 60%。
  • 工具调用成本:某些工具调用本身就是计费的(如调用外部的地址验证 API、信用评分查询 API)。新版 Agent 是否比旧版多调用了这些计费工具?

轴三:延迟回归(Latency Regression)

新模型可能更快,也可能更慢。关键不在于延迟的绝对值,而在于延迟的分布——特别是 p95 和 p99 延迟。如果新版 Agent 的平均延迟从 2.3s 降到 1.8s(改善了),但 p95 延迟从 4.5s 升到了 9.7s(恶化了两倍以上),意味着新模型对某些类型的请求有严重的尾部延迟问题。延迟回归的阈值建议为:p95 延迟 ≤ 基线 p95 的 2 倍。

渐进式上线的 YAML 配置

# progressive_rollout.yaml — Agent 渐进式上线配置
# 作用:将新版 Agent 的流量从 10% 逐步提升至 100%,
# 每个阶段由语义质量、成本偏差、延迟回归三项指标守住。

progressive_rollout:
  enabled: true
  total_duration_hours_max: 8          # 总上线时长上限
  auto_advance: true                   # 指标通过后自动推进到下一阶段
  on_stage_failure: "rollback_to_previous"

  stages:
    # ─── 阶段 1:10% 流量 ───
    - stage: 1
      traffic_ratio: 0.10
      observation_window_minutes: 30   # 观察 30 分钟
      gates:
        semantic_quality:
          metric: "semantic_equivalence_score"
          threshold: 0.95
          operator: "gte"
          min_samples: 200             # 至少 200 个样本(10% × 30min ≈ 250 个样本)

        cost_regression:
          metric: "avg_tokens_per_task_ratio"
          # 新版 per-task Token / 旧版 per-task Token
          threshold: 1.15              # 增长 ≤ 15%
          operator: "lte"
          baseline_source: "pre_deploy_baseline_7d"  # 部署前 7 天的基线数据

        latency_regression:
          metric: "p95_latency_ratio"
          threshold: 2.0               # p95 延迟 ≤ 基线的 2.0 倍
          operator: "lte"

    # ─── 阶段 2:25% 流量 ───
    - stage: 2
      traffic_ratio: 0.25
      observation_window_minutes: 45
      gates:
        semantic_quality:
          metric: "semantic_equivalence_score"
          threshold: 0.95
          operator: "gte"
          min_samples: 500

        cost_regression:
          metric: "avg_tokens_per_task_ratio"
          threshold: 1.12              # 收紧到 12%(大样本下应更精确)
          operator: "lte"

        latency_regression:
          metric: "p95_latency_ratio"
          threshold: 2.0
          operator: "lte"

        # 阶段 2 新增:工具调用成功率
        tool_call_success:
          metric: "tool_call_success_rate"
          threshold: 0.995             # 工具调用成功率 ≥ 99.5%
          operator: "gte"

    # ─── 阶段 3:50% 流量 ───
    - stage: 3
      traffic_ratio: 0.50
      observation_window_minutes: 60
      gates:
        semantic_quality:
          metric: "semantic_equivalence_score"
          threshold: 0.94              # 大样本下允许轻微下降(样本多样性增加)
          operator: "gte"
          min_samples: 1000

        cost_regression:
          metric: "avg_tokens_per_task_ratio"
          threshold: 1.10
          operator: "lte"

        latency_regression:
          metric: "p95_latency_ratio"
          threshold: 1.8               # 收紧到 1.8x(大流量下不应有太多尾延迟)
          operator: "lte"

        tool_call_success:
          metric: "tool_call_success_rate"
          threshold: 0.995
          operator: "gte"

        # 阶段 3 新增:幻觉率对比
        hallucination_rate:
          metric: "hallucination_rate_delta"
          threshold: 0.015             # 幻觉率增长 ≤ 1.5 个百分点
          operator: "lte"

    # ─── 阶段 4:100% 流量(全量上线)───
    - stage: 4
      traffic_ratio: 1.0
      observation_window_minutes: 120  # 全量后持续观察 2 小时
      gates:
        cost_regression:
          metric: "avg_tokens_per_task_ratio"
          threshold: 1.10
          operator: "lte"

        latency_regression:
          metric: "p95_latency_ratio"
          threshold: 1.5               # 全量后延迟应接近基线
          operator: "lte"

        tool_call_success:
          metric: "tool_call_success_rate"
          threshold: 0.995
          operator: "gte"

        # 全量后不需要持续采样语义评分(成本太高),
        # 改为定期离线评估(每天一次)。
        offline_evaluation:
          enabled: true
          frequency: "daily"
          semantic_threshold: 0.95

  # ─── 成本退化检测的细粒度配置 ───
  cost_monitoring:
    # 按任务类型分组的 Token 统计
    task_type_breakdown: true
    task_types:
      - "customer_inquiry"
      - "order_tracking"
      - "refund_request"
      - "product_recommendation"
      - "complaint_escalation"

    # 成本退化告警阈值(触发后暂停流量推进但不回滚)
    cost_alerts:
      - metric: "avg_tokens_per_task_ratio"
        threshold: 1.25                # 增长超过 25% 立即告警
        action: "alert_oncall_and_pause_advance"
      - metric: "daily_cost_estimate_ratio"
        threshold: 1.30                # 预估日成本增长 > 30%
        action: "alert_oncall"

    # Token 统计排除项
    token_exclusions:
      - "evaluation_tokens"            # 排除评估用的 Token(不是 Agent 任务的成本)
      - "health_check_tokens"          # 排除健康检查的 Token

  # ─── 观察仪表板 ───
  dashboard:
    prometheus_queries:
      semantic_score: |
        avg(agent_semantic_score{version="canary"}) /
        avg(agent_semantic_score{version="baseline"})

      tokens_per_task: |
        sum(rate(agent_llm_tokens_total{version="canary"}[5m])) /
        sum(rate(agent_task_completed_total{version="canary"}[5m]))

      p95_latency: |
        histogram_quantile(0.95,
          sum(rate(agent_task_duration_seconds_bucket{version="canary"}[5m]))
          by (le))

    grafana_dashboard_uid: "agent-progressive-rollout"
    alertmanager_route: "agent-deploy-oncall"

成本退化检测的工程实现

成本退化不是靠月底的 AWS 账单发现的——那晚了 30 天。成本退化需要在渐进式上线的每个阶段都有实时的 per-task Token 对比。具体实现路径:

  1. Token 埋点:在 Agent 运行时的 LLM 调用封装层中,记录每次调用的 prompt_tokenscompletion_tokenstotal_tokens。将这些指标以 agent_idtask_typeversion 为标签写入 Prometheus 的 Counter 指标。
  2. 基线建立:在渐进式上线开始前,从旧版 Agent 的 Prometheus 数据中提取过去 7 天的 per-task Token 中位数和 p95。这些值成为每个阶段的对比基线。
  3. 实时对比:在渐进式上线的每个观察窗口内,持续计算 avg_tokens_per_task_ratio = canary_avg_tokens / baseline_avg_tokens。如果这个比值在观察窗口结束时的滚动平均值超过了当前阶段的阈值(阶段 1 为 1.15,阶段 2 为 1.12 等),暂停流量推进。
  4. 成本预估:将 per-task Token 乘以 LLM Provider 的公开定价,生成 daily_cost_estimate——这个数字不是精确的账单金额,而是一个足够精确的方向性信号。如果新版 Agent 的日均预估成本比旧版高出 30%,即使语义质量完美,也需要在推进之前进行评估——"更好的输出是否值得 30% 的成本增加?"

关于成本观测的完整设计——包括 Token 预算管理、多模型 Provider 的成本比较、和成本异常检测——参见 Agent 成本可观测性设计。渐进式上线的成本检测是一个运行在部署时刻的成本快照——它依赖成本观测基础设施提供的实时 Token 指标。

成本退化的静默性:在所有 Agent 部署风险中,成本退化是最容易被忽视的——它不会触发任何 PagerDuty 告警,没有用户抱怨,没有错误日志。它唯一的症状是月底的账单数字变大了。正因为它的静默性,成本退化检测必须被硬编码进渐进式上线的阶段门控中——它不是可选的"建议",而是每个阶段必须满足的硬性条件。如果你的系统还没有 per-task Token 埋点,那么你所有的部署决策都在没有成本信息的情况下做出——相当于蒙着眼睛开车。

渐进式上线与可观测性的关系

渐进式上线的每一个阶段门控都依赖实时的可观测性数据——语义评分、Token 消耗、p95 延迟、工具调用成功率。如果这些指标的数据管道在渐进式上线期间出现延迟或中断,渐进式上线会陷入一个危险的状态:流量已经进入下一阶段,但门控的判断依据已经过期或缺失。

解决这个问题需要两个机制:

  • 数据新鲜度守卫(Data Freshness Guard):在每个阶段门控的判断逻辑中,不仅检查指标的值,还检查指标的数据新鲜度。如果 Prometheus 的最新数据点超过 2 分钟未更新(例如因为指标管道故障),阶段门控必须进入"等待"状态而非"通过"或"失败"——在缺乏数据时,不做推进决策。
  • 可观测性降级策略:如果整个指标管道不可用,渐进式上线应暂停流量推进并保持当前比例——不多也不少。这是内置在渐进式上线配置中的安全默认值。关于可观测性管道的完整设计和告警策略,参见 Agent 可观测性设计

§5 Agent 部署风险监控矩阵

前三节分别介绍了金丝雀发布、蓝绿部署和渐进式上线三种策略。每一种策略都内嵌了多个监控检查点——语义评分阈值、工具调用匹配率、per-task Token 增长率、p95 延迟比值。当这些检查点分散在各个策略的 YAML 配置中时,容易产生两个问题:一是遗漏(某个风险维度被忽略),二是阈值不一致(金丝雀阶段和渐进式阶段对同一指标使用了不同的阈值导致判断冲突)。

本节将所有 Agent 部署的关键风险维度汇总为一张统一的监控矩阵——每个维度都标注了检测方法、告警阈值、适用的部署阶段、和数据来源。这不是"又一个要配置的东西"——它是前面三节所有 YAML 配置中监控参数的集中索引。

风险类别 检测方法 核心指标 金丝雀阈值 渐进式阈值 数据来源
模型漂移检测 影子流量成对评分 semantic_equivalence_score ≥ 0.95(50+ 样本) ≥ 0.95(阶段 1-2);≥ 0.94(阶段 3) 语义评估器 + S3 日志
工具 API 兼容性 工具调用序列对比 + 烟雾测试 tool_call_match_rate / tool_call_success_rate 工具调用匹配率 ≥ 0.99 工具调用成功率 ≥ 0.995 Agent 运行时工具中间件
成本退化监控 per-task Token 对比 + LLM 调用次数统计 avg_tokens_per_task_ratio 软告警(推理步骤比 ≤ 1.25) ≤ 1.15(阶段 1)→ ≤ 1.10(阶段 3) Prometheus Counter + LLM Provider 计费 API
状态一致性 蓝绿环境会话迁移验证 session_abandon_rate N/A(金丝雀不涉及全量状态切换) 会话放弃率 ≤ 0.10(蓝绿切换后) Redis 会话存储 + 负载均衡器日志
幻觉率退化 采样 + 自动评估 / 人工抽查 hallucination_rate_delta 增长 ≤ 2 个百分点 增长 ≤ 1.5 个百分点 离线评估管道 + 人工标注采样
延迟回归 p95/p99 分布对比 p95_latency_ratio N/A(金丝雀流量太少,统计意义不足) ≤ 2.0(阶段 1-2)→ ≤ 1.5(全量) Prometheus Histogram
Token 产出速率 实时吞吐量对比 token_throughput_ratio ≥ 0.70(软告警) ≥ 0.85(隐含在延迟回归中) LLM API 响应流 Timestamp 差值

如何阅读这张矩阵:每一行代表一个独立的监控维度。金丝雀发布和渐进式上线对同一维度的阈值可能不同——这不是不一致,而是样本量不同导致的置信度差异。金丝雀只有 50+ 样本,阈值可以适度宽松以避免误报(如成本退化用软告警而非强制回滚)。渐进式上线有 500-1000+ 样本,阈值可以收紧(如成本退化从 1.25 收紧到 1.10)。这种"随样本量收紧阈值"的模式是 Agent 部署监控的核心设计原则。

模型漂移检测的深度分析

模型漂移是 Agent 部署中最隐蔽的风险——它不像工具 API 断裂那样有明确的 400 错误,也不像成本退化那样会在账单上体现。模型漂移的唯一症状是用户觉得 Agent "变笨了"——这种主观感受很难转化为可量化的告警指标。语义评分的核心价值就在于将这种主观感受转化为客观的 0-1 分数。

模型漂移有三个来源:

  1. Provider 无公告模型更新:LLM Provider 可能在后台更新模型权重但保持 API 端点名称不变。你调用的 gpt-4o-2024-05-13 在 6 月 1 日的实际行为可能与 5 月 15 日不同。持续金丝雀(5% 永久金丝雀流量)是检测这类漂移的唯一方法。
  2. 系统提示词变更:看似微小的提示词调整——"请友好地回复"改为"请专业地回复"——可能改变 Agent 的工具选择偏好和推理路径。提示词变更应该像模型变更一样经过金丝雀发布。
  3. 依赖数据漂移:Agent 依赖的知识库、工具 API 返回的数据结构、外部服务的响应格式发生变化——这些不是 Agent 本身的问题,但会导致 Agent 的行为漂移。工具调用一致性监控可以捕获这类漂移。

告警阈值的工程校准

阈值设定是监控矩阵中最需要工程判断的部分。以下原则来自生产环境的经验数据:

  • 语义评分 0.95 的由来:在生产系统中,即使是完全相同的模型和配置,影子流量中的语义评分也会因为 LLM 的非确定性(即使 temperature=0)而在 0.96-0.98 之间波动。将阈值设为 0.99 会导致 40% 以上的误报率。0.95 是一个经过多个生产系统验证的实用平衡点——它容忍正常的非确定性波动,但能捕获实质性的推理变化。
  • 成本阈值先松后紧:金丝雀阶段对成本的容忍度较高(推理步骤比 1.25 仅触发软告警),因为小样本下的成本估算噪声较大。渐进式阶段随着样本量增大逐步收紧阈值(1.15 → 1.12 → 1.10),因为更大的样本量提供了更精确的成本估计。到了全量阶段(100%),Token 消耗的任何显著增长都会通过成本可观测性管道触发持续监控。
  • 组合条件优于单阈值:单独看 tool_call_match_rate < 0.99 可能是一次性网络抖动。但如果同时 semantic_equivalence_score < 0.93avg_tokens_per_task_ratio > 1.20,这三个信号同时触发时,模型行为的实质性变化的概率远高于单个指标的误报概率。组合条件是减少告警疲劳的关键。

§6 配置架构:从 Research 到 VERIFIED 的权限链

部署策略的 YAML 配置(如前面三节中的 canary_deploy.yamlblue_green_deploy.yamlprogressive_rollout.yaml)需要一个控制框架来管理它们的生命周期——谁可以创建配置、谁可以批准配置、配置如何从实验环境晋级到生产环境。这就是配置架构(Configuration Architecture)要解决的问题。它与 Agent 发布门控设计 紧密配合——配置架构定义了"什么可以被部署",而门控系统定义了"在什么条件下可以被部署"。

Agent 部署配置的四级成熟度模型

Agent 部署配置从实验到生产的生命周期分为四个阶段,类比于软件开发生命周期:

阶段 状态 环境 允许的部署操作 审批要求
1. Research 实验阶段 开发 / Staging 金丝雀发布(仅影子流量) 无需审批
2. Validated 通过语义评估 Staging 金丝雀发布 + 蓝绿部署 同行评审(Peer Review)
3. Staged 通过烟雾测试 预生产 渐进式上线(10% 上限) 技术负责人审批
4. VERIFIED 通过全部门控 生产 全量渐进式上线(100%) 自动化门控 + 发布经理确认

配置 Schema 版本化

Agent 部署配置本身也有 Schema 演进——新的部署功能需要新的配置字段,旧的字段可能被弃用。以下是一个 Schema 版本迁移的示例:

# deploy_config v1(早期版本)—— 仅支持简单的金丝雀发布
    # schema_version: "1.0.0"
    deploy:
      canary: true
      canary_percent: 5
      rollback_on_error: true

    # ─────────────────────────────────────────────

    # deploy_config v2(当前版本)—— 支持完整的三种策略 + 成本门控
    # schema_version: "2.0.0"
    deployment:
      strategy: "canary"                  # canary | blue_green | progressive
      canary:
        traffic_ratio: 0.08
        evaluation:
          semantic_threshold: 0.95
          tool_call_match_threshold: 0.99
        rollback:
          auto_rollback: true
          hard_conditions: [...]         # 见 §2 完整配置
      progressive_rollout:               # 仅当 strategy=progressive 时生效
        stages: [...]                    # 见 §4 完整配置
      cost_gate:
        enabled: true                    # v2 新增:成本门控
        per_task_token_ratio_max: 1.15

    # Schema 版本不兼容检测:
    # 如果蓝环境的配置使用 schema_version 1.0.0,绿环境使用 2.0.0,
    # 部署系统自动拒绝切换并提示升级蓝环境配置。

与 xslyl 门控系统的集成

上述四级成熟度模型在实际工程中通过 Agent 发布门控系统 落地。门控系统在每个状态转换点执行自动化检查:当部署配置从 Validated 晋级到 Staged 时,门控系统自动运行 L2 工具调用一致性检查;从 Staged 晋级到 VERIFIED 时,自动检查渐进式上线阶段 1 的所有指标是否达标。

部署配置与门控系统的集成在 YAML 中通过 gate_integration 字段表达:

# 部署配置中的门控集成声明
    gate_integration:
      enabled: true
      gate_system_endpoint: "https://gates.xslyl.internal/api/v1"
      required_gates:
        - gate_id: "semantic-equivalence-check"
          stage: "research_to_validated"
          timeout_seconds: 300
        - gate_id: "tool-smoke-test"
          stage: "validated_to_staged"
          timeout_seconds: 600
        - gate_id: "cost-regression-check"
          stage: "staged_to_verified"
          timeout_seconds: 900
        - gate_id: "latency-regression-check"
          stage: "staged_to_verified"
          timeout_seconds: 300
      gate_failure_policy: "block_advance"   # block_advance | warn_only

      # 门控通过后自动推进到下一成熟度阶段
      auto_promote_on_gate_pass: true

这种集成的核心理念是:配置本身不携带审批权限——权限在门控系统中统一管理。部署配置定义了"要部署什么"和"阈值是多少",门控系统负责"我是否允许这个配置进入下一阶段"。这种关注点分离使得部署配置可以频繁迭代(研发团队可以自由创建 Research 阶段的配置),而不会绕过安全阀(任何配置要进入生产都必须经过门控系统的自动化验证)。

§7 实战流程:从配置生成到生产部署

前面五节分别讨论了部署策略(§2-4)、监控矩阵(§5)和配置架构(§6)。本节将这些组件串联起来,展示一个完整的 Agent 部署流水线——从研发团队提交新版本 Agent 配置,到全量部署在生产环境运行。下图描述了这一流程中的关键决策点。

完整部署流水线(7 个阶段)

  1. 配置生成(Config Generation)——研发环境:开发者提交新版本 Agent 的配置(模型版本、系统提示词、工具注册表版本),生成 deploy_config.yaml。配置自动标记为 maturity: research。在这一阶段,配置可以在 Staging 环境中以 0% 生产流量(仅影子流量)运行金丝雀评估。
  2. 金丝雀验证(Canary Validation)——Staging:在 Staging 环境中,配置通过影子流量进行语义评估。如果语义评分 ≥ 0.95 且工具调用匹配率 ≥ 0.99(持续 50+ 样本),配置自动晋级为 maturity: validated。如果任一硬性指标未达标,流程终止,开发者收到详细的评分对比报告——报告精确到哪些类型的请求导致了评分下降。
  3. 蓝绿烟雾测试(Blue-Green Smoke Test)——Staging → 预生产:晋级到 Validated 后,配置在预生产环境中启动一个完整的绿环境。烟雾测试 L1-L3(端点连通 → 工具调用一致性 → 端到端语义一致性)全部通过后,配置晋级为 maturity: staged。此阶段由同行评审(Peer Review)作为人工确认——至少一名其他工程师确认烟雾测试结果。
  4. 渐进式上线阶段 1(Progressive Stage 1)——10% 生产流量:配置进入生产环境,流量控制在 10%。观察 30 分钟,门控检查:语义评分 ≥ 0.95、per-task Token 增长 ≤ 15%、p95 延迟 ≤ 基线 2.0x。
  5. 渐进式上线阶段 2(Progressive Stage 2)——25% 生产流量:阶段 1 通过后,流量自动扩大到 25%。观察 45 分钟,门控收紧:per-task Token 增长 ≤ 12%、新增工具调用成功率检查 ≥ 99.5%。
  6. 渐进式上线阶段 3(Progressive Stage 3)——50% 生产流量:流量扩大到 50%。观察 60 分钟,新增幻觉率检查(增长 ≤ 1.5 个百分点)。如果所有门控通过,配置自动晋级为 maturity: verified
  7. 全量部署(Full Rollout)——100% 生产流量:配置晋级为 VERIFIED 后,流量扩大到 100%。持续观察 2 小时确认稳定性。之后语义评分切换为每日离线评估模式(降低成本),但成本回归和延迟回归保持实时监控。全量部署完成后,旧版本的蓝环境在保持 24 小时待命后可以安全回收。

关键决策流程图

以下文本流程图展示了部署流水线中每个阶段的决策逻辑。每个阶段有三个可能的出口:通过(推进到下一阶段)、暂停(保持当前流量比例,等待人工判断)、回滚(退回上一阶段或完全撤销)。

┌──────────┐      ┌──────────────┐      ┌───────────────┐
    │ Research │ ───→ │  Canary 验证  │ ───→ │ 蓝绿烟雾测试   │
    │ (配置生成) │      │  (Staging)    │      │  (预生产)      │
    └──────────┘      └──────┬───────┘      └───────┬───────┘
                            │                      │
                    语义评分 < 0.95?         L1-L3 未通过?
                    工具匹配 < 0.99?         → 回滚到 Research
                    → 终止,返回开发者           │
                            │              ┌─────┴─────┐
                    全部通过 → Validated ──→│   Staged   │
                                           └─────┬─────┘
                                                 │
                              ┌──────────────────┼──────────────────┐
                              │                  │                  │
                        10% 流量阶段        25% 流量阶段        50% 流量阶段
                       (30min 观察)       (45min 观察)       (60min 观察)
                              │                  │                  │
                        成本增长 >15%?    成本增长 >12%?   幻觉率 >1.5%?
                        延迟 >2.0x?      工具成功率 <99.5%?  → 回滚到 25%
                        → 回滚到 Staged    → 回滚到 10%           │
                              │                  │                  │
                        通过 → 25%         通过 → 50%         通过 → VERIFIED
                                                                      │
                                                              100% 全量部署
                                                             (2h 持续观察)

    任何阶段的数据管道中断(可观测性不可用):
    → 暂停流量推进,保持当前比例,通知 on-call
    → 数据恢复后,重新执行当前阶段的观察窗口

流水线的"安全默认值"原则:在上述流程中,每一个决策点的默认行为都是不推进——如果门控系统无法确定是否通过(例如可观测性数据缺失、评估模型不可用),流水线不会假设"通过"而是进入"暂停"状态。这个设计原则确保了在任何不确定性面前,系统的默认行为是保守的——宁可暂停上线,也不在缺乏数据的情况下冒险推进流量。

§8 与传统部署的对比:Agent 系统的特殊挑战

阅读到这里,你可能已经注意到 Agent 部署与传统软件部署之间存在根本性的范式差异。本节将这些差异系统化地总结为一张对比表——这不仅是为了学术上的完整,而是因为如果你用传统 DevOps 的思维来设计 Agent 部署流水线,你会漏掉至少一半的风险

对比维度 传统软件部署 Agent 系统部署
核心假设 确定性:相同输入 → 相同输出 非确定性:相同输入 → 语义近似但可能不同的输出
验证方式 结构化验证:HTTP 状态码、JSON Schema、响应时间 语义验证 + 结构化验证:语义等价评分、工具调用序列对比、推理路径一致性
回归类型 代码回归:功能正确性、接口契约 语义回归:行为漂移、推理逻辑变化、输出质量退化
回滚对象 基础设施回滚:容器镜像、配置文件、数据库迁移 状态回滚 + 基础设施回滚:会话状态、记忆存储、工具注册表、模型版本、提示词版本
成本模型 固定成本:CPU/内存/存储的资源配置 可变成本:per-task Token 消耗 × 任务量、工具调用计费、评估模型 Token
健康检查 静态探针:/healthz 返回 200、进程存活 动态探针 + 语义探针:工具端点可达性、LLM 推理可用性、语义评分管道正常、成本计数器递增
灰度/金丝雀验证时长 分钟级:5-15 分钟即可判断回滚 小时级:需要足够的样本量(50-1000+)才能产生统计上显著的语义评分和成本估算
回滚触发条件 错误率、延迟、资源使用率的单一指标超阈值 多维度组合条件:语义评分下降 + 成本增长 + 工具调用失败率上升的交叉验证
部署频率容忍度 高频:CI/CD 流水线支持日部署数十次 中低频:每次部署需要完整的语义评估周期(30 分钟到数小时),但模型热更新(Provider 侧)可能在任何时间静默发生

从传统 DevOps 到 Agent DevOps 的思维转变

这九个维度的差异指向同一个核心结论:Agent 部署需要的不是传统 DevOps 工具的"AI 版本",而是一套从假设层开始就不一样的部署哲学。

三个关键的思维转变:

  1. 从"部署即上线"到"部署即实验":在传统 DevOps 中,部署的终点是"代码在生产环境中运行"。在 Agent DevOps 中,部署的终点是"新 Agent 在真实流量中通过了所有门控"——在此之前,每一次部署都是一个正在进行中的实验。金丝雀发布的 50+ 样本、渐进式上线的三个流量阶梯,都是实验的观察窗口。部署不是二元的(成功/失败),而是连续置信度的("基于当前 500 个样本,语义评分 0.96,成本增长 8%,我们有 90% 的把握认为这个部署是成功的")。
  2. 从"监控基础设施"到"监控业务语义":传统 DevOps 监控 CPU、内存、磁盘 I/O——这些是基础设施指标。Agent DevOps 监控的是语义等价分数、per-task Token 消耗、工具调用一致性——这些是业务语义指标。基础设施指标告诉你的 Pod 是否健康,业务语义指标告诉你的 Agent 是否"聪明"。部署决策必须基于后者。
  3. 从"回滚是预案"到"回滚是一等公民":传统部署中,回滚是"出了问题才执行的紧急操作"。在 Agent 部署中,回滚必须被设计为每一个部署阶段的正常退出路径——金丝雀的自动回滚条件、蓝绿的路由回切、渐进式上线的阶段回退,都是预设的、自动化的、毫秒级可执行的操作。关于回滚的完整设计,参见 Agent 回滚设计

§9 结论与最佳实践

三种部署模式的选择指南

三种模式并不是"选一个用"——它们是一个组合工具箱。以下是根据你的 Agent 系统规模和风险承受能力的选择指南:

场景 推荐组合 理由
小团队、原型阶段、低风险 Agent 金丝雀发布(5%)→ 手动确认 → 全量 只需语义评估基础设施,成本可控,流程简单
中型团队、生产 Agent、中等风险 金丝雀发布(10%)→ 渐进式上线(10%→50%→100%) 组合了语义验证和成本/性能监控,蓝绿部署对中型团队可能过重
大型平台、高可用性要求、高风险 Agent 蓝绿部署 → 金丝雀发布(10% 在绿环境内)→ 渐进式上线(10%→25%→50%→100%) 完整的三层安全网:环境隔离 → 语义验证 → 成本/性能监控
模型热更新(Provider 侧无公告更新) 金丝雀发布(持续运行,5% 永久金丝雀) Provider 更新无法控制——持续金丝雀可以第一时间检测到模型行为的静默漂移

三条黄金法则

以下三条原则总结了 Agent 部署的核心哲学:

  1. 永远用流量说话,不要用测试集:测试集是静态的快照,它是过去某一天真实流量的代表。当新版本 Agent 上线时,真实用户的请求分布可能与测试集完全不同。金丝雀发布的 5-10% 流量是唯一能代表真实世界的验证信号。测试集验证是部署前的必要条件,不是充分条件。
  2. 成本是部署的一等门控:在传统软件部署中,成本不在部署 checklist 上——CPU 和内存使用率已经是成本的全部信息。在 Agent 部署中,per-task Token 消耗必须与语义质量和延迟并列,成为每个部署阶段的决策依据。把成本退化检测从"月底看一下"提前到"每个阶段必查",这是 Agent 部署工程化的标志。
  3. 每个环境都是可独立回退的:蓝绿部署的蓝环境不应该在切换后 5 分钟就销毁。渐进式上线的每个中间阶段(10%、25%、50%)都应该保持足够长的时间窗口来收集指标,也保持足够短的回滚路径。如果 25% 流量阶段触发了成本退化告警,系统应该能一键切回 10%——而不是退回 0%。

常见问题

金丝雀发布和 A/B 测试有什么区别?

金丝雀发布和 A/B 测试的核心区别在于目的流量分配方式。金丝雀发布的目标是验证新版本的稳定性——用小比例流量(5-10%)验证新版 Agent 的语义质量、工具调用和成本是否与旧版一致,验证通过后全量上线。A/B 测试的目标是比较两个版本的效果——将流量按用户维度分为两组(各 50%),比较哪个版本的 Agent 在业务指标上表现更好(如用户满意度、问题解决率),是一个产品决策工具而非部署安全工具。在 Agent 系统中,金丝雀发布的验证周期通常为 30 分钟到数小时,A/B 测试的运行周期通常为数天到数周。

蓝绿部署的成本是否过高?

蓝绿部署确实需要两套完整的环境同时运行,在传统微服务中这通常意味着双倍的云资源成本。但在 Agent 系统中,蓝绿部署的额外成本需要从三个角度评估:第一,Agent 系统的核心运行成本是 LLM API 调用(Token 消耗),而非计算资源——蓝环境和绿环境的 Compute 资源(Pod)成本相对固定且较低,而 Token 成本是由实际流量驱动的,蓝环境在切换到绿环境后只有排空中的活跃会话在消耗 Token,新会话全部分配到绿环境。第二,绿环境可以在切换前以最小规模运行(仅满足烟雾测试需要),切换后再扩容。第三,这笔额外成本必须与没有蓝绿部署时的风险成本比较——如果没有并行环境,一次失败的部署可能导致 State 污染(如会话状态损坏),修复成本远高于一个额外的 Staging 级绿环境。

渐进式上线的每个阶段应该持续多久?

没有放之四海而皆准的固定时长——而是取决于你的流量密度。阶段观察窗口的设计原则是"积累足够的样本量以获得统计显著性"而非"等待固定的时间"。建议的最小样本量:阶段 1(10% 流量)需要 200+ 个请求,阶段 2(25%)需要 500+ 个请求,阶段 3(50%)需要 1000+ 个请求。如果你的系统日均请求量为 10,000,那么 10% 流量约每小时产生 42 个请求,积累 200 个请求需要约 5 小时——此时阶段 1 的观察窗口应设为至少 5 小时。如果你的系统日均请求量为 1,000,000,10% 流量每小时产生约 4,200 个请求,30 分钟即可积累 2,100 个请求。简而言之:样本量定时长,而非时长定样本量

如何检测模型热更新导致的静默漂移?

模型热更新(Provider 在未通知的情况下更新了模型权重)的检测需要持续金丝雀(Permanent Canary)——始终保持 5% 的流量同时路由到评估管道,即使没有任何主动部署操作。评估模型持续对金丝雀输出和基线输出进行语义评分,评分结果以时间序列写入 Prometheus。当语义评分的 1 小时滚动平均值出现持续下降趋势(而非单点波动)时,触发告警。具体来说,可以使用统计过程控制(SPC)方法——计算语义评分的历史均值和标准差,当评分在连续 3 个采样窗口内下降超过 2 个标准差时,判定为显著的模型漂移。此外,结合幻觉率监控——如果幻觉率在无明显系统变更的情况下出现统计显著增长,同样是模型热更新的强烈信号。

如果渐进式上线中途可观测性管道故障怎么办?

这是渐进式上线设计中必须处理的场景——在流水线的任何阶段,如果可观测性数据不可用(Prometheus 无响应、评估模型超时、日志管道中断),渐进式上线必须暂停流量推进。具体的处理流程:第一,流量保持在当前阶段的比例不变——不增加也不回退;第二,数据新鲜度守卫(Data Freshness Guard)检测到指标超过 2 分钟未更新时,自动将阶段状态标记为 PAUSED_DATA_UNAVAILABLE;第三,系统向 on-call 通道发送告警,但不触发自动回滚——因为回滚决策也需要数据支持,在数据不可用时回滚风险和推进风险相当;第四,当可观测性管道恢复后,系统重新开始当前阶段的观察窗口(不接续之前的数据),因为中断期间可能已经进入了不同类型的请求,续接数据会导致样本偏差。如果可观测性管道在 30 分钟内未恢复,应由人工决定是回滚到上一个安全阶段还是继续等待。

下一步阅读