一、同一项脚本任务,为什么会长成两套 Runtime

假设用户交来一项很普通的任务:“把数据清洗脚本改成支持 region 字段,运行检查,再把结果交给我。” 我们先不问产品叫 Coding Agent 还是 General Agent,只看任务怎样发生。

第一种场景里,Agent 从已经打开的 repository 开始。它知道当前目录,读取源码和项目规则,修改文件,运行测试, 再把 diff、退出码和测试结果留在同一个工作区。用户第二天回来,文件与 Git 状态通常还在;但昨天启动的后台进程、 尚未完成的工具调用和模型会话是否还在,是另外三个问题。

第二种场景里,用户只上传了一份压缩包。服务先创建 task 与 session,再给这次运行分配 sandbox, 把输入材料恢复到 workspace。Agent 仍然可以改文件和跑命令,但当前 worker 与 sandbox 都可能被回收。 最终报告必须离开临时现场,保存成有用户、会话和版本归属的 artifact;下次请求也不能只靠“碰巧还在这台机器的目录”继续。

先记住结论: General / Coding 描述产品把哪种工作对象放在中心;Local / Cloud 描述执行环境与持久状态由谁拥有。 它们是两条坐标,不是一条从“普通”到“高级”的能力等级。

这篇固定跟踪同一项脚本任务,只回答五个问题:

  1. “workspace 是第一公民”具体承诺了什么?
  2. 会执行代码,为什么还不一定是 Coding Agent?
  3. 云端 sandbox、workspace 与 durable storage 为什么必须拆开?
  4. Session、Artifact、Memory 和文件目录各自保存什么?
  5. 本地与云端恢复分别会在哪些地方停止?

证据边界。 本文用 Pi 的 coding harness、AgentScope 的 service example、Agno 的 AgentOS,以及 tRPC-Agent-Go 的 Session、CodeExecutor、workspace、Artifact 与 Memory 公开源码说明可见契约。文中的四象限与“工作现场”是跨框架的工程归纳; 不推断任何产品未公开的容器实现、存储拓扑、调度策略或保留时长。

二、第一公民不是“工具列表里有 bash”

如果 Agent 的 tools 里出现 read_filebash,我们最多只能确认模型可以请求两种动作。 “第一公民”是更强的运行契约:runtime 不仅暴露操作,还要认识操作发生在哪个对象上,并接住它的整个生命周期。

回到这次脚本修改。一个真正的一等 workspace 至少要回答五件事:

  1. 身份:这是哪个 repository、branch、task 或 workspace,而不是一个随手拼出的路径。
  2. 操作:读取、搜索、patch、shell、测试和 Git 都围绕同一个现场发生。
  3. 治理:路径、命令、网络、Secrets 与审批有明确边界。
  4. 证据:文件变化、命令退出码、测试报告和生成物可以被观察与关联。
  5. 恢复:进程或客户端离开以后,runtime 知道哪些状态可以重新装载,哪些已经丢失。
只“拥有一个工具” 把对象做成第一公民 差别会在哪里暴露
bash(command) 命令绑定 workspace、权限、环境、取消和结果记录 失败后能否知道命令在哪运行、改了什么
write_file(path) 文件属于 repository 或 task workspace,并能形成 diff 下一轮读取的是同一份状态,还是另一台机器的空目录
返回下载链接 Artifact 有 owner、版本、媒体类型和生命周期 链接失效后,服务能否按 task/session 重新找到结果
把几句话写进数据库 Memory 有用户作用域、更新、删除、检索和采用规则 旧事实怎样被纠正,多个用户怎样避免串线

所以,通用 Agent 加一个代码解释器后,可以完成代码任务;Coding Agent 也可以借助文件和 shell 写报告、整理数据、制作演示。 分类不能靠“能做什么”硬切。更稳定的判断是:产品默认围绕什么对象组织上下文、权限、结果和恢复。

三、先分任务坐标,再分部署坐标

3.1 Coding / General:哪种工作对象处在中心

Coding-oriented Agent 通常把 project 或 repository 当作主对象。模型输入会主动吸收项目规则、文件结构和当前 diff; 工具结果天然表现为文件修改、命令输出和测试证据;完成标准往往是“patch 正确、测试通过、改动可审查”。

General-purpose Agent 更常把 user task、session 或业务记录放在中心。文件可能只是输入材料,代码执行只是处理材料的一种手段; 最终结果也可能是答案、表格、报告、CRM 更新或审批记录。它更关心用户身份、业务权限、跨渠道 session 与 artifact 交付。

