五类 Agent Harness 对比:Session Compact、长任务与 Memory

对比五类 Agent Harness 后可以看到:长任务的核心不只是压缩上下文,而是保存状态、控制副作用并允许人重新介入。

Agent Harness 很容易被理解成“给模型装上工具”。但只要任务持续得足够久,真正困难的部分就会浮现:上下文会膨胀,执行现场会消失,副作用无法简单回滚,人也需要在中途重新介入。

因此,比较 Harness 不能只看一次 Agent Loop 跑得多漂亮。更有价值的问题是:Session 如何保存,Compact 丢掉了什么,长任务怎样恢复,Memory 又在哪一层发挥作用。下面从这些边界出发,对比 Codex CLI、Mastra、Pi、DeepSeek Harness 与 Downcity。

先说结论:Compact 只是长任务的一环

五个系统表面上都在做“让模型循环调用工具”,但它们对状态的基本判断完全不同:

  • Codex CLI:Session 是可恢复的工程线程,compact 是服务化的上下文维护能力。 它把模型调用、线程存储、usage、沙箱、审批和审计放进一个强工程化运行时。压缩既可以本地完成,也可以交给 Responses API 的服务端 /responses/compact;子 Agent 通过父子 thread 树派生,适合一次任务内的短生命周期并行执行。
  • Mastra Agent:Session 是 workflow 的运行实例,compact/memory 是框架内置的 context runtime。 Agent loop 被表达为可快照的 workflow,支持 pending、paused、suspended 和 resumeStream()。Memory 不只是历史消息,而是 working、semantic、observational、history 等多层能力;Observational Memory 用 Observer/Reflector 后台把原始轨迹压成 observation log。
  • Pi Agent:Session 是可导航的分支树,compaction 是可回溯的有损压缩。 历史以 JSONL 保存,/tree/fork/clone 让用户在历史任一点分叉。压缩只改变当前工作上下文,不删除完整历史;压缩摘要还会保留 readFiles、modifiedFiles 等文件级工作线索。它是五者中 Session UX 最成熟、最适合人工探索和回溯的系统。
  • DeepSeek Harness:Session log 是唯一事实源,compact 是插件化的可替换能力。 dsh 以 “Everything is a Plugin” 为架构原则,agent loop、模型、工具注册表、会话日志和 compaction 都位于插件树中。它用 Model-visible ⟺ logged 约束模型所见内容必须可由日志重建,并通过 Cordis 的可逆副作用和响应式依赖支持组合、热替换与自修改。
  • Downcity SDK:以既有 Workspace 为边界的分层 Agent Runtime。 Downcity 把 Agent、Workspace、Session、Turn 分开,SessionLoop 负责命令队列和 turn 生命周期,Executor 负责单次执行编排,CoreEngineRunner 负责工具循环;compact 基于 provider 返回的真实 usage,memory 保持为插件而不是核心状态系统。它的重点不是做一个全栈 Agent 产品,而是让 Agent 进入用户已有项目,并在其上叠加 Shell、Sandbox、Plugin、City/Federation 等产品化能力。

最重要的结论不是谁“压缩算法最好”,而是五者在解决四个不同层面的问题:

  1. Compact 解决的是当前请求如何不超过窗口,以及如何降低 context rot。
  2. Session 解决的是一次对话/线程如何持久化、分支、恢复和审计。
  3. Long-running execution 解决的是模型循环、工具进程、审批等待、网络中断和跨进程恢复能否继续。
  4. Memory 解决的是哪些经验应跨 turn、跨 session、跨 agent 留存,以及如何被检索、修改、审计和遗忘。

如果把这四层混成一个“memory”对象,系统很快会变得不可解释。正确的设计应当是:

Session log / event journal       = 事实与审计层
Compact summary                   = 当前上下文的有损视图
Execution checkpoint              = 运行现场的恢复层
Working / semantic / episodic     = 可检索的记忆层
Files / skills / artifacts        = 人可编辑的外部知识层

四种状态不能混为一谈

Conversation history 不等于 Memory

最小 Session 通常保存:用户消息、assistant 消息、tool call、tool result、系统事件和运行元数据。它回答“这次发生了什么”。

Memory 则回答“哪些内容值得在未来再次使用”。它需要 scope、重要性、时间、来源、冲突、权限、召回和淘汰策略。把完整 transcript 每次原样塞回 prompt,只是 history persistence,不是长期记忆。

Compact 不等于 checkpoint

Compact 通常是把旧消息压成摘要,替换当前 prompt 中的一段历史。它保存的是模型继续工作所需的语义状态,不一定保存执行现场。

Checkpoint 保存的则可能是:当前 workflow step、pending tool call、审批状态、重试次数、任务预算、子进程句柄、内核状态或 event offset。摘要告诉模型“之前做了什么”,checkpoint 让 runtime 知道“下一步从哪里继续”。

