Agent 部署与运维

7/6/2026 AI Agent容器化部署监控

# Agent 部署与运维

从 Demo 到生产——部署、监控、灰度、CI/CD 全流程

# 19.1 Demo 能跑 ≠ 生产能用

在 Jupyter Notebook 里跑通一个 Agent Demo 只需要 30 分钟。但把它放到生产环境,面对真实用户、真实流量、真实故障,需要解决完全不同的问题。

🧪 Demo 级 Agent

  • 单进程、单用户、无并发
  • API Key 硬编码在代码里
  • 没有日志,出了问题靠 print
  • LLM 报错就直接崩溃
  • 无限流、无重试、无超时
  • 更新代码需要停机

🏭 生产级 Agent

  • 多实例、负载均衡、高可用
  • 密钥管理(Vault / KMS)
  • 全链路日志 + 可观测性
  • 优雅降级 + 自动重试 + 超时控制
  • 限流 + 熔断 + 步数控制
  • 蓝绿部署 / 灰度发布 / 滚动更新

# 19.2 生产级 Agent 部署架构

🏗️ 推荐架构:API Gateway + Agent Service + LLM Proxy

🌐 API Gateway (Nginx / Kong) — SSL 终止、限流、认证、请求路由

🤖 Agent Service (多实例) — Python/Java 服务,处理 Agent 逻辑,无状态可水平扩展

🔗 LLM Proxy (自建网关) — 多模型路由、Key 轮换、缓存、降级、成本统计

💾 数据层 — Redis(会话/缓存)+ PostgreSQL(持久化)+ 向量数据库(RAG)

📊 监控层 — Prometheus(指标)+ Grafana(大屏)+ LangSmith/Langfuse(Trace)

# Dockerfile 模板

FROM python:3.11-slim

# 时区
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

# 安装依赖
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# 复制代码
COPY . .

# 健康检查
HEALTHCHECK --interval=30s --timeout=10s --retries=3 \
  CMD curl -f http://localhost:8080/health || exit 1

# 启动
EXPOSE 8080
CMD ["gunicorn", "--bind", "0.0.0.0:8080", "--workers", "4", \
     "--timeout", "120", "--access-logfile", "-", "app:app"]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

# Docker Compose 部署

version: '3.8'

services:
  agent-app:
    build: .
    container_name: agent-app
    restart: on-failure:3       # 最多重启 3 次
    ports:
      - "8080:8080"
    environment:
      - REDIS_URL=redis://redis:6379
      - DB_URL=postgresql://user:pass@postgres:5432/agent
      - LLM_API_KEY=${LLM_API_KEY}   # 从 .env 读取
      - ENV=production
    depends_on:
      redis:
        condition: service_healthy
      postgres:
        condition: service_healthy
    deploy:
      resources:
        limits:
          memory: 2G
          cpus: '2.0'
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"

  redis:
    image: redis:7-alpine
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]

  postgres:
    image: postgres:16
    environment:
      POSTGRES_DB: agent
      POSTGRES_USER: user
      POSTGRES_PASSWORD: pass
    healthcheck:
      test: ["CMD", "pg_isready"]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43

# 19.3 CI/CD:持续集成与持续部署

Agent 的 CI/CD 与传统软件不同,需要额外关注 Prompt 版本管理评估回归

CI/CD 流程: 📝 代码提交 → 🧪 单元测试 → 📊 评估回归 → 🐳 构建镜像 → 🚀 灰度发布 → 📈 全量上线

🔑 Agent CI/CD 的特殊环节:评估回归 传统 CI 只跑单元测试(assert x == y)。Agent CI 需要额外跑 评估数据集(EDD),确保 Prompt 修改没有导致回答质量下降。如果评估分数低于阈值,CI 自动阻止发布。

name: Agent CI/CD

