把 Agent SDK 塞进生产容器:13 条部署清单

Claude 中文知识站 Lv4

Agent SDK 本地跑起来挺舒服。但是一旦你要把它塞进生产环境——容器里跑、k8s 里调度、被监控系统盯着——就会发现本地那套玩法不够用。

这篇是把我自己踩过的坑和客户现场见过的部署方式整理成一份清单。不保证面面俱到,但至少少走弯路。

1. 多阶段 Dockerfile

别用单阶段,node:20 基础镜像加依赖动辄 1.2GB。我的模板大概是这样:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
FROM node:20-alpine AS builder
WORKDIR /app
COPY package.json pnpm-lock.yaml ./
RUN corepack enable && pnpm install --frozen-lockfile
COPY . .
RUN pnpm build

FROM node:20-alpine AS runtime
WORKDIR /app
RUN apk add --no-cache git tini
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/.claude ./.claude
ENV NODE_ENV=production
ENTRYPOINT ["/sbin/tini", "--"]
CMD ["node", "dist/agent-runner.js"]

几个点:alpine 小巧但要装 git(agent 经常要用),tini 做 PID 1 保证信号正确转发(否则 SIGTERM 传不到 node 进程),.claude/ 目录里的 agent 定义和 hook 配置要一起打进镜像。

最后镜像大小大概 340MB,对比单阶段小了一大截。

2. secrets 不要硬编码

这条应该不用说,但我真见过有人把 ANTHROPIC_API_KEY 直接写 Dockerfile 里。

生产用 Secret Manager(k8s Secret、AWS Secrets Manager、Vault 都行)。pod 启动时注入环境变量,或者挂载成文件。我偏向后者,轮转 key 时不用重启 pod。

3. 环境变量清单

Agent SDK 实际在意的环境变量不少,我整理了一份:

变量 作用 我的生产值
ANTHROPIC_API_KEY API 密钥 secret 注入
ANTHROPIC_MODEL 默认模型 claude-sonnet-4-7
CLAUDE_AGENT_SESSION_DIR session 目录 /data/sessions
CLAUDE_AGENT_CONFIG_DIR agent 配置目录 /app/.claude
HTTP_PROXY / HTTPS_PROXY 出站代理 按环境
NO_PROXY 代理白名单 localhost,127.0.0.1,10.0.0.0/8
OTEL_EXPORTER_OTLP_ENDPOINT OTel 上报地址 按环境
CLAUDE_AGENT_LOG_LEVEL 日志级别 info

CLAUDE_AGENT_SESSION_DIR 尤其重要——默认放在工作目录下,容器重启就没了。必须挂到 PersistentVolume 或者 emptyDir 根据需求选。

4. 资源限制别太紧

我最初给 agent pod 配的是 memory: 512Micpu: 0.2,跑了一天就 OOM。

实测下来的合理配置:

  • 内存下限 1.5Gi(session 里的 filesystem snapshot 会涨,prompt cache 也占内存)
  • 内存上限 3Gi
  • CPU 下限 0.5(agent 本身不算 CPU 密集,但同时跑多个工具会突增)
  • CPU 上限 2

如果 agent 会跑重量级工具(比如本地跑 ML 推理),资源得往上翻。

5. 健康检查要检查 API 可达

这条是我的一次生产事故换来的。

我最初的 readiness probe 只检查 HTTP 端口是否监听:

1
2
3
readinessProbe:
tcpSocket:
port: 3000

结果有一次 Anthropic API 某个区域抽风,agent 进程活着、端口开着,但所有 API 调用都超时。k8s 以为 pod 健康,继续把流量打过来,全挂。

改成 HTTP 探测 + 自定义 /healthz 接口,里面做一次轻量级的 API 连通性检查(每 30 秒缓存一次,不要每次都真的调):

1
2
3
4
5
6
readinessProbe:
httpGet:
path: /healthz?deep=true
port: 3000
periodSeconds: 10
timeoutSeconds: 3

/healthz?deep=true 的实现里,我们会检查:本地 session 目录可写、Anthropic API 可达(cached 30s)、MCP server 连接正常。

6. 日志 JSON 格式 + 脱敏 + trace_id

这三样缺一不可。

JSON 格式:便于 ELK/Loki 直接解析。

脱敏:我前面那篇提过,output 里可能带 API key、数据库密码、用户隐私。正则过滤是兜底,更好的做法是 hook 里主动标记字段。

trace_id:每个 session 绑定一个 trace_id,所有 log 都带上。配合 OTel 能实现”看到一条日志,跳转到完整 trace”。

7. 滚动发布的优雅中断

agent 跑长任务时(比如一个 15 分钟的 code migration),滚动升级直接 kill 会丢掉当前进度。