Memory 不等于“越多越好”

长上下文存在 context rot:输入越长,相关但不能回答问题的干扰项越多,检索和推理互相挤占。LongMemEval 类问题也显示,只给相关片段时表现较好,把完整长历史全部塞入时反而显著下降。

因此,Memory 的核心不是存储容量,而是在正确时机,以正确粒度,向模型暴露正确内容。这也是 token budget、priority、recency、scope 和 progressive disclosure 必须成为一等设计的原因。


Codex CLI:以工程线程为中心

Session/Thread 的基本模型

Codex CLI 的 Session 更接近“工程任务线程”,而不是一个长期人格 Agent。核心循环在 ModelClientSession 中通过 Responses API 流式运行;thread store、状态数据库、audit、rollout、usage 和 TUI/IDE app-server 共同支撑它。

在多 Agent 场景中,Codex 采用父子执行树,而不是长期 Agent 团队:

Parent thread/session
  ├─ spawn child task
  ├─ send_message / followup_task
  ├─ wait
  └─ resume / interrupt / close

子 Agent 有 parent session、path、depth、任务名和生命周期状态。派生时可以继承完整历史、使用压缩后的上下文、切换角色指令、指定模型和 reasoning effort。因此,spawn 本身也是一次上下文切分:父线程保留控制权,子线程只承接完成局部任务所需的上下文。

Compact 的实现逻辑

工作区源码索引显示,Codex 的压缩由 compact.rscompact_remote_v2.rscompact_model_fallback.rs 等模块组成,主要逻辑可以还原为:

  1. 读取 provider 返回的真实 usage,而不是完全依赖本地估算。
  2. 根据 token budget 判断当前上下文是否接近或超过窗口。
  3. 选择本地或服务端压缩路径。
  4. 将较早的消息、工具事务和工作进展压缩为 checkpoint/summary。
  5. 保留不能被破坏的最新 user 消息和最新工具事务。
  6. 将压缩后的上下文继续交给 Responses API 执行。

其关键特点是服务端 compact:本地运行时只需要关心预算、历史边界和恢复;模型侧的压缩可由 OpenAI 服务完成。这减少了客户端对具体摘要 prompt、tokenizer 和 provider 差异的负担,但也进一步强化了对 OpenAI Responses API 的绑定。

长任务策略

Codex 的长任务能力主要来自四个部分:

  • 真实 usage 驱动的上下文维护:避免因为本地估算误差导致请求突然溢出。
  • 可恢复的 thread/store:会话、rollout、audit 和状态库让任务具备暂停后重启的基础。
  • 父子执行树:把大任务切成短生命周期子任务,由父 Agent 汇总,降低单个上下文不断膨胀的压力。
  • 安全运行时:Linux 的 bubblewrap、Landlock、seccomp,macOS Seatbelt,Windows sandbox,以及网络代理和 guardian 审查,使长任务不等于长时间无限制执行。

但 Codex 的长任务本质仍是“工程线程持续推进”,不是 Prime Agent 那种 daemon + heartbeat + autonomous goal,也不是 Mastra 那种通用 durable workflow。它擅长把一次编码任务跑完并可恢复,不以长期后台人格或跨任务自我学习为中心。

Memory 设计

Codex 具备 memories、thread-store、状态日志和 skills 等能力,但应区分:

  • thread store:保存当前/历史线程;
  • rollout/audit:保存执行和安全审计;
  • memories:提供更长期的经验或偏好入口;
  • skills:人或系统维护的可复用程序性知识。

Codex 的优势是“模型所做过的事情”被工程日志、usage 和审计体系包围;局限是长期 Memory 的领域模型不是它最突出的产品中心,而且完整云侧能力与 ChatGPT/OpenAI 服务绑定。它更像强 Session + 强安全 + 可选 Memory,而不是 memory-first 框架。

评价

Codex 的设计取舍是:宁可绑定一个强大的云端协议,也要把安全、用量、恢复和可观测性做成完整系统。它适合企业级 coding agent、受控工作区和一次任务内并行协作;不适合需要多模型一等公民、跨 provider 的本地长期记忆实验。


Mastra:把 Agent Loop 变成可恢复 Workflow

Session 与 Workflow 的关系

Mastra 最关键的判断是:Agent loop 不应只是一个不可见的 while,而应是可以持久化和恢复的 workflow。其 agentic loop 以 createWorkflow().dowhile(agentic-execution) 表达,并拆成多个步骤:LLM execution、tool call、mapping、background-task check、signal drain、task completion 和 goal step。

因此,Mastra 的 Session 更接近一个 workflow run:

Session / Run
  └─ Workflow execution
      ├─ LLM step
      ├─ Tool step
      ├─ background/signal step
      └─ checkpoint snapshot

快照重点覆盖 pending、paused、suspended 三类状态,resumeStream() 从暂停点继续;DurableAgent 则把这个能力延伸到跨进程恢复。

