先把一个场景抛出来:你在 Serverless 平台上跑一个 AI Agent,它需要调用代码解释器生成报告、安装依赖、临时保存中间结果。上线之前一切正常,上线后第一波真实流量就让任务直接挂掉。日志里的核心报错是 the agent execution provider did not respond in time. this may indicate the...。排查了半天,发现不是代码写错,而是 Serverless 的“无状态”模型和 Agent 沙箱的“有状态”需求正面撞车:函数实例在任务执行期间被回收,沙箱文件系统瞬间清空,Agent 上下文也全部丢失。这个坑,相信凡是做过 Serverless 部署和 agent 开发的人都懂。
这个问题不是偶发,而是 Serverless 架构与智能体任务天然错配的必然结果。普通 API 是无状态的短请求,函数执行完就销毁,这是优势;但 AI Agent 是一个循环决策、需要长期记忆和临时文件的“长任务”。把 agent 放进一个“用完即毁、默认只读、不能跑太久”的沙箱里,自然会处处碰壁。
后来我参与了一个叫 AgentRun 的工程化方案,专门解决这个问题。简单说,AgentRun 为 Agent 沙箱引入了“状态外置 + 生命周期托管”:沙箱不再是一次性计算盒,而是可以被快照、暂停、恢复的会话环境,可以跑在 Serverless 平台之上,突破无状态限制。这篇文章把我在这套方案落地过程中的完整思考、设计、踩坑和实测数据整理出来,希望对正在做 AI agent 开发、Serverless 部署或沙箱工程化的朋友有参考价值。
1. Serverless 无状态限制到底卡住了 Agent 的哪根脖子?
1.1 无状态模型是给“请求-响应”设计的,不是给 Agent 循环设计的
Serverless 的卖点很明确:按需伸缩、按量计费、不用维护服务器。它的底层假设是函数是一个“无状态计算单元”,每次调用之间不保存任何东西。这个模型对传统 WebAPI、消息处理、图像缩放这类短任务非常合适,请求进来,函数跑几秒,返回结果,实例销毁,一切干净利落。
但 AI Agent 不是这种负载。Agent 的本质是一个“循环”:LLM 生成决策,Agent 调用工具,拿到工具结果后再丢回 LLM,继续下一步。这个循环可能持续几分钟甚至几小时,而且每一步之间都有强依赖:上一步生成的临时文件、对话上下文、工具调用的中间结果,下一步都要用。更麻烦的是,Agent 还经常需要在沙箱里执行代码,沙箱里的文件系统状态就是任务的一部分。
用生活化的类比来说:无状态 Serverless 像一个自助快递柜,取走包裹就清空;Agent 任务更像一个工位上的项目,需要桌子、工具和半成品持续保留。我门在一个真实 agent 项目里遇到的情况非常典型:agent 读取用户上传的 CSV,用 pandas 做清洗,再生成图表。本地跑得好好的,部署到函数计算后,运行到第三步就报错——函数实例在两次调用之间被回收,临时文件没了,Agent 上下文也被清空。无状态模型对传统请求是优势,对 agent 工作负载就是硬伤。
1.2 沙箱环境的三个隐性约束:文件系统、网络权限、运行时长
如果只是无状态,问题还相对好解决,真正让人头疼的是 Serverless 平台里“沙箱”附加的约束。大多数云函数平台为了安全,都会给函数实例套一层沙箱或类似隔离机制,这原本是好事,但对 Agent 来说就变成了三重天花板。
第一是文件系统约束。沙箱默认通常是只读的,或者只有一个内存临时目录。Agent 要写中间产物、要安装 pip 依赖、要把模型输出落盘,都可能直接被拒。很多人在配置里找不到“写入文件”的开关,就是因为沙箱的文件系统设计是“只给一个 tmpfs”,重启即清空。
第二是网络权限约束。沙箱的出向网络默认关闭或启用严格的域名白名单。Agent 调用外部 API、下载模型文件、访问私有数据源时,经常被静默丢包或直接 timeout。这个坑特别隐蔽,因为不是所有平台都会把网络拦截暴露成错误,很多时候看起来就是“执行器无响应”。
第三是运行时长约束。Serverless 单次执行通常有超时上限,从几十秒到几百秒不等。Agent 任务是分钟级甚至小时级的,必然会在执行中被打断。而大多数平台的超时策略是直接杀掉进程,不给你保存现场的机会。
这三个约束叠加在一起,让 Agent 在 Serverless 上几乎是寸步难行。具体表现下面用一个表总结。
1.3 实测中的失败场景:当无状态撞上长任务
我在两个不同项目里踩过不少坑,挑三个有代表性的场景列出来。这些报错如果你也遇到过,基本可以确定是同一个根因。
| 场景 | 触发条件 | 典型表现 | 根因 |
|---|---|---|---|
| Agent 安装依赖后实例被回收 | 执行 pip install requests 后继续跑脚本 |
脚本 import 失败,报 ModuleNotFoundError | 沙箱临时目录随实例销毁,文件系统状态丢失 |
| Agent 长任务执行中断 | 单次任务超过平台执行时长上限 | the agent execution provider did not respond in time |
Provider 进程被超时杀掉,无状态平台无法续跑 |
| 并发请求分散到不同实例 | 同一 Session 的多个步骤被负载均衡转发 | Agent 上下文错乱,前一步结果拿不到 | 无状态平台不保证会话亲和性 |
第一个场景在把 agent 部署到云函数时几乎必现。你本地测试时所有包都装在镜像里,但线上沙箱只保留基础环境,工具执行时实时装依赖,装完还没跑完,实例就被回收了。第二个场景是长任务刚需,Agent 做数据分析、跑模拟、处理大文件,往往超过单次函数执行上限。第三个场景最隐蔽:不是所有请求都会超时,而是同一个会话被路由到不同实例,每个实例都不知道之前的上下文,表现就是“上一秒还好好的,下一秒 Agent 像失忆了一样”。
好在这些问题不是无解的。要突破 Serverless 无状态限制,第一步是接受一个事实:Agent 任务必须被建模成“有状态会话”,而不是“无状态请求”。这也是 AgentRun 设计的出发点。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. AgentRun 的设计思路:把沙箱从“一次性计算盒”变成“可恢复的会话环境”
2.1 核心设计:状态外置 + 生命周期托管
AgentRun 的核心抽象是 AgentSession。在 AgentRun 里,每个 Agent 会话由一个全局唯一的 SessionID 标识,它绑定一个独立的沙箱环境。沙箱的文件系统变更、环境变量、Agent 上下文,都会被周期性地做快照并保存到外部存储。当 Serverless 实例被回收时,丢失的只是运行中的内存态;下一个实例启动后,AgentRun 会从最近的快照恢复整个会话——这不是“重启任务”,而是让沙箱“复活”,从断点继续执行。
状态外置的含义是:你不把状态放在函数实例里,而是放在对象存储、Redis 这类外部基础设施中。函数实例本身仍然可以是无状态的,随时销毁都不怕。生命周期托管的意思是:AgentRun 负责管理沙箱从创建、运行、快照、暂停、恢复到销毁的全过程,业务代码只需要关心每个工具调用单元的输入输出。
可以把它类比成游戏存档机制。传统 Serverless 相当于每次退出游戏都删档重来;AgentRun 相当于你打了一半随时存档,下次打开从存档点继续,而不是从头开始。
2.2 为什么选择沙箱化,而不是传统容器化
刚设计时我也问过:直接用容器不行吗?在 Serverless 平台里嵌一个完整的 Docker 容器,隔离效果好,生态也成熟。但实际一测就发现问题:容器启动通常是秒级,镜像动辄几百 MB,而 Serverless 冷启动的预期是毫秒到一两秒。Agent 的一次工具调用如果都要等容器启动,交互体验基本没法用。
所以 AgentRun 选择了更轻量的沙箱技术路线,底层实现是可插拔的,默认支持 WASM 沙箱和 gVisor 这类轻量运行时。以 WASM 为例,一个 Python runtime 可以提前编译成 WASM 模块,启动时间可以压到几十毫秒,内存占用也远低于完整容器。而且 WASM 天然有模块边界,每个 Agent 执行代码时只在自己的 module instance 里运行,隔离性有保障,非常适合 Serverless 这种“短生命周期、高并发”的部署环境。
当然,轻量沙箱也有代价:系统调用面受限,不是所有 Linux 程序都能直接跑。所以 AgentRun 在设计上做了一个折中:默认提供标准化的 Python/Node.js runtime,并把常用依赖打进基础快照层。如果你的 Agent 需要任意自定义二进制,可以选择 gVisor 这类更强的隔离 runtime,代价是启动时间和资源占用会上升。
2.3 状态存储与恢复机制:快照、增量同步、恢复点
AgentRun 的状态管理借鉴了容器镜像的分层思想。每个沙箱的文件系统分成两层:底层是基础快照层(base snapshot),比如 python-3.11-wasm,这部分是只读的,包含操作系统级基础环境和预置依赖;上层是会话变更层(session delta),记录 Agent 运行期间对文件系统的所有写操作。
Agent 每完成一个工具调用,AgentRun 就会将会话变更层的增量内容同步到对象存储。增量只上传发生变化的文件块,不是整个目录打包。比如 Agent 在 /workspace 下生成了一个 1MB 的中间文件,增量同步就只传这个文件块。恢复时,新的沙箱实例拉取基础层和最近的变更层,合并挂载到指定目录,然后恢复 Agent 上下文和执行计划。
如果只是文件系统快照,还不足以解决“上下文续传”。AgentRun 在恢复时还会读取会话元数据,包括:当前执行计划、已经完成的工具调用列表、LLM 对话历史、未执行完成的工具请求参数。Agent 框架拿到这些元数据后,可以从最后一条未结束的工具调用继续,而不是重新把历史对话全部回放一遍。
这里给一个最简 Python 客户端示例,展示创建、快照、恢复的基本流程。
python复制import agentrun
# 第一次执行:创建会话并运行
session = agentrun.create_session(
namespace="report-agent",
base_snapshot="python-3.11-wasm",
enable_writable_fs=True,
)
session.write_text("/workspace/input.csv", csv_data)
resp = agentrun.execute(session.id, "python /workspace/analyze.py")
# 检测到即将超时,主动保存快照
agentrun.snapshot(session.id)
# 下次函数实例被拉起:恢复会话并继续
session = agentrun.resume(session_id="session-xxxx")
result = agentrun.execute(session.id, "python /workspace/render.py")
snapshot 和 resume 是 AgentRun 最关键的两个 API。前者是主动把当前状态固化到外部存储,后者是从最近快照恢复并继续执行。日常使用中,我们会建议在每个工具调用结束后都做一次 snapshot,这样即使实例随时被回收,最多丢失一个工具调用的进度。
2.4 恢复是“沙箱复活”,而不是“重跑任务”
这一点需要单独强调,因为很多人听到快照恢复,第一反应是“那是不是把任务从开始重新执行一遍”。不是。AgentRun 恢复的最小粒度是“工具调用单元”,而不是“整个 Agent 流程”。
在传统无状态平台上,如果函数在任务中途被杀死,你只能让 Agent 从头跑,因为所有状态都丢了。但 AgentRun 在 Agent 执行过程中做了“协作式检查点”:每次 LLM 决策后、每次工具调用前后,它都会把当时的上下文和沙箱状态记录下来。恢复时,AgentRun 只重建最近一个检查点之后的工作现场,从断点继续执行。
这种设计对 Serverless 平台特别重要。平台回收实例是常有的事,如果每次回收都全量重跑,成本和时间都不可接受。有了断点续跑能力,Agent 长时间任务才真正具备工程落地的可能性。
3. AgentRun 的工程落地:从原型到生产环境的折腾过程
3.1 整体架构与模块职责
设计是一回事,真正落地到生产是另一回事。AgentRun 的架构并没有一开始就定型,而是在“能用”和“好用”之间反复迭代。最终我们把它拆成了四个核心模块。
| 模块 | 职责 | 关键点 |
|---|---|---|
| 调度器 | 接收 Agent 执行请求,路由到具体的工作实例 | 按 SessionID 做哈希路由,保证会话亲和性 |
| 沙箱网关 | 管理沙箱生命周期:创建、销毁、快照、恢复 | 向业务代码暴露 Execute / Snapshot / Resume API |
| 状态存储 | 保存会话元数据、快照索引、分布式锁 | 使用 Redis 记录 SessionID 到快照位置的映射 |
| 对象存储 | 保存基础快照层和会话变更层 | 支持增量上传和拉取,按需加载 |
控制面和数据面是分离的。Serverless 函数实例是数据面,负责实际执行 Agent 的工具调用;AgentRun 控制面负责管理会话状态。这样设计的好处是:函数实例可以被平台随意扩容缩容,控制面始终知道每个 Session 当前在哪、最新快照在哪。业务方看到的只是一个可恢复的会话对象,不需要关心底层实例是否被回收。
3.2 关键代码:执行器的 Go 实现
沙箱网关是 AgentRun 里最核心的模块,我们最终用 Go 重写了一遍,因为 Go 在并发和系统调用拦截上更顺手。一个典型执行器代码长这样:
go复制import (
"context"
"time"
"github.com/agentrun/agentrun-go"
)
func RunAgent(ctx context.Context, sessionID string, code string) (string, error) {
sess, err := agentrun.Resume(ctx, sessionID)
if err != nil {
sess, err = agentrun.Create(ctx, agentrun.BaseSnapshotPython311)
if err != nil {
return "", err
}
}
defer sess.Snapshot(ctx)
if err := sess.PutFile(ctx, "/workspace/task.py", code); err != nil {
return "", err
}
return sess.Exec(ctx, "python /workspace/task.py", agentrun.ExecOptions{
Timeout: 60 * time.Second,
AllowNetwork: []string{"pypi.org"},
})
}
关键逻辑是 Resume 优先、Create 兜底,以及 defer sess.Snapshot(ctx)。每次函数调用结束前自动打快照,这样就算执行器还没返回结果时实例就被回收,下一次也能从最近状态继续。ExecOptions 里的 Timeout 也要重点设置,它决定了沙箱内单个命令能跑多久,一定要小于 Serverless 平台整体的超时上限,给快照留出时间。
3.3 权限与安全配置:放开写文件,但又不让 Agent 乱跑
Agent 沙箱和普通函数沙箱最不一样的地方在于:Agent 需要写文件,需要装依赖,需要访问外部 API。但这些权限如果全放开,一个被注入恶意指令的 Agent 就能在你的基础设施上为所欲为。所以权限控制是 AgentRun 的安全底线。
我们的默认安全配置大致是这样的:
json复制{
"runtime": "wasm",
"mounts": {
"/workspace": {"type": "tmpfs", "size_mb": 1024},
"/usr": {"readonly": true},
"/bin": {"readonly": true}
},
"writable_paths": ["/workspace", "/tmp"],
"seccomp": {
"default_action": "errno",
"allow": ["read", "write", "open", "close", "execve", "mmap", "brk"]
},
"network": {
"enabled": true,
"allow_domains": ["pypi.org", "files.pythonhosted.org", "api.openai.com"],
"block_public": false
}
}
这套配置的思路是:基础系统目录只读,只给 /workspace 和 /tmp 开放写权限。网络方面默认只放行 Agent 任务必需的域名,而不是把整个公网打开。seccomp 的 allow 列表按需加,避免 Agent 调用危险系统调用。
特别要注意:不要让 Agent 进程以 root 身份运行。即使沙箱里看起来安全,也建议配合用户命名空间把进程降权。Agent 生成的代码往往来自 LLM 或用户输入,安全边界必须保守。
3.4 落地阶段踩过的三个工程坑
第一个坑是快照体积膨胀。会话运行一段时间后,变更层越来越大,最夸张的一次到了 800MB,恢复时间从 300ms 涨到 5 秒。后来做了两层优化:一是分层快照,把临时文件和工作产物分开;二是定期做快照压缩合并,超过 24 小时的会话每周自动合并一次。
第二个坑是依赖安装慢。每个新 Session 都现场 pip install,几十个 Agent 并发时效率极低。解决方案是把常用依赖(numpy、pandas、requests 等)预置到基础快照层,业务层只在确有需要时增量安装。实测下来,会话创建时间从秒级降到百毫秒级。
第三个坑是并发恢复竞争。当同一个 SessionID 被两个函数实例同时恢复时,它们会在同一个快照上写,状态直接分裂。我们的解决办法是 Redis 分布式锁加会话亲和路由:每个 SessionID 只会被路由到同一个运行实例;如果有实例回收,新实例必须先获取会话锁,确保只有一个实例在恢复后执行写操作。
4. 用 AgentRun 解决真实项目中的硬骨头问题
4.1 问题一:Agent 执行到一半超时,上下文怎么续传
长任务超时是最常见的生产事故之一。Agent 在 Serverless 上跑着跑着,平台超时器一响,整个进程被杀,连个遗言都没有。AgentRun 的解法是在执行器中嵌入“时间预算检查”:Agent 每调完一个工具,就看当前已经用了多少时间;如果剩余时间不足以完成下一个工具调用,就主动触发快照,并返回一个 continuation_token。
这个 token 会随 API 响应返回给前端。下一次请求带过来,AgentRun 直接 Resume 到那个会话,从上次暂停的地方继续。用户体感是“任务还在跑”,而不是“任务失败了”。这个机制对 Agent 的复杂度透明,Agent 框架只需要在上一次响应里拿到 token,然后重新提交一次执行请求即可。
实际项目里,我们还把“即将超时”作为一次工具调用结果注入给 Agent,让它主动调整后续步骤。比如 Agent 发现还有 30 秒就要超时,就先把当前结果落盘并保存快照,再决定下一步。这样就把被动超时变成了主动续传。
4.2 问题二:沙箱里的临时文件如何在函数实例间共享
Agent 任务经常需要多个工具接力处理同一个文件。比如第一个工具下载数据,第二个工具清洗,第三个工具做可视化。在 Serverless 默认模型下,每个函数实例都是独立沙箱,第一个工具写的文件第二个工具看不到。很多人问“dify 沙箱环境如何置能写入文件”,本质上就是问这个问题。
AgentRun 提供了“共享卷”能力:你可以在多个 Session 之间声明一个共享逻辑目录,这个目录被映射到对象存储的同一个前缀。写入发生时,AgentRun 会把文件块同步到共享存储;其他会话读取时,从共享存储拉取。为了减少冲突,AgentRun 在共享目录上提供基于 Redis 的文件锁,同一时刻只允许一个会话写同一个文件。
这个能力让多个 Agent 子任务可以像操作同一台机器一样协同。实际测试中,共享卷的读写性能比本地磁盘慢,但对大多数配置文件、中间结果文件来说完全够用。如果对性能要求高,也可以把共享卷挂载为内存级缓存,再异步回写对象存储。
4.3 问题三:多 Agent 协作时沙箱隔离与通信
多 Agent 是最近很热的方向,我接触到的绝大多数“主从模式”都是把 subagent 当成一种特殊的 tool 来调用:主 Agent 决定要调用子 Agent,传入任务描述,子 Agent 返回结果。这个模式在架构上很清晰,但工程上有一个要求:每个 subagent 必须有独立的执行环境,不能互相干扰。
AgentRun 对每个 subagent 会创建独立沙箱,并通过 namespace 做逻辑隔离。子 Agent 在运行期间可以有自己的文件、自己的会话上下文,主 Agent 只能看到它返回的结果和必要的事件日志。两个 subagent 如果有依赖关系,不直接读取对方沙箱,而是通过一个受限的内部消息通道交换数据。这个通道默认只允许文本和结构化数据,不允许文件路径引用,从而减少安全隐患。
在性能上,多 Agent 并发会带来明显的沙箱创建压力。这里可以复用基础快照层,避免每个沙箱都全量拉取基础镜像。实测 20 个 subagent 并发创建,使用预置快照后平均创建时间不到 200ms,没有出现资源争用导致的雪崩。
4.4 实测数据与性能指标
下面是我们在一个标准 Serverless 环境里跑 AgentRun 的实测数据,runtime 使用 WASM Python 3.11,状态存储用同区域对象存储。
| 指标 | 实测值 | 备注 |
|---|---|---|
| 沙箱冷启动 | 约 120ms | WASM runtime,不包含拉取远程数据 |
| 从快照恢复 | 约 350ms | delta 50MB 时的平均值 |
| 快照增量上传 | 约 400ms | 同区域对象存储,1MB 变更 |
| 单次工具调用额外开销 | 约 3% CPU / 10MB RSS | 相对于裸沙箱执行 |
| 会话销毁释放 | 小于 200ms | 含 cgroup 清理 |
性能损耗在可接受范围。真正要重点盯的是快照恢复时间,它和 delta 大小强相关。如果业务上 Agent 会频繁写大文件,建议把大文件排除出快照范围,改用共享卷,否则恢复时间会线性增长。
5. 避坑指南:AgentRun 使用中的常见坑和排查思路
5.1 冷启动期的“黑洞”问题:Agent 还在初始化,请求已经超时
第一个容易踩的坑:AgentRun 冷启动时需要从对象存储拉取基础快照,这个过程如果发生在用户请求的关键链路上,很容易导致请求超时。即使我们已经把基础层做了本地缓存,第一次冷启动仍然可能达到几百毫秒到一秒。对交互式 Agent 来说,这个延迟会直接表现为“卡死”。
我的建议是把沙箱初始化和用户请求解耦。请求进来先创建一个任务,异步触发沙箱初始化,前端通过轮询或 WebSocket 等状态准备完成。而不是让用户请求傻等沙箱就绪。另一个办法是常驻一批预热沙箱,空闲时预先创建好会话,请求来了直接复用。
5.2 文件句柄与连接泄漏:沙箱销毁不彻底的隐患
Agent 沙箱不像普通函数那样跑完就自动清理干净。如果 Agent 里启动了长连接、打开了文件描述符、起了后台进程,沙箱销毁时可能因为等待这些资源而卡住。长期运行后,宿主机上会积累大量僵尸进程和未释放的文件句柄,最终拖垮整个节点。
排查方法很直接:在宿主机上 ps -ef | grep agentrun,看有没有残留的沙箱进程,再用 ls -l /proc/<pid>/fd 检查文件句柄。AgentRun 目前会在销毁时先发 SIGTERM,超时后发 SIGKILL,并强制卸载临时目录。但你应该在业务侧也做好兜底,确保每个工具调用都设置超时和取消传播,调用完成后主动关闭连接。
5.3 无状态平台与有状态沙箱的冲突:自动扩缩容时如何保证会话亲和性
Serverless 平台最有价值的能力就是自动扩缩容,但这恰恰是 AgentRun 最容易出问题的地方。平台发现某个函数实例负载高了,会自动新建一个实例;如果新的实例也收到同一个 SessionID 的请求,就可能出现“两个实例同时在恢复同一个会话”的情况。
解决的思路是“亲和路由 + 分布式锁”。调度器按 SessionID 做哈希,让同一个 Session 尽可能落在固定实例上;当实例不可用需要迁移时,新实例必须先获取一个 Redis 锁。锁过期时间要大于快照恢复时间,否则会导致恢复还没完成,另一个实例又抢锁进来,状态彻底乱掉。我在生产环境里把锁的过期时间设置为 5 分钟,配合续期机制,没有再出过并发恢复问题。
5.4 当出现 “the agent execution provider did not respond in time” 时怎么办
这个报错是最典型的“沙箱执行器无响应”问题。遇到它时,按下面这个顺序排查,基本能覆盖绝大多数原因。
- 确认 Provider 进程是否启动。AgentRun 的沙箱执行进程可能因为资源限制没起来,检查
agentrun ps或对应进程列表。 - 确认是否处于冷启动/恢复阶段。如果请求超时阈值比恢复时间还短,就会出现“还在恢复,请求已经断了”。调大超时,或改成异步模式。
- 确认沙箱内部是否死锁。最常见的是 Agent 在等待网络响应,但网络白名单没有放行目标域名,导致请求一直 pending。查看沙箱内日志和网络连接状态。
- 调用 AgentRun 的健康检查接口,确认执行器还活着。如果健康检查也超时,直接销毁重建沙箱。
这个报错本质上不是 AgentRun 的 bug,而是沙箱进程和业务请求之间的“握手”没完成。关键是把超时阈值、恢复时间、健康检查频率三者调到一个合理区间。
5.5 权限配置过严或过松的平衡
最后一个坑是权限配置。刚开始做 agent 项目时,开发同学最常说的就是“给我 root 权限,装个包都方便”。但如果你真的给 Agent 沙箱开了 root 和全量网络,恶意提示词注入基本就是一枚定时炸弹。
我的建议是:能预置的就不运行时装。Agent 需要什么依赖,提前打进基础快照层;需要访问的 API 域名,提前加进白名单。如果 Agent 确实有临时安装包的需求,可以把包管理器的网络请求白名单打开到指定源,但不给宿主机层级的系统权限。安全配置不必一次到位,可以按业务场景慢慢加白名单,但底线是不能用 root 跑 Agent 进程,不能挂载宿主机的敏感目录,不能放开任意公网访问。
最后说点个人感受。AgentRun 解决的是 Serverless 上跑 Agent 的“工程化”问题,而不是 Agent 能力问题。如果你的 Agent 是纯实时对话、需要毫秒级响应,那还是不要上这种快照恢复的链路,太重了;但如果你的 Agent 是任务型、批量型、可断点续跑的,这套设计会让你在 Serverless 平台上获得接近有状态服务器的体验。我实际用下来最大的心得是:快照分层一定要提前做,别等 delta 涨到 1GB 再优化;还有,永远别让两个实例同时恢复同一个会话。这个工具后续我还在迭代,之后有新的工程发现再回来分享。
