Agent 架构文档 · Markdown

上下文工程在 10 家 Agent 框架的深度对比

版本:2026 04 25 配套:本文是 5 个主题对比之一,专讲 System prompt 组装、context window 管理、压缩、prompt cache、按需召回、工具结果压缩、多 turn 稳定性、checkpoint 持久化 ;长期记忆架构(PG/Milvus/Neo4j/向量库/用户画像)属于另一篇《记忆系统》主题,本文只在交集处指明边

来源文件:context-engineering-comparison.md · 阅读时间 15 分钟

版本:2026-04-25 配套:本文是 5 个主题对比之一,专讲 System prompt 组装、context window 管理、压缩、prompt cache、按需召回、工具结果压缩、多 turn 稳定性、checkpoint 持久化;长期记忆架构(PG/Milvus/Neo4j/向量库/用户画像)属于另一篇《记忆系统》主题,本文只在交集处指明边界。


#目录


#零、为什么单独写"上下文工程"

LLM 调用唯一的输入是一段 token 序列。Agent 框架的全部"工程"都是在决定这段序列长什么样

  • 每轮 system prompt 拼几段、按什么顺序
  • context window 接近上限时是丢、是压、还是分叉
  • 哪些段必须保住才能命中 prompt cache
  • 哪些资料是"启动就在",哪些是"用到才查"
  • tool 输出是原文塞回,还是落盘只塞 path
  • 长会话怎么不让 system prompt 自己漂移

这 7 件事合起来叫"上下文工程"。它不是记忆系统(那是"长期记什么"),也不是工具系统(那是"能干什么"),而是每一轮真正喂给 LLM 的那段 token 是怎么生成的。十家答案差异巨大,从"写死禁止改"(Hermes)到"四档动态召回"(Cursor),跨度比记忆系统还大——值得专门写一篇。


#一、10 家速览大表

一行装得下一家的"上下文取向"——剩下的章节都是这张表的展开。

项目 默认模型 ctx 压缩策略 Cache 哲学 召回方式 System prompt 段数 session 持久化
OpenClaw 200K(取决 model) command:new/reset 触发 session-memory flush → session:compact:before/after 包住模型驱动 compact 取决 model provider(仓库无内置"prompt cache 压缩点对齐") Active Memory 子代理 + memory_search 工具 SOUL + AGENTS + TOOLS + IDENTITY + MEMORY + active_memory_plugin(6 段) session.jsonl append-only
Hermes 模型自选(4 系最高 256K) ContextCompressor v2,token-budget tail + Iterative summary 写死禁止 mid-conversation 改 prompt / tools / memory memory_manager.prefetch() 预取 + Honcho 注入 Personality + MEMORY + SKILL + ctx files + tool guidance + tools + model-specific(7 段) SQLite + FTS5 + session lineage
Claude Code 200K / 1M(按模型) auto-compact 三阶(drop tool out → summarize → 报错) 压缩后 project root CLAUDE.md re-inject,skill 按 25K 预算 re-attach CLAUDE.md 沿目录树 + auto memory + skill description always-on system + CLAUDE.md 链 + MEMORY.md + skill desc + subagent memory(5 层) session JSONL + agent-memory/
OpenAI Codex 取决于 gpt-5-codex /compact 显式 + Responses API server-side encrypted_content encrypted_content 由 OpenAI 后端管,CLI 持引用 AGENTS.md 多层级合并 + /init 骨架,无自动 memory system + product + merged AGENTS.md(嵌套)+ profile + subagent dev_instructions(5 段) 本地 SQLite + codex resume / fork / /side
Cursor 长 ctx MoE(Composer) 官方未公开(待核实) 官方未公开(待核实) 4 档触发:Always / Auto-Attached / Agent-Requested / Manual mode prompt + rules(按召回)+ Memories + AGENTS.md + @ 引用展开 服务端 chat + Codebase Index Merkle
Cline 200K(一般) /smol(同 task 自压缩)+ /newtask(切 task) 不主动管理 @file/@folder/@problems/@terminal/@git/@url 六种 @ 引用,token 暴力 内置 prompt + .clinerules 合并 + 文件树 + mode 标记(4 段) ~/.cline/data/taskHistory.json + 影子 git checkpoint
OpenHands 取决于 model Condenser 协议:NoOp / Recent / LLMSummarizing / ObservationMasking / AmortizedForgetting / Rolling 摘要本身也 emit 成 SummaryEvent Microagents triggers 关键词触发 + RecallAction → RecallObservation agent prompt + repo.md(永久) + microagent 触发注入 EventStream(确定性可重放)
AutoGen 取决于 model ChatCompletionContext 4 种策略:Unbounded / Buffered(N) / HeadAndTail / TokenLimited 用户自决 Memory protocol → update_context push system_message + Memory.update_context 注入(2 段) team.save_state() / load_state()
LangGraph 取决于 model pre_model_hook + trim_messages(用户写) 用户自决,可 reducer 控 Store API(namespace tuple)+ ToolNode 注入 完全用户决定,没框架级"system 段"概念 Pregel Checkpointer(Memory/SQLite/Postgres/Redis)