3.2 Local / Cloud:谁拥有执行环境与持久状态

Local 不等于“只有命令行”,Cloud 也不等于“没有文件系统”。这里问的是 authoritative worksite 在哪里。 本地型 runtime 通常直接借用用户机器的目录、进程、凭据与操作系统身份;云端型 runtime 则由服务分配 worker 或 sandbox, 并把需要跨 worker 生存的状态放到外部 owner。

两条轴交叉后,四个象限都成立:

形态 工作现场 常见第一公民 首要工程压力
本地 Coding Agent 用户机器上的 repository cwd、files、Git、shell、tests 项目信任、权限、环境污染与可审查 patch
云端 Coding Agent 远程 repository workspace 或受管开发环境 task、repo snapshot、patch、build/test artifact 环境重建、Secrets、网络策略、并发与成本
本地通用 Agent 个人设备与桌面应用 用户文件、桌面工具、个人上下文 设备权限、隐私、应用间副作用
云端通用 Agent 多租户 service + 临时或受管 sandbox user、session、task、artifact、business tool 租户隔离、恢复、配额、审计与长期状态

这张表不是四种互斥产品。云端控制面可以把某些命令交给本地执行器;本地客户端也可以租用远程 sandbox。 混合架构里最重要的不是给整套产品贴一个标签,而是逐项标出 workspace、执行权限、durable record 和最终副作用的 owner。

四、本地 Coding Harness 为什么天然围绕 Workspace

Pi 提供了一个足够清楚的本地参照。它把模型接入、agent loop、coding harness 与终端 UI 拆成 四层 package。 可复用 core 负责模型、工具调用和事件;coding-agent 层再装配 read、write、edit、bash、resources、session tree 与 compaction。 这说明 workspace 能力不是 provider API 自带的,而是产品 runtime 主动接走的责任。

把脚本任务写成运行记录,可以看到本地路径里哪些对象天然稳定:

Task C-17:增加 region 字段
worksite = repository / branch

read schema.py
edit cleaner.py
bash pytest -q
  -> exit 1:缺少 fixture
edit test_cleaner.py
bash pytest -q
  -> exit 0

observable result = files + diff + test output

会话账本与磁盘仍然不是一回事。Pi 的 SessionManager 用 append-only JSONL tree 保存 message、tool result、 model change、branch 与 compaction entry;当前 leaf 决定恢复哪条会话路径。 上下文重建 可以恢复 model-visible history,却不会把 repository 自动回滚到旧 leaf。真正试验另一份代码状态仍需要 Git branch、worktree 或 sandbox。

安全边界也直接继承现场。Pi 的 project trust 决定是否加载项目中的 settings、extensions、skills 和 prompts, 但官方 Security 文档 明确说它不是 sandbox。没有额外 gate 时,文件与命令仍继承启动进程的操作系统权限。 本地带来了丰富环境,也把用户机器变成了真实 blast radius。

本地磁盘存在,只能证明某些文件还在。 它不自动证明旧 shell 进程仍活着、外部 API 没有重复执行、会话可以重放,或模型能解释每一处现存修改。

五、云端 Runtime 为什么要把现场拆成多个 Owner

云端版本不能假定下一次请求一定落在同一进程。于是“一个目录”必须被拆成几种不同承诺: task/session 保存运行身份,sandbox 提供当前执行环境,workspace 承载可变文件,artifact store 保存已交付结果, memory store 保存以后还要检索的知识。

5.1 先创建运行身份,再租用执行环境

一个典型的服务路径会先把用户请求正规化成带身份的 run,再为需要执行代码的步骤准备 sandbox。 下面只是 shape-level 路径,不对应任何私有产品 schema:

request
  {user_id, task_id, session_id, input_refs}

service plane
  -> authorize tenant and tool policy
  -> lease sandbox
  -> restore task workspace
  -> run agent loop and stream events
  -> promote selected outputs to artifacts
  -> persist run/session state
  -> release or snapshot sandbox

顺序里最关键的是“promote selected outputs”。临时目录中的 cache、依赖、半成品与日志不会因为任务结束就全部成为永久资产; 应用必须决定哪些文件带着 owner、版本和媒体类型离开现场。

5.2 Service plane 接住多用户与重连,但不能靠组件名证明恢复

