在 Kubernetes 上运行 AI Agent,最直觉的设计是“一个 Agent 一个 Pod”。但 Agent 往往具有突发性、短生命周期、可派生子 Agent,以及等待人工审批等特征。把这些逻辑实体直接绑定到 Pod,会让调度、扩缩容和资源利用都变得笨重。
kagent 项目提出了一个值得借鉴的方向:Pod 更适合承担长期运行的 Worker,而不是代表每一个逻辑 Agent。Agent-substrate 则进一步引入控制平面,把逻辑上的 Actor 调度到长期存活的 Worker Pod 上。
Pod 不是 Agent 的天然边界
Pod 是 Kubernetes 的部署与资源调度单元,适合承载持续运行的进程。AI Agent 却更像一次次被触发的工作单元:它可能只处理几秒钟的请求,也可能在执行过程中创建子任务,然后等待用户确认或外部系统回调。
如果采用一个 Agent 一个 Pod,常见问题包括:
- 大量短任务导致 Pod 频繁创建、销毁和重新调度。
- Agent 在等待人工批准时仍然占用 Pod 的 CPU、内存以及调度位置。
- 子 Agent 的数量不可预测,容易把 Pod 数量直接推高。
- 每个 Pod 都需要携带运行时、网络、日志和监控开销。
- Agent 的业务生命周期与 Pod 的基础设施生命周期被强行绑定。
这并不意味着 Agent 不能使用 Pod。更合理的边界是:Pod 提供稳定的执行环境,Agent 作为可以被调度、暂停、恢复和回收的逻辑 Actor 运行在其中。
Actor 与 Worker 如何分工
可以把这套模型拆成两层:
- Actor:代表一个逻辑 Agent 或一次 Agent 会话,保存任务状态、上下文、权限和等待条件。
- Worker Pod:长期运行的执行进程,负责接收 Actor 的工作、调用模型和工具,并返回事件或结果。
- 控制平面:负责 Actor 排队、分配、重试、暂停、恢复和释放 Worker。
这样,Worker Pod 的数量可以根据并发量和资源类型进行相对稳定的管理,而 Actor 数量可以独立增长。一个 Worker 可以先后处理多个 Actor;当任务等待人工审批时,控制平面可以释放执行槽位,让其他 Actor 使用同一个 Worker 集群。
这种架构也更适合处理子 Agent。父 Actor 创建子 Actor 后,控制平面可以按照优先级、租户、模型类型或工具权限进行调度,而不必为每个子 Agent 立即创建一个新的 Pod。
一个可改造的最小实现
下面的 YAML 是一个概念性 Worker 部署示例,假设 Worker 镜像提供了一个内部调度接口。它不是某个具体项目的固定 API,但可以作为实现 Agent Worker 池的起点。
运行前需要把 example/agent-worker:latest 替换为实际镜像,并根据环境补充模型服务地址、密钥和队列配置。
apiVersion: apps/v1
kind: Deployment
metadata:
name: agent-worker
labels:
app: agent-worker
spec:
replicas: 3
selector:
matchLabels:
app: agent-worker
template:
metadata:
labels:
app: agent-worker
spec:
containers:
- name: worker
image: example/agent-worker:latest
ports:
- name: http
containerPort: 8080
env:
- name: ACTOR_QUEUE
value: agent-actors
- name: WORKER_CONCURRENCY
value: "8"
resources:
requests:
cpu: "500m"
memory: "512Mi"
limits:
cpu: "2"
memory: "2Gi"
readinessProbe:
httpGet:
path: /ready
port: http
periodSeconds: 5
---
apiVersion: v1
kind: Service
metadata:
name: agent-worker
spec:
selector:
app: agent-worker
ports:
- name: http
port: 8080
targetPort: http
可以这样部署并检查 Worker 池:
kubectl apply -f agent-worker.yaml
kubectl rollout status deployment/agent-worker
kubectl get pods -l app=agent-worker
在这个模型中,Actor 不应该通过 Kubernetes API 创建 Pod。一个简化的控制平面可以只把 Actor 放入队列:
curl -X POST http://actor-control-plane.example/actors \
-H 'Content-Type: application/json' \
-d '{
"actor_id": "support-session-42",
"task": "分析订单退款请求",
"priority": "normal",
"requires_human_approval": true
}'
Worker 从队列领取 Actor 后执行任务。遇到人工审批时,它提交一个暂停事件并释放并发槽位;审批完成后,控制平面重新投递 Actor,并由任意可用 Worker 恢复执行。真正落地时,还需要为 Actor 状态选择可靠存储,并设计幂等键、租约、超时和重试策略。
这种设计的收益与代价
Worker 池可以减少 Pod 抖动,并把 Kubernetes 资源管理与 Agent 业务调度分开。模型服务、工具访问、租户隔离和优先级策略也能集中放到控制平面或 Worker 的运行时中处理。
但这不是免费抽象。系统需要额外维护:
- Actor 状态机,以及运行中、等待审批、失败和已完成等状态。
- Worker 租约和心跳,避免 Worker 故障后任务永久卡住。
- 任务幂等与恢复,防止网络重试导致工具被重复调用。
- 隔离边界,避免不同租户的 Actor 在同一个 Worker 上意外共享上下文或凭据。
- 可观测性,把 Actor ID、任务 ID 和 Worker Pod ID 关联到日志、指标和链路中。
对于需要强隔离、固定依赖或不可信代码执行的任务,单独 Pod 甚至独立 Job 仍然可能是更好的选择。Actor/Worker 并不是替代所有 Kubernetes 工作负载,而是针对 Agent 高并发、突发和长等待特征提供另一种部署边界。
采用前的检查清单
可以从以下问题开始评估:
- Agent 是否经常短时间完成,或大量时间处于等待状态?
- 一个进程是否能够安全地轮换处理多个 Actor?
- Actor 状态是否能在 Worker 重启后恢复?
- 子 Agent 是否需要独立的权限、网络和资源配额?
- 哪些任务必须获得独立内核、文件系统或 Pod 级别的安全隔离?
- 控制平面是否能够处理重复投递、Worker 故障和人工审批超时?
如果答案显示 Agent 的业务生命周期明显短于基础设施生命周期,那么“长期运行的 Worker Pod 加逻辑 Actor”通常比“每个 Agent 一个 Pod”更贴近实际运行特征。关键不是减少 Pod 数量本身,而是让 Kubernetes 管资源,让控制平面管 Agent 的生命周期。