我们的做法:

  • pod 收到 SIGTERM 时,agent 先停止接受新任务
  • 当前任务跑完再退出
  • terminationGracePeriodSeconds 设到 300 秒(匹配最长任务预期)
  • 如果真的要强杀,session 会保留 checkpoint,新 pod 起来之后可以 resume

deployment 里的关键配置:

1
2
3
4
5
6
7
spec:
terminationGracePeriodSeconds: 300
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 0
maxSurge: 1

maxUnavailable: 0 保证滚动时服务容量不降。

8. 真实的 k8s deployment 片段

客户现场一份简化版:

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
apiVersion: apps/v1
kind: Deployment
metadata:
name: review-agent
spec:
replicas: 3
selector:
matchLabels:
app: review-agent
template:
metadata:
labels:
app: review-agent
spec:
terminationGracePeriodSeconds: 300
containers:
- name: agent
image: registry.internal/review-agent:v2.4.1
resources:
requests: {cpu: "500m", memory: "1536Mi"}
limits: {cpu: "2000m", memory: "3Gi"}
env:
- name: ANTHROPIC_API_KEY
valueFrom: {secretKeyRef: {name: claude-secret, key: api-key}}
- name: ANTHROPIC_MODEL
value: claude-sonnet-4-7
- name: CLAUDE_AGENT_SESSION_DIR
value: /data/sessions
volumeMounts:
- name: sessions
mountPath: /data/sessions
readinessProbe:
httpGet: {path: /healthz?deep=true, port: 3000}
periodSeconds: 10
livenessProbe:
httpGet: {path: /healthz, port: 3000}
periodSeconds: 30
failureThreshold: 3
volumes:
- name: sessions
persistentVolumeClaim: {claimName: agent-sessions}

不完整但能看明白大致结构。

9. PersistentVolume 的容量规划

session 目录占用会随时间线性增长。我的经验数据:

  • 一个活跃 agent pod 每天产生大约 2.3GB session 数据
  • 90% 数据在 7 天后就没人用了
  • 建议 PVC 容量 = 日增量 * 保留天数 * 1.5(1.5 是安全系数)

我们另外跑了个定时 job,每天凌晨把 30 天以上的 session 归档到 S3,释放 PVC 空间。

10. 网络策略:出站白名单

生产环境别让 agent 容器无限制访问外网。agent 理论上可能被 prompt injection 诱导发起外联。

我们的 NetworkPolicy 只允许:

  • api.anthropic.com:443
  • 内部 MCP server 的 IP 段
  • 内部 Git server
  • DNS(kube-dns)

其他全 deny。

11. 并发控制

Anthropic API 有速率限制。多实例并发跑 agent,一不小心就超限。

我们在 agent runner 里加了一层 token bucket,限制单实例对 API 的 QPS。集群层面再用 Redis 做分布式限流。两层兜底。

12. 成本监控和追踪

agent 是真的烧钱。没有成本监控,月底账单会吓死你。

我们每次 API 调用的 usage 信息(input_tokens、output_tokens、cache_read、cache_creation)全上报到 OTel,再在 Grafana 上算成本。

单个 review agent 实例日均 $0.47,单个 migration agent 日均 $2.13。集群总成本月均大概 $2800。有了这个数据才能做优化决策——比如是不是切一部分任务到 Haiku 能省钱。

我们还设了成本告警,单实例日成本超过基线 2 倍就 page。一般是 agent 陷入死循环或者 context 打爆 导致成本飙升。

13. 灾备:API 不可用时怎么办

Anthropic API 偶尔会抽风(不常,但发生过)。我们的兜底:

  • 首选:retry with exponential backoff,3 次后放弃
  • 次选:切换到 fallback 区域(如果合同里有多区域)
  • 最终:agent 标记任务为 pending_api,写队列等恢复

业务侧看到的是”任务排队中”,用户体验还能接受。

一点碎碎念

这 13 条不是一次性想出来的,是踩过坑之后沉淀下来的。有些坑可能你永远碰不到,有些坑我没踩过但你会踩到。

部署这事儿没有银弹,只有”少犯几次错”。每次出事故认真复盘,把它固化到流程和配置里,下次就能避开。

SDK 的可观测性那套 和部署配合起来,线上 agent 才算真正可以交给运维。

系列总结
Agent SDK 这个批次 5 篇到这里就收尾了。从上手、工具、session、观测到部署,基本覆盖了一个生产级 agent 系统要踩的主要坑。如果你正在搭 agent 系统,建议按这个顺序往下读:从入门开始
  • 标题: 把 Agent SDK 塞进生产容器:13 条部署清单
  • 作者: Claude 中文知识站
  • 创建于 : 2026-04-19 13:07:00
  • 更新于 : 2026-04-19 18:24:00
  • 链接: https://claude.cocoloop.cn/posts/agent-sdk-production-deploy/
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。
评论