AgentScope 的 example service 把 create_appRedisStorage、message bus、 LocalWorkspaceManager、MCP 与 subagent template 接到一起。 这条装配路径 证明它考虑了 service、storage 和 workspace;但单独看见 RedisStorage,仍不足以证明 pending tool state、 event cursor 与 workspace snapshot 已经支持跨进程恢复。

Agno 把平台责任展示得更完整。AgentOS 同时装配 agents、teams、workflows、database、authorization、 registry、scheduler、tracing 和 interfaces;初始化时还会注入 OS-level database/checkpoint 并开启 event storage。 对应源码在 AgentOS.__init__运行对象初始化。 这类 service plane 的第一公民是 run、session、identity 与 platform service,不是某台 worker 的 cwd。

5.3 CodeExecutor、Workspace 与 Artifact 解决三种问题

tRPC-Agent-Go 的源码把这条边界说得很直白: CodeExecutor 回答“程序怎样运行”; stageSkill 为一次执行准备可写工作副本; artifact.Service 则按 Session、文件名与 revision 保存交付文件。

因此“支持代码执行”只覆盖中间那段尝试。若没有 workspace owner,输入、依赖与中间文件没有一致现场; 若没有 artifact owner,最终报告仍困在可能被回收的目录。三者可以由同一台机器实现,但语义上不能合并。

六、四种状态,不是一块磁盘

现在把同一项任务的状态摆在一起。Session、Workspace、Artifact 和 Memory 都可能最终落到文件或数据库, 但存储介质相同不代表生命周期相同。

Agent Runtime 四种状态手绘图:Session 账本保存运行经过,Workspace 承载可变文件,选中的文件被提升为 Artifact,完成后的会话证据再经提炼进入跨会话 Memory;文件持久化不等于进程恢复或长期记忆
状态 owner 这次任务里保存什么 谁会再次读取 它不承诺什么
Session ledger 消息、事件、tool call/result、暂停点与 run 状态 恢复 runtime、构造下一轮 model view、前端回放 不保存完整工作目录,也不撤销业务副作用
Workspace 源码、输入文件、依赖、临时输出与当前修改 文件工具、shell、代码执行器和测试 目录还在不代表进程、会话和网络连接还在
Artifact 被选中交付的报告、图片、压缩包或构建结果 用户、前端、后续工具或业务系统 生成成功不代表内容已经验证或正式采用
Memory 跨会话仍有价值的 fact、episode、偏好或方法 未来 session 的检索与上下文装配 不是原始 transcript,也不应该收下全部文件

6.1 为什么 Artifact 必须经过“提升”

Workspace 是尝试现场,允许出现失败脚本、未完成报告和大量缓存;Artifact 是产品承诺,应该只保存明确选择的输出。 tRPC-Agent-Go 的 workspace_save_artifact 就把已有 workspace 文件保存成 artifact reference, 并把引用写进 state delta。源码在 文件提升路径。 这不是一次普通 copy,而是 owner 从“当前执行现场”变成“按 session 可引用的交付物”。

6.2 为什么 Memory 必须经过“提炼”

如果把每条日志、每份文件和每个失败尝试都写进长期 Memory,未来检索只会得到噪声。 tRPC-Agent-Go 的 Memory Service 把跨 Session 的 fact 与 episode 放在独立接口中; 当前 Session 仍保存原始运行记录。公开边界见 memory.Service。 自动抽取还要在 run 完成后读取增量消息、判断是否值得提炼,再执行 add/update/delete,而不是每轮必写。

七、Coding Agent 的 Memory 为什么看起来不一样

Coding Agent 有一个很强的外部状态源:repository 本身。项目规则可以写进说明文件,设计决策可以留在文档, 代码变化进入 Git,测试把预期固化成可执行证据。未来任务重新打开同一个 project 时,这些材料无需先被压成一段“用户记忆”。

但不能因此说“filesystem 就是 Memory”。文件可能只是当前实现,也可能包含过时注释、构建缓存和用户不希望长期保留的材料。 Session compaction 解决模型窗口压力,Git 记录代码版本,project instructions 约束工作方式,semantic Memory 才负责跨任务检索事实或经验。 它们可以都落在文件上,却仍然有不同 owner 与采用规则。