on:
  push:
    branches: [main]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      
      # 1. 单元测试
      - name: Run Unit Tests
        run: |
          pip install -r requirements.txt
          pytest tests/ --cov=app --cov-report=xml
      
      # 2. Agent 评估回归(关键!)
      - name: Run Evaluation Regression
        env:
          LLM_API_KEY: ${{ secrets.LLM_API_KEY }}
        run: |
          python -m eval.run_eval \
            --dataset eval/datasets/prod.json \
            --threshold 0.85 \
            --report eval/report.json
          # 如果评估分数 < 0.85,CI 失败,阻止发布
      
      # 3. 构建 Docker 镜像
      - name: Build Docker Image
        run: |
          docker build -t my-agent:${{ github.sha }} .
          docker tag my-agent:${{ github.sha }} my-agent:latest
      
      # 4. 灰度部署(10% 流量)
      - name: Deploy Canary
        run: |
          ./scripts/deploy.sh --canary --image my-agent:${{ github.sha }}
      
      # 5. 等待观察 5 分钟
      - name: Canary Observation
        run: sleep 300
      
      # 6. 检查灰度指标,决定全量 or 回滚
      - name: Promote or Rollback
        run: |
          METRICS=$(./scripts/check_canary.sh)
          if [ "$METRICS" = "healthy" ]; then
            ./scripts/deploy.sh --full --image my-agent:${{ github.sha }}
          else
            ./scripts/rollback.sh
            exit 1
          fi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54

# 19.4 灰度发布策略

Agent 的输出有随机性,新版本可能有未知问题。灰度发布让你 先给一小部分用户用新版本,观察指标正常后再全量。

策略 方式 适合场景
蓝绿部署 两套环境,一键切换 快速回滚、停机时间零
金丝雀发布 新版先承接 5%-10% 流量 Agent 版本升级
A/B 测试 按用户分组,对比指标 Prompt 效果对比
影子发布 新版处理真实请求但不返回结果 验证新 Agent 无副作用

# 金丝雀发布实现

# 10% 流量到新版本,90% 到旧版本
upstream agent_v1 {
    server agent-v1:8080;
}

upstream agent_v2 {
    server agent-v2:8080;
}

# 按用户 ID 哈希分配,同一用户始终命中同一版本
split_clients "${remote_addr}${http_user_id}" $agent_backend {
    10%  agent_v2;      # 10% 用户走新版本
    *    agent_v1;      # 90% 用户走旧版本
}

