拓十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Agent Substrate:在K8s之上为Agent补齐编排原语

Agent Substrate:在K8s之上为Agent补齐编排原语 Kubernetes 之父对谈 Agent Substrate为什么要在 K8s 之上给 Agent 造一层新原语这个话题乍一看是个标准的云原生新闻标题但拆开揉碎之后你会发现它其实在问一个非常要命的问题K8s 这套已经赢了十年的编排范式是不是真的可以直接拿给 Agent 用如果答案是不能那缺的那一层到底该怎么造、由谁来造、造完之后长什么样。我过去几年一直在做云原生基础设施相关的落地工作最近半年又开始重度接触 Agent 类应用。站在这个交叉点上我越来越认同一个判断K8s 和 Agent 之间不是能不能跑的问题而是跑得好不好、协作得顺不顺的问题。今天这篇文章我想从一个普通基础设施从业者的视角聊聊为什么 Agent 需要新的原语、K8s 到底给 Agent 留了哪些空以及Agent Substrate这件事现在做到哪一步了。1. 从容器调度到 Agent 协作编排对象的一次历史转向1.1 K8s 为什么会成为云原生操作系统先回到根上。Kubernetes 之所以能成为今天所有云厂商的默认底座不是因为它调度容器调度得多快而是它重新定义了运维接口。在 K8s 之前我们描述一个应用要写一堆启动脚本、健康检查、负载均衡配置、扩缩容策略在 K8s 之后你只需要写一个 YAML声明我要三个副本、每个副本监听 8080、内存上限 512Mi剩下的交给控制面。这个转变的本质是把命令式操作变成了声明式期望。你告诉系统目标状态系统自己想办法收敛到目标状态。Deployment 里的 replicas 字段就是最典型的例子它不是一个启动三个进程的指令而是一个永远保持三个副本的承诺。这个承诺由 ReplicaSet、Controller、etcd、kubelet 这一整套机制在背后背书。这套机制厉害到什么程度它把运维这种以前靠老师傅经验和人肉盯监控的活儿变成了一门可以在任何云上复用的工程学科。所以后来大家说 K8s 是云原生操作系统一点也不夸张。1.2 Agent 缺一个属于自己的控制平面但问题来了。当我们开始认真把 Agent 当作生产级应用来部署时你会发现这套操作系统并不完全适配 Agent 的生理结构。传统的服务是无状态的请求进来、处理、返回进程本身不保留对话记忆状态全部外置到数据库。所以 K8s 对传统服务的抽象非常精准——Pod 随时可以被杀掉重建因为只要是无状态杀了也无所谓。Agent 不一样。一个 Agent 实例背后挂着会话上下文、工具调用链路、多步推理的中间状态、甚至长期记忆库。今天很多团队跑 Agent 的方式本质上是把它当成一个有状态的长跑服务硬塞进 K8s然后用 Redis、Postgres、向量库在外面疯狂打补丁。这就好比你想盖一座桥却硬要用造独木舟的工具。不是工具不好是对象完全不匹配。Agent 需要的不只是调度容器而是调度对话、记忆和协作关系。这些东西在 K8s 的 API 对象里找不到对应物。1.3 原语这个词到底指什么聊到这儿必须把原语primitive这个概念说清楚不然很多人会以为这是一个装腔作势的学术词。原语简单理解就是系统提供给你的、不可再拆解的基础构件。K8s 里的 Pod、Service、Deployment、Ingress 都是原语。你不需要自己实现容器生命周期管理因为 Pod 帮你做了你不需要自己搞服务发现因为 Service 帮你做了。原语的意义在于把高频、复杂、容易出错的操作封装成低层的、语义清晰的、人人可用的接口。Agent Substrate 的核心主张就是要在 K8s 之上为 Agent 补充一组这样的原语。这些原语不再以容器为单位而是以任务Task、记忆Memory、工具Tool、代理Agent为单位。说白了就是把 Agent 世界里那些反复出现的模式沉淀成像 Pod 一样人人都会用、人人都按同一个规范来实现的东西。2. K8s 给 Agent 留了哪三个空2.1 身份与状态Controller Loop 对 Agent 太僵化先说最痛的一点K8s 的自动化模型是持续收敛而 Agent 的工作模式是临场发挥。K8s 的 Controller Loop 假设世界是这样的资源有期望状态和实际状态Controller 不断比较两者有偏差就纠正。这套模型处理无状态 Web 应用堪称完美——流量大了给你加副本Pod 死了给你重启配置变了给你滚动更新。但 Agent 呢Agent 的工作流程是一个带有目标导向性和不确定性的过程。它可能需要在对话中途暂停等用户确认某个操作再继续可能需要调用十几个工具每个工具的返回值都会改变它接下来的策略它可能运行两个小时也可能在第五步就发现目标不可达需要换一条路径。在这种情况下期望状态是什么实际状态又是啥你没法用 replicas 字段描述一个正在多步推理的 Agent。如果你强行让 Controller 按 K8s 那套逻辑去管 Agent只会有两种结果要么 Agent 被频繁重启导致对话上下文丢失要么你被迫把整个推理过程包在一个巨型 Pod 里、放弃弹性和可观测性。这就是第一个空Agent 缺一个能描述有状态、长周期、过程可变任务的运行时原语。2.2 通信模型Service 更像是寻址系统不是对话系统第二个空在通信层。K8s 的 Service 解决的是一个很经典的问题客户端怎么稳定地找到一组 Pod它通过 Label Selector 选出一组 Pod再通过 kube-proxy 或 DNS 做负载均衡本质上是一个静态寻址系统。但 Agent 之间的通信不是Client - Server那么简单而是Agent A - Agent B - Agent C 的协作文档有时是链式传递有时是广播通知有时还需要带上下文来回扯皮。这里面有两个 K8s 原生能力完全顾不上的诉求动态拓扑Agent 协作的网络结构不是固定的经常是先和数据分析 Agent 聊再决定要不要调任务规划 Agent这种关系由一个中心规划器动态生成。Service 的静态 selector 对这种运行时才决定和谁说话的场景毫无帮助。带记忆的会话Agent 之间的一次对话是连续的、有上下文状态的。Service 只管把请求转给一个后端它不保证同一个会话始终由同一个 Agent 实例处理也不保存任何中间语义状态。你完全可以在应用层自己做会话亲和sticky session但这对一个需要水平扩展、弹性伸缩的系统来说只是在给基础设施擦屁股。2.3 生命周期Pod 和 Job 都假设任务是有终点的第三个空是生命周期模型。K8s 提供的最长生命周期的对象是 Job / CronJob但 Job 的语义是执行完就结束。Agent 的任务往往不是执行完就结束而是执行到一个阶段后挂起等外部事件继续。举个例子一个采购 Agent 被指派找一个价格低于 5000 块的 GPU 云服务器。它查了十家云厂商发现都没有满足条件的于是它不应该结束而应该等待——等新机型上线等某个降价通知甚至等用户手动调整预算。这个等待可能持续几小时也可能持续几天。用 K8s 原生模型处理这种挂起-唤醒的任务非常别扭你可以用一个 Pod 在那儿 sleep但这是在浪费资源你也可以把任务拆成多段、每段一个 Job但中间状态怎么传、怎么管理、怎么重试全得自己造轮子。Agent Substrate 想补的恰恰是这种可暂停、可恢复、生命周期以业务目标为准的任务原语。3. Agent Substrate 在填的其实是三层协作协议聊完缺口再来看 Agent Substrate 具体在做什么。我把它拆成三层来讲这样你会发现它其实不是某个具体项目而是一整套设计思路。3.1 运行时层Agent 进程谁启动、怎么盯着最底层是运行时管理。Agent Substrate 不是要取代 K8s 的 Pod而是要在 Pod 之上定义一个新的 Workload 类型比如可以叫 AgentPod 或者 TaskRun。这种 Workload 的 CRD 大体长这样apiVersion: agent.run/v1alpha1 kind: Agent metadata: name: procurement-agent spec: model: provider: anthropic name: claude-sonnet-4 memory: maxTokens: 32000 storageClass: agent-mem tools: - name: cloud-vendor-api endpoint: http://cloud-vendor-service:8080 permissions: allowedActions: [query, compare, notify] lifecycle: suspendOnIdle: true resumeOn: [schedule, webhook]注意这里的变化它声明的不是镜像和副本数而是Agent 的模型、记忆、工具权限、生命周期策略。Controller 创建出来的也不是一个裸 Pod而是一个带持久化卷、带工具网关、带状态存储的复合执行单元。这就是我理解的运行时原语——它把 Agent 的很多通用能力模型接入、记忆挂载、工具调用权限从代码里抽出来放进声明式配置里。3.2 记忆与状态层把上下文和复盘做成持久化原语第二层是记忆与状态。这是 Agent Substrate 和传统调度器差别最大的一层。在 K8s 里状态是外置的数据库自己跑Pod 不碰数据。但在 Agent 场景里记忆就是 Agent 本身。一个没有记忆的 Agent 和一段无状态的 HTTP 接口没有任何区别。所以 Agent Substrate 里有一个类似于 PersistentVolumeClaim 的东西但它申请的不是一块磁盘而是一个记忆会话。这个记忆会话的典型结构大概是conversation_id: uuid thread: - role: user content: ... timestamp: ... - role: assistant content: ... tool_calls: [...] timestamp: ... long_term: - topic: cloud vendor pricing summary: as of 2025-Q3, vendor A is cheaper... last_updated: ...底层可以接向量库、Redis、或者普通 Postgres但这不重要。重要的是——记忆被抽象成了平台级能力而不是每个 Agent 自己额外搭一套的私活。以后你换掉底层记忆库Agent 代码一行都不用改。3.3 协作层从 MCP/编排协议到多 Agent 操作系统的内核第三层是协作。这一层目前是整个领域最活跃、也最混乱的部分。一方面大家已经在做标准化的尝试比如 MCPModel Context Protocol就是把Agent 如何调用工具这件事标准化OpenAI 后来推的 Agents SDK 又把Agent 如何编排子任务做了一层定义LangGraph 则在更上层提供了状态图和条件分支的抽象。但在 Agent Substrate 的理念里这些还不够——它们解决的是Agent 与工具和Agent 与子任务的协议问题但Agent 与 Agent之间公共基础设施还几乎是空白。一个多 Agent 系统里A 要委托任务给 B谁来负责任务路由谁持有任务状态的全局视图B 失败之后工作流状态如何回滚A 和 B 共用的记忆库如何避免脏读写这就需要一个类似于分布式事务协调器 消息队列 状态机的复合组件运行在每个 Agent Pod 的旁边负责它们之间的协作。在 Agent Substrate 的设计里每个 Agent 被拉起时会同时拉起一个 Sidecar这个 Sidecar 就是它的协作接口接收来自其他 Agent 的任务写入本地队列汇报自己的状态和进度到中心控制面在任务失败时向调度器申请重试或回滚。你可能会说这不就是把 Service Mesh 换了个马甲吗有那味但侧重点完全不同。Service Mesh 管的是流量Agent Substrate 的协作层管的是语义和状态它要理解任务完成和任务失败与HTTP 200 和 500之间的本质差异。流量层面的东西反而退居其次因为 Agent 之间的对话帧率不重要语义一致性才重要。4. 现在就想上车实操侧的三种姿势与踩坑预判理论聊再多都得落到能不能上手。以目前2025 年下半年Agent 基础设施的成熟度我总结出三条务实的接入路径大家可以根据自己的处境选择。4.1 姿势一用 CRD 扩展已有 K8s 集群最稳如果你团队里已经有一套 K8s并且你不想把 Agent 的编排逻辑写死在业务代码里我建议你从 CRD Operator 模式开始。用 Kubebuilder 或者 controller-runtime 定义一个你自己的 Agent CRD字段可以比我上面写的例子更精简先覆盖三个最高频的需求任务生命周期管理、记忆持久化、工具调用审计。写一个 Controller 去 watch 这个 CR 的变化一旦有人创建了一个 Agent 自定义资源你的 Controller 负责拉起对应的 Deployment/StatefulSet挂载记忆卷可以先用一个 PVC 怼着注册到这个 Agent 的路由表里报告 READY 状态。这一步的成本大概是一个中级工程师 1-2 周的工作量。但收益很大你团队里所有 Agent 项目从此有统一的部署形态和运维面板后续再加 Agent 不再需要从零写编排逻辑。我记得我第一次用 Kubebuilder 搭这类扩展时最容易被绕进去的是Controller 的 Reconcile 逻辑设计你要搞清楚哪些状态变化需要触发 Reconcile哪些不需要。如果你把每次记忆更新都当成一次 K8s 事件etcd 会被写爆Controller 会被活活累死。记忆同步应该走数据面不走控制面——这是我从那个坑里爬出来之后最深刻的心得。4.2 姿势二把 Agent 编译成次世代 Workload跑在集群上第二种姿势激进一点把 Agent 的运行时直接容器化但再加一层适配器让它能原生地使用 K8s 平台的调度、伸缩、观测能力。开源生态里已经有不少类似的尝试比如 Dapr 的 Actors 模型、以及一些专门面向 AI 工作负载的运行时项目。Dapr 的思路很值得参考你的 Agent 代码照写但把状态管理、发布订阅、Actor 激活/停用这些能力都通过 Sidecar 的 HTTP/gRPC API 暴露给业务代码。这样 K8s 依然负责最底层的容器调度而 Agent 能享受到的平台能力比裸跑在 Pod 里多得多。这种姿势的优点是渐进式你的业务代码可以一点点从硬编码的状态管理迁移到 Sidecar API不用推倒重来。缺点是 Sidecar 本身是个长期运行的 Pod资源占用不低内存普遍 200-500MB 起步而且目前这些项目大多还在快速迭代API 说变就变一不留神就得跟着升级做兼容。4.3 姿势三直接采用某个 Agent Substrate 项目最快但不一定最对第三种就是直接押注某个宣称要做 Agent 基础设施 的平台或开源项目比如一两年前洛林·张Lorin Zhang在 KubeCon 上演示过的一些 Agent 编排原型以及目前各类做 Agent Gateway、Agent Runtime 的创业项目。我的态度是可以密切关注但生产环境先别急着踩坑。原因很简单这个领域目前连Agent 的部署单元是什么都还没完全统一。你今天部署的平台可能半年后就改架构了。如果你只是一个普通业务团队你不太适合当小白鼠。我个人的建议是把姿势二作为主要路径用姿势一的 CRD 方式管理周边依赖然后持续跟踪姿势三那边有没有出现社区大量采用 接口稳定的信号等信号明确了再上也不迟。4.4 三个我预判一定会踩的坑最后分享几个我预判以及部分已经踩过的坑给你们提前打个预防针。坑一CRD 数量失控。这东西和微服务化一样一不留神就会设计出十几个 CRD。结果控制面复杂度爆炸一个集群里 run 着几百个 Controller-created 的资源谁是谁的依赖都说不清。我建议你在设计 CRD 时给自己立一条规矩能复用 K8s 原生对象的不要自己造。比如配置用 ConfigMap 就好状态用 Status 字段就好DataSource 挂载用 PVC 语义就好。坑二:LLM 返回不稳定导致 Reconcile 循环抖动。K8s 的收敛模型建立在结果可预期的基础上但 LLM 的输出天生有随机性。如果你让一个 Controller 根据 LLM 的返回去调节某个资源很可能陷入改了又改、永远收敛不了的循环。我的应对方案是**:在 Controller 和 LLM 之间加一个轻量的规则引擎或者策略层**LLM 只负责提出建议最终是否变更由确定性规则裁决这样既能保留智能又不会让集群状态反复横跳。坑三记忆存储的选择过早优化。我看过很多团队一上来就用向量数据库存全部记忆结果成本和运维复杂度直接起飞。实际上短期记忆用 Redis 就够了长期记忆里真正值得向量化的可能只有一成——那些需要语义检索的决策记录和背景知识。先按访问频率把记忆分热温冷三层再决定每层用什么存储你会省下大量冤枉钱。5. 边界与隐忧新原语会不会变成过度抽象聊了这么多新原语的好处我也得泼几盆冷水。Agent Substrate 这个方向我很认可但它并不天然正确甚至存在几个值得警惕的倾向。5.1 平台复杂性的螺旋上升加一层抽象解决眼前的问题往往是在为未来制造新的复杂度。K8s 本身就是最好的例子——它解决了单体脚本时代的问题但代价是控制面的复杂度高到只有专业团队才玩得转以至于后来催生了K8s 太复杂我们要 Serverless的反弹。Agent Substrate 如果只是把容器编排升级成任务编排最终很可能陷入同样的困境CRD 越写越厚Controller 越写越重Sidecar 一个接一个。我特别担心的一点是很多团队会把多 Agent 协作这个配置密集型的工作搞成比手写业务流程还要复杂的 YAML 瀑布。能不能避免可以前提是新原语必须真正减少重复劳动而不是把重复劳动搬个家。比如记忆持久化确实减少了每个 Agent 项目自己接数据库的工作这就是有效抽象但如果某个原语只是把原来的一个步骤拆成五个步骤那它就是过度设计。5.2 安全审计的空白期另一个绕不开的问题是安全。传统 K8s 环境里网络策略、RBAC、PodSecurityContext 是一套相对成熟的体系。但 Agent 的权限模型完全不同——一个 Agent 可能被赋予调用云 API 的权限、读写内部知识库的权限、甚至执行财务操作的权限。这些权限如果只是映射成 K8s 的 RBAC 角色粒度完全不够。我见过的 Agent 攻击面有两个尤其需要关注工具调用链的提权一个本来只有只读权限的 Agent在推理过程中可能会调用另一个有写权限的工具如果工具网关不校验调用来源这就是一条提权路径。Agent Substrate 在做工具原语时必须把谁在用这个工具、工具调用的可追溯性作为一等公民。记忆投毒如果恶意用户能在你共享的记忆库里塞入虚假信息Agent 在后续推理时就可能把错误信息当作事实使用导致输出幻觉变成认知污染。这个风险已经被安全团队注意到了比如 a-memguard 等防御框架的出现说明大家已经开始正视它。5.3 标准化未定别把项目写成时代的眼泪最后是一个很现实的问题标准化。K8s 之所以成为今天的 K8s是因为有 CNCF 背书有 Google 拉着各大厂商一起搞。而 Agent Substrate 目前还处在各说各话的战国时代——你家的 Memory API 和我家的完全对不上他家的 Agent CRD 和我的 Controller 根本没法互通。这种情况下押错宝的代价很大。我观察到有些团队已经在做选择有的是 Dapr LLM 混合有的是在 LangGraph 的 graph 定义外面再包一层 K8s CRD有的干脆自己造轮子。我觉得这会是一个持续两到三年的混沌期等到 MCP 这类协议被大规模接纳、几个头部开源项目形成事实标准之后赛道才会逐渐清晰。在那之前我的建议是接口多用标准开放的实现尽量薄别把自己绑定在任何一家私有 API 上。6. 说点我个人看法聊到最后聊聊我自己对这个方向的真实感受。我确实经历过一个转变。最早我做云原生相关工作天天在琢磨 Pod、Deployment、Helm Chart满脑子都是编排一切的冲动。当时看 Agent 类的应用总觉得它们是花架子——不就一个 LLM API 套壳吗有什么好编排的直到我真的开始把一些业务逻辑交给 Agent 去跑比如让它自主调研竞品价格、生成报告、并且根据结果触发内部工单流转我才意识到问题比我想象的复杂得多。Agent 最难的不是写 Prompt而是怎么让这个有自主性的东西在一条负责任、可审计、可回滚的轨道上工作。这恰好是基础设施层最应该解决、而现有 K8s 完全没有解决的问题。所以我对 Agent Substrate 这类方向的评价是方向对了路还长。K8s 当年的成功很大程度上是因为它把分布式系统运维这一混乱领域标准化了。Agent 的编排、记忆、协作协议现在也是一片沼泽谁能在保持工程简洁的前提下把这片沼泽填成马路谁就握住了下一代基础设施的船票。最后再分享一个我自己踩过记忆存储坑之后的实操经验。如果你现在就打算在自己的 K8s 集群里小规模试跑 Agent 工作负载不用急着引入任何新平台。最快的起步方案是一个 StatefulSet 挂 PVC 存短期会话一个 Postgres 存长期决策记录一个简单的 Restful 接口把 Agent 的每个决策点暴露出来打日志。先用这套最朴素的组合把 Agent 跑起来等你真的遇到三个 Agent 抢同一份记忆或者任务挂起就忘了唤醒这类问题了再开始研究要不要上 Substrate。到时候你会比那些追着热度走但从未被问题教育过的人更能辨清哪些原语是刚需哪些只是新瓶装旧酒。
返回列表