Compact 与 Observational Memory

Mastra 将“历史太长”拆成两个相互配合的机制:

第一层是 history/context 管理。 当前对话历史仍然需要进入运行上下文,框架通过 token threshold、context budget 和 storage adapter 控制加载范围。

第二层是 Observational Memory。 Observer 和 Reflector 作为后台 Agent:

  1. 读取增长中的 message/tool history。
  2. 形成密集的 observation log,而不是继续保留全部原始轨迹。
  3. 在需要时通过 temporal marker、extractor 和 working-memory update 重组上下文。
  4. 通过异步 buffering 尽量不阻塞主 agent loop。

这不是简单的“把前 N 条消息截断”,而是把历史转换为另一种面向任务的表示:保留目标、事实、进展、决策和重要观察,减少模型每轮重新扫描工具输出的成本。

Prompt cache 的取舍

Observational Memory 的工程难点是压缩会改变 prompt 前缀。即使最近消息保持原样,只要 system/history 前面的结构从原始 transcript 变成 observation,provider 的 prompt cache 也可能失效。因此 Mastra 通过阈值、异步 buffer 和密集 observation 来减少频繁重写。

这里存在三角权衡:

信息保真度  ↔  上下文长度  ↔  Prompt cache 命中率

压缩过频,缓存不断重建且摘要会有损;压缩过晚,context rot 和请求成本上升。Mastra 的方向是后台观察和批量压缩,而不是每个 tool call 后立即总结。

长任务策略

Mastra 是五者中对“长任务运行时”抽象最完整的之一:

  • workflow snapshot:记录步骤和状态;
  • pause/resume:审批、外部事件或资源不足时挂起;
  • signals:运行中注入异步事件;
  • schedules/background tasks:把工作移出当前请求;
  • DurableAgent/EventedAgent:支持跨进程和事件驱动;
  • workspace/process 工具:执行长进程、读取输出、kill process;
  • 远程 workspace:Docker、E2B、Daytona、Modal 等后端。

这套逻辑解决了“模型还没完成,但 HTTP 请求已经结束”的问题。需要注意,workflow checkpoint 和 shell 子进程现场仍是两个层次:恢复 workflow 不必然能恢复一个已经消失的操作系统进程,除非 workspace backend 自己提供进程持久化。

Memory 设计

Mastra 的 Memory 是内置能力,至少包含:

  • history:会话消息历史;
  • working memory:当前用户/任务的结构化状态,通常通过工具调用或 schema 更新;
  • semantic memory:跨 session 的事实和相似内容召回;
  • observational memory:从长轨迹沉淀出的密集观察。

同时它拥有多种 storage adapter,以及 RAG、embedding、rerank 等配套。优点是开箱即用,应用很快得到一条完整链路;代价是 Memory 与 Mastra Agent、Storage、RAG 生命周期耦合较深。观察日志仍是模型派生物,不能自动当成不可争议的事实源。生产系统仍应保留原始证据、来源和可编辑的 canonical data。

评价

Mastra 的核心创新不是某一个摘要 prompt,而是把上下文、执行、存储和记忆统一成可持久化 runtime。它最适合作为 TypeScript Agent SDK 的默认参考:如果产品需要 HITL、后台任务、RAG、working memory 和 durable execution,Mastra 的完成度很高。缺点是全内置带来复杂度、耦合和较重的依赖面,且开源框架层与托管云能力需要分开评估。


Pi:用 Session Tree 支持回溯

Session 是树,不是线

Pi 的 Session 采用 JSONL 持久化,但逻辑上是一棵树。每个节点是消息/事件,分叉点保留 parent 关系。用户可以:

  • /tree:浏览历史树;
  • /fork:从任意历史点开新分支;
  • /clone:复制当前分支继续实验;
  • bookmark/label:给重要状态打标。

这意味着“错误尝试”不必被删除,“新方向”也不必污染主线。Session 不只保存最终 transcript,还保存用户对执行历史的导航选择。

Compaction 的具体流程

Pi 的压缩逻辑具有四个要点:

  1. 自动触发 + 手动触发:turn 结束后检查上下文占用,接近窗口时自动 compact;用户也可用 /compact 主动触发。
  2. 保留最近窗口:按可配置 token budget 原样保留最近一段消息,默认约 20K token;之前历史交给独立 LLM 请求总结。
  3. 摘要请求与主对话隔离:改变 system prompt 和 user instruction,让模型输出覆盖目标、进展、决策、关键上下文的结构化交接摘要;可以使用更便宜的模型。
  4. 溢出兜底:如果 turn 执行中已经撞到窗口上限,先 compact,再恢复未完成的任务,而不是直接让会话报废。

压缩后的摘要写回 Session,作为纯文本继续参与后续请求。模型切换时摘要可移植,不必因换 provider 重新压缩。