server {
    listen 80;
    
    location /api/agent {
        proxy_pass http://$agent_backend;
        proxy_set_header X-Canary $agent_backend;
        add_header X-Agent-Version $agent_backend;
    }
    
    # 紧急回滚:把 10% 改成 0%
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

# 19.5 监控与告警体系

生产环境必须做到 5 分钟发现、5 分钟定位、5 分钟恢复。没有监控的 Agent 就像闭眼开车。

监控层 指标 工具 告警阈值
系统层 CPU/内存/磁盘/网络 Prometheus + Node Exporter CPU > 80%
应用层 QPS/延迟/错误率 Prometheus + Grafana P99 > 10s
Agent层 成功率/步数/Token消耗 LangSmith / Langfuse 成功率 < 85%
LLM层 API延迟/配额/费用 自定义 LLM Proxy 费用 > 预算 80%
业务层 用户满意度/投诉率 反馈系统 差评率 > 5%
from prometheus_client import Counter, Histogram, Gauge

# Agent 指标定义
agent_requests = Counter(
    'agent_requests_total', 
    'Total agent requests',
    ['chapter', 'status']  # 标签:章节、状态(success/fail)
)

agent_latency = Histogram(
    'agent_latency_seconds',
    'Agent response latency',
    ['chapter'],
    buckets=[0.5, 1, 2, 5, 10, 30, 60, 120]  # 延迟分桶
)

agent_tokens = Counter(
    'agent_tokens_total',
    'Total tokens consumed',
    ['model', 'type']  # 模型、类型(input/output)
)

agent_steps = Histogram(
    'agent_steps_count',
    'Number of steps per request',
    buckets=[1, 3, 5, 10, 15, 20]
)

# 在 Agent 执行流程中埋点
def handle_request(user_input, chapter):
    start = time.time()
    try:
        result = agent.invoke(user_input)
        agent_requests.labels(chapter=chapter, status='success').inc()
        return result
    except Exception as e:
        agent_requests.labels(chapter=chapter, status='fail').inc()
        raise
    finally:
        agent_latency.labels(chapter=chapter).observe(time.time() - start)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40

# 19.6 成本优化策略

Agent 的最大成本是 LLM API 调用费用。一个不加优化的 Agent,月账单可能从 $100 飙到 $10,000。

💰 五大成本优化策略

1. 模型分级路由 — 简单问题用 mini 模型($0.15/M),复杂问题才用旗舰模型($5/M)。80% 问题用 mini 解决,成本降 5-10 倍。

2. 语义缓存 — 用向量相似度判断"是否问过类似问题",命中缓存直接返回,不再调用 LLM。命中率 20-40%。

3. Prompt 压缩 — 精简 System Prompt,去掉不必要的示例和说明。每省 1000 Token = 每次省 $0.01-0.05。

4. 步数控制 — 限制 Agent 最大步数(如 10 步),避免无限循环烧 Token。每多一步 = 一次完整 LLM 调用。

5. 批量处理 — 多个独立任务合并为一次 LLM 调用(batch)。OpenAI Batch API 半价,适合非实时场景。

def route_model(query: str, has_tools: bool) -> str:
    """根据问题复杂度选择模型"""
    
    # 简单问答 → mini 模型(便宜 30 倍)
    if not has_tools and len(query) < 100:
        return "gpt-4o-mini"
    
    # 需要工具调用 → 标准模型
    if has_tools and not is_complex_task(query):
        return "gpt-4o"
    
    # 复杂推理 → 旗舰模型
    return "claude-3.5-sonnet"

# 成本对比(每百万 Token):
# gpt-4o-mini:  $0.15  ← 80% 请求用这个
# gpt-4o:       $2.50  ← 15% 请求用这个
# claude-3.5:   $3.00  ← 5% 请求用这个
# 
# 不分级:100% 用 gpt-4o = $2.50/M
# 分级后:80%×$0.15 + 15%×$2.50 + 5%×$3.00 = $0.57/M
# 节省 77%!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import numpy as np

class SemanticCache:
    """基于向量相似度的缓存"""
    
    def __init__(self, threshold=0.95):
        self.cache = {}  # {query_vector: response}
        self.threshold = threshold  # 相似度阈值
    
    def get(self, query: str) -> str | None:
        query_vec = embeddings.embed_query(query)
        
        for cached_vec, response in self.cache.items():
            similarity = cosine_similarity(query_vec, cached_vec)
            if similarity > self.threshold:
                return response  # 缓存命中
        
        return None  # 未命中
    
    def set(self, query: str, response: str):
        vec = embeddings.embed_query(query)
        self.cache[vec] = response

# 使用
cache = SemanticCache(threshold=0.95)

def chat(query):
    # 先查缓存
    cached = cache.get(query)
    if cached:
        return cached  # 命中,不调用 LLM
    
    # 未命中,调用 LLM
    response = llm.invoke(query)
    cache.set(query, response)
    return response
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36

# 面试八股

Q:Demo 级 Agent 和生产级 Agent 的区别是什么?

A: Demo 关注功能跑通:单进程、无并发、无监控、无重试。生产级关注可靠运行:多实例高可用、限流熔断、全链路监控、优雅降级、灰度发布、成本控制。面试关键:能说出 Demo 的 5 个缺陷和对应的生产级解决方案(密钥管理、日志监控、错误重试、超时控制、资源限制)。

Q:Agent 的 CI/CD 和传统软件有什么不同?

A: 最大的区别是 评估回归。传统 CI 跑单元测试(assert),Agent CI 额外要跑评估数据集(EDD),确保 Prompt 修改没有导致回答质量下降。如果评估分数低于阈值(如 0.85),CI 自动阻止发布。这是因为 Agent 输出有随机性,代码逻辑没变但 Prompt 变了可能导致行为退化。

Q:什么是金丝雀发布?Agent 为什么需要它?

A: 金丝雀发布:新版本先承接 5-10% 流量,观察指标正常后再全量。Agent 需要它因为:① LLM 输出有随机性,测试集无法覆盖所有情况;② Prompt 微调可能有副作用;③ 新工具可能有未知的失败模式。金丝雀发布让问题影响范围最小化,发现问题可以快速回滚。

Q:Agent 的监控体系应该包含哪些层面?

A: 五层监控:① 系统层(CPU/内存/磁盘);② 应用层(QPS/延迟/错误率);③ Agent层(成功率/步数/Token消耗,用 LangSmith/Langfuse);④ LLM层(API延迟/配额/费用);⑤ 业务层(用户满意度/投诉率)。每层设定告警阈值,实现 5 分钟发现-定位-恢复。

Q:如何优化 Agent 的 LLM API 成本?

A:模型分级路由:80% 简单问题用 mini 模型($0.15/M),复杂问题才用旗舰模型,成本降 5-10 倍;② 语义缓存:相似问题命中缓存直接返回,命中率 20-40%;③ Prompt 压缩:精简 System Prompt;④ 步数控制:限制最大步数防止烧 Token;⑤ 批量处理:非实时任务用 Batch API(半价)。

# 课后练习

# 第 1 题(单选)

Agent CI/CD 相比传统软件 CI/CD 最大的区别是?

A. 需要构建 Docker 镜像 B. 需要跑评估回归(EDD),确保 Prompt 修改没有降低回答质量 C. 需要单元测试 D. 需要代码审查

答案与解析

答案:B

Agent CI/CD 额外需要评估回归(EDD),用评估数据集验证回答质量。代码逻辑没变但 Prompt 变了可能导致行为退化,传统的 assert 测试无法覆盖。

# 第 2 题(单选)

金丝雀发布的策略是?

A. 一次性全量切换到新版本 B. 新版本先承接 5-10% 流量,观察指标正常后再全量 C. 两套环境同时运行,手动切换 D. 新版本处理请求但不返回结果给用户

答案与解析

答案:B

金丝雀发布:新版先承接小比例流量(5-10%),观察指标正常后逐步扩大到全量。问题影响范围最小化,发现异常可快速回滚。

# 第 3 题(多选)

生产级 Agent 监控体系应该包含哪些层面?(多选)

A. 系统层(CPU/内存/磁盘) B. 应用层(QPS/延迟/错误率) C. Agent层(成功率/步数/Token消耗) D. 代码注释覆盖率

答案与解析

答案:A、B、C

五层监控:系统层、应用层、Agent层、LLM层、业务层。代码注释覆盖率不是运维监控指标。

# 第 4 题(单选)

模型分级路由如何降低成本?

A. 所有请求都用最便宜的模型 B. 80% 简单问题用 mini 模型,复杂问题才用旗舰模型,成本降 5-10 倍 C. 不使用 LLM,改用规则引擎 D. 只在夜间调用 LLM API

答案与解析

答案:B

分级路由:简单问题用 mini($0.15/M),复杂问题用旗舰($5/M)。80% 请求用 mini,综合成本可降 5-10 倍。

# 第 5 题(单选)

语义缓存的作用是?

A. 缓存 LLM 模型参数,加快推理 B. 用向量相似度判断"是否问过类似问题",命中则直接返回不调 LLM C. 压缩 Prompt 减少 Token D. 缓存工具调用结果

答案与解析

答案:B

语义缓存:将用户问题的向量化后比对,相似度超过阈值(如 0.95)则返回缓存的回答,不再调用 LLM。命中率 20-40%,直接省掉对应的 API 费用。

# 第 6 题(多选)

Agent 的成本优化策略包括?(多选)

A. 模型分级路由(简单问题用 mini) B. 语义缓存(相似问题不重复调 LLM) C. 步数控制(限制最大步数防烧 Token) D. 增加 LLM 参数量

答案与解析

答案:A、B、C

模型分级、语义缓存、步数控制都是有效成本优化策略。增加 LLM 参数量反而增加成本。

# 第 7 题(单选)

Docker Compose 中 restart: on-failure:3 的含义是?

A. 容器每天重启 3 次 B. 容器失败时自动重启,最多重试 3 次 C. 运行 3 个容器副本 D. 容器 3 秒后自动重启

答案与解析

答案:B

on-failure:3 表示容器因错误退出时自动重启,最多重试 3 次。超过 3 次不再重启,防止无限重启循环。