
1. 从“ax”这个标题说起一个被低估的运行时编排命题第一次看到“ax”这个标题很多人会一头雾水——两个字母既不像产品名也不像技术栈缩写。但把热搜词摊开来看线索就清楚了agentic、orchestration、runtime、Kubernetes这几个词反复出现再加上“karmada正式毕业”“agentic cloud坚实底座”这类行业动态基本可以判断这里讨论的“ax”指向的是Agentic eXecution这一类命题——也就是在 Kubernetes 之上如何把一堆各自为政的智能体Agent组织成一个能稳定跑起来的运行时系统。我先把话说在前面这不是一篇讲某个具体开源项目 API 的文档而是一份从工程视角出发的拆解笔记。核心问题是——当你想把“agentic orchestration”真正落到 Kubernetes 上时会遇到哪些坑运行时该怎么设计调度该怎么分层以及为什么很多人第一步就走错了。适合谁看如果你正在做 AI Agent 平台、多智能体协作系统、或者想把 LLM 驱动的任务流跑在容器编排层上这篇内容对你有用。如果你只是听说过“agentic”这个词但没动过手也能从中拿到一套可落地的思路。全文我会尽量用大白话把原理讲透参数和步骤能给到的都给到踩过的坑也会如实说。先给一个整体判断Agentic Runtime 的本质不是“把 Agent 塞进 Pod”而是重新定义“谁来决定下一步做什么”。传统 Kubernetes 的调度是声明式的、静态的而 Agent 的执行是探索式的、动态的。这两者的矛盾就是所有工程难点的根源。理解了这一点后面所有的设计取舍都能自洽。2. 核心概念拆解ax、agentic、orchestration、runtime 到底各指什么2.1 ax 的两种可能解读与我的判断“ax”在技术语境里至少有两条线索。一条是Agent eXecution即智能体执行层另一条是Abstract eXecutor即抽象执行器。结合热搜词里 agentic、orchestration、runtime 的高频共现我倾向于前者——它描述的是一套面向 Agent 的执行框架而不是某个单点工具。为什么这么判断因为“orchestration”和“runtime”这两个词放在一起时通常指向的是控制平面 数据平面的组合。Orchestration 负责“决定做什么、按什么顺序做”Runtime 负责“实际把活干出来”。这两层分开是成熟系统的标志。如果 ax 只是一个执行器那它不需要和 orchestration 并列出现。所以我的工作假设是ax 一套 Agentic 执行运行时向上承接编排决策向下管理容器化/进程化的 Agent 实例。这个假设贯穿全文如果你手上的 ax 是别的含义把类比替换掉即可方法论是通用的。2.2 agentic 不是“用了 LLM”而是“具备自主决策闭环”很多人把 agentic 等同于“调用了大模型”这是最大的误解。一个系统称得上 agentic至少要满足三个条件有目标不是被动响应一次请求而是围绕一个目标持续行动有决策能根据中间结果选择下一步动作而不是走固定流程有反馈闭环执行结果会回流影响后续决策用生活化的类比普通 API 调用像自动售货机投币出货一次结束agentic 系统像派出去办事的助理你给个目标他自己规划路线、遇到问题绕路、办完回来汇报。这个差别决定了运行时设计完全不同——售货机不需要“记忆”助理需要。2.3 orchestration 与 runtime 的职责边界这两个词经常被混用但在工程上必须分清否则架构会糊成一团。我用一张表说清楚维度Orchestration编排层Runtime运行时层核心职责决定任务拆解、执行顺序、依赖关系实际执行单个 Agent/任务单元状态关注全局状态、任务图单实例状态、资源占用失败处理重试策略、补偿、回滚进程崩溃恢复、超时终止典型实现工作流引擎、DAG 调度器容器运行时、进程管理器时间尺度秒级到小时级毫秒级到分钟级注意把编排逻辑写进运行时是新手最常见的架构错误。一旦运行时开始“思考下一步”它就不再是运行时而变成了一个失控的编排器。2.4 为什么 Kubernetes 成了默认底座热搜里 Kubernetes 出现频率极高还有“karmada 正式毕业”这样的动态说明大家默认把 K8s 当作 Agentic Cloud 的底座。原因很实在调度能力现成Pod 调度、亲和性、资源配额不用重造隔离机制成熟namespace、cgroup、网络策略天然适合多租户 Agent生态完整监控、日志、服务发现全都有但 K8s 有个根本性错配它是为“长期稳定的服务”设计的而 Agent 是“短时突发的任务”。一个 Agent 可能跑 3 秒就结束也可能跑 3 小时还在等外部 API。这种不确定性是后面所有问题的源头。3. 架构设计把 Agentic 编排落到 K8s 上的分层思路3.1 三层架构控制面、编排面、执行面我在实际项目里验证过一套分层效果比较稳分享出来控制面Control Plane负责 Agent 注册、能力描述、权限管理。这一层不碰具体任务只管“有哪些 Agent 可用、它们能干什么”编排面Orchestration Plane接收用户目标拆解成任务图决定调用哪些 Agent、按什么顺序执行面Execution Plane每个 Agent 实例跑在这里对应 K8s 里的一个 Pod 或一组 Pod这样分的好处是编排逻辑变了不用动执行层执行层换实现比如从容器换成微虚拟机编排层无感。解耦带来的可维护性在 Agent 数量上到几十个之后会非常明显。3.2 为什么不用原生 K8s Job 直接跑 Agent有人会问K8s 不是有 Job 和 CronJob 吗直接拿来跑 Agent 不行吗我试过能跑但很快会遇到三个问题Job 是一次性的Agent 往往需要多轮交互中途还要保持上下文Job 的“跑完即止”模型不匹配状态无处安放Agent 的中间记忆、对话历史放 Pod 里一重启就没了放外部存储又要处理并发调度粒度太粗Job 调度的是 Pod但 Agent 调度需要的是“能力匹配”比如“找一个会调数据库的 Agent”这超出了 K8s 原生调度器的语义所以我的做法是用 K8s 管生命周期用自定义控制器管 Agent 语义。K8s 负责把 Pod 拉起来、保证它活着控制器负责决定“这个 Pod 里应该跑哪个 Agent、给它什么上下文”。3.3 状态管理的取舍外部化还是本地化Agent 的状态分两类会话状态对话历史、中间结果和执行状态当前步骤、重试次数。这两类的处理方式完全不同。会话状态我建议外部化放到 Redis 或专门的向量库里。理由是 Agent 可能被调度到任意节点本地状态无法跟随。执行状态可以本地化放在 Pod 的内存里因为它是短时的丢了重跑即可。这里有个参数经验会话状态的 TTL 我一般设30 分钟到 2 小时取决于业务。太短会导致长任务上下文丢失太长会撑爆存储。实测下来大部分 Agent 任务的活跃窗口在 15 分钟内超过 1 小时还在跑的通常是卡在等外部响应这时候应该考虑超时而不是无限等待。3.4 调度策略能力匹配优先于资源匹配K8s 默认调度看的是 CPU、内存这些资源。但 Agent 调度真正关心的是能力——这个 Agent 会不会用某个工具、能不能访问某个数据源。我的做法是在 Pod 上加自定义标签比如agent.capability/db-query: true然后写一个调度器扩展Scheduler Extender或者干脆用自定义控制器做二次调度。这样当编排层说“需要一个能查数据库的 Agent”时能精准命中。提示能力标签不要设计得太细否则标签爆炸。我的经验是控制在 3 层以内比如capability/tool/db再细就用注解annotation而不是标签。4. 实操落地从零搭一个最小可用的 Agentic Runtime4.1 环境准备与版本选择先说版本。热搜里出现了kubernetes version: v1.26.0这是个比较稳的版本我实测过 1.26 到 1.28 都能跑这套方案。再新的版本要注意 API 弃用问题比如一些 beta API 被移除。基础组件清单Kubernetes 集群1.26单节点也能跑通验证容器运行时containerd 或 CRI-O别用已经废弃的 dockershimRedis会话状态一个自定义控制器框架我用 kubebuilder也可以用 operator-sdk注意热搜里那条container runtime is not running的报错八成是 containerd 服务没起来或者 kubelet 配置里的 socket 路径不对。排查顺序是先systemctl status containerd再看/var/lib/kubelet/kubeadm-flags.env里的--container-runtime-endpoint指向是否正确。4.2 定义 Agent 的自定义资源CRD核心是定义一个 Agent 资源。我用的字段结构大致如下apiVersion: ax.example.com/v1 kind: Agent metadata: name: db-query-agent spec: image: registry.example.com/agents/db-query:1.2.0 capabilities: - tool/db - tool/sql maxConcurrency: 5 timeoutSeconds: 300 stateStore: type: redis endpoint: redis://state-svc:6379 status: phase: Ready activeInstances: 2字段说明几个关键的capabilities是给调度器看的maxConcurrency控制单个 Agent 能同时处理多少任务timeoutSeconds是硬超时防止 Agent 卡死。为什么要有maxConcurrency因为 Agent 背后往往是一个 LLM 服务并发太高会打爆下游。我一般按下游 QPS 除以单次调用耗时来估算比如下游能扛 100 QPS单次调用 2 秒那并发上限大概 50留点余量设 40。4.3 编写控制器让 Agent 资源真正跑起来控制器要做的事监听 Agent 资源变化确保对应数量的 Pod 在运行并把 Pod 的状态回写到 Agent 的 status 里。核心逻辑用伪代码表示func (r *AgentReconciler) Reconcile(ctx, req) { agent : fetchAgent(req) desired : agent.Spec.MaxConcurrency current : countRunningPods(agent) if current desired { createPod(agent, buildPodSpec(agent)) } else if current desired { deleteExcessPods(agent, current-desired) } updateStatus(agent, current) }这里有个坑Pod 创建是异步的你刚创建完下一次 Reconcile 时它可能还没 Running导致重复创建。解决办法是用OwnerReference加GenerateName让 K8s 保证幂等同时在控制器里做去重判断。4.4 编排层的任务图执行编排层我建议用 DAG 来表达任务依赖。一个典型的目标拆解后长这样目标分析上周销售数据并生成报告 ├─ 任务1拉取销售数据Agent:>