Pi 的独特性在于:压缩是当前分支的工作视图变化,不是历史事实的删除。 完整历史仍在 JSONL 中,可通过 /tree 回看和从旧节点 fork。

文件级上下文追踪

Coding agent 的摘要不能只写“完成了若干工作”。Pi 的 compaction utils 会统计 readFiles、modifiedFiles 等文件操作,提醒后续 Agent 哪些文件已经读过、改过、验证过。这个设计把“代码工作状态”显式写进 handoff briefing,减少压缩后模型重新扫描整个仓库的需要。

长任务策略

Pi 的长任务主要依靠:

  • 持续的流式 agent step;
  • queue mode 和 steering,在运行中插入用户引导;
  • abort signal 与工具输出截断;
  • 文件 mutation queue,避免并发写文件互相覆盖;
  • session tree/fork/clone,让人可以在长任务中保留多个方案;
  • 扩展系统接入 sandbox、permission gate、subagent、SSH、git checkpoint 等能力。

Pi 原生更强调“一个人和一个可导航的 Agent 一起工作”,而不是 durable workflow 平台。默认没有内建强沙箱,安全主要通过扩展实现;也没有 Codex/Mastra 那样系统级的跨进程 workflow 恢复。对于交互式 coding,它的可控性和可探索性极强;对于无人值守长任务,需要额外 daemon、sandbox、heartbeat 和外部 supervisor。

Memory 设计

Pi 的核心 memory 是“可回看的 Session 历史 + 压缩摘要 + 文件工作线索”,而不是内置企业级长期事实库。它通过扩展实现更强的 memory、skill、subagent 或外部检索。

这是一种有意的窄内核策略:

  • 原始证据留在 JSONL;
  • 当前 prompt 使用 compact summary;
  • 可复用知识沉淀到扩展、skill 或项目文件;
  • 其他长期 Memory 由插件决定。

优势是可移植、透明、不会强迫用户接受某一种向量数据库;缺点是跨 session 事实提炼、冲突治理、权限和自动召回需要自行搭建。

评价

Pi 解决的是“长对话如何不丢失可回溯性,以及人如何继续掌控分支”。它证明了 compact 不必等于不可逆删历史:压缩当前上下文,保留完整事件源,是 coding harness 非常值得采用的模式。


DeepSeek Harness:不可变日志与可逆 Runtime

Session log 是唯一事实源

dsh 的架构铁律是:Model-visible ⟺ logged。凡是到达模型请求的内容,都必须能够从 session log 重建;fork、resume、transcript、telemetry 和持久化都从这条日志派生。

这与普通“保存聊天记录”不同:日志不是 UI transcript 的附属物,而是 runtime 的 canonical event stream。它使以下能力具有共同基础:

  • 重建某次模型请求;
  • 审计模型看到了什么;
  • 从历史 fork 出新 Session;
  • 在压缩后解释摘要来自哪些事件;
  • 在插件卸载/替换后恢复运行状态。

Compact 作为插件

dsh 的包结构包含 compaction/context/,但它们不被设计成不可替换的核心黑盒。Profile、bundle、patch 可以组合插件树;agent loop、session log、工具和模型也都是插件。

因此 dsh 的 compact 逻辑可以理解为:

  1. session log 持续追加原始事件;
  2. context 插件根据 token budget/上下文策略决定需要压缩的范围;
  3. compaction 插件生成新的上下文表示;
  4. 新表示仍作为可重建、可记录的事件/派生视图进入日志体系;
  5. 后续 fork/resume 使用同一事实源,而不是只依赖内存中的 prompt 数组。

dsh 的重点不是公开一个固定的摘要参数,而是让压缩成为可替换的 runtime seam。这允许不同 profile 使用不同 compact 策略,也符合其“能力定义 + provider + consumer”的三角色能力缝。

长任务与可逆副作用

DeepSeek Harness 的长任务优势不主要体现在一个专门的 autonomous scheduler,而在于运行时组合能力:

  • 插件树:可以替换模型、工具、loop、workspace、sandbox、session 和 compaction;
  • Cordis temporal composability:插件产生的副作用带有可追踪逆操作,卸载时可以 unwind;
  • Cordis spatial composability:插件声明依赖并响应式获取服务,能力变更能通知消费者;
  • headless/web/ACP:同一个 runtime 通过不同宿主运行;
  • self-modification:Agent 可以自省并挂载插件,但这依赖严格的权限和可回退机制;
  • 可替换 sandbox:本地、E2B、远程执行世界可以通过 provider 迁移。

这是一种“runtime 长寿命”而非“单任务无限变长”的路线。它回答的是:当任务需要热装卸能力、改变工具面、切换执行后端或从中断点继续时,如何不把系统变成一堆残留回调和隐式状态。

Memory 设计