云端通用 Agent 更难借用一个稳定 repository 作为共同事实源。同一用户可能从多个入口发起任务,请求落到不同 worker, 业务数据还分散在外部系统。因此它通常更依赖 user/app-scoped Memory store、Session store、knowledge retrieval 与 Artifact store。 这不是因为 General Agent “记性更好”,而是因为状态必须从单机环境外部化,才能被多节点重新找到。

需要留下的东西 Coding-oriented 默认落点 Cloud general-purpose 默认落点 采用前要检查
项目约束 repository instructions、Skill、配置 应用策略、tenant 配置、tool policy 作用域和优先级是否正确
当前任务进度 session ledger + workspace + Git run/session store + sandbox snapshot 能否关联同一个 task 与副作用
跨任务知识 项目文档、已审查 Skill、可选 Memory user/app Memory、knowledge store 来源、更新、删除和隐私边界
最终交付 commit、patch、build/test artifact versioned artifact 或业务记录 内容校验、回归、审批与发布

八、恢复时,最容易混淆的是四种“还在”

用户说“昨天的任务还在吗”,可能同时在问四件事:对话记录还在吗,文件还在吗,进程还活着吗,外部副作用已经发生了吗。 Runtime 若只回答一个“是”,就会把不同恢复层级混成虚假保证。

中断 本地现场通常还剩什么 云端现场必须外部化什么 恢复边界
客户端断线 本地进程可能仍运行 run id、event cursor、buffer 或 event store 重连事件流不等于重启计算
Agent 进程退出 磁盘文件通常仍在 Session、pending state、workspace snapshot 未持久化的工具内部状态会丢失
执行环境回收 不常发生或由用户自己管理 输入引用、环境描述、snapshot、artifact 文件可重建不代表后台进程可续跑
外部写入超时 都需要幂等键、业务回执或补偿记录 恢复 agent loop 不能证明副作用 exactly-once

Agno 的 API 路由提供了一个很好的区分:continue 可以从持久化 run state 推进执行, resume 则用 last_event_index 补发 missed events 并重连仍在运行的流。 两条路径分别见 continue runresume stream。 “继续计算”与“重新看见事件”是两种恢复,不能因为都叫 resume 就合并。

九、把同一项任务完整重放一遍

本地 Coding 路径

用户选择 repository
  -> Agent 读取项目规则
  -> files / shell / tests 在同一 cwd
  -> Session 记录工具与模型过程
  -> Git diff 保存可审查修改
  -> 测试与人工 review 验证
  -> 用户决定是否 commit / merge

云端服务路径

服务创建 task / session
  -> 鉴权并分配 sandbox
  -> 恢复 workspace 与输入
  -> Agent 执行并流式发事件
  -> 选中输出提升为 artifact
  -> 校验器或审批验证结果
  -> 产品决定发布或交付

两条路径最后都必须分开三个状态。Agent 产生 patch 或报告,只能说明 output produced; 测试、schema 校验、安全扫描或业务规则通过,才是 output validated; commit、merge、发布、写入业务系统或由用户接收,才是 output adopted。 本地丰富的工具面与云端完整的 service plane 都不能替代最后两道门。

十、最后用这组问题选择 Runtime

设计问题 答案偏左时 答案偏右时
主要对象是长期 repository,还是一次 user task? 优先 coding-oriented workspace 优先 task/session service plane
authoritative files 在用户设备,还是由服务管理? 本地权限、project trust、Git 是核心 snapshot、artifact、tenant identity 是核心
依赖与后台进程是否必须跨天保留? 可复用现有开发环境 需要 named environment 或明确重建合同
请求是否会跨 worker、入口或设备继续? 本地 session 可能已经足够 必须外部化 run、event、pending state
哪些知识要跨任务生效? 项目文件、文档、Skill 可先承担 需要 user/app Memory 与检索治理
最终产物怎样进入真实世界? patch/test/review/merge artifact validation/approval/publish

可复用判断: 不要问“这个 Agent 能不能写代码”,要问 workspace 是否有稳定身份,执行权限由谁治理, Session、文件、进程和 Artifact 分别能活多久,Memory 对谁可见,以及最终结果由谁验证并采用。

下一篇把这些 owner 放到系统边界上。 当前端、工具服务、远程 Agent、编辑器与模型 provider 可以独立实现和升级时, runtime 还需要公开约定怎样发现能力、创建任务、传输事件和关联结果。 这时再读 MCP、A2A、AG-UI 与 Agent Client Protocol,就能看清每条协议连接的是哪两个工作现场。

参考源码与延伸阅读