别把每个 AI Agent 都做成一个 Pod:Kubernetes 上的 Actor 与 Worker 思路

2026-08-06 53 预计阅读时间: 1 分钟
来源: infoq.com AI 摘要 Original link

Disclaimer: This article is an AI-assisted summary. Read it together with the original source when precision matters. The summary may omit context, version differences, or edge cases and is not official documentation.

预计阅读时间:8 分钟

在 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 的生命周期。


相关推荐