dsh 的 Memory 基础首先是 event log,而不是内置的 semantic memory 产品。它提供了形成 Memory 所需的正确锚点:模型可见内容可重建、工具轨迹可审计、fork/resume 有统一来源、插件可替换。

但“日志是事实源”不意味着“日志就是长期记忆”。要实现跨 session 的用户事实、团队知识、skill 或向量检索,还需要额外的 memory plugin。dsh 的强项是为这些插件提供一致的 runtime 生命周期和事件输入;弱项是 developer preview 阶段仍不应把插件化能力等同于成熟的长期记忆治理。

评价

dsh 把问题下沉到组合语义:如何把一个能力装上、使用、卸下并干净回滚。它最值得借鉴的不是“所有东西都插件化”这句口号,而是两个工程不变式:

  1. 模型所见必须可重建。
  2. 运行时副作用必须可回退。

这会让 compact、memory、self-modification 和长任务恢复拥有共同的可审计基础。代价是架构复杂度和学习成本较高,且 developer preview 的 breaking change 风险需要单独计入。


把五种 Harness 放在一起

核心机制矩阵

维度 Codex CLI Mastra Agent Pi Agent DeepSeek Harness Downcity SDK
Session 隐喻 工程 thread workflow run 可导航 session tree append-only session log Workspace 内的 Agent Session
原始事实源 thread/store + audit/log storage + workflow snapshot JSONL 全历史 session log,模型所见必记录 JSONL message store + SessionEventHub
Compact 触发 usage/token budget,含服务端 compact context budget + observational pipeline turn 后自动、手动、溢出兜底 context/compaction 插件策略 provider 真实 usage,约 95% 触发并回落至约 50%
Compact 结果 checkpoint/summary,偏继续执行 observation/working context 结构化 handoff summary 可替换的 context 派生视图 checkpoint summary,原子保留最新 user/tool transaction
原始历史是否保留 由 thread/store 与 rollout 能力支持 取决于 storage/config,通常与 memory 分层 保留,压缩可回溯 日志作为 canonical source JSONL 持久化,checkpoint 作为当前视图
运行恢复 thread、app-server、状态/审计基础 workflow snapshot + resumeStream 交互式 resume,非完整 durable workflow log + plugin runtime + resume 方向 SessionLoop/Executor 恢复策略,尚未等同 durable workflow
运行中注入 parent message/followup、控制面 signals/background tasks steering/queue mode interaction/event/plugin 机制 Session command queue、stop/cancel、ActionSchedule
长任务重点 安全、恢复、父子并行 durable workflow、HITL、后台任务 人机导航、分支、扩展 热替换、可逆副作用、可组合 runtime Workspace 边界、审批、usage、可复用 runtime
内置长期 Memory 有入口但非中心 working/semantic/observational/history 核心较轻,扩展为主 事件源为基础,Memory 插件化 Memory 插件化,Session 不与 Memory 混同
多模型 OpenAI 绑定较深 AI SDK + gateway/router 30+ provider 一等支持 provider 可插件化 AI SDK 注入,City 负责路由/计量
安全 最强:沙箱 + guardian + 网络策略 native/remote workspace,能力丰富 默认安全依赖扩展 sandbox provider 可替换,需看 profile deny-default 沙箱 + ShellApprovalRuntime
适合场景 企业 coding、受控执行 全栈 Agent 应用、durable workflow 交互式 coding、探索和分叉 可组合、自修改、可替换 harness 多产品 Agent 基础设施、repo-native workflow

四种不同的 Compact 哲学

Codex:服务化压缩。 重点是让强 provider 处理压缩,客户端保持工程边界和恢复能力。

Mastra:观察式压缩。 重点是把历史持续转成 observation,借后台 Agent 和异步 buffer 维护长会话。

Pi:交接式压缩。 重点是摘要像换班 briefing,当前上下文变短,但完整历史仍可回看和分叉。

dsh:组合式压缩。 重点是 compact 不应成为核心魔法,而应通过插件、日志和 capability seam 被替换、审计和回退。


Downcity:Workspace-native 的分层 Harness

它解决的问题不同

Downcity SDK 不把自己定位成另一个面向终端用户的编码 Agent,也不把 Agent loop 做成一个全栈应用框架。它的基本边界是:Agent 进入一个已有 Workspace,在项目原生的文件、目录、脚本、文档、配置和工作流中执行。

对象关系可以概括为:

Agent
├─ model / instruction / plugins
└─ enter(Workspace)
   └─ AgentWorkspace
      └─ Sessions
         └─ Turn

Workspace 负责项目路径、Shell、Sandbox 和环境;Agent 负责模型、指令和插件;Session 负责连续交互;Turn 表示一次 prompt 到结果的执行过程。这个所有权划分很关键:它避免把项目文件、模型身份、会话历史和长期 Memory 塞进一个大对象。

执行循环的分层