两个抽象坐标

  • 横轴:System prompt 是动态还是静态? 左边是 Hermes(写死禁止改)、AutoGen / LangGraph(用户决定);右边是 Cursor(4 档动态召回)、Claude Code(auto-compact 后 re-inject)、OpenHands(Microagent 触发性注入)。
  • 纵轴:Compaction 是框架默认还是用户责任? 顶端是 OpenHands(一等公民 Condenser)、Claude Code(auto-compact)、Codex(server-side encrypted_content);底端是 LangGraph / AutoGen(用户自己写 trim node)。

#二、System prompt 组装的 8 种哲学

"system prompt 是 agent 的身份证。怎么拼出来这张证,决定了 agent 是谁。"

#2.1 八种拼装模式

① 数据库 driven                                  ② 文件目录 driven
   apc_skill_dir_list 从 S3 拉 + 工具 schema 注入     SOUL + AGENTS + TOOLS + IDENTITY 4 个 md 拼

③ "三件套写死"                                  ④ "工程文件沿目录树"
   Hermes                                            Claude Code
   Personality + MEMORY + SKILL + ctx + tools        CLAUDE.md 沿 cwd 向上递归 +
   prompt_builder.py 一次性渲染                       auto memory MEMORY.md + skill description

⑤ "四层级合并"                                  ⑥ "模式 + Rules + 召回"
   Codex                                             Cursor
   ~/.codex/AGENTS.override.md → ~/.codex/AGENTS.md  mode prompt + rules(4 档触发)+
   → <git_root>/AGENTS.md → <cwd>/AGENTS.md          Memories + AGENTS.md + @ 引用

