设计 AI Agent 时,模型能力当然重要,但真正决定 Agent 能不能长期稳定工作的,往往是记忆系统。
原因很简单:大语言模型(Large Language Model,LLM)本身没有运行时状态。每一次调用模型,模型只看本次请求里提供的上下文;如果某个事实、规则、历史步骤没有进入上下文,模型就无法可靠地使用它。
所以,Agent 框架必须在模型外面补一套记忆系统,用来解决四个问题:
| 问题 | 设计含义 |
|---|---|
| 存什么 | 哪些事实、规则、偏好、经验需要保留,哪些内容应该丢弃 |
| 存在哪 | 放在文件、数据库、向量库,还是直接放进上下文窗口 |
| 怎么取 | 通过路径加载、关键词搜索、语义检索,还是由 Agent 主动调用工具 |
| 怎么管 | 如何更新、压缩、淘汰,避免记忆越积越乱 |
OpenClaw、Claude Code、Hermes Agent 分别代表了三种典型路线:
- OpenClaw 把文件系统当作记忆的事实来源。
- Claude Code 把上下文窗口当作稀缺资源来调度。
- Hermes Agent 把记忆按访问模式分层,并把情景记忆作为能力积累的核心。
这三种设计没有绝对优劣,关键在于目标不同:有人要透明可控,有人要 Token 使用高效,有人要 Agent 随时间积累经验。
Agent 记忆的四个层次
讨论具体框架前,需要先把“记忆”拆开。Agent 记忆不是单一概念,至少可以分成四层。
flowchart TB
A[Agent 记忆系统] --> B[上下文记忆<br/>In-context Memory]
A --> C[外部记忆<br/>External Memory]
A --> D[情景记忆<br/>Episodic Memory]
A --> E[参数记忆<br/>Parametric Memory]
B --> B1[当前 Prompt 和对话历史<br/>访问最快,容量有限]
C --> C1[文件、数据库、向量库<br/>可跨会话保存]
D --> D1[任务过程、工具调用、结果反馈<br/>用于从经验中学习]
E --> E1[模型权重中的知识<br/>运行时不可直接修改]
| 记忆类型 | 存储位置 | 访问方式 | 生命周期 | 主要问题 |
|---|---|---|---|---|
| 上下文记忆 | 当前 Token 窗口 | 模型直接读取 | 单次会话或单次请求 | 容量有限,长对话会被压缩 |
| 外部记忆 | 文件、数据库、向量库 | 检索后注入上下文 | 可持久化 | 检索质量决定可用性 |
| 情景记忆 | 结构化经验记录 | 按任务召回 | 可长期积累 | 如何判断哪些经验有复用价值 |
| 参数记忆 | 模型权重 | 模型内部调用 | 随模型存在 | 运行时无法更新,可能产生幻觉 |
真正需要架构设计的,主要是外部记忆和情景记忆。上下文记忆受 Token 窗口限制,参数记忆又不受 Agent 框架直接控制;外部记忆和情景记忆才是 Agent 框架可以主动塑造的部分。
OpenClaw:文件系统就是记忆事实来源
OpenClaw 的核心约束很直接:长期状态必须写进磁盘文件。没有写入文件的内容,只能算临时上下文,不能算被 Agent 真正记住。
典型目录结构类似这样:
~/.openclaw/workspace/
├── MEMORY.md # 长期记忆:稳定事实、用户偏好、工作规范
├── SOUL.md # Agent 身份定义
└── memory/
├── 2026-04-12.md # 当日日志:短期工作记录
├── 2026-04-11.md # 昨日日志
└── ...
这种设计把 Markdown 文件同时当作三种东西:
- 记忆存储介质;
- 人类可读的调试界面;
- 人机协作时可以直接修改的控制面。
为什么用文件,而不是数据库
文件系统的查询能力不如数据库,但 OpenClaw 选择文件并不是为了查询性能,而是为了透明性和可控性。
| 存储方式 | 优点 | 代价 |
|---|---|---|
| Markdown 文件 | 可读、可改、可 Git 版本控制、容易审计 | 查询能力弱,复杂关系难表达 |
| 关系型数据库 | 精确查询强,结构化能力强 | 人类直接查看和修改不方便 |
| 向量数据库 | 适合语义召回 | 可解释性弱,精确匹配不稳定 |
当用户想知道 Agent 到底记住了什么,MEMORY.md 可以直接打开;当某条记忆不准确,也可以手动改掉;当记忆发生变化,还可以用 Git 查看修改历史。
文件方案牺牲了一部分自动化检索能力,换来的是调试友好和人类控制权。
短期日志和长期记忆分层
OpenClaw 没有把所有内容都塞进一个文件,而是拆成短期层和长期层。
flowchart LR
A[对话与任务过程] --> B[当日日志<br/>memory/YYYY-MM-DD.md]
B --> C[近期上下文自动加载<br/>今天和昨天]
B --> D[更早日志按需检索]
B --> E[人工或自动提炼]
E --> F[长期记忆<br/>MEMORY.md]
F --> G[每次会话固定加载]
短期日志负责“不丢信息”。当天发生的对话、任务进展、临时线索,可以先追加进去,不要求立刻整理。
长期记忆负责“高频可用”。稳定事实、长期偏好、项目规则、反复使用的约定,应该沉淀到 MEMORY.md,因为它每次会话都会加载。
这解决了一个常见矛盾:Agent 需要记住很多东西,但上下文窗口不允许无限加载。短期层允许信息先落盘,长期层保证真正重要的信息常驻上下文。
问题也随之出现:哪些内容应该从日志升级成长期记忆?OpenClaw 的答案偏向人类主导,自动化机制只做辅助。这样记忆质量更可控,但用户需要参与维护。
混合检索:语义搜索加关键词搜索
只靠语义搜索会遇到一个问题:它擅长找“意思相近”的内容,却不擅长找“字面精确匹配”的内容。
比如用户搜索一个 API 路径、函数名、错误码,向量相似度可能返回一批语义相关但不准确的片段。OpenClaw 用混合搜索降低这个风险:
flowchart LR
A[查询请求] --> B[语义搜索<br/>向量相似度]
A --> C[BM25 关键词搜索]
B --> D[候选片段]
C --> D
D --> E[排序与合并]
E --> F[注入当前上下文]
BM25 是一种经典关键词相关性算法,适合处理精确词命中;向量搜索适合处理表达方式不同但含义接近的内容。两者并行,可以覆盖更多检索场景。
OpenClaw 的向量索引可以放在 SQLite 里,通过 sqlite-vec 这类扩展实现,不必额外部署独立向量数据库。这样安装和迁移更简单,但大规模数据下性能通常不如专用向量库。
Context Compaction 的风险和 Memory Flush
长会话会不断消耗 Token。接近上下文窗口上限时,系统通常会压缩历史对话,也就是 Context Compaction。
压缩本身没问题,但它会制造一个危险场景:
sequenceDiagram
participant U as 用户
participant A as Agent
participant C as 上下文历史
participant F as 文件记忆
U->>A: 以后生成代码都遵守某条规则
A-->>U: 好的
A->>C: 规则只存在对话历史中
Note over C: 会话变长,触发压缩
C->>C: 历史被摘要替换
A->>F: 没有写入文件
Note over A: 规则丢失,后续行为可能违反约定
用户以为 Agent 已经记住了规则,但规则只停留在对话历史里。压缩发生后,原始对话被摘要替换,重要细节可能消失。
OpenClaw 用 Memory Flush 处理这个问题:在压缩前插入一个静默轮次,让 Agent 把当前上下文里的重要信息写入文件,再执行压缩。
flowchart TD
A[检测到上下文即将压缩] --> B[触发静默 Memory Flush]
B --> C[Agent 扫描当前上下文]
C --> D[把重要事实、规则、进展写入日志或 MEMORY.md]
D --> E[执行 Context Compaction]
E --> F[继续会话]
这个机制把“写进文件才算长期记住”的原则变成系统保障,而不是完全依赖用户提醒。
Dreaming:自动沉淀长期记忆
OpenClaw 的 Dreaming 机制可以定期扫描日志,对内容进行评分,再把高价值内容提升到 MEMORY.md。它试图把人工整理的一部分工作自动化。
难点在于“高价值”很难用简单规则定义。某句话是否应该长期保存,取决于上下文、用户偏好、任务类型和后续复用概率。自动沉淀如果过于激进,会把长期记忆变成噪音堆;如果过于保守,又起不到积累作用。
所以 OpenClaw 的整体风格仍然是:人类可见、可改、可审计,自动化能力围绕这个原则展开。
Claude Code:上下文工程优先
Claude Code 的记忆系统不像 OpenClaw 那样强调“外部存储”,它更像是一套上下文工程系统。
核心判断是:Token 窗口是稀缺资源,不能只看窗口最大长度,还要考虑信息放在上下文里的位置。
语言模型存在 Lost in the Middle 现象:上下文开头和结尾的信息更容易被模型关注,中间内容更容易被忽略。也就是说,把大量记忆粗暴堆进上下文,不等于模型就会稳定使用这些记忆。
Claude Code 的重点不是“存更多”,而是“在正确时间,把正确内容放到正确位置”。
系统提示分层注入
Claude Code 每次调用模型前,会组装系统提示。这个组装过程不是简单拼接,而是按层次和条件注入。
flowchart TB
A[模型调用前组装 Prompt] --> B[固定注入层]
A --> C[条件注入层]
B --> B1[Agent 身份与行为规范]
B --> B2[编码原则]
B --> B3[工具调用规则]
B --> B4[风险操作确认逻辑]
C --> C1[CLAUDE.md 规则文件]
C --> C2[Git 状态快照]
C --> C3[Skills 名称与描述]
C --> C4[Token 预算指令]
固定注入层可以利用 Prefix Cache。Prefix Cache 指模型服务对稳定前缀做缓存,后续请求复用相同前缀时可以减少计算和费用。条件注入层则按需加载,避免每次调用都浪费 Token。
这种设计把记忆系统变成了 Token 预算分配器:哪些信息常驻,哪些信息按需进入,哪些信息只保留索引。
用路径编码相关性
Claude Code 的规则文件采用分层作用域:
~/.claude/CLAUDE.md # 用户级:所有项目加载
~/project/CLAUDE.md # 项目级:进入项目加载
~/project/src/CLAUDE.md # 目录级:进入目录加载
当前工作目录决定加载哪些 CLAUDE.md 文件。路径结构本身就表达了相关性。
flowchart LR
A[当前工作目录<br/>~/project/src] --> B[加载用户级 CLAUDE.md]
A --> C[加载项目级 CLAUDE.md]
A --> D[加载 src 目录级 CLAUDE.md]
B --> E[组装系统提示]
C --> E
D --> E
这是一种非常工程化的设计:不依赖复杂检索算法,直接用文件路径做规则选择。查找成本低,行为也容易预测。
代价是动态性不足。路径能回答“当前目录适用哪些规则”,但不能很好回答“当前任务语义上需要哪些历史经验”。如果一个规则跨目录复用,或者一个任务需要过去某次类似任务的经验,单靠路径层级就不够。
Token 预算三档预警
Claude Code 会监控上下文消耗,并设置分级阈值:
| Token 使用比例 | 系统行为 | 目的 |
|---|---|---|
| 约 70% | 提醒压缩可能接近 | 让 Agent 提前调整计划 |
| 约 85% | 提醒压缩即将发生 | 让 Agent 优先处理关键步骤 |
| 约 90% | 自动压缩,或停止并提示 | 防止上下文溢出 |
更关键的是,Token 使用状态会进入 Agent 自身上下文。这样 Agent 在规划任务时可以知道“剩余预算”:
flowchart TD
A[Token 使用率上升] --> B[预算状态注入上下文]
B --> C[Agent 感知剩余 Token]
C --> D[调整任务计划]
D --> E[优先处理关键文件或关键步骤]
E --> F[必要时准备压缩前总结]
这让记忆系统不只是被动后端,而是 Agent 推理的一部分。Agent 可以根据剩余上下文预算决定要不要继续读文件、是否先做总结、是否把关键中间结论保存下来。
Claude Code 的边界
Claude Code 对工程任务非常适合,尤其是规则清晰、项目结构明确、任务边界相对独立的代码场景。
它的短板也很明确:缺少强情景记忆。它可以加载规则,可以读取当前项目状态,可以管理上下文预算,但不会像 Hermes Skills 那样把“这类任务怎么做更好”沉淀成可迭代经验。
换句话说,Claude Code 更像一个擅长上下文调度的工程助手,而不是一个持续积累任务经验的学习型 Agent。
Hermes Agent:按访问模式分层,情景记忆是核心
Hermes Agent 的记忆设计更系统化。它不把所有记忆混在一起,而是按访问模式分成多层。
核心原则是:不同访问频率、不同稳定性、不同用途的信息,应该放在不同介质里,用不同方式访问。
flowchart TB
A[Hermes Agent 记忆系统] --> B[热记忆<br/>每次会话固定注入]
A --> C[历史归档<br/>按需搜索]
A --> D[情景记忆 Skills<br/>任务经验]
A --> E[用户建模<br/>可选增强]
B --> B1[MEMORY.md<br/>环境事实]
B --> B2[USER.md<br/>用户偏好]
C --> C1[SQLite + FTS5]
D --> D1[Markdown Skill 文件]
E --> E1[Honcho 用户模型]
热记忆:小而稳定
Hermes 的热记忆通常放在两个文件中:
~/.hermes/memories/
├── MEMORY.md # 环境事实,约 800 token 上限
└── USER.md # 用户偏好,约 500 token 上限
这两个文件每次会话都会直接注入系统提示,不需要检索,访问延迟为零。
上限很小是一个关键设计。热记忆越大,越容易退化成垃圾桶;每条新内容都应该接受筛选:它是否足够稳定?是否经常用到?是否有资格占用系统提示空间?
小热记忆还有一个工程收益:更利于 Prefix Cache。固定且短的系统提示前缀更容易命中缓存。
历史归档:不自动加载,由 Agent 主动搜索
Hermes 会把会话历史存进 SQLite,并使用 FTS5 全文索引。FTS5 是 SQLite 内置的全文搜索能力,适合做关键词检索。
~/.hermes/state.db # SQLite,包含会话历史与 FTS5 全文索引
历史归档不会每次自动进入上下文。Agent 判断当前任务可能需要历史时,才调用 session_search 工具搜索。
sequenceDiagram
participant A as Agent
participant DB as SQLite 历史归档
participant L as 轻量 LLM 摘要
participant C as 当前上下文
A->>A: 判断当前任务需要历史信息
A->>DB: 调用 session_search
DB-->>A: 返回相关历史片段
A->>L: 请求压缩摘要
L-->>A: 返回摘要
A->>C: 注入当前上下文
按需检索的好处是系统提示不会随着使用时间膨胀。历史只有在相关时才进入上下文。
缺点是 FTS5 语义理解弱。搜索 “auth service” 不一定能找到记录里写的“身份验证微服务”。如果任务大量依赖语义相似召回,可以用向量搜索增强这一层。
Skills:真正的情景记忆
Hermes 最有特点的是 Skills 系统。Skills 不是存事实,而是存经验。
事实记忆回答“用户喜欢什么”“项目目录在哪”;情景记忆回答“遇到这类任务时,怎么做效果更好”。
目录结构类似这样:
~/.hermes/skills/
├── research-workflow.md # 研究类任务流程
├── image-generation.md # 图片生成任务经验
└── data-analysis.md # 数据分析任务方法
一个 Skill 文件可以记录:
- 适用任务类型;
- 推荐执行步骤;
- 常用工具组合;
- 过去遇到的问题;
- 解决方法;
- 哪些做法效果不好。
Hermes 会在复杂任务完成后评估执行过程。如果任务包含多次工具调用,并且过程有复用价值,Agent 可以把经验写成 Skill。
渐进式披露:先加载索引,再加载全文
如果每个 Skill 都完整注入上下文,很快就会撑爆 Token。Hermes 用渐进式披露解决这个问题。
flowchart TD
A[会话开始] --> B[加载 Skill 名称和描述]
B --> C[Agent 判断当前任务是否相关]
C -->|不相关| D[不加载完整内容]
C -->|相关| E[加载完整 Skill]
E --> F[按 Skill 执行任务]
F --> G[发现更好做法]
G --> H[更新 Skill 文件]
平时只加载 Skill 的名称和描述,Token 占用很低。只有当前任务和某个 Skill 相关时,才加载完整内容。
这让 Agent 可以积累几十个甚至上百个 Skill,而不会让上下文失控。
Skill 自我更新
Hermes 的情景记忆还有一个重要点:Skill 可以在使用中更新。
Agent 使用某个 Skill 执行任务,如果发现某个步骤不够好,或者某个工具组合更稳定,就可以修改 Skill 文档。这样经验会随着任务执行而迭代。
这是情景记忆和普通历史记录的区别:
| 类型 | 记录内容 | 是否指导未来任务 |
|---|---|---|
| 会话历史 | 过去发生了什么 | 需要检索和总结后才能使用 |
| 事实记忆 | 稳定事实和偏好 | 能提供约束,但不描述过程 |
| Skill | 某类任务怎么做 | 直接指导下一次执行 |
Hermes 因此更适合长期运行、重复任务多、希望 Agent 越用越熟悉流程的场景。
深度用户建模
Hermes 还可以接入 Honcho 做用户建模。用户建模不只是记录“用户说过什么”,还会尝试从长期交互中推断用户偏好、表达习惯、决策风格。
这一层很重,需要额外服务,也会带来隐私和数据治理问题。对于个人长期助手、强个性化 Agent,它可能有价值;对于普通工程任务,热记忆和 Skills 通常已经够用。
三种架构的核心差异
三种框架的差异可以压缩成一张表。
| 维度 | OpenClaw | Claude Code | Hermes Agent |
|---|---|---|---|
| 核心理念 | 文件系统是长期记忆事实来源 | Token 预算和上下文调度优先 | 按访问模式分层,积累情景经验 |
| 主要介质 | Markdown 文件、SQLite 向量索引 | 分层规则文件、动态系统提示 | Markdown、SQLite、Skills、可选用户模型 |
| 长期记忆 | MEMORY.md | CLAUDE.md 规则文件 | MEMORY.md、USER.md |
| 短期记忆 | 日志文件 | 当前上下文和项目状态 | 会话历史数据库 |
| 情景记忆 | Dreaming 方向的实验机制 | 不突出 | Skills 是核心能力 |
| 检索方式 | 语义搜索 + BM25 | 路径层级加载,按需注入 | FTS5 搜索,Agent 主动调用 |
| 人类可控性 | 很强,文件可直接编辑 | 中等,规则文件可编辑 | 中等偏强,Skill 和记忆文件可编辑 |
| 系统复杂度 | 中等 | 中等偏低 | 较高 |
| 主要代价 | 需要维护记忆质量 | 缺少强经验积累 | 架构复杂,需要长期使用才能体现价值 |
OpenClaw 的取舍
OpenClaw 把可见性放在第一位。记忆写在文件里,用户可以直接看、直接改、直接版本控制。
适合场景:
- 用户希望完全知道 Agent 记住了什么;
- 记忆错误需要快速人工修正;
- 调试和审计比自动化程度更重要;
- 个人 Agent 或小规模工作区。
不适合场景:
- 需要复杂结构化查询;
- 记忆量很大,检索性能要求高;
- 用户不愿意维护长期记忆文件。
Claude Code 的取舍
Claude Code 把上下文窗口当作核心资源来管理。它不追求无限记忆,而是尽量让当前任务需要的信息准确进入 Prompt。
适合场景:
- 代码工程任务;
- 项目规则可以按目录组织;
- 任务之间相对独立;
- Token 成本和上下文质量都很重要。
不适合场景:
- 需要从长期执行经验中持续学习;
- 任务规则不是目录相关,而是语义相关;
- 需要跨项目复用复杂经验。
Hermes Agent 的取舍
Hermes 追求长期积累。热记忆、历史归档、Skills、用户建模各自承担不同职责,避免所有记忆混成一团。
适合场景:
- 长期运行的个人助手;
- 重复性任务很多;
- 任务流程可以不断改进;
- 需要让 Agent 从过去执行中学习。
不适合场景:
- 一次性任务;
- 不希望引入复杂存储和后台评估;
- 对隐私和数据驻留要求非常严格,但没有配套治理能力。
设计自己的 Agent 记忆系统时,先做三组选择
如果要从零设计一个 Agent 记忆系统,不必一开始就做成 Hermes 那样完整。更稳妥的方式是先回答三组问题。
透明性还是自动化
如果用户必须能直接审计和修改记忆,文件方案更合适;如果系统希望自动组织大量历史,数据库和检索系统更合适。
| 目标 | 推荐设计 |
|---|---|
| 人类可读、可改、可 Git 管理 | Markdown 文件 |
| 精确查询、结构化管理 | SQLite 或关系型数据库 |
| 大规模语义召回 | 向量库或 SQLite 向量扩展 |
| 复杂经验积累 | Skill 类情景记忆 |
常驻记忆还是按需检索
常驻记忆访问最稳定,但会占用 Token;按需检索节省上下文,但依赖检索判断。
一个实用分层可以这样设计:
flowchart TB
A[所有候选记忆] --> B{是否每次都需要?}
B -->|是| C[热记忆<br/>固定注入]
B -->|否| D{是否需要长期保存?}
D -->|否| E[只留在当前上下文]
D -->|是| F{是否描述任务过程?}
F -->|是| G[情景记忆 Skill]
F -->|否| H[历史归档或外部记忆]
热记忆一定要小。可以给自己设硬限制,例如:
hot_memory:
environment_facts_max_tokens: 800
user_preferences_max_tokens: 500
archive:
storage: sqlite
search:
- fts5
- vector_optional
episodic_memory:
format: markdown_skill
load_strategy: progressive_disclosure
记忆更新由谁负责
记忆更新可以由人负责,也可以由 Agent 自动负责,或者采用混合模式。
| 更新方式 | 优点 | 风险 |
|---|---|---|
| 人工维护 | 准确、可控 | 成本高,容易忘记维护 |
| 自动写入 | 省人工,覆盖更多上下文 | 容易写入噪音或错误结论 |
| 自动建议 + 人工确认 | 平衡质量和效率 | 交互链路更复杂 |
| 自动写入 + 可审计回滚 | 适合长期系统 | 需要日志和版本管理 |
比较稳的做法是:短期日志自动写,长期记忆谨慎写,关键规则变更可人工确认。
常见坑
把所有历史都自动注入上下文
历史越多,模型越不一定用得好。过多无关信息会稀释关键指令,还会触发 Lost in the Middle。
更好的做法是:热记忆固定注入,历史按需检索,检索结果再摘要压缩。
只用向量搜索
向量搜索适合语义召回,但对函数名、路径、错误码、配置键这类精确内容不稳定。Agent 记忆系统通常需要混合检索:
flowchart LR
A[用户问题] --> B[关键词搜索]
A --> C[语义搜索]
B --> D[合并排序]
C --> D
D --> E[去重、摘要、注入]
不处理压缩前的记忆落盘
长会话压缩前,必须把关键事实、约定和中间结论保存到外部记忆。否则用户刚刚交代的重要规则可能在压缩后消失。
长期记忆没有上限
长期记忆不是越多越好。热记忆尤其要严格限制大小。可以定期做三件事:
- 删除过时事实;
- 合并重复规则;
- 把低频内容移入可检索归档。
没有纠错入口
Agent 可能会记错。如果用户无法查看和纠正记忆,系统会逐渐失去可信度。即使使用数据库,也应该提供可审计、可编辑、可回滚的入口。
一个简化版落地方案
综合三种架构,可以设计一个轻量但可扩展的 Agent 记忆系统:
~/.agent/
├── memories/
│ ├── MEMORY.md # 热记忆:稳定事实,限制 token
│ └── USER.md # 热记忆:用户偏好,限制 token
├── logs/
│ ├── 2026-06-07.md # 短期日志
│ └── ...
├── skills/
│ ├── code-review.md # 情景记忆
│ └── data-analysis.md
└── state.db # 历史归档与索引
运行流程可以设计成这样:
flowchart TD
A[新请求进入] --> B[加载热记忆]
B --> C[加载当前任务上下文]
C --> D{是否需要历史?}
D -->|是| E[搜索 state.db]
E --> F[摘要后注入]
D -->|否| G[跳过历史检索]
F --> H{是否匹配 Skill?}
G --> H
H -->|是| I[加载完整 Skill]
H -->|否| J[正常执行]
I --> J
J --> K[写入短期日志]
K --> L{是否产生可复用经验?}
L -->|是| M[创建或更新 Skill]
L -->|否| N[结束]
这样的系统吸收了三种思路:
- 像 OpenClaw 一样保留可读文件;
- 像 Claude Code 一样控制常驻上下文;
- 像 Hermes 一样把经验沉淀为 Skill。
记忆系统的目标不是让 Agent 什么都记住,而是让它在需要的时候拿到正确的信息,并且能把重复任务中的有效做法沉淀下来。OpenClaw、Claude Code、Hermes Agent 的差异,本质上就是在透明性、上下文效率和长期学习能力之间做取舍。