已有源码拆解显示,Downcity 的执行链分成三层:

  • SessionLoop:Session command queue 的唯一消费者,拥有 turn 生命周期。Prompt 进入 FIFO 队列,stop 可以取消排队项。
  • Executor:编排一次 session execution,处理 recovery policy、重试以及错误后的压缩恢复。
  • CoreEngineRunner:执行模型与工具的循环;CoreEngineLoopDecision 将“不完整响应恢复、工具调用续跑、text-only 续跑、停止”等判断抽成纯函数。

这套分层与 Mastra 的 workflow 不同。Mastra 把循环表达为可快照 workflow;Downcity 把循环表达为命令队列 + 执行器 + 纯函数决策。前者天然适合 durable step resume,后者天然适合在一个 Workspace 中插入 prompt、取消排队命令、连接插件和控制执行边界。

Compact 的实现取舍

Downcity 的 compact 不是按字符长度或调用前估算触发,而是根据 provider 返回的真实 usage 管理上下文。已有源码分析记录的策略是:上下文使用量达到窗口约 95% 时触发,压缩后回落到约 50% 以内;历史折叠成 checkpoint,并原子保留 user 消息与最新 tool transaction。

这带来三个工程收益:

  1. provider 的 tokenizer 和实际计费差异不会完全由客户端猜测;
  2. 最新用户意图和正在完成的工具事务不被摘要过程拆散;
  3. Executor 可以把“出错 → 压缩 → 重试”作为明确的恢复路径,而不是把 overflow 当成终止错误。

它的主要不足也很清楚:当前模型更接近“checkpoint 压缩 + session continuation”,还没有 Pi 那样完整的 session tree/fork UX,也没有 Mastra 那样成熟的 observational memory 后台流水线。若要达到 durable execution,必须进一步持久化挂起点、当前 loop step、审批状态、重试预算和外部进程状态,而不只是保存一份摘要。

长任务与 Workspace 边界

Downcity 的长任务能力主要建立在 Workspace 和控制面之上:

  • SessionLoop 提供命令排队、停止和 turn 生命周期;
  • ExecutorRecoveryPolicy 负责失败恢复与压缩重试;
  • ShellApprovalRuntime 把需要授权的命令放到审批网关;
  • macOS Seatbelt、Linux Bubblewrap、Windows MXC/SRT 提供可替换沙箱后端;
  • ActionScheduleStore 支持定时动作;
  • SessionEventHub、JSONL message store 和 usage 记录提供可观察性;
  • City/Federation 负责模型目录、路由、认证、计量、计费和跨 Agent/Workspace 的产品化边界。

这里的长任务不是“一个 Agent 在后台自主运行”的默认形态,而是“一个可进入既有项目的 runtime 能持续、安全、可计量地执行工作流”。与 Prime Agent 的 daemon、heartbeat、autonomous goals 相比,Downcity 的主线更偏多产品基础设施;与 Mastra 的远程 workspace 相比,它更强调 repo-native 边界和审批控制。

Memory:明确保持为插件

Downcity 当前有意不把 Memory 做成 Agent 核心。这个决策与 Session 边界有关:Session 保存这次运行发生的事实,Memory 插件决定哪些事实值得跨 session 保留。

其合理的最小 Memory SPI 可以覆盖:

read / write / observe / consolidate

这样可以接入本地文件或 SQLite,也可以接入 Mastra memory、mem0、Cognee 等外部实现。关键是适配器不应取代 Session 的 canonical history,也不应让某个向量数据库定义 Downcity 的领域模型。

这个选择牺牲了 Mastra 式的开箱即用,但保留了更强的替换自由度。对 Downcity 来说,长期差异化不应是再实现一个通用向量记忆,而是把 Memory 与 Workspace、项目文件、Skill、权限、usage 和 City 计量连接起来。

Downcity 的独特层:City/Federation

Codex、Pi、Mastra 和 dsh 主要竞争 Agent 运行时本身;Downcity 额外提供 City/Federation:

  • Agent、Workspace 和 Plugin 的服务化索引;
  • 模型路由和 fallback;
  • AI usage 和 metering;
  • 账户、余额、支付和组织服务;
  • bureau token、远程 Agent 和跨组织连接。

这使 Downcity 更像“Agent Harness + Agent Productization Base”。它的竞争问题不是“是否比 Mastra 多一个工具”,而是能否让多个 Agent 产品共享相同的执行、计量、权限和工作区边界。

评价

Downcity SDK 最值得保留的设计是边界清晰:Workspace 不拥有 Agent,Session 不冒充 Memory,Executor 不直接承担 City 的产品逻辑,插件提供能力而不是把核心循环复制一遍。

它当前最明显的缺口也与这个定位直接相关:测试数量、durable pause/resume、Memory 默认实现、evals 和跨进程执行恢复仍需要补齐。换句话说,Downcity 的架构方向与成熟方案一致,但可信度必须由恢复测试、压缩测试、沙箱测试、计量测试和 Memory adapter 测试来兑现。