⑦ "目录拼起来"                                  ⑧ "完全交给用户"
   Cline                                             AutoGen / LangGraph
   .clinerules/*.md 合并 + 内置 prompt +              system_message 自由字段,
   文件树 + plan/act mode 标记                        没有"框架级 system 段"约定

#2.2 几个跨家共识

  • AGENTS.md 已成事实标准:Codex / Cursor / OpenClaw 原生识别这个文件名;OpenClaw 兼容 CLAUDE.md 软链。Claude Code 自己用 CLAUDE.md,官方建议在 CLAUDE.md 里写 @AGENTS.md 引入(不直接读取)。Cline 用 .clinerules/ 目录(同一逻辑、不同命名)。这是 2025-2026 行业最重要的一次开放胜利。
  • 嵌套合并 = developer-native:Codex 是嵌套层级最严密的(~/.codex/AGENTS.override.md~/.codex/AGENTS.md → 沿 git root 一路向 cwd 走),上限 32 KiB(project_doc_max_bytes,见 codex-agent-architecture.md §1.4 / §5.2)。Claude Code 用 4 个 scope(managed > project > user > local)+ 沿 cwd 向上递归(见 claude-code-agent-architecture.md §5.2)。
  • "frontmatter 是 schema 的最后一站":Cursor .mdc、Claude Code subagent .md、OpenHands microagent、Hermes SKILL.md,全部约定 YAML frontmatter 表达 metadata(name / description / triggers / globs / tools),主体走 markdown。这是行业里少见的"自然形成 schema"。

#2.3 最复杂的一份:Hermes prompt_builder

hermes-agent-architecture.md §1.4 的明确顺序:

[1] Personality(今天扮谁,~/.hermes/personalities/<name>.md)
[2] MEMORY.md         ← agent 长期记忆摘要
[3] 已加载的 SKILL.md  ← 程序性记忆
[4] 上下文文件 / context files
[5] Tool-use guidance(针对当前模型)
[6] <tools>...</tools>(function schema)
[7] Model-specific instructions(Hermes 4 → 是否启用 <think>)

7 段都进 system prompt,且整个会话内不变——这是 Hermes 把 prompt cache 完整性当成顶级硬约束的直接结果(见第四章)。

#2.4 最少的一份:AutoGen / LangGraph

AutoGen 的 AssistantAgent 只有一个 system_message: str 字段;LangGraph 没有"system 段"的概念,用户自己在 node 函数里拼 messages。框架不替你拼。这是"开放协议派"的写法——好处是想干啥都行,代价是新人写 agent 要从零搭框架。


#三、上下文压缩的 5 种算法对照

"context window 一定会爆——区别只在框架是把它当默认问题,还是当 plugin 问题。"

#3.1 五种主流算法

   - 触发:messages.token_count() > 150K
   - 步骤:fold_messages 把早期 N 轮合并成 [FOLD] 占位 → LLM summarize → Message.system 替代
   - 关键:折叠点对齐 prompt cache point(见 4.1)

② ContextCompressor v2(Hermes)
   - 触发:token usage 比例 + structured budget 联合判断(v0.2 的固定 50% 阈值已废弃)
   - 步骤:tail 保护按 token-budget(非固定条数)→ 中段 LLM summarize → 替换;旧摘要不被新摘要覆盖
     (Iterative summary 跨多次 compaction 累加)
   - 关键参数:SUMMARY_RATIO=0.20、_MIN_SUMMARY_TOKENS=2000、_SUMMARY_TOKENS_CEILING=12000
   - 关键:只压不归档(原文在 SQLite + FTS5 随时检索);summary 模板显式区分
     Resolved / Pending / Remaining Work,并带 preamble 防止被 LLM 误读成系统指令
   - 出处:hermes-agent-architecture.md §5.2

③ Auto-compact 三阶(Claude Code)
   - Step 1: 清掉旧 tool outputs(尤其大 file reads)
   - Step 2: 总结对话,保留你的请求 + 关键代码 + 每个已 invoke skill 前 5K(总 25K 预算)
   - Step 3: 报错 thrashing,停下来等用户介入
   - 关键:project root CLAUDE.md re-inject;skill 按预算 re-attach;嵌套 CLAUDE.md 不 re-inject
   - 出处:claude-code-agent-architecture.md §5.4

④ Server-side encrypted_content(Codex)
   - 触发:用户显式 `/compact`
   - 步骤:当前可见对话 → 替换成 type=compaction 的 input item,里面是 encrypted_content
   - 关键:server-side stateful,CLI 只持有引用;保留模型潜在理解状态而非简单总结
   - 代价:不能导出/迁移到别家 provider
   - 出处:codex-agent-architecture.md §5.4

⑤ Condenser 协议(OpenHands)
   - 这是一个抽象基类,不是单一算法
   - 实现:NoOp / RecentEvents / LLMSummarizing(前 K + 摘要 + 后 M)/ ObservationMasking
          / AmortizedForgetting / Rolling
   - 关键:摘要本身 emit 成 SummaryEvent,进 EventStream,能审计能回放
   - 实测:长 session cost 从二次方增长变线性增长
   - 出处:openhands-agent-architecture.md §5.3 + §8.5

#3.2 三种"用户自管"派

OpenClaw:bundled hook `session-memory` 在 compact 之前 flush,把要长期记的事写到
          `MEMORY.md` / `memory/YYYY-MM-DD-HHMM-<slug>.md`(slug 由 LLM 现场生成),
          再让 `session:compact:before` → 模型驱动 compact → `session:compact:after` 跑完。
          当前 flush 挂在 `command:new` / `command:reset`(用户主动 `/new` 或 `/reset` 时触发),
          外加 `session.idle` / `session.maxAge` 兜底——无固定 daily 时间。
          → 关键创新:"压缩前先抢救一次"——issue #56072 daily reset 丢上下文事故的修复。
          出处:openclaw-agent-architecture.md §5.2-5.4

Cline:双路径 ——
       /smol:同 task 内 LLM 自压缩(180K → 10K summary + 20K 最近原文)
       /newtask:阶段切换,把 plan + 已完成 + 关键文件 + 下一步 打包成新 task 的初始 user message
       出处:cline-agent-architecture.md §5.4

AutoGen:ChatCompletionContext 4 种策略组件 ——
       UnboundedChatCompletionContext / BufferedChatCompletionContext(buffer_size=N)
       / HeadAndTailChatCompletionContext(head=k, tail=m) / TokenLimitedChatCompletionContext
       出处:autogen-agent-architecture.md §5.1

LangGraph:pre_model_hook + langchain_core.messages.utils.trim_messages,全部用户在 node 里写
       出处:langgraph-agent-architecture.md §5.1

Cursor:官方未公开长会话 summarization / pruning 机制(待核实)。社区可观测现象是
       "对话拉长后老 ctx 会被有损压缩",但具体阈值和算法未披露。
       出处:cursor-agent-architecture.md §5.4 标注官方未披露

#3.3 "保前 K + 保后 N + LLM 总结中段" 是公约数

不论哪家,凡是做了主动压缩的,公式高度相似:

keep_first_n            (系统消息 + 最初任务描述,开场上下文丢不得)
   +
LLM(summarize(middle))  (中段交给便宜模型生成摘要)
   +
keep_last_n             (最近 N 条 / 最后 ≥20 条,必须完整)

具体参数:

项目 keep_first keep_last summarize 模型
Hermes(v2) token-budget(非固定条数) token-budget tail 辅助模型(用户配)
OpenHands LLMSummarizingCondenser k 轮(系统 + 初始 user) M 条(最近详细历史) LLM client
Claude Code 隐式(CLAUDE.md re-inject + 用户请求) 隐式(最近一段 + 已 invoke skill 前 5K) Anthropic 内部

唯一不走这套的是 Codex 的 encrypted_content——那不是"保 K 段 + 摘要",而是把模型的 KV 状态以加密形式存在 OpenAI 后端,本质上是模型 server 的能力,不是 framework 的能力。


#四、Prompt cache 完整性的取舍光谱

"你想用 prompt cache,那 cache invalidation 就成了头等事——这件事每家答案都不一样。"

#4.1 光谱:从"写死禁止"到"动态注入"

最严格(cache 完整性 = 顶级约束)                     最自由(cache 让位于动态性)
←──────────────────────────────────────────────────────────────────────────→

AGENTS.md 写死       压缩点固定在         auto-compact 后     摘要也是 event    Memories + 4 档 rules
"do NOT alter past   turn 边界 +         project CLAUDE.md   push 到 stream,  动态召回不同 rules
context              cache point         re-inject,         microagent 触发    每次 prompt 不一样
mid-conversation"    设在压缩点之后       skill 按 25K        会破坏 cache       cache hit 率较低
                                         re-attach           (见 §4.6)         但灵活度最高

#4.2 Hermes 的"硬约束"(业内最严,值得抄)

AGENTS.md 里有一条原文(见 hermes-agent-architecture.md §1.4 / §8.6):

"Do NOT implement changes that would alter past context mid-conversation, change toolsets mid-conversation, [or] reload memories or rebuild system prompts mid-conversation."

直接后果:

  • system prompt 7 段在整个会话内不变
  • 任何破坏 cache 的 slash command(如 /skills 加新技能)默认 deferred 到下一会话生效,想立即生效必须显式 --now
  • "记忆 reload" 只发生在会话开始;中途不重建

启发:用 prompt cache 后,默认行为应该是"不破坏 cache",破坏要用户显式选

# 压缩点固定在 turn 边界
fold_turn_id = calculate_fold_point(messages)
memory.messages = [
    Message.system(summary),      # 摘要替代早期对话
    *messages[fold_turn_id:],     # 最近的对话原样保留
]
self._set_cache_at_position(fold_turn_id)   # 关键:cache point 设在压缩点之后

核心思路:变化集中在末尾(最近几轮 + 用户新消息),cache 边界画在变化点之前,这样 cache hit 比例最大化。

#4.4 Claude Code 的"压缩后 re-inject"

claude-code-agent-architecture.md §5.4 列举的"幸存优先级":

  • ✅ project root CLAUDE.md:会被 re-inject(重新从盘上读)
  • ❌ 嵌套 CLAUDE.md:等下次 Claude 读那子目录文件时才会回来
  • ✅ 已 invoke 的 skill:按 25K 总预算 re-attach(可能丢老的)
  • ❌ 对话里口头说的临时规则:会丢 → 所以官方建议持久规则放 CLAUDE.md

启发:压缩后哪些段必须回来,哪些段可以丢——这是设计 compaction 时的核心决策,不能"全压全丢",也不能"全保全留"。

#4.5 Codex 的"cache 不归你管"

Codex 走 Responses API,encrypted_content 由 OpenAI 后端持有。框架本身不操心 cache invalidation——这是把 cache 设计权外包给 model server。代价:换 provider 的话这部分上下文带不走。

#4.6 Cursor / OpenHands 的"动态优先"

  • Cursor:4 档 rules 召回意味着每次 prompt 注入的 rules 不同,cache hit 率天然受限。换来的是"硬盘有 50+ rules,进 prompt 的远少于 50"的容量优势。
  • OpenHands:Microagent 触发性注入意味着每次匹配关键词的不同,注入的 microagent body 也不同,影响 cache hit。但 EventStream 把摘要本身做成 event,理论上能审计每一次 prompt 变化。

#五、按需召回机制对照

"硬盘上能塞 100 份资料,prompt 里只能装 5 份——决定哪 5 份的机制叫召回。"

#5.1 四种触发模式

① Always-on             ② Glob / Path 触发        ③ Agent-decides           ④ Manual / @-mention
   每次都注入              文件路径相关时注入         description 给 agent      用户主动调
                                                   它自己决定要不要拉

Cursor: alwaysApply:true   Cursor: globs:[...]      Cursor: description+      Cursor: 空 frontmatter
Claude Code: project        Cline: paths frontmatter alwaysApply:false        + @rule-name
   CLAUDE.md                                       OpenHands: triggers:[...]  Cline: @file/@folder/
Hermes: 启动加载的           OpenClaw: subagent       (关键词)                  @problems/@terminal/
   skill                    queryMode: recent/full                            @git-changes/@url
   工具集
OpenHands: repo.md

#5.2 Cursor 是 4 档最完整的(值得抄)

cursor-agent-architecture.md §1.2

模式 frontmatter 关键字段 何时塞进 system prompt
Always alwaysApply: true 每次 agent 调用都注入
Auto Attached 非空 globs 对话里出现匹配该 glob 的文件时自动注入
Agent Requested 非空 descriptionalwaysApply: false 把 description 给 agent,由 agent 自己决定要不要拉
Manual 空 frontmatter 用户写 @rule-name 才加载

为什么是 4 档?因为 .cursor/rules/ 能塞 50+ 文件,硬塞会爆 ctx。实际进 prompt 的 rules 远少于硬盘上的 rules——这是"按需召回"最好的注脚。

preload  = "Agent 的本能"                每次推理都看得到
           project_plan / memory_graph /
           content_verify / capability_advisor

on-demand = "Agent 通过 find_assets 学到的新技能"
            浏览器 / dev / pdf_processor / visual_processor / ...
            发现 → skill() 工具加载

find_assets 是元工具——它的存在让 LLM 知道"还有别的能力但不知道详细 schema"。要用了才查。这跟 OpenAI 的 ToolSearch 模式同源。

#5.4 OpenClaw 的"子代理抢跑"(独特)

openclaw-agent-architecture.md §5.3

用户消息: "那个项目今天怎么样了?"
   │
   ▼
active memory sub-agent (blocking, 只有 memory_search / memory_get 工具)
   │  memory_search("项目状态 最近")
   │  memory_get("MEMORY.md")
   ▼
返回 summary: "用户提到的项目应该是 'XX',上周决定走 A 方案,今天 deploy 计划在 16:00"
   │
   ▼
这段 summary 作为 hidden <active_memory_plugin> 块拼到主 LLM 的 system 段
   │
   ▼
主 agent 这才正式 infer

代价:多一次 LLM 开销 + "agent 不知道自己看到的 context 来自哪里"的不可解释性。 好处:用户感受不到延迟(与主调用串行但短)+ 主 agent 不用自己写记忆查询代码。

#5.5 OpenHands Microagent 的"关键词触发"

openhands-agent-architecture.md §5.4

user: "我想加个 useEffect 管下副作用"
   │ event_stream.add_event(MessageAction)
   ↓
agent.step:
   ├ 检查 user message keywords → 命中 "useEffect"
   ├ emit RecallAction(query="useEffect")
   ↓
Memory.recall (openhands/memory/memory.py)
   ├ 扫已注册的 knowledge microagents triggers
   ├ 命中 react-best-practices.md
   └ emit RecallObservation(content=microagent_text)
   ↓
event_stream 收到 RecallObservation
   ↓ 下一轮 step
ConversationMemory 把 RecallObservation 转成 system 区注入
LLM 看到 React 最佳实践 → 输出更准

frontmatter 长这样:

---
name: react-best-practices
type: knowledge
triggers: [react, hooks, useState]
---

#5.6 Cline 的"@ 引用"是用户控的最纯粹版

cline-agent-architecture.md §5.2,6 类引用:

引用 注入什么
@/path/to/file 完整文件内容(带 import 上下文)
@/path/to/folder/ 整个目录树 + 每个文件全文
@problems VSCode Problems 面板里的 errors/warnings
@terminal 最近终端输出(保留格式)
@git-changes@<commit-hash> uncommitted diff 或某个 commit 的 diff
@https://example.com webfetch 抓回该页面 markdown

注意:`@ 引用展开后直接拼进 user message,不经过任何 retriever / 向量召回,纯 token 暴力。这是"不做语义召回"的极端选择——把召回完全外包给用户。


#六、工具结果压缩对照

"一个 grep 输出 50K 行,全塞回 LLM 就废了——怎么处理 tool 结果是 context 工程的"暗工程"。"

#6.1 几家做了的

项目 做法 出处
OpenHands 单个 observation 内容超过 max_message_chars(默认 30k)尾部截断 + "... [N chars truncated] ..." 提示 openhands-agent-architecture.md §5.2
Claude Code auto-compact 时优先清掉旧 tool outputs(尤其大 file reads);这是 Step 1 claude-code-agent-architecture.md §5.4
Cursor 工具结果落成 file reference + preview;详细机制未公开(待核实)

#6.2 没主动做的

  • Hermes / Cline / Codex / AutoGen / LangGraph:没有框架级"工具结果自动压缩"机制。Cline 的 @file 是用户控的全文塞,不带截断。Codex 的 shell 工具输出走 sandbox,默认会被 truncate 但 sandbox 层做的(不是 framework)。

#6.3 一个被低估的设计:OpenHands 的"observation 也是 event"

OpenHands 的 EventStream 抽象让"观察一个大输出 + 截断 + 提示用户"这件事变成 event 操作:

  • L1(EventStream history)保留完整 observation 内容(甚至 30k 之外)
  • L2(ConversationMemory)翻译给 LLM 时才截断
  • 后续如果用户回头看 audit log,完整原文还在 L1

#6.4 一个常见但少有人写的反模式

反模式:"tool 返回大字符串,agent 每轮都把它全塞给 LLM。"

正确做法(业内共识,但只有 OpenHands / Claude Code 在 framework 层做):

工具执行 → 大输出
    │
    ├─→ 完整原文落盘(path / file_id / db row)
    └─→ 给 LLM 的:preview 前 N 行 + "完整内容见 path X,可用 read_file 拉"

#七、长会话稳定性 / state 持久化对照

"会话内是不是允许动态改 system prompt / 工具集 / memory?这是个深得能撕裂哲学派系的问题。"

#7.1 静态派 vs 动态派

静态派("会话内 system prompt 不变")          动态派("按需注入新内容")

Hermes        AGENTS.md 写死禁止                Cursor       4 档 rules 召回
              用 find_assets 但不动 system                   嵌套目录读到才 inject
Codex         AGENTS.md 启动拼一次,会话内      OpenHands    Microagent triggers 关键词触发
              不再动                            OpenClaw     Active Memory 子代理每轮抢跑

适合:长会话 + 高 cache hit                     适合:项目大 + 资料多
代价:临时规则得手动改                           代价:cache hit 率低、debug 难

#7.2 Session / checkpoint 持久化对照

项目 持久层 关键能力
OpenClaw session.jsonl append-only 人类可读、可 git、可 cat
Hermes SQLite + FTS5 + session lineage 单进程、本地优先、跨 session 沿 lineage 检索;short timeout(1s) + retry(20-150ms × 15) + WAL checkpoints every 50 writes
Claude Code session JSONL + agent-memory/ 多 surface 共享同一 session
Codex 本地 SQLite(sqlite_home / CODEX_SQLITE_HOME codex resume 续 / codex fork 分叉 / /new 同进程开新对话 / /side 临时小窗口(fresh ctx 不污染主线)
Cursor 服务端 chat history + Codebase Index Merkle tree 跨设备复用(账号绑定);plaintext 永不上服务端
Cline ~/.cline/data/taskHistory.json + 影子 git task 级 messages + cost;影子 git per-step commit 让 YOLO 模式有底气
OpenHands EventStream(核心抽象) deterministic replay:从任意 event_id 起跑、可分叉、可审计
AutoGen team.save_state() / load_state()(v0.4 新) dict → json.dump;包含每个 agent 的 model_context、memory、speaker pointer、termination 累积
LangGraph Pregel Checkpointer(Memory/SQLite/Postgres/Redis) Time Travel:从历史 checkpoint 重放、可改 state 再跑;Pregel 通道版本号决定 next superstep 哪些节点要跑

#7.3 三条最值得提的设计

(1) OpenHands EventStream = state 是 derived value

openhands-agent-architecture.md §5.1:把 conversation = ordered event log 当作核心抽象,state 不是存起来的,是从 event log 重算出来的。这给了三个超能力:完全可重放、可审计、可分叉。

代价:副作用必须 emit 成 event 才"算数",agent 不能在 step 内偷偷改外部状态而不留 event。这对工程纪律要求很高。

(2) LangGraph Time Travel

langgraph-agent-architecture.md §5.3

history = list(app.get_state_history(config))
old_cp = history[3]
new_config = {"configurable": {"thread_id": "...", "checkpoint_id": old_cp.config["configurable"]["checkpoint_id"]}}
app.invoke(None, new_config)             # 从老 checkpoint 接着跑
app.update_state(new_config, {"plan": "...new..."})  # 改 state 再跑

这是 Pregel 模型的副产品——每个 superstep 都能重放,能改 state 再走。比 print + 复现快十倍,是调试 agent 的杀手锏。

(3) Codex /side 临时 fresh context

codex-agent-architecture.md §5.3:在同一个 CLI 进程内开一个独立"小窗口"问个简短问题(fresh context),不污染主线 thread。这是个少有人提的小创新——承认 "agent 主线 ctx 不应该被任何 ad-hoc 问题污染"


#八、最值得抄走的 5 个设计创新

"看了 10 家设计,挑 5 个 '这家做了别家没做' 的事,给设计自家上下文工程时直接套。"

#8.1 Hermes:把 cache 完整性写进 AGENTS.md 当顶级硬约束

"do NOT alter past context mid-conversation" 写成项目文档的硬约束——这件事看起来微小,但它把 prompt cache 从"性能优化"提升到"架构约束"。所有破坏 cache 的操作(slash command 改 skills / memory reload / system prompt rebuild)默认 deferred 到下一会话,用户要立即生效必须 --now

启发:当一个性能优化的不命中代价 = 整轮重算 token,那它就该被当成架构约束写进规范,而不是"如果命中了不错,没命中也没事"。

#8.2 OpenHands:Condenser 是一等公民 + 摘要也是 event

把上下文压缩从"用户 plugin"提到"框架核心抽象",加上"摘要本身也是 event 进 stream",让长 session cost 从二次方变线性、且摘要可审计可回放。

启发:任何会改变 LLM 输入的操作都应该 emit 成 typed event 而不是隐藏在框架内部。这让你可以审计任何一次 prompt 变化的来源。

#8.3 Cursor:4 档 rules 触发模式

Always / Auto-Attached / Agent-Requested / Manual 四档解决了"硬盘 50 份 rules、prompt 只能装 5 份"的问题。每档由 frontmatter 的不同字段触发,零代码就能让用户决定召回模式。

启发:召回机制不应该只有"全塞" or "完全靠语义检索"两档。在两端之间至少有 4 个有用的中间档(确定性 + 模糊 + agent 自决 + 用户手动)。

把"什么时候压缩"和"cache point 设在哪"绑成同一个决策——压缩点固定在 turn 边界,cache 边界画在压缩点之后。这样:

  • 变化集中在末尾(最近几轮 + 用户新消息),cache hit 比例最大化
  • 压缩之后 cache 重建的成本可预测
  • 调试时能清晰看出 "这轮命没命中 cache"

启发:性能边界(cache point)应该跟语义边界(turn / 压缩点)对齐,而不是各拍各的。

#8.5 Codex:嵌套 AGENTS.md + override 机制

合并顺序设计:

1. ~/.codex/AGENTS.override.md   ← 个人最高优先级
2. ~/.codex/AGENTS.md            ← 个人默认
3. <git_root>/AGENTS.override.md ← 项目最高优先级(不进 git?或进)
4. <git_root>/AGENTS.md          ← 项目默认
5. <git_root>/<sub_dir>/AGENTS.md ← 子目录细化
...
N. <cwd>/AGENTS.md               ← cwd 最具体

每层都有 .override.md + AGENTS.md 两个文件,外层覆盖内层。32 KiB 上限强制不能堆超大文件。这把"工程文件作为系统提示"做到了最完整的层级表达。

启发:当一个配置文件可能被多 scope 覆盖时,提供 .override.md + 默认 + 嵌套 三件套,而不是单一文件。这是 git workflow 直接套到 prompt engineering。


#九、趋势观察 + 一句话各家总结

#9.1 三个跨家共识

(1) AGENTS.md 已成事实标准。 Codex / Cursor / OpenClaw 原生识别这个文件名;OpenClaw 还兼容 CLAUDE.md 软链。Claude Code 自家用 CLAUDE.md,官方建议在 CLAUDE.md 里写 @AGENTS.md 引入而非直接读取(见 claude-code-agent-architecture.md §5.2)。Cline 用 .clinerules/ 目录,与 AGENTS.md 同一逻辑(每次失败 → 一条永久规则)但文件命名不同。这是 2025-2026 行业最重要的一次"开放协议吃下私有后台"——之前各家想做"自家 memory 后台 + 仪表盘",最后市场给的答案是"放回 git 里"。

(3) 工具结果压缩仍是个 framework 层的空白。 OpenHands / Claude Code 做了一点(observation 截断、auto-compact 优先丢 tool output),但没有任何一家有"tool 返回大输出自动落盘 + 给 LLM preview"的框架级约定。每个工具自己 truncate,agent 看不到"这个工具会输出多大",这是后续可以做的事。

#9.2 一句话各家总结

项目 一句话
OpenClaw 全 markdown + session:compact:before 配合 session-memory hook,"压缩前先抢救一次";Active Memory 子代理预跑
Hermes AGENTS.md 写死"会话内禁止改 prompt/tools/memory",cache 完整性顶级硬约束
Claude Code 5 层记忆 + auto-compact 三阶 + project CLAUDE.md re-inject + skill 25K 预算 re-attach
OpenAI Codex AGENTS.md 嵌套 + override;compaction 走 Responses API encrypted_content(server-side stateful)
Cursor 4 档 rules 召回(Always / Auto / Agent-Requested / Manual),动态注入派天花板
Cline 用户全控派:6 类 @ 引用 + /smol + /newtask 双路径,影子 git 兜底
OpenHands Condenser 是一等公民;EventStream 让摘要也是 event,state = derived value
AutoGen ChatCompletionContext 4 种策略 + Memory protocol,没有"框架级 system 段"约定
LangGraph 完全交给用户:state 字段 + reducer + checkpointer,Time Travel 是免费副产品

#附:源文档章节对照(供深读)

主题 主要出处
工具结果压缩 openhands §5.2 / claude-code §5.4
Session/checkpoint hermes §5.3 + §5.6 / codex §5.3 / openhands §5.1 / langgraph §5.2-5.3 / autogen §5.4 / cline §5.3 + §5.5
8 大对比综述 agent-architectures-comparison.md §6

返回 Agent 资料库