
1. 从能跑到跑得住云端智能体的基础设施缺口到底在哪过去一年我参与过三个不同规模的智能体项目落地从最初在本地笔记本上跑通一个能查资料、能调工具的小助手到后来把它塞进容器里、挂到集群上、接上真实业务流量中间踩的坑几乎全部集中在同一个地方——基础设施。模型能力本身反而没怎么拖后腿真正让人半夜爬起来看告警的是运行时环境、沙箱隔离、资源调度和状态管理这些脏活累活。这个现象其实很普遍。现在大家聊智能体注意力大多集中在框架选型、提示词工程、工具编排上这些确实重要但它们解决的是智能体能不能完成任务的问题。而一旦你要让智能体在云端持续对外提供服务面对的是另一类问题它会不会因为一次工具调用超时把整个进程拖死多个用户会话之间会不会互相污染上下文一个失控的循环会不会把集群的 CPU 吃满这些问题的答案不在智能体框架里而在它脚下的基础设施里。我把这类问题统称为扩展瓶颈。注意这里的扩展不只是横向加机器那么简单它包含三个维度单实例的稳定性扩展从跑一次到跑一万次不出错、并发维度的扩展从单用户到多租户、以及能力维度的扩展从单一工具到复杂工具链。这三个维度对基础设施的要求完全不同但很多团队在早期只考虑了第一个等到用户量上来才发现后两个才是真正的深水区。这篇文章想做的事情是把云端智能体需要什么样的基础设施这个问题拆开讲透。我会从运行时环境、沙箱隔离、编排调度、状态与可观测性几个层面结合 Kubernetes 这类成熟基础设施的实践讲清楚每个环节为什么需要、怎么做、以及我实际踩过的坑。目标读者是那些已经能让智能体跑起来、但正准备把它推向生产环境的工程师如果你还在本地调试阶段也可以先看看提前避坑。提示本文讨论的云端智能体指的是以服务形式对外提供、需要处理真实并发请求的智能体系统不包括纯本地运行的实验性脚本。两者的基础设施诉求差异极大。2. 运行时环境为什么在我机器上能跑在云端必然翻车2.1 智能体运行时的特殊性它不是一个普通的 Web 服务普通 Web 服务的运行时行为是相对确定的接收请求、查数据库、返回响应整个链路的资源消耗和耗时基本可预测。智能体完全不是这个路子。一个智能体处理一次请求内部可能经历思考—调用工具—观察结果—再思考的多轮循环每一轮的耗时、内存占用、外部依赖都是动态的。更麻烦的是这个循环的轮数在运行时才能确定极端情况下可能因为工具返回异常而陷入反复重试。这意味着智能体的运行时环境必须能容忍不确定的执行时长和不确定的资源峰值。我见过一个案例某个智能体在处理一份复杂文档时因为工具返回格式不符合预期连续重试了四十多次单次请求的 CPU 占用从正常的 5% 飙到 90%持续了将近两分钟。如果这个进程和主服务共享资源整个服务都会被拖垮。所以第一件事就是给智能体一个独立的、可限制的运行时边界。这个边界要能回答几个问题这个智能体最多能用多少 CPU 和内存它最多能跑多久它崩溃了会不会影响别人在 Kubernetes 的语境下这些对应的是 ResourceQuota、LimitRange、Pod 的 resources 配置以及 activeDeadlineSeconds 这类机制。2.2 依赖地狱Python 版本、系统库与工具链的版本锁定智能体项目对依赖的敏感度比普通服务高得多。原因在于它往往要同时集成多个来源的工具有的工具依赖特定版本的 Python 库有的需要调用系统命令行工具有的要加载特定版本的模型推理库。这些依赖之间经常打架。我印象最深的一次是某个智能体需要同时用到一个较新的向量检索库和一个较老的文档解析库前者要求 Python 3.10 以上后者的某个底层依赖在 3.10 上有兼容问题。本地开发时因为环境是逐步搭建的凑合能跑一打成镜像部署到集群直接起不来。解决这类问题的核心思路是把运行时环境当成不可变制品来管理。具体做法用多阶段构建multi-stage build把构建依赖和运行依赖彻底分开最终镜像只保留运行必需的内容。所有依赖版本在锁文件里写死包括间接依赖不要依赖最新版。系统级依赖如某些命令行工具、字体、证书显式安装并记录版本不要假设基础镜像里有。镜像构建后做一次冷启动冒烟测试在一个干净容器里跑一遍核心链路确认没有隐藏的本地依赖。这里有个容易被忽略的点智能体经常需要动态安装或加载工具。有些框架支持运行时注册新工具如果这个工具需要额外的系统依赖而镜像里没有就会在运行时失败。我的建议是生产环境的智能体工具集应该是构建期确定的运行时只做加载不做安装。如果业务上确实需要动态扩展那也要走预置一批可选工具镜像的路子而不是让智能体在运行时随意装东西。2.3 冷启动与预热别让第一个用户等太久智能体服务有个特点冷启动特别慢。加载模型、初始化向量库连接、预热工具链这些加起来可能几十秒甚至几分钟。如果按普通 Web 服务的思路做弹性伸缩用户请求打过来时 Pod 还在初始化体验会非常糟糕。我在一个项目里用过几种应对方式各有取舍方式做法优点代价常驻最小副本始终保持至少 N 个已预热副本响应快资源常驻成本就绪探针精细化readinessProbe 检查真实可用性而非端口避免流量打到未就绪实例探针逻辑要写对启动预热脚本容器启动后主动跑一遍核心链路提前暴露问题延长启动时间镜像分层缓存把模型和依赖放在不常变的基础层加速拉取镜像管理复杂实测下来常驻最小副本 精细化就绪探针的组合最稳。就绪探针不要只检查端口通不通要真正调用一次轻量级的健康检查接口确认模型已加载、工具链可用。我见过太多因为探针写得太简单导致流量打到半初始化实例上的事故。注意就绪探针的检查逻辑本身不能太重否则会拖慢整个调度。建议用一个专门的轻量健康检查端点只验证关键依赖的可用性不要跑完整业务链路。3. 沙箱隔离智能体执行不可信代码的最后一道防线3.1 为什么智能体必须要有沙箱智能体和普通服务的根本区别在于它会执行自己生成的代码或命令。这是它强大的地方也是它危险的地方。一个能写代码、能调 shell 的智能体如果没有任何隔离理论上可以读取宿主机上的任意文件、发起任意网络请求、消耗任意资源。这不是危言耸听。我在测试环境里就遇到过智能体因为理解错了任务生成了一个递归删除文件的命令。幸好当时跑在隔离环境里否则后果不堪设想。所以沙箱不是锦上添花而是生产环境的硬性要求。沙箱要解决的核心问题有三个文件系统隔离它只能看到自己该看的、网络隔离它只能访问允许的地址、资源隔离它不能吃光宿主机资源。这三个维度缺一不可。3.2 从容器到微虚拟机隔离强度的阶梯很多人第一反应是用 Docker 容器做沙箱。容器确实方便启动快、生态好但它的隔离强度是有限的——共享内核意味着存在逃逸风险对于执行完全不可信代码的场景容器级别的隔离往往不够。我把常见的隔离方案按强度排个序供选型参考普通容器隔离最弱共享内核适合执行相对可信的代码。启动最快开销最小。加固容器配合 seccomp、AppArmor、只读根文件系统、非 root 用户等手段隔离强度提升明显是很多场景的性价比之选。用户态内核如 gVisor 这类方案在应用和内核之间加一层拦截系统调用隔离强度接近虚拟机但启动比虚拟机快。微虚拟机如 Kata Containers 这类方案每个沙箱一个轻量虚拟机隔离强度最高启动开销介于容器和传统虚拟机之间。选哪个取决于你的智能体要执行什么。如果只是跑一些受限的表达式求值加固容器足够如果要执行用户提交的任意代码微虚拟机或用户态内核更稳妥。我在实际项目里的做法是分层常规工具调用走加固容器高风险代码执行走微虚拟机两套运行时并存按任务类型路由。3.3 沙箱的生命周期管理创建、复用与回收沙箱不是创建完就完事了它的生命周期管理是个精细活。创建太慢影响体验复用不当导致状态污染回收不及时浪费资源。我总结的几个实践要点沙箱池化预先创建一批空闲沙箱请求到来时直接分配避免每次现创建。池的大小根据并发峰值和创建耗时来定一般保持在峰值并发的 1.2 到 1.5 倍。一次性 vs 可复用执行不可信代码的沙箱建议一次性使用用完即销毁杜绝状态残留执行可信工具调用的沙箱可以复用但要确保每次调用前清理工作目录和环境变量。超时强制回收每个沙箱都要有硬性超时到点无论任务是否完成都强制销毁。这个超时要比业务预期的最长执行时间留出余量但不能无限长。资源配额硬限制CPU、内存、磁盘、进程数、文件描述符都要设上限防止单个沙箱拖垮节点。这里有个坑我踩过沙箱池化时如果回收逻辑有 bug会导致沙箱被泄漏——既不在池里也不被销毁慢慢把节点资源吃光。解决办法是给每个沙箱打上创建时间戳后台有个清理任务定期扫描超期未回收的沙箱强制清理。3.4 网络策略默认拒绝按需放行沙箱的网络访问必须严格控制。默认应该是全部拒绝只放行明确需要的地址。这一点在 Kubernetes 里可以用 NetworkPolicy 实现但要注意它依赖 CNI 插件的支持不是所有集群都默认生效。具体策略上我一般这样设计沙箱默认不能访问集群内部服务防止它探测内网。只允许访问明确的外部 API 地址且最好通过一个代理层统一出口方便审计和限流。禁止沙箱访问云厂商的元数据服务地址这是很多安全事件的入口。DNS 解析也要限制避免通过 DNS 做数据外泄。提示网络策略配置完一定要实测验证不要假设它生效了。我见过因为 CNI 插件不支持导致 NetworkPolicy 形同虚设的情况测试方法很简单从沙箱里尝试访问一个应该被拒绝的地址看是否真的被拦。4. 编排与调度Kubernetes 能做什么不能做什么4.1 Kubernetes 是智能体基础设施的好底座但不是开箱即用Kubernetes 提供了容器编排的通用能力调度、伸缩、自愈、服务发现、配置管理。这些能力对智能体服务同样适用所以把它作为底座是合理的选择。但智能体有一些特殊诉求Kubernetes 的原生能力覆盖不到需要额外设计。最典型的几个缺口任务级调度智能体的执行单元往往是一次任务而非一个长期存活的进程Kubernetes 原生更擅长管理长期服务对短生命周期、高频创建销毁的任务支持需要借助 Job 或自定义控制器。会话亲和性多轮对话场景下同一会话的请求最好落到同一个实例上避免上下文反复加载。这需要会话粘性或者外部状态存储来配合。异构资源智能体可能同时需要 CPU、GPU、大内存等不同资源调度策略要能表达这些约束。快速弹性智能体的负载波动可能很剧烈原生 HPA 基于 CPU/内存的伸缩往往滞后需要结合自定义指标。4.2 用自定义资源定义智能体的任务抽象在 Kubernetes 里管理智能体一个有效的做法是用 CRD自定义资源定义把智能体任务抽象出来。比如定义一个 AgentTask 资源包含任务类型、输入、资源需求、超时等字段然后写一个控制器监听这些资源负责创建对应的沙箱 Pod、监控执行、收集结果、清理资源。这样做的好处是把智能体的业务语义和 Kubernetes 的编排能力解耦。业务侧只需要提交 AgentTask不用关心底层是 Pod 还是别的什么基础设施侧可以独立演进调度策略不影响业务。控制器的核心逻辑大致是监听 AgentTask 的创建事件。根据任务类型和资源需求从沙箱池里分配或新建一个执行环境。把任务输入注入执行环境启动执行。监控执行状态处理超时和异常。收集结果写回 AgentTask 状态清理执行环境。这套模式我在两个项目里用过扩展性和可维护性都不错。难点在于控制器的健壮性——要处理各种边界情况比如执行环境创建失败、任务执行中途节点宕机、结果收集超时等。建议用成熟的控制器框架来写不要从零造轮子。4.3 调度策略把合适的任务放到合适的节点智能体的任务类型差异很大有的吃 CPU有的吃内存有的需要 GPU有的对网络延迟敏感。把它们无差别地丢给调度器资源利用率会很差。我的做法是给节点打标签给任务设节点亲和性。比如GPU 节点专门跑需要模型推理的任务。大内存节点跑文档处理类任务。普通节点跑轻量的工具调用任务。同时配合污点和容忍度防止不合适的任务被调度到专用节点上。这套组合用好了资源利用率能提升不少。另外优先级和抢占也要考虑。交互式的用户请求应该比后台批处理任务优先级高资源紧张时能抢占后者的资源。Kubernetes 的 PriorityClass 可以表达这个但要配合调度器的抢占策略一起调。4.4 弹性伸缩别只盯着 CPU 利用率前面提过智能体的负载特征和普通服务不同基于 CPU 的 HPA 经常反应迟钝。更合理的做法是结合业务指标做伸缩比如待处理任务队列长度、平均任务等待时间、活跃会话数。实现上可以用 KEDA 这类基于事件驱动的伸缩组件它支持从消息队列、数据库等来源读取指标来驱动伸缩。我用它对接过任务队列效果比原生 HPA 好很多尤其是应对突发流量时。但弹性伸缩有个前提实例要能快速启动。如果冷启动要几分钟伸缩再灵敏也没用。所以前面讲的预热和镜像优化和弹性伸缩是配套的不能分开看。5. 状态管理智能体的记忆该放在哪5.1 无状态化是理想但智能体天然有状态普通 Web 服务可以做到完全无状态会话数据放 Redis实例随便扩缩。智能体要复杂一些它的状态至少包含几类对话历史、工具调用中间结果、长期记忆、任务执行上下文。这些状态有的生命周期很短单次请求内有的很长跨会话。把所有状态都塞进实例内存是最省事的做法但这样实例就无法随意扩缩也无法在故障时快速恢复。我的建议是按状态的生命周期分层处理请求级状态放在请求上下文里随请求结束销毁不持久化。会话级状态放外部存储如 Redis实例通过会话 ID 读写。长期记忆放向量数据库或专门的存储按需检索。任务执行状态放数据库支持断点续跑和故障恢复。5.2 会话亲和性的取舍如果会话状态放在外部存储理论上不需要会话亲和性任何实例都能处理任何请求。但实际中加载会话上下文是有成本的如果每次都从存储里拉全量历史延迟和开销都不小。所以很多团队会选择会话亲和性同一会话的请求尽量落到同一实例实例内存里缓存该会话的上下文。这能显著降低延迟但代价是扩缩容和故障转移变复杂——实例下线时会话要迁移扩容时新实例接不到已有会话。我的经验是交互式场景用亲和性批处理场景不用。交互式对话对延迟敏感值得为亲和性付出复杂度批处理任务对延迟不敏感无状态化更简单可靠。如果要用亲和性记得设置合理的会话过期时间避免实例被长期占用。5.3 上下文窗口与状态压缩智能体的上下文窗口是有限的长对话迟早会超出。这时候需要做状态压缩把历史对话摘要化只保留关键信息。这个压缩逻辑放在哪执行也是个基础设施问题。放在实例内执行简单但每个实例都要重复实现放在独立的服务里执行可以统一管理和优化但增加了一次网络调用。我倾向于后者尤其是当压缩逻辑需要调用模型时独立服务更便于做限流和缓存。6. 可观测性智能体出问题时你怎么知道发生了什么6.1 传统监控指标不够用CPU、内存、网络这些基础指标当然要监控但对智能体来说远远不够。你还需要知道每个任务的执行轮数、每轮的工具调用情况、模型调用的延迟和 token 消耗、任务的成功率和失败原因分布。这些是智能体特有的可观测性需求。我的做法是在智能体的执行框架里埋点把每个关键节点的事件结构化输出。比如任务开始、每轮思考开始结束、每次工具调用开始结束、任务结束都打一条结构化日志。这些日志汇总起来就能还原出任务的完整执行链路。6.2 分布式追踪把一次任务的全链路串起来智能体的一次任务可能跨越多个服务网关、调度器、沙箱、模型服务、工具服务。出问题时你需要能把这条链路串起来看。分布式追踪在这里非常有用。实现上给每个任务分配一个全局 trace ID在跨服务调用时透传。每个服务把自己的 span 上报到追踪系统最后就能看到完整的调用树。我用这套方法定位过好几次性能问题比如发现某个工具调用在特定条件下会卡住十几秒从追踪图上一眼就能看出来。6.3 日志的采集与脱敏智能体的日志里往往包含用户输入、模型输出、工具返回等敏感内容。采集日志时要注意脱敏尤其是涉及个人信息、凭证、内部数据的内容。这个工作最好在日志产生时就做而不是等到存储后再处理。另外日志量可能非常大尤其是高频调用的场景。要做好采样和分级关键事件全量记录常规事件按比例采样避免日志系统被压垮。7. 我踩过的几个真实坑与应对经验7.1 沙箱泄漏导致节点资源耗尽前面提过沙箱池化的坑这里展开说。当时我们的沙箱回收逻辑依赖任务正常结束触发结果有个任务因为工具调用卡死既没正常结束也没触发超时超时配置写错了单位沙箱就一直挂着。几天后节点资源被吃光新任务全部调度失败。修复方案是加了一个独立的清理守护进程定期扫描所有沙箱凡是超过最大存活时间的无论状态如何一律强制清理。同时把超时配置做了校验防止单位写错。这个教训是任何依赖正常流程的回收机制都不可靠必须有兜底的强制清理。7.2 模型服务限流引发的雪崩智能体高频调用模型服务如果模型服务有 QPS 限制很容易触发限流。触发限流后智能体如果直接重试会加剧限流形成雪崩。我们当时就遇到了这个情况一个上游限流导致整个智能体服务大面积超时。应对方法是在智能体侧做限流和退避。具体来说给模型调用加一个令牌桶限流器控制调用速率失败重试要带指数退避和抖动避免所有实例同时重试再配合熔断机制当失败率超过阈值时快速失败给下游恢复的时间。7.3 上下文污染导致的诡异 bug多租户场景下如果会话隔离没做好A 用户的上下文可能泄漏到 B 用户的会话里。我们遇到过一次用户反馈智能体记得自己没说过的话排查后发现是会话 ID 生成有碰撞导致两个会话共用了同一份上下文。修复很简单把会话 ID 换成全局唯一且不可预测的格式。但这个 bug 提醒我们多租户隔离要在每一层都验证不能假设某一层做了隔离其他层就安全了。存储层、缓存层、日志层都要检查。7.4 镜像体积过大拖慢弹性伸缩早期我们的智能体镜像里塞了完整的模型和所有依赖体积好几个 G。结果弹性伸缩时新节点拉镜像要几分钟完全跟不上流量变化。后来做了镜像分层把不常变的模型和基础依赖放底层业务代码放上层日常发布只更新上层拉取时间大幅缩短。这个经验是镜像体积直接影响弹性能力在智能体场景下尤其明显因为镜像里往往包含模型这类大文件。设计镜像结构时要考虑更新频率把变化频率不同的内容分层。8. 面向未来的基础设施演进方向8.1 从通用编排到智能体专用运行时现在大家基本是用通用容器编排来跑智能体未来可能会出现更专用的运行时。这类运行时会原生理解智能体的执行模型多轮循环、工具调用、状态管理、沙箱隔离把这些作为一等公民来支持而不是让开发者自己拼装。我观察到一些方向已经在探索比如把沙箱生命周期管理和任务调度深度集成把状态存储和会话管理做成运行时内置能力。这些如果成熟会大幅降低智能体基础设施的搭建成本。8.2 异构算力的统一调度智能体对算力的需求是多样的有的任务需要 GPU 做推理有的需要大内存做数据处理有的需要低延迟网络做实时交互。如何把这些异构资源统一调度让合适的任务落到合适的硬件上是个持续的挑战。Kubernetes 在这方面有基础能力但表达力和调度效率还有提升空间。尤其是当 GPU 这类稀缺资源需要细粒度共享时现有的调度模型会显得笨重。8.3 安全隔离的持续强化随着智能体执行的任务越来越复杂、越来越接近真实系统操作安全隔离的要求只会越来越高。微虚拟机、用户态内核这些技术的成熟和普及会让高强度隔离的成本降下来从而成为更普遍的选择。同时运行时的行为监控也会更重要。不只是隔离还要能实时检测智能体的异常行为比如异常的调用模式、异常的资源消耗及时干预。9. 给正在搭建智能体基础设施的团队的一些实操建议如果你现在正准备把智能体从实验推向生产我建议按这个顺序推进先把运行时环境做扎实。镜像分层、依赖锁定、就绪探针、资源限制这些是地基地基不稳后面全是坑。别急着上复杂的调度和隔离先让单个实例能稳定跑起来。然后解决沙箱隔离。哪怕初期用加固容器也一定要有隔离不要裸跑。网络策略默认拒绝资源配额硬限制超时强制回收这三条是底线。接着是状态管理。想清楚哪些状态放内存、哪些放外部存储会话亲和性要不要用。这个决策会影响后面的扩缩容设计早想清楚省事。最后才是编排和可观测性的精细化。用 CRD 抽象任务、用业务指标驱动伸缩、用分布式追踪串链路这些是锦上添花但前提是前面几层已经稳了。我个人在实际操作中的体会是智能体基础设施的难点不在于某一项技术有多深而在于多个层面的协同。运行时、沙箱、调度、状态、可观测性每一层单独看都不算特别复杂但要让它们配合好需要反复调试和权衡。别指望一次设计到位留出迭代空间边跑边改比一开始追求完美架构更实际。