长任务的难题远不止 Compact

一个任务要持续数小时甚至数天,至少要同时解决以下问题:

上下文膨胀

工具结果、文件内容、失败尝试和模型中间轨迹不断增加。解决方案是 compact、prune、渐进披露和检索,而不是简单扩大 context window。

执行现场消失

HTTP 请求结束、进程重启、机器断电后,模型摘要不足以恢复 shell 进程、审批等待、未完成工具调用和外部资源锁。Mastra 的 workflow snapshot、Codex 的 thread/state、dsh 的 event log 都是在解决这层;Pi 默认仍更偏交互式会话。

人类需要重新介入

长任务不是完全无人值守。审批、澄清、预算超限、目标改变和错误恢复都要求 Agent 能暂停并等待。Mastra 的 HITL pause/resume 最直接;Codex 有强审批策略;Pi 通过 steering 和扩展完成;dsh 把 interaction 也视为插件能力。

代码和工具的外部副作用

长任务可能修改文件、启动服务、写数据库、消耗 token、访问网络。恢复时必须知道哪些副作用已经发生,不能仅凭模型自述。Codex 的 audit/guardian、Pi 的 git checkpoint 扩展、dsh 的 revertible effects,以及事件日志,分别提供了不同答案。

预算和调度

长任务需要 token、时间、工具调用次数、并发数、费用和失败重试预算。Mastra 有后台任务和 workflow 生态,Codex 有 usage/rollout,Pi 可由扩展和上层 supervisor 补齐,dsh 可通过插件组合。真正生产化的系统必须把预算状态写入可恢复的 execution state。


Memory 应该分层,而不是堆成一个池

从五个系统可以抽出一套更稳定的 Memory 分层:

L0:原始 Session/Event Log

不可变或 append-only,保存用户消息、模型输出、工具调用、工具结果、审批和系统事件。它是证据层,不直接全部注入 prompt。

L1:Working Memory

当前任务的结构化状态,例如目标、约束、已确认决定、待办、已修改文件、测试状态、外部资源 ID。它应可由 Agent 工具显式更新,最好有 schema、版本和 owner。

L2:Compaction / Observation

从近期或历史轨迹生成的密集交接摘要。它服务于当前 context,不应自动升级为事实数据库。应保存来源 event range、生成模型、时间和版本,支持重建与重新生成。

L3:Semantic/Episodic Memory

跨 session 检索的事实、过去案例、用户偏好、项目知识和经验。需要 scope、时态、置信度、来源、权限、冲突和删除策略。

L4:Procedural Assets

Skills、规则、模板、代码片段、workflow 和可复用工具。它们比向量记录更接近“能直接改变未来行为”的知识,必须版本化、可审阅、可回滚。

L5:Live Execution State

正在运行的进程、内核变量、网络连接、队列、scheduler、checkpoint 和资源锁。这是 Prime Agent 所展示的“活内核”路线,也是最难审计、最不可移植的一层。不能把它与 L0-L4 混称为 memory。

推荐的注入顺序为:

system policy
→ project / user working memory
→ relevant semantic/episodic memories
→ compacted session briefing
→ recent raw messages and tool transactions

每一层都应有 token budget;召回结果应渐进披露,而不是把全部结果一次塞进上下文。


哪些机制值得学习

最值得学习的机制

  • Codex:真实 provider usage 驱动 compact;安全策略、网络策略和审计必须进入主架构;子任务用父子执行树隔离上下文。
  • Mastra:把 agent loop 设计成可 snapshot/resume 的 workflow;审批不是结束流后重新发起,而是从挂起点继续;Memory 应有 working、observational、semantic 的明确分层。
  • Pi:保留完整原始历史,压缩只是当前工作视图;session tree/fork/clone 是长任务的人类控制面;摘要应包含文件、决策和未完成事项,而非泛泛总结。
  • dsh:建立 Model-visible ⟺ logged 不变式;为插件副作用登记逆操作;让 compaction、workspace、sandbox、model 和 loop 通过 capability seam 替换,而不是散落硬编码。

不应直接照搬的部分

  • 不应把所有 history 都直接变成长期 Memory;Mastra observation 也必须保留 evidence。
  • 不应只做摘要而不做 execution checkpoint;否则“知道发生过什么”仍不能“从中断点继续”。
  • 不应为了插件化把每个内部对象都抽象掉;dsh 的组合能力很强,但产品级 runtime 仍需清晰的稳定核心。
  • 不应把 daemon、heartbeat、autonomous scheduler 当作长任务的全部答案;它们解决调度,不解决安全、审计、事实一致性和恢复。
  • 不应把 prompt cache 当作压缩后的附带问题;压缩策略必须记录缓存失效成本,并以批量、阈值和异步 buffer 控制频率。

