25d - 更新与回滚策略
本文是《AI Agent 实战手册》第 25 章第 4 节。 上一节:25c-日志管理与审计 | 下一节:25e-成本优化
概述
OpenClaw 作为 24/7 自主运行的 AI Agent 平台,更新操作远比传统 Web 应用复杂——不仅涉及容器镜像替换,还需要处理 LLM 模型版本切换、Prompt 模板迁移、工具兼容性验证和活跃会话的连续性保障。一次失败的更新可能导致 Agent 行为异常、用户会话中断甚至数据丢失。2026 年的最佳实践是将蓝绿部署、金丝雀发布和版本锁定三种策略组合使用,根据更新类型(基础设施/模型/Prompt/工具)选择最合适的发布方式。
本节提供从版本管理到回滚恢复的完整操作指南,涵盖 Docker Compose 蓝绿切换、Nginx 流量分割、数据库迁移回滚和 AI Agent 特有的版本管理策略。
1. AI Agent 更新的特殊挑战
传统应用 vs AI Agent 更新对比
与传统 Web 应用不同,AI Agent 平台的更新涉及多个独立变化维度,每个维度都可能引发不可预测的行为变化。
| 维度 | 传统 Web 应用 | AI Agent 平台(OpenClaw) |
|---|---|---|
| 代码更新 | 前后端代码替换 | Gateway + Worker + 插件代码替换 |
| 模型更新 | 不涉及 | LLM 模型版本切换(如 Claude 3.5 → 4) |
| Prompt 更新 | 不涉及 | 系统 Prompt、Agent 角色定义变更 |
| 工具更新 | API 版本升级 | MCP Server、插件、外部工具兼容性 |
| 状态管理 | Session/Cookie | Agent 记忆、对话上下文、任务队列 |
| 回滚复杂度 | 镜像回退即可 | 需同时回退代码+Prompt+模型配置 |
| 验证难度 | 功能测试 | 行为一致性验证(LLM 输出不确定性) |
OpenClaw 更新的四大类型
┌─────────────────────────────────────────────────────────────┐
│ OpenClaw 更新类型矩阵 │
├──────────────┬──────────────┬───────────────┬───────────────┤
│ 基础设施更新 │ 模型更新 │ Prompt 更新 │ 工具更新 │
│ │ │ │ │
│ • Docker 镜像 │ • LLM 版本 │ • 系统 Prompt │ • MCP Server │
│ • 依赖升级 │ • 嵌入模型 │ • Agent 角色 │ • 插件版本 │
│ • 数据库迁移 │ • 模型参数 │ • 输出格式 │ • API 端点 │
│ • 配置变更 │ • 提供商切换 │ • 安全规则 │ • 工具权限 │
├──────────────┼──────────────┼───────────────┼───────────────┤
│ 推荐:蓝绿部署 │ 推荐:金丝雀 │ 推荐:版本锁定 │ 推荐:金丝雀 │
│ 风险:中 │ 风险:高 │ 风险:中 │ 风险:高 │
│ 回滚:快速 │ 回滚:即时 │ 回滚:即时 │ 回滚:中等 │
└──────────────┴──────────────┴───────────────┴───────────────┘工具推荐
| 工具 | 用途 | 价格 | 适用场景 |
|---|---|---|---|
| Nginx | 反向代理 / 流量切换 | 免费(开源)/ Plus $2,500/年 | 蓝绿切换、金丝雀流量分割 |
| Traefik | 动态反向代理 | 免费(开源)/ Enterprise 联系销售 | Docker 原生标签路由、自动发现 |
| Docker Compose | 多容器编排 | 免费 | 单节点蓝绿部署 |
| Watchtower | Docker 镜像自动更新 | 免费(开源) | 开发/测试环境自动拉取最新镜像 |
| Portainer | Docker 管理 GUI | 免费(CE)/ Business $5/节点/月 | 可视化容器管理和回滚 |
| Kubernetes | 容器编排 | 免费(开源)/ 托管 $72+/月 | 多节点滚动更新、金丝雀发布 |
| Argo Rollouts | K8s 渐进式交付 | 免费(开源) | K8s 环境蓝绿/金丝雀自动化 |
| Flyway / Liquibase | 数据库迁移管理 | 免费(社区版)/ Teams $498+/年 | 数据库 Schema 版本控制和回滚 |
2. Docker 镜像版本管理
镜像标签策略
生产环境绝对不要使用 latest 标签。每次部署必须使用明确的版本标签,确保可追溯和可回滚。
# ❌ 错误:使用 latest 标签
docker pull openclaw/openclaw:latest
# ✅ 正确:使用语义化版本标签
docker pull openclaw/openclaw:2026.2.6
# ✅ 正确:使用 Git commit SHA 标签(精确追溯)
docker pull openclaw/openclaw:2026.2.6-abc1234版本锁定配置
在 docker-compose.yml 中锁定所有镜像版本:
# docker-compose.yml — 版本锁定示例
version: "3.8"
services:
openclaw-gateway:
image: openclaw/openclaw:2026.2.6 # 锁定版本,不用 latest
container_name: openclaw-gateway
restart: unless-stopped
env_file: .env
volumes:
- openclaw_data:/app/data
- ./config:/app/config:ro
ports:
- "3000:3000"
openclaw-worker:
image: openclaw/openclaw-worker:2026.2.6
container_name: openclaw-worker
restart: unless-stopped
env_file: .env
depends_on:
- openclaw-gateway
postgres:
image: postgres:16.4 # 数据库也锁定版本
container_name: openclaw-db
restart: unless-stopped
volumes:
- pg_data:/var/lib/postgresql/data
environment:
POSTGRES_DB: openclaw
POSTGRES_USER: openclaw
POSTGRES_PASSWORD: ${DB_PASSWORD}
redis:
image: redis:7.4-alpine # 缓存也锁定版本
container_name: openclaw-redis
restart: unless-stopped
volumes:
- redis_data:/data
volumes:
openclaw_data:
pg_data:
redis_data:版本记录文件
维护一个 versions.env 文件,集中管理所有组件版本:
# versions.env — 集中版本管理
OPENCLAW_VERSION=2026.2.6
OPENCLAW_WORKER_VERSION=2026.2.6
POSTGRES_VERSION=16.4
REDIS_VERSION=7.4-alpine
NGINX_VERSION=1.27-alpine
# AI 模型版本
DEFAULT_LLM_MODEL=claude-sonnet-4-20250514
EMBEDDING_MODEL=text-embedding-3-small
FALLBACK_LLM_MODEL=gpt-4.1-mini
# Prompt 版本
SYSTEM_PROMPT_VERSION=v3.2.1
AGENT_CONFIG_VERSION=v2.1.0在 docker-compose.yml 中引用:
services:
openclaw-gateway:
image: openclaw/openclaw:${OPENCLAW_VERSION}
environment:
- DEFAULT_MODEL=${DEFAULT_LLM_MODEL}
- SYSTEM_PROMPT_VERSION=${SYSTEM_PROMPT_VERSION}3. 蓝绿部署(Blue-Green Deployment)
原理
蓝绿部署维护两套完全相同的生产环境(Blue 和 Green),任何时刻只有一套对外提供服务。更新时将新版本部署到空闲环境,测试通过后切换流量,实现零停机更新。如果新版本出现问题,立即切回旧环境。
┌─────────────┐
│ Nginx │
│ 反向代理 │
└──────┬──────┘
│
┌────────────┼────────────┐
│ 当前活跃 │ │
▼ │ ▼
┌────────────┐ │ ┌────────────┐
│ Blue 环境 │ │ │ Green 环境 │
│ v2026.2.5 │ ◄─────┘ │ v2026.2.6 │
│ (活跃) │ 切换流量 │ (待命) │
└────────────┘ └────────────┘操作步骤
步骤 1:准备蓝绿双环境 Docker Compose
# docker-compose.blue-green.yml
version: "3.8"
services:
# ===== Blue 环境 =====
openclaw-blue:
image: openclaw/openclaw:${BLUE_VERSION}
container_name: openclaw-blue
restart: unless-stopped
env_file: .env.blue
volumes:
- openclaw_data:/app/data
- ./config/blue:/app/config:ro
networks:
- openclaw-net
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
interval: 10s
timeout: 5s
retries: 3
# ===== Green 环境 =====
openclaw-green:
image: openclaw/openclaw:${GREEN_VERSION}
container_name: openclaw-green
restart: unless-stopped
env_file: .env.green
volumes:
- openclaw_data:/app/data
- ./config/green:/app/config:ro
networks:
- openclaw-net
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
interval: 10s
timeout: 5s
retries: 3
# ===== 共享基础设施 =====
postgres:
image: postgres:${POSTGRES_VERSION}
container_name: openclaw-db
restart: unless-stopped
volumes:
- pg_data:/var/lib/postgresql/data
environment:
POSTGRES_DB: openclaw
POSTGRES_USER: openclaw
POSTGRES_PASSWORD: ${DB_PASSWORD}
networks:
- openclaw-net
redis:
image: redis:${REDIS_VERSION}
container_name: openclaw-redis
restart: unless-stopped
volumes:
- redis_data:/data
networks:
- openclaw-net
nginx:
image: nginx:${NGINX_VERSION}
container_name: openclaw-nginx
restart: unless-stopped
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx/conf.d:/etc/nginx/conf.d:ro
- ./nginx/certs:/etc/nginx/certs:ro
depends_on:
- openclaw-blue
- openclaw-green
networks:
- openclaw-net
networks:
openclaw-net:
driver: bridge
volumes:
openclaw_data:
pg_data:
redis_data:步骤 2:配置 Nginx 流量切换
# nginx/conf.d/openclaw.conf
# 当前活跃环境:blue
# 切换时修改 upstream 指向并 reload
upstream openclaw_active {
server openclaw-blue:3000;
}
upstream openclaw_standby {
server openclaw-green:3000;
}
server {
listen 80;
server_name openclaw.example.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl;
server_name openclaw.example.com;
ssl_certificate /etc/nginx/certs/fullchain.pem;
ssl_certificate_key /etc/nginx/certs/privkey.pem;
# 健康检查端点(不经过 upstream)
location /nginx-health {
return 200 "ok";
}
# 所有流量转发到活跃环境
location / {
proxy_pass http://openclaw_active;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# WebSocket 支持(Agent 实时通信)
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 86400;
}
}步骤 3:蓝绿切换脚本
#!/bin/bash
# scripts/blue-green-switch.sh
# 用法: ./blue-green-switch.sh [blue|green]
set -euo pipefail
DEPLOY_DIR="/opt/openclaw"
NGINX_CONF="${DEPLOY_DIR}/nginx/conf.d/openclaw.conf"
BACKUP_DIR="${DEPLOY_DIR}/backups/$(date +%Y%m%d_%H%M%S)"
# 读取当前活跃环境
CURRENT_ACTIVE=$(grep -oP 'server openclaw-\K(blue|green)' "$NGINX_CONF" | head -1)
TARGET=${1:-$([ "$CURRENT_ACTIVE" = "blue" ] && echo "green" || echo "blue")}
echo "=========================================="
echo "蓝绿切换: ${CURRENT_ACTIVE} → ${TARGET}"
echo "=========================================="
# 1. 备份当前配置
mkdir -p "$BACKUP_DIR"
cp "$NGINX_CONF" "${BACKUP_DIR}/openclaw.conf.bak"
cp "${DEPLOY_DIR}/.env.${CURRENT_ACTIVE}" "${BACKUP_DIR}/.env.bak"
echo "✅ 配置已备份到 ${BACKUP_DIR}"
# 2. 健康检查目标环境
echo "🔍 检查 ${TARGET} 环境健康状态..."
for i in $(seq 1 10); do
if docker exec "openclaw-${TARGET}" curl -sf http://localhost:3000/health > /dev/null 2>&1; then
echo "✅ ${TARGET} 环境健康检查通过"
break
fi
if [ "$i" -eq 10 ]; then
echo "❌ ${TARGET} 环境健康检查失败,中止切换"
exit 1
fi
echo " 等待 ${TARGET} 就绪... (${i}/10)"
sleep 3
done
# 3. 切换 Nginx upstream
echo "🔄 切换流量到 ${TARGET}..."
sed -i "s/server openclaw-${CURRENT_ACTIVE}:3000/server openclaw-${TARGET}:3000/" \
"$NGINX_CONF"
# 4. 平滑重载 Nginx(不中断现有连接)
docker exec openclaw-nginx nginx -t && \
docker exec openclaw-nginx nginx -s reload
echo "✅ Nginx 已重载,流量切换到 ${TARGET}"
# 5. 验证切换结果
sleep 2
RESPONSE=$(curl -sf -o /dev/null -w "%{http_code}" https://openclaw.example.com/health)
if [ "$RESPONSE" = "200" ]; then
echo "✅ 切换成功!当前活跃环境: ${TARGET}"
echo "${TARGET}" > "${DEPLOY_DIR}/.active-env"
else
echo "❌ 切换后健康检查失败 (HTTP ${RESPONSE}),正在回滚..."
cp "${BACKUP_DIR}/openclaw.conf.bak" "$NGINX_CONF"
docker exec openclaw-nginx nginx -s reload
echo "⚠️ 已回滚到 ${CURRENT_ACTIVE}"
exit 1
fi
# 6. 记录切换日志
echo "$(date -Iseconds) | SWITCH | ${CURRENT_ACTIVE} → ${TARGET} | SUCCESS" \
>> "${DEPLOY_DIR}/logs/deploy.log"步骤 4:完整更新流程
#!/bin/bash
# scripts/deploy-blue-green.sh
# 完整蓝绿部署流程
set -euo pipefail
NEW_VERSION=$1
DEPLOY_DIR="/opt/openclaw"
# 确定目标环境
CURRENT_ACTIVE=$(cat "${DEPLOY_DIR}/.active-env" 2>/dev/null || echo "blue")
TARGET=$([ "$CURRENT_ACTIVE" = "blue" ] && echo "green" || echo "blue")
echo "📦 部署 OpenClaw ${NEW_VERSION} 到 ${TARGET} 环境"
# 1. 拉取新镜像
echo "⬇️ 拉取新镜像..."
docker pull "openclaw/openclaw:${NEW_VERSION}"
# 2. 更新目标环境版本
echo "${TARGET^^}_VERSION=${NEW_VERSION}" > "${DEPLOY_DIR}/.env.${TARGET}.version"
# 3. 停止并重建目标环境容器
echo "🔄 重建 ${TARGET} 容器..."
docker compose -f docker-compose.blue-green.yml up -d "openclaw-${TARGET}"
# 4. 等待目标环境就绪
echo "⏳ 等待 ${TARGET} 环境就绪..."
sleep 10
# 5. 运行冒烟测试
echo "🧪 运行冒烟测试..."
if ! bash scripts/smoke-test.sh "openclaw-${TARGET}"; then
echo "❌ 冒烟测试失败,中止部署"
docker compose -f docker-compose.blue-green.yml stop "openclaw-${TARGET}"
exit 1
fi
# 6. 切换流量
bash scripts/blue-green-switch.sh "${TARGET}"
echo "🎉 部署完成!OpenClaw ${NEW_VERSION} 已上线"4. 金丝雀发布(Canary Release)
原理
金丝雀发布将新版本先部署给一小部分用户(如 5%→20%→50%→100%),通过逐步扩大流量比例来验证新版本的稳定性。对于 AI Agent 平台尤其重要,因为 LLM 行为的不确定性意味着即使通过了所有测试,生产环境中仍可能出现意外行为。
用户请求 ──→ Nginx ──┬──→ 95% ──→ 稳定版 v2026.2.5 (主集群)
│
└──→ 5% ──→ 金丝雀 v2026.2.6 (测试实例)
│
▼
监控指标对比
├─ 错误率 < 1%?
├─ 延迟 P99 正常?
├─ Agent 成功率 ≥ 95%?
└─ 用户满意度无下降?
│
┌───────┴───────┐
│ 通过 │ 失败
▼ ▼
扩大到 20% 回滚到 0%操作步骤
步骤 1:Nginx 加权流量分割配置
# nginx/conf.d/openclaw-canary.conf
# 金丝雀发布配置 — 5% 流量到新版本
upstream openclaw_stable {
server openclaw-stable:3000 weight=95;
}
upstream openclaw_canary {
server openclaw-canary:3000 weight=5;
}
# 使用 split_clients 实现精确百分比分割
split_clients "${remote_addr}${request_uri}" $upstream_variant {
5% openclaw_canary;
* openclaw_stable;
}
server {
listen 443 ssl;
server_name openclaw.example.com;
ssl_certificate /etc/nginx/certs/fullchain.pem;
ssl_certificate_key /etc/nginx/certs/privkey.pem;
# 金丝雀标记 Header(用于监控区分)
add_header X-Canary-Version $upstream_variant always;
location / {
proxy_pass http://$upstream_variant;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Canary $upstream_variant;
# WebSocket 支持
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}步骤 2:金丝雀流量渐进脚本
#!/bin/bash
# scripts/canary-rollout.sh
# 用法: ./canary-rollout.sh <new_version> [initial_percent]
set -euo pipefail
NEW_VERSION=$1
PERCENT=${2:-5}
DEPLOY_DIR="/opt/openclaw"
NGINX_CONF="${DEPLOY_DIR}/nginx/conf.d/openclaw-canary.conf"
METRICS_URL="http://localhost:9090/api/v1/query" # Prometheus
echo "🐤 金丝雀发布: v${NEW_VERSION},初始流量 ${PERCENT}%"
# 1. 部署金丝雀实例
docker pull "openclaw/openclaw:${NEW_VERSION}"
CANARY_VERSION="${NEW_VERSION}" \
docker compose -f docker-compose.canary.yml up -d openclaw-canary
# 2. 等待金丝雀就绪
echo "⏳ 等待金丝雀实例就绪..."
for i in $(seq 1 15); do
if docker exec openclaw-canary curl -sf http://localhost:3000/health > /dev/null 2>&1; then
echo "✅ 金丝雀实例就绪"
break
fi
[ "$i" -eq 15 ] && { echo "❌ 金丝雀启动失败"; exit 1; }
sleep 2
done
# 3. 设置初始流量比例
update_canary_weight() {
local pct=$1
local stable_pct=$((100 - pct))
sed -i "s/[0-9]*% openclaw_canary/${pct}% openclaw_canary/" "$NGINX_CONF"
docker exec openclaw-nginx nginx -t && docker exec openclaw-nginx nginx -s reload
echo "📊 流量分配: 稳定版 ${stable_pct}% | 金丝雀 ${pct}%"
}
update_canary_weight "$PERCENT"
# 4. 监控阶段 — 检查关键指标
check_canary_health() {
# 检查金丝雀错误率
ERROR_RATE=$(curl -s "${METRICS_URL}" \
--data-urlencode 'query=rate(openclaw_request_errors_total{variant="canary"}[5m])' \
| jq -r '.data.result[0].value[1] // "0"')
# 检查金丝雀 P99 延迟
LATENCY_P99=$(curl -s "${METRICS_URL}" \
--data-urlencode 'query=histogram_quantile(0.99, rate(openclaw_request_duration_seconds_bucket{variant="canary"}[5m]))' \
| jq -r '.data.result[0].value[1] // "0"')
# 检查 Agent 任务成功率
AGENT_SUCCESS=$(curl -s "${METRICS_URL}" \
--data-urlencode 'query=rate(openclaw_agent_task_success_total{variant="canary"}[5m]) / rate(openclaw_agent_task_total{variant="canary"}[5m])' \
| jq -r '.data.result[0].value[1] // "1"')
echo " 错误率: ${ERROR_RATE} | P99延迟: ${LATENCY_P99}s | Agent成功率: ${AGENT_SUCCESS}"
# 判断是否健康(错误率 < 1%,P99 < 5s,成功率 > 95%)
if (( $(echo "$ERROR_RATE < 0.01" | bc -l) )) && \
(( $(echo "$LATENCY_P99 < 5.0" | bc -l) )) && \
(( $(echo "$AGENT_SUCCESS > 0.95" | bc -l) )); then
return 0
else
return 1
fi
}
# 5. 渐进式扩大流量
STAGES=(5 20 50 100)
for stage in "${STAGES[@]}"; do
update_canary_weight "$stage"
echo "⏳ 观察 ${stage}% 流量,等待 5 分钟..."
sleep 300
if ! check_canary_health; then
echo "❌ 金丝雀在 ${stage}% 流量时指标异常,回滚!"
update_canary_weight 0
docker compose -f docker-compose.canary.yml stop openclaw-canary
echo "⚠️ 金丝雀已回滚"
exit 1
fi
echo "✅ ${stage}% 流量阶段通过"
done
echo "🎉 金丝雀发布完成!v${NEW_VERSION} 已全量上线"步骤 3:基于 Cookie 的定向金丝雀(内部测试)
对于内部团队优先测试新版本的场景:
# 基于 Cookie 的金丝雀路由
map $cookie_canary $target_upstream {
"true" openclaw_canary;
default openclaw_stable;
}
server {
listen 443 ssl;
server_name openclaw.example.com;
# 内部测试入口 — 设置金丝雀 Cookie
location /enable-canary {
add_header Set-Cookie "canary=true; Path=/; Max-Age=3600; HttpOnly";
return 302 /;
}
location /disable-canary {
add_header Set-Cookie "canary=; Path=/; Max-Age=0";
return 302 /;
}
location / {
proxy_pass http://$target_upstream;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}5. AI Agent 特有的版本管理
5.1 模型版本管理
LLM 模型版本更新是 AI Agent 平台最高风险的变更类型。模型行为的微小变化可能导致 Agent 输出格式改变、工具调用失败或安全规则失效。
# config/model-versions.yml — 模型版本配置
models:
primary:
provider: anthropic
model: claude-sonnet-4-20250514
max_tokens: 8192
temperature: 0.7
version_pinned: true # 锁定到具体日期版本
fallback:
provider: openai
model: gpt-4.1-mini
max_tokens: 4096
temperature: 0.7
version_pinned: true
embedding:
provider: openai
model: text-embedding-3-small
dimensions: 1536
# 模型切换策略
switching_policy:
# 新模型必须通过评估套件才能上线
require_eval_pass: true
eval_threshold: 0.95 # 评估通过阈值
canary_percent: 5 # 模型金丝雀初始比例
observation_hours: 24 # 观察期模型版本切换提示词模板
你是一个 AI 运维工程师。我需要将 OpenClaw 的 LLM 模型从 [当前模型版本] 升级到 [目标模型版本]。
请帮我:
1. 分析两个模型版本之间的主要差异(能力、API 变更、定价变化)
2. 生成一个模型切换评估清单,包括:
- Agent 核心功能回归测试用例(至少 10 个)
- 工具调用兼容性检查项
- 输出格式一致性验证
- 安全规则有效性测试
3. 制定分阶段切换计划(金丝雀 5% → 20% → 50% → 100%)
4. 编写回滚脚本,确保可以在 30 秒内切回旧模型
当前 Agent 配置:
- 角色:[Agent 角色描述]
- 主要工具:[工具列表]
- 日均调用量:[调用量]5.2 Prompt 版本管理
Prompt 是 AI Agent 行为的核心定义,必须像代码一样进行版本管理。
prompts/
├── system/
│ ├── v3.2.1/
│ │ ├── base-system-prompt.md
│ │ ├── safety-rules.md
│ │ └── output-format.md
│ └── v3.3.0/
│ ├── base-system-prompt.md
│ ├── safety-rules.md
│ └── output-format.md
├── agents/
│ ├── devops-agent/
│ │ ├── v2.1.0/
│ │ │ └── role-definition.md
│ │ └── v2.2.0/
│ │ └── role-definition.md
│ └── email-agent/
│ └── v1.5.0/
│ └── role-definition.md
└── prompt-registry.json # Prompt 版本注册表// prompt-registry.json — Prompt 版本注册表
{
"active_versions": {
"system-prompt": "v3.2.1",
"devops-agent": "v2.1.0",
"email-agent": "v1.5.0"
},
"canary_versions": {
"system-prompt": "v3.3.0"
},
"rollback_versions": {
"system-prompt": "v3.1.0",
"devops-agent": "v2.0.0"
},
"version_history": [
{
"component": "system-prompt",
"version": "v3.2.1",
"deployed_at": "2026-02-01T10:00:00Z",
"deployed_by": "ops-team",
"change_summary": "增强工具调用格式约束",
"eval_score": 0.97
}
]
}5.3 工具兼容性管理
当 MCP Server 或插件更新时,必须验证与当前 Agent 配置的兼容性。
#!/bin/bash
# scripts/tool-compat-check.sh
# 工具兼容性检查脚本
set -euo pipefail
echo "🔧 OpenClaw 工具兼容性检查"
echo "=========================="
# 1. 检查所有 MCP Server 连接
echo "📡 检查 MCP Server 连接..."
SERVERS=("filesystem" "github" "slack" "database")
for server in "${SERVERS[@]}"; do
if docker exec openclaw-gateway \
curl -sf "http://localhost:3000/api/mcp/${server}/health" > /dev/null 2>&1; then
echo " ✅ ${server}: 连接正常"
else
echo " ❌ ${server}: 连接失败"
FAILED=true
fi
done
# 2. 检查工具 Schema 兼容性
echo "📋 检查工具 Schema..."
docker exec openclaw-gateway node -e "
const tools = require('/app/config/tools.json');
const schemas = require('/app/config/tool-schemas.json');
let errors = 0;
for (const [name, schema] of Object.entries(schemas)) {
if (!tools[name]) {
console.log(' ⚠️ Schema 定义了 ' + name + ' 但工具未注册');
errors++;
}
}
console.log(' 检查完成: ' + errors + ' 个问题');
process.exit(errors > 0 ? 1 : 0);
"
# 3. 运行工具调用冒烟测试
echo "🧪 运行工具调用冒烟测试..."
docker exec openclaw-gateway npm run test:tools -- --smoke
echo "✅ 工具兼容性检查完成"5.4 会话连续性保障
更新期间必须保障活跃用户会话不中断。
# config/session-continuity.yml
session:
# 会话存储(使用 Redis 确保跨实例共享)
store: redis
redis_url: redis://openclaw-redis:6379/0
ttl: 86400 # 会话 24 小时过期
# 更新期间的会话处理策略
update_policy:
# 优雅关闭:等待活跃会话完成
graceful_shutdown_timeout: 300 # 最多等待 5 分钟
# 会话迁移:将活跃会话从旧实例迁移到新实例
migration_enabled: true
# 长任务处理:正在执行的 Agent 任务不中断
preserve_running_tasks: true
task_completion_timeout: 600 # 最多等待任务完成 10 分钟# 优雅关闭脚本 — 等待活跃会话完成后再停止旧实例
#!/bin/bash
# scripts/graceful-shutdown.sh
OLD_CONTAINER=$1
TIMEOUT=${2:-300}
echo "🔄 优雅关闭 ${OLD_CONTAINER}..."
# 1. 标记为 draining(不再接受新连接)
docker exec "$OLD_CONTAINER" curl -sf -X POST \
http://localhost:3000/admin/drain
# 2. 等待活跃连接归零
ELAPSED=0
while [ "$ELAPSED" -lt "$TIMEOUT" ]; do
ACTIVE=$(docker exec "$OLD_CONTAINER" curl -sf \
http://localhost:3000/admin/connections | jq '.active')
if [ "$ACTIVE" = "0" ]; then
echo "✅ 所有连接已关闭"
break
fi
echo " ⏳ 剩余活跃连接: ${ACTIVE},已等待 ${ELAPSED}s"
sleep 5
ELAPSED=$((ELAPSED + 5))
done
# 3. 停止容器
docker stop "$OLD_CONTAINER"
echo "✅ ${OLD_CONTAINER} 已停止"6. 数据库迁移与回滚
迁移策略
数据库迁移是更新过程中最危险的环节。OpenClaw 使用 PostgreSQL,迁移必须遵循”向前兼容”原则——新旧版本的代码都能正常使用迁移后的数据库 Schema。
迁移安全原则:
┌─────────────────────────────────────────────────┐
│ ✅ 安全操作(可回滚) │ ❌ 危险操作(不可逆) │
├─────────────────────────┼───────────────────────┤
│ 添加新列(有默认值) │ 删除列 │
│ 添加新表 │ 重命名列 │
│ 添加索引 │ 修改列类型 │
│ 添加约束(NOT VALID) │ 删除表 │
│ 扩大 VARCHAR 长度 │ 缩小 VARCHAR 长度 │
└─────────────────────────┴───────────────────────┘迁移前备份脚本
#!/bin/bash
# scripts/db-backup-before-migration.sh
# 迁移前必须执行的数据库备份
set -euo pipefail
BACKUP_DIR="/opt/openclaw/backups/db"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
BACKUP_FILE="${BACKUP_DIR}/openclaw_pre_migration_${TIMESTAMP}.sql.gz"
mkdir -p "$BACKUP_DIR"
echo "💾 开始数据库备份..."
# 1. 创建完整备份(含 Schema 和数据)
docker exec openclaw-db pg_dump \
-U openclaw \
-d openclaw \
--format=custom \
--compress=9 \
--verbose \
| gzip > "$BACKUP_FILE"
# 2. 验证备份完整性
echo "🔍 验证备份完整性..."
gunzip -t "$BACKUP_FILE"
BACKUP_SIZE=$(du -h "$BACKUP_FILE" | cut -f1)
echo "✅ 备份完成: ${BACKUP_FILE} (${BACKUP_SIZE})"
# 3. 记录当前 Schema 版本
docker exec openclaw-db psql -U openclaw -d openclaw \
-c "SELECT version, description, installed_on FROM schema_migrations ORDER BY installed_on DESC LIMIT 5;" \
> "${BACKUP_DIR}/schema_version_${TIMESTAMP}.txt"
echo "📋 当前 Schema 版本已记录"
# 4. 保留最近 10 个备份,清理旧备份
ls -t "${BACKUP_DIR}"/openclaw_pre_migration_*.sql.gz | tail -n +11 | xargs -r rm
echo "🧹 旧备份已清理(保留最近 10 个)"数据库回滚脚本
#!/bin/bash
# scripts/db-rollback.sh
# 数据库回滚到指定备份
set -euo pipefail
BACKUP_FILE=$1
DEPLOY_DIR="/opt/openclaw"
if [ -z "$BACKUP_FILE" ]; then
echo "用法: ./db-rollback.sh <backup_file>"
echo "可用备份:"
ls -lt "${DEPLOY_DIR}/backups/db/"*.sql.gz | head -5
exit 1
fi
echo "⚠️ 即将回滚数据库到: ${BACKUP_FILE}"
echo "⚠️ 此操作将覆盖当前数据库!"
read -p "确认继续?(yes/no): " CONFIRM
[ "$CONFIRM" != "yes" ] && { echo "已取消"; exit 0; }
# 1. 停止 OpenClaw 服务(防止写入)
echo "🛑 停止 OpenClaw 服务..."
docker compose -f docker-compose.blue-green.yml stop openclaw-blue openclaw-green
# 2. 恢复数据库
echo "💾 恢复数据库..."
gunzip -c "$BACKUP_FILE" | docker exec -i openclaw-db \
pg_restore -U openclaw -d openclaw --clean --if-exists
# 3. 验证恢复结果
echo "🔍 验证恢复结果..."
docker exec openclaw-db psql -U openclaw -d openclaw \
-c "SELECT count(*) as table_count FROM information_schema.tables WHERE table_schema='public';"
# 4. 重启 OpenClaw 服务
echo "🔄 重启 OpenClaw 服务..."
docker compose -f docker-compose.blue-green.yml up -d
echo "✅ 数据库回滚完成"配置版本管理
# 使用 Git 管理所有配置文件
# config/ 目录结构
config/
├── .git/ # Git 版本控制
├── docker-compose.yml
├── versions.env
├── model-versions.yml
├── nginx/
│ └── conf.d/
│ └── openclaw.conf
├── prompts/
│ └── system/
│ └── v3.2.1/
└── .env.production
# 每次配置变更都提交 Git
git add -A && git commit -m "chore: upgrade OpenClaw to v2026.2.6"
git tag "deploy-2026.2.6-$(date +%Y%m%d)"实战案例:OpenClaw v2026.2.5 → v2026.2.6 蓝绿部署全流程
场景描述
团队需要将 OpenClaw 从 v2026.2.5 升级到 v2026.2.6,此版本包含:
- Gateway 安全补丁
- 新增 Notion 集成插件
- 系统 Prompt 优化(v3.2.1 → v3.3.0)
- 数据库新增
agent_metrics表
完整操作流程
# ===== 阶段 1:准备(T-30 分钟)=====
# 1.1 通知团队
echo "📢 计划在 30 分钟后执行 OpenClaw 升级 v2026.2.5 → v2026.2.6"
# 1.2 备份当前环境
bash scripts/db-backup-before-migration.sh
cp -r /opt/openclaw/config /opt/openclaw/backups/config_$(date +%Y%m%d)
# 1.3 拉取新镜像并验证
docker pull openclaw/openclaw:2026.2.6
docker inspect openclaw/openclaw:2026.2.6 | jq '.[0].Config.Labels'
# 1.4 更新 Prompt 版本
cp -r prompts/system/v3.3.0 /opt/openclaw/config/prompts/system/
# 暂不激活,等蓝绿切换后再切换 Prompt 版本
# ===== 阶段 2:部署到 Green 环境(T-15 分钟)=====
# 2.1 确认当前活跃环境
cat /opt/openclaw/.active-env
# 输出: blue
# 2.2 更新 Green 环境版本
echo "GREEN_VERSION=2026.2.6" > /opt/openclaw/.env.green.version
# 2.3 启动 Green 环境
docker compose -f docker-compose.blue-green.yml up -d openclaw-green
# 2.4 等待 Green 就绪
sleep 15
docker exec openclaw-green curl -sf http://localhost:3000/health
# 输出: {"status":"ok","version":"2026.2.6"}
# ===== 阶段 3:数据库迁移 =====
# 3.1 运行迁移(向前兼容,Blue 仍可正常工作)
docker exec openclaw-green npm run db:migrate
# 输出: Migration 20260206_add_agent_metrics: applied
# 3.2 验证迁移结果
docker exec openclaw-db psql -U openclaw -d openclaw \
-c "\dt agent_metrics"
# ===== 阶段 4:冒烟测试 =====
# 4.1 对 Green 环境运行测试
bash scripts/smoke-test.sh openclaw-green
# 输出:
# ✅ 健康检查: 通过
# ✅ Agent 创建: 通过
# ✅ 工具调用: 通过
# ✅ Notion 集成: 通过
# ✅ WebSocket: 通过
# ===== 阶段 5:流量切换 =====
# 5.1 执行蓝绿切换
bash scripts/blue-green-switch.sh green
# 输出:
# 蓝绿切换: blue → green
# ✅ Green 环境健康检查通过
# ✅ Nginx 已重载,流量切换到 green
# ✅ 切换成功!当前活跃环境: green
# 5.2 验证线上服务
curl -sf https://openclaw.example.com/health
# 输出: {"status":"ok","version":"2026.2.6"}
# ===== 阶段 6:激活新 Prompt 版本 =====
# 6.1 更新 Prompt 注册表
jq '.active_versions["system-prompt"] = "v3.3.0"' \
config/prompt-registry.json > tmp.json && mv tmp.json config/prompt-registry.json
# 6.2 热重载 Prompt 配置
docker exec openclaw-green curl -sf -X POST \
http://localhost:3000/admin/reload-prompts
# ===== 阶段 7:监控观察(持续 1 小时)=====
# 7.1 观察关键指标
watch -n 30 'curl -sf http://localhost:9090/api/v1/query \
--data-urlencode "query=rate(openclaw_request_errors_total[5m])" \
| jq ".data.result[0].value[1]"'
# ===== 阶段 8:确认或回滚 =====
# 如果一切正常:
echo "✅ 升级成功,停止旧 Blue 环境"
bash scripts/graceful-shutdown.sh openclaw-blue
# 如果出现问题:
# bash scripts/blue-green-switch.sh blue # 立即切回 Blue
# bash scripts/db-rollback.sh <backup_file> # 如需回滚数据库案例分析
本次升级的关键决策点:
- 选择蓝绿而非金丝雀:因为包含数据库迁移,需要确保新旧环境使用相同的数据库 Schema,蓝绿部署的”向前兼容迁移”策略更合适
- Prompt 版本延迟激活:先切换基础设施,确认稳定后再切换 Prompt,降低同时变更多个维度的风险
- 保留旧环境 1 小时:不立即销毁 Blue 环境,留出充足的观察和回滚窗口
- 迁移前备份:数据库备份是回滚的最后防线,必须在迁移前完成
避坑指南
❌ 常见错误
-
使用
latest标签部署生产环境- 问题:
latest标签指向的镜像随时可能变化,无法精确追溯当前运行的版本,回滚时也无法确定应该回到哪个版本 - 正确做法:始终使用语义化版本标签(如
2026.2.6)或 Git commit SHA 标签,并在versions.env中集中记录所有组件版本
- 问题:
-
同时变更多个维度(代码 + 模型 + Prompt)
- 问题:当多个维度同时变更时,出现问题后无法判断是哪个变更导致的,增加排查和回滚的复杂度
- 正确做法:每次更新只变更一个维度,按”基础设施 → 工具 → Prompt → 模型”的顺序逐步更新,每步之间留出观察期
-
数据库迁移不可逆(直接删列、改类型)
- 问题:执行了不可逆的数据库变更后,如果需要回滚代码,旧版本代码无法兼容新的数据库 Schema,导致服务崩溃
- 正确做法:遵循”向前兼容”原则——先添加新列,部署新代码,确认稳定后再在下一个版本中删除旧列(两阶段迁移)
-
更新时不处理活跃会话
- 问题:直接停止旧容器会导致正在进行的 Agent 任务中断、用户会话丢失,影响用户体验和数据完整性
- 正确做法:使用优雅关闭策略——先标记旧实例为 draining 状态,等待活跃连接归零或超时后再停止
-
金丝雀发布没有自动回滚机制
- 问题:手动监控金丝雀指标容易遗漏异常,特别是在非工作时间,可能导致问题扩大
- 正确做法:配置自动化指标检查和回滚触发器,当错误率、延迟或 Agent 成功率超过阈值时自动将金丝雀流量降为 0%
-
忽略 Prompt 版本管理
- 问题:Prompt 变更没有版本记录,出现 Agent 行为异常时无法追溯是哪次 Prompt 修改导致的,也无法快速回滚
- 正确做法:将 Prompt 文件纳入 Git 版本控制,使用 Prompt 注册表管理活跃版本,支持一键切换和回滚
✅ 最佳实践
- 建立更新检查清单:每次更新前执行标准化检查清单(备份、健康检查、冒烟测试、回滚验证),避免遗漏关键步骤
- 维护回滚手册:为每种更新类型(基础设施/模型/Prompt/工具)编写专门的回滚操作手册,确保任何团队成员都能在 5 分钟内完成回滚
- 定期演练回滚:每月至少进行一次回滚演练,验证备份有效性和回滚流程的可操作性
- 更新窗口选择:选择业务低峰期执行更新(如工作日上午 10 点),确保团队在线可以快速响应问题
- 变更日志自动化:每次部署自动生成变更日志,记录版本号、变更内容、部署时间、操作人员,便于事后审计
相关资源与延伸阅读
- OpenClaw 官方 GitHub 仓库 — 源码、Issue 跟踪和版本发布说明
- OpenClaw Docker 镜像(Docker Hub) — 官方 Docker 镜像和标签列表
- Nginx 官方文档 — 负载均衡 — upstream 配置和流量分割参考
- Argo Rollouts 文档 — Kubernetes 环境下的蓝绿/金丝雀自动化工具
- Flyway 数据库迁移工具 — 数据库 Schema 版本控制和迁移管理
- Traefik 动态路由文档 — Docker 原生的反向代理和流量管理
- AI Agent 版本管理与回滚最佳实践(gofast.ai) — AI Agent 特有的版本管理策略
- AI Agent 发布管理 2026(neuronex-automation.com) — Prompt、工具和工作流的发布管理实践
- DigitalOcean Agent 版本回滚指南 — 云平台 Agent 版本管理参考
- OpenClaw 更新指南(apidog.com) — OpenClaw 跨部署方式的安全更新实践
参考来源
- Canary Releases and Blue-Green Deployments Without Kubernetes (2026-06)
- AI Agent Release Management 2026 (2026-01)
- Versioning & Rollbacks in Modern Agent Deployments (2026-03)
- Agent Versioning and Rollbacks: Lessons from Production Failures (2025-06)
- AI Agent Version Rollback Disasters: MLflow 3.0 Safeguards (2025-03)
- Zero-Downtime Deployments: Blue-Green with Docker Compose (2025-04)
- Container Rollback: Safely Revert Docker & Kubernetes Deployments (2025-12)
- How to Update OpenClaw (2026-06)
- OpenClaw Installation and Deployment Guide (2026-06)
- Building Resilient Databases with Reversible Migrations (2025-10)
📖 返回 总览与导航 | 上一节:25c-日志管理与审计 | 下一节:25e-成本优化