一个更完整的目标架构

一个面向现有工作区、支持长任务的 harness,可以采用如下分层:

SessionEventLog(append-only canonical source)
        ↓
Turn / Tool Transaction / Approval Event
        ↓
Execution Checkpoint(loop step、预算、挂起点、资源状态)
        ↓
Context Manager
  ├─ recent raw window
  ├─ compaction summary
  ├─ working memory
  └─ relevant long-term memory
        ↓
Model request(所有可见内容可从 log 重建)

实现优先级:

  1. P0:日志不变式——记录所有模型可见内容、工具事务和审批事件,并可重放一次请求。
  2. P0:真实 usage compact——支持阈值触发、溢出兜底、最新工具事务原子保留、摘要来源可追溯。
  3. P0:working memory——用 schema 管理目标、决策、待办、文件和验证状态,避免全部依赖自然语言摘要。
  4. P1:pause/resume checkpoint——先实现审批挂起,再扩展到外部事件、跨进程和长进程。
  5. P1:Session tree/fork——保留原始 history,允许从任意 checkpoint 创建分支。
  6. P1:Memory SPI——冻结 read / write / observe / consolidate 等最小接口,允许接本地 SQLite、Mastra、mem0 或其他服务,而不把 provider 核心化。
  7. P2:可逆 effect——为文件修改、插件挂载、环境变量和进程等副作用逐步增加 undo/rollback 能力。
  8. P2:evals 与成本报表——评估摘要事实保真度、恢复成功率、召回准确率、缓存命中率和每任务成本。

建议的最小评测指标

  • compact 后任务继续成功率;
  • 摘要遗漏关键决策率;
  • 文件状态和测试状态保真率;
  • overflow recovery 成功率;
  • pause/resume 后重复副作用率;
  • memory 召回 precision/recall;
  • prompt cache 在 compact 前后的命中率;
  • 长任务每有效完成任务的 token、时间与费用;
  • 从原始 log 重建 model-visible context 的一致率。

最后:Harness 管理的是连续性

五个 Harness 的竞争,不是“谁有更多工具”,而是“谁能把状态变成可靠的执行基础设施”:

  • Codex 把可靠性押在 工程化、安全和 provider 服务
  • Mastra 把可靠性押在 workflow、存储和内置 Memory runtime
  • Pi 把可靠性押在 可回溯 Session 和人类导航
  • DeepSeek Harness 把可靠性押在 日志不变式、可逆副作用和插件组合语义

对于未来的 Agent 产品,最可能成为默认配置的不是单一方案,而是五者的组合:

Codex 的安全与 usage
+ Mastra 的 durable workflow 与分层 memory
+ Pi 的 session tree 与可回溯 compact
+ dsh 的 event-sourced plugin runtime 与可逆 effects

但组合时必须守住边界:原始日志是证据,compact 是视图,checkpoint 是恢复状态,Memory 是经过治理的可复用知识,live runtime 是执行现场。

真正的机会也不在再造一个更大的 Agent loop,而在于把这五类状态之间的转换做成可观察、可恢复、可审计、可计量的协议。谁能让长任务在压缩之后仍然知道“目标是什么、已经做了什么、下一步是什么、哪些副作用已经发生、哪些记忆值得保留”,谁才真正拥有下一代 Agent Harness 的基础设施能力。


资料来源与边界

  1. 03-研究/源码拆解/Agent 源码对比:Hermes · Codex CLI · Pi · Downcity.mdx:Codex、Pi、Mastra 的源码快照对比,以及 Mastra workflow/memory 对比。
  2. 03-研究/源码拆解/DeepSeek Harness (dsh) 与 Downcity Harness 对比.mdx:DeepSeek Harness 的插件树、Cordis、session log、Model-visible ⟺ logged 与可逆副作用分析。
  3. 03-研究/领域调研/web plugin/memory 2.mdx:Mastra Observational Memory、Session/Memory 边界、Memory 分层和其他方案横向研究。
  4. LanLance on X 读懂 Pi 的上下文压缩机制 - X.mdx:Pi compaction 的触发、保留窗口、溢出兜底、缓存代价与交接摘要设计。
  5. deepseek-harness-团队面试准备 · yopedia.mdx:Downcity Agent/Workspace/Session/Turn 的运行时组织方式,可作为 dsh 对照的工作区背景资料。
  6. 03-研究/源码拆解/Agent 源码对比:Hermes · Codex CLI · Pi · Downcity.mdx:Downcity SDK 的 SessionLoopExecutorCoreEngineRunner、真实 usage compact、沙箱、插件和 City/Federation 源码拆解。

边界声明:本文不把工作区中关于未来版本、生态规模或未逐行复核的实现描述当作稳定 API;涉及具体模块名和参数时,应以相应仓库当前源码与官方文档重新核验。