开源 Agents 调研
本文最后更新于:7 小时前
开源 Agent 实现调研
调研日期:2026-09-06。范围按初稿链接:Hermes Agent、Prime Agent、Letta Code、OpenClaw。本文阅读了官方文档与固定版本源码,未安装运行四个项目,也未做学习效果、召回率、延迟或成本基准测试。
Overview
表格比较实现方式和默认路径,不作性能排名。此前的星级改为机制描述,便于追溯与后续实测。各行依据和默认条件见对应项目正文。
| Project | 自主学习 | 长上下文管理 | 持久 Memory | Agent loop 编排 |
|---|---|---|---|---|
| Hermes Agent · 详解 | 主动 memory/skill 工具 + 默认后台复盘;经验写成文本和技能,含技能生命周期整理。 | 工具输出卸载 + 有损摘要 + 近期尾部;SQLite 历史可补检;独立子 Agent。 | 有容量上限的 MEMORY.md/USER.md 常驻提示;技能为程序性记忆;FTS5 检索历史,外部 memory provider 可选。 |
Python AIAgent 显式循环;工具按可并发性分段;delegate/cron 为外层编排。 |
| Prime Agent · 详解 | 默认自动 review,或 /refine;结构化修改四类 harness 条目,可回滚;默认 session-local。 |
持久 Python REPL 外置数据;有损摘要与 JSONL 历史;RLM 独立子上下文;有界 kernel 快照恢复。 | local/global JSON harness;短摘要注入,详情通过 Python API 读取;当前路径无默认向量召回。 | daemon → worker → AgentSession → ipython/host bridge;goal、quality gate、heartbeat、schedule 控制续跑。 |
| Letta Code · 详解 | 显式记忆编辑 + 默认回合末 reflection;子代理在 Git worktree 提炼经验后合并;Cloud 可接管调度。 | API 后端持有窗口;local 压缩实现已开源;摘要与完整 transcript 分离;文件按需加载。 | Git MemFS;核心内容注入、其它内容按需读;按 agent 跨 conversation 复用;默认非向量文件库。 | 客户端 harness 与后端 stream 交替推进;本地工具审批/执行/回传;同库有 local runtime/App Server。 |
| OpenClaw · 详解 | 默认 Dreaming 三阶段记忆巩固 + 默认 auto Skill Workshop;存在来源门槛和变更校验。 | 工具结果 pruning 投影 + safeguard compaction + 压缩前 memory flush;不同 runtime 策略有区别。 | Markdown 内容源 + SQLite 索引/状态;关键词与可用时的向量 hybrid;默认路径 QMD 已移除。 | Gateway → session/global 队列 → 自有 agent-core 或其它 harness;子任务后台执行、结果异步送达。 |
最影响理解的四点:
- 四者目前都能通过修改外部状态形成经验复用。这里的“学习”主要发生在提示、记忆、技能层;本次核查未证明常规运行循环会更新模型权重,也未证明自动更新必然提高成功率。
- 长上下文能力来自多层组合:控制进入窗口的数据量、压缩旧消息、保留可恢复原始历史、按需检索,以及拆分子任务上下文。持久 Memory 解决的是未来如何再用知识,不能替代当前窗口管理。
- 持久化不等于跨独立会话自动复用。例如 Prime 默认 local harness 可随同一 session 恢复,但新 session 不自动读取它;Letta 的复用边界主要是 agent;Hermes 通常是 profile;OpenClaw 还受会话类型和 DM 隔离策略影响。
- “停止”也分层:模型结束本轮、Agent 结束一次 run、目标被标记完成、调度器未来不再唤醒,是不同事件。压缩、断线恢复和后台运行也分别管理不同状态。
版本基准
以下为本次获取的 main 快照,不保证等同用户机器上安装的 release。源码链接固定到对应 commit;官方动态网页仅作补充。
| 项目 | 固定 commit | 提交时间(Asia/Shanghai) |
|---|---|---|
| Hermes Agent | 245e48008fa8 | 2026-09-06 08:00:18 |
| Prime Agent | 9c54a35dac3a | 2026-09-06 03:12:41 |
| Letta Code | 701f2a536782 | 2026-09-06 09:02:04 |
| OpenClaw | 047fdfe90fef | 2026-09-06 11:06:22 |
统一概念
| 概念 | 本文含义 | 容易混淆的边界 |
|---|---|---|
| 自主学习 | 从轨迹/纠正/使用结果提取经验,更新可复用状态,后续任务再加载。 | “能写 skill”只是机制一环;还要看触发、写入控制、召回和效果验证。 |
| Working context | 当前模型请求中的系统提示、消息、工具 schema、结果等。 | 窗口有限;放进历史数据库不等于已经进入模型上下文。 |
| Compaction summary | 为继续当前工作而压缩出的有损摘要。 | 摘要可能丢信息、随任务变化;不应直接等同经过整理的长期知识。 |
| Episodic history | 原始对话、工具轨迹、执行事件。 | 留存用于恢复/取证/检索,并不意味着逐条长期注入。 |
| Semantic / procedural memory | 稳定事实、偏好、决策,以及可复用步骤或技能。 | 数据库存储、向量检索、Markdown 文件是实现选择,不是 memory 是否存在的定义。 |
| 参数学习 | 通过训练更新模型权重。 | 本文讨论的默认记忆/技能更新路径不能据此宣称持续训练。 |
下面是跨项目的概念关系图,不是任一项目的逐函数调用图;具体实现见各节。
flowchart LR
A[用户输入或调度唤醒] --> B[组装本轮上下文]
M[持久记忆与技能] -->|核心注入或按需加载| B
B --> C[模型与工具循环]
C --> H[原始历史与执行产物]
C --> D{窗口压力}
D -->|压缩与外置| S[摘要及保留尾部]
S --> B
H -->|检索旧细节| B
C -->|满足触发条件| R[经验复盘]
R --> V[写入校验与可选评估]
V --> M
C --> E[本次运行结束]
E -->|目标或调度策略继续| A
Hermes Agent
1. 自主学习:提示驱动的经验外化闭环
事实:主 agent 在执行中可调用 memory 和 skill_manage。此外具有真实的后台复盘路径:memory 默认每 10 个用户回合计数触发;skills 默认累计 10 次工具迭代后,在回合结束检查。只有产生最终回复、未中断、未设置 skip_background_review 且触发复盘时才启动后台 fork;自动复盘默认开启,可配置关闭,/refine 为显式入口。H1
观察材料是刚完成的对话快照;同模型 fork 重放快照,另行路由的复盘使用摘要历史。复盘 prompt 识别用户纠正、有效解决步骤、遗漏或过期技能,要求先更新已使用的相关技能,再考虑已有通用技能和支持文件,最后才新建。运行时白名单限制到 memory、skill 管理和有关读取工具;不是“给主模型一句记得学习”而已。现有技能修改需当前复盘重新读取;后台仅能改 curator 管理的技能,用户拥有、固定、内置及 Hub 安装技能受保护。H2
写入产物是 $HERMES_HOME/skills/.../SKILL.md、references/scripts/templates,以及 memories 下的文本条目。后续通过系统提示中的技能名称/描述索引选择,再 skill_view 按需加载正文和关联文件;memory 则直接注入。判断:这是程序性知识和事实记忆的提示驱动更新,不是模型参数在线训练。H3
评估边界:skill 写入有 frontmatter/大小校验、lint、读取前置保护;agent-created 安全扫描为可选,默认关闭。复盘 prompt 要求不把未解决失败包装成可靠方法,但这仍是模型判断。未发现该常规复盘路径强制执行“新技能运行→基准评分→优于旧版才晋升”的自动效果验证,也未见反向传播/优化器更新;不能把库中 evals 或轨迹生成能力当成每次学习已验收的证明。H2、H3
另有 curator:默认每 7 天且空闲至少 2 小时检查;默认只做确定性的长期未用技能 stale/archive 转换(30/90 天),LLM 合并整理默认关闭。run_curator_review 先备份、做状态迁移,再按配置 fork 整理并记录报告;其存在不代表学习质量得到了任务级评估。H4
2. 长上下文:有损摘要、可恢复历史与输出卸载
默认 engine 为内置 ContextCompressor,可显式配置插件替换;不能默认称为无损上下文。配置基础比例为 50%,但**小于 512,000 tokens 的模型窗口将比例提高到至少 75%**,部分 Codex 路由另有 85% 自动提高。实际 token 阈值以扣除输出预留的有效输入预算计算,还受最小值及绝对 token cap 影响,不能直接当作完整窗口占用百分比。使用 API 报告的 prompt tokens,缺失时估算。Gateway 回合前另有 85% session hygiene 安全网。不能只写一个全局固定 50%。H5
压缩流程:先廉价裁减旧工具结果/空白行,再确定首部、摘要中段及近期尾部,辅助 LLM 总结中段,修复工具调用配对。当前默认 lean 尾部预算是窗口 2.5%,夹在 10K–25K tokens,默认保护最近 20 条及至少 1 个真实用户消息;保护可能使实际保留量超过软预算。摘要附加机械提取的标识符索引、预算内原文用户请求和 session_search 恢复提示;超大摘要输入会采样,因此摘要不是无损复制。legacy 大尾部为可选。H6
默认 in-place 压缩保持 session id,把被压缩旧消息软归档为 active=0, compacted=1,保留搜索;可选择旧式 session 轮换。摘要用于继续当前上下文,SQLite 历史用于按需恢复,curated memory 用于跨会话稳定知识,三者用途不同。自动压缩失败有 60/300/900 秒冷却及无效压缩熔断;手动 /compress 或有界的 provider overflow 恢复可重试。H5、H6
工具结果还有独立卸载层:普通结果默认上限 100K 字符、MCP 50K、每轮总量 200K,较小窗口按比例缩小;超限全文写 $HERMES_HOME/cache/spillover,上下文留下约 1,500 字符预览与路径。read_file 豁免以免读回又卸载;多模态另走路径。若写盘失败则明确 inline truncation,故“所有输出永远可恢复”不成立。H7
子 agent 具有独立消息上下文,父任务仅传 goal/context,回传摘要并按父窗口余量限额;它是主动隔离中间材料的机制,不能假设自动分享完整父历史。H11
3. 持久 Memory:小型文本笔记与独立历史库
默认 $HERMES_HOME 通常为 ~/.hermes;内置 memory 位于 memories/MEMORY.md(agent 环境/经验)、USER.md(用户信息),分别默认 2,200/1,375 字符,条目以 \n§\n 分隔。MemoryStore 是每 AIAgent 一份实例,写入时文件锁、重读、原子保存;add/replace/remove,也支持按最终预算原子批量操作,唯一子串定位修改。超限返回错误让模型合并/删减,而非后台自动语义压缩;失败次数还有每回合限制。H8
索引与注入:内置两文件没有向量检索;全部有界内容形成系统提示快照。会话期间 tool 写盘而不逐次刷新前缀。需要特别纠正文档的绝对说法:源码 invalidate_system_prompt 在上下文压缩后会重新从磁盘加载,因此“整场会话永不更新、只能下一场可见”不准确。Memory 可由主 agent、后台 reviewer 或用户文件编辑更新;入口权限/写入审批另可配置。H8、H9
历史则是 profile 下 state.db,session_search 使用 SQLite FTS5,支持发现、会话浏览和围绕消息滚动,默认发现 3 个结果、adaptive detail,不需 LLM。文档/源码差异:官方 memory 页面称“不截断”,但当前发现结果每条内容明确有 4,000 字符截断标记;原消息可另外滚动/读取,不能描述为每次搜索回传完整无限历史。H10
隔离默认是 profile/home,不是每个 session 单独一份 memory;同 profile 会话共享。删除 memory 条目不等于删历史。session_search(profile=...) 可显式只读访问其他 profile,按 session id 还会定位其他 profile DB;因此 profile 文件组织不是对同一 OS 用户的严格安全边界。可选 memory.provider 加载外部 provider,与内置共存;不能把 Honcho/向量/图检索当作默认内置能力。未逐一验证各外部插件的召回和删除语义。H8、H10、H12
4. Agent loop 与任务编排
核心入口 AIAgent 委托到 agent.conversation_loop.run_conversation:build_turn_context→循环中的 begin_iteration/prepare_iteration→组装请求与 preflight→_run_api_retry_loop→规范化模型回复→有工具则 run_tool_round,否则 finish_text_response→finalize_turn 持久化和后台复盘。是显式 Python 状态循环,不是固定 DAG。codex_app_server 模式是可选的整回合外包 runtime 分支,应与 Hermes 自己的常规循环区分。H12
主循环受 max_iterations 与共享 iteration_budget 约束,构造器默认 sys.maxsize(实际近于无限),可另配时间预算;最终文本、预算耗尽、中断、不可恢复 API/持久化失败等退出。API 外层默认 3 次尝试,错误分类决定是否恢复/重建/失败;上下文溢出另受压缩次数约束,不能等同于“任何错误都重试三次”。硬中断/steer 有专门状态路径。H12
工具批次由 _plan_tool_batch_segments 按模型给出顺序分段:可并行的只读、互不重叠文件目标、显式允许的 MCP 同段并行;其他工具形成串行屏障。底层有顺序/线程池/分段执行器,超时与中断可终止等待;这比“全部工具串行”或“同轮全部并发”更准确。H11
delegate_task 新建 AIAgent:skip_memory=True,子工具集禁 memory/cron/clarify;默认最多并发 10 个子任务、深度 1,深度可配,父中断传播到孩子。上下文隔离不自动等于文件系统隔离,可选 worktree 另处理。cron 则 tick→run_one_job→run_job→_construct_cron_agent→run_conversation,独立运行、存结果并投递,支持并行和无 LLM 的 script-only;当前 cron 明确加载 memory(skip_memory=False)但禁止后台复盘(skip_background_review=True)。H11、H12
源码导航
H1 复盘触发及默认值:memory 回合计数;后台复盘 gate;默认间隔。
H2 复盘观察、更新策略与真实 fork:纠错→技能及保护规则;白名单和 run_conversation;自动启用。
H3 技能读写及验证边界:读索引/正文工具;写入位置与可选扫描;格式校验;lint 是 advisory。
H4 Curator 实现:默认周期和非 LLM 剪枝;完整 review 流程;官方触发说明。
H5 压缩默认与例外:官方默认引擎、双阈值、冷却;75% 下限实现;配置和可选剪枝。
H6 有损压缩与恢复:压缩主流程;lean 尾预算;机械恢复附件;阈值和熔断。
H7 工具卸载:预算、豁免和窗口比例;全文保存/失败截断;调用链。
H8 内置 Memory 存储及变更:格式、默认容量、快照、原子操作;profile 路径与批量工具;增删替换。
H9 压缩时刷新冻结快照:invalidate_system_prompt;系统提示注入。
H10 历史检索及隔离边界:发现结果截断、FTS 查询;4000 字符和查询;跨 profile 只读 DB;默认参数。
H11 工具并发和子任务:分段调度入口;子 agent 构造;子工具禁用;并发/深度默认;父窗口控制返回量。
H12 主循环、外部记忆和 cron:主循环与 runtime 分支;默认迭代无限;API 重试默认;可选外部 memory provider;cron agent 的 memory/review 开关;cron 进入 agent 并执行。
Prime Agent
实现定位
Prime 将 RLM 执行环境与 Continual Harness 可编辑状态分开:前者让模型通过持久 Python REPL 操作数据、工具和子 Agent;后者保存提示补充、事实记忆、技能调用说明、子 Agent 规范。TypeScript AgentSession 负责模型调用、调度、压缩和落盘。正常交互由 daemon 托管,关闭终端只是客户端 detach。架构
自主学习:自动 review → 结构化 refinement → 后续注入
- 触发:可手动
/refine,也可由模型通过refine.run请求。当前autoRefine默认开启,间隔默认 25 个 assistant turns,压缩后也可检查,默认冷却 20 分钟;自动路径限于有持久 harness 目录的根会话。这些是检查条件,不保证每次都会写入。默认配置、根会话限制 - 提炼:自动路径先由 LLM 判断
shouldRefine;通过后结合 harness、历史 refinement 和轨迹提出 JSONcreate/update/delete。轨迹取序列化会话末尾 80,000 字符,并非全部历史无损复盘。修改对象是prompt / memory / skill / subagent四类条目,基础 system prompt 不在可编辑范围。review 调度、提案生成 - 写入与复用:校验字段、检查条目是否在规划期间变化;保留版本和 before/after,支持 rollback。应用后重建 system prompt,后续 turn 可看到新摘要。默认写 session-local;跨独立会话复用需显式 global refinement 或 global 写入。应用与冲突检查、落盘及重新注入
评估边界:这里的学习是外部状态更新,未在这条路径看到模型参数训练。记录的 expectedOutcome 是预期效果,不是已测得的收益;字段校验也不等于经验正确性评测。skill 条目记录 Python 能力的调用契约,/refine 本身不会把描述自动构建、测试并安装成新 Python 包;可执行技能另有创建流程。refinement 约束、技能机制
长上下文:外置工作数据 + 对话压缩 + 独立子上下文
- 外置数据:默认内置模型工具是
ipython。模型把文件、解析结果、函数留在 Python 环境,按需读取和打印;rlm(...)建立独立子会话。这减少每次模型请求需要携带的数据,但打印出来的内容仍消耗上下文。RLM 接口 - 压缩:默认开启,触发为
contextTokens > contextWindow - reserveTokens,默认预留 16,384 tokens、目标保留最近约 20,000 tokens。旧消息由 LLM 摘要;JSONL 保留原始条目及 compaction 记录,模型上下文重建为“摘要 + 保留消息 + 后续消息”。预算及触发、上下文重建 - 恢复边界:kernel 一般跨压缩保留,并注入剩余变量名;当前实现也会清理超过单变量快照限制的变量。跨进程恢复依赖
dill尽力快照,默认总量 256 MiB、单变量 16 MiB,不可序列化对象会跳过。持久 REPL 不意味着所有对象永不丢失,大数据宜显式存文件。压缩后变量处理、快照限制
持久 Memory:有作用域的 JSON 条目库
| 层 | 存储与使用方式 |
|---|---|
| 会话经验 | <session artifact dir>/harness/harness_state.json;默认 refinement 写入这里,恢复同一会话时复用。 |
| 跨会话经验 | 默认 ~/.prime/agent/harness/harness_state.json;显式 global 写入,另有 refinements.jsonl 历史。 |
| 注入与访问 | 合并 global/local state,默认每类最多展示 6 条,内容摘要 180 字符;详情通过 Python harness API 的 list/get 等读取。该路径不是按当前 query 做 embedding 检索。 |
| 操作与纠错 | create/update/delete/upsert,记录版本、来源和作用域;refinement 可回滚。删除活跃条目不等于删除历史审计记录。 |
依据:路径与原子保存、摘要选择规则、Python harness API。
Agent loop 编排
1 | |
底层 runLoop 有“模型—工具”内循环及 follow-up/continuation 外循环,检查 abort、工具终止和宿主停止策略。通用工具调度可并行,但 ipython 标记 sequential 以保护共享 kernel;并行主要在 Python 中编排和独立子会话中运行。rlm() 返回接纳句柄,不等待最终答案,结果通过显式消息或文件交付。loop、工具模式、ipython 顺序执行
外层 goal 保存目标与进度,autonomous mode 按 turn/token/time/continuation 预算及可选命令 quality gate 决定是否再跑,heartbeat/schedule 负责以后重新入队。达到预算是停止原因,不是成功证据。关闭终端、压缩上下文、恢复进程分别作用于不同状态层,不能用单一“支持 resume”涵盖。长期执行策略
Letta Code
定位与重要版本边界
当前 Letta Code 已不只是旧 Letta API 的薄 CLI:同仓库包含交互终端、headless harness、本地 runtime、App Server 与消息渠道。当前 letta-ai/letta 主分支仅为项目入口,README 明确旧 V1 server 已退休,源码保存在 archive;因此不能将旧 Python 服务端的 core/archival/recall 架构直接等同于当前 CLI 默认实现。L1
源码 backend resolver 未显式覆盖时默认 api,可通过 --backend local 使用进程内 runtime,App Server 也可选择 local。默认 API 地址为 https://api.letta.com。Cloud 路径中,agent 身份、conversation、消息和云端 memory repository 属于后端状态,harness 在当前计算机执行本地工具;local 路径则将这些状态保存在本机。源码仍用 experimental 命名 local 的环境开关,但官方已提供正式自托管使用说明,不宜仅据内部变量名断言功能不可用。L2
1. 自主学习:实际更新 token-space,未见参数训练闭环
这里的学习对象是 memory 文件、可复用 skill 和运行环境配置,主要依赖 LLM 从交互中提炼经验、修改文件并提交 Git。默认提示明确要求把用户纠正、偏好和重复错误写入核心记忆;/remember 是显式教学入口,/init 用于项目记忆初始化。模型是否识别并记录某条经验仍由推理决定,不能理解成每次交互都有确定、完整的知识提取。L3
后台 dreaming/reflection 有可核查控制流:本地设置默认 step-count、25 步、auto 合并;maybeLaunchPostTurnReflection 在回合结束且 transcript delta 已追加后检查累计步数,也可配置压缩事件触发或关闭。它要求 MemFS;不是每25条用户消息,也不是独立于活跃进程的通用夜间定时训练。若 Cloud 返回 cutover=true,客户端退出该自动启动路径,由 Cloud 管理,云端实际调度器实现未在此次仓库中核实。L4
reflection 子代理读取最近 transcript 切片以及父 memory 快照,在独立 Git worktree 中整理错误纠正、偏好、事实和重复流程;提示词要求去重、替换过时事实、排除一次性任务状态,必要时更新最多一项 skill。产出提交后由 harness 合并;也可配置由主 agent 在另一后台 conversation 审阅和修订,并非必然请求用户批准。失败或冲突不应消耗待反思 transcript,成功后推进反思游标。上述是运行成功与整合检查,不能当成任务能力提升的实证评测;/doctor 是记忆布局、重复和提示词 token 使用审计,未核实默认运行独立基准、量化奖励或模型权重更新。L5
2. 长上下文:持久历史与当前窗口分开
API 模式的 sendMessageStream 发往 conversation 的是本次消息或 approval 结果、client tools/skills,而不是每轮由 CLI 重传完整历史;请求开启 compaction messages。conversation 后端持有当前上下文和历史。CLI 有 compact API 调用及压缩事件处理,但这只能证明接口和事件契约;当前云服务的完整压缩算法、预算阈值及数据库实现未由开源客户端证明。L6
local 模式的算法则已开源:预算优先使用最近模型 usage,再估算其后消息;无可信 usage 时计算提示词、消息和 tool schema(字符数/4,图片固定估算)。预留量为 min(16384, max(1, floor(window×0.2))),超出窗口减预留的阈值会提前压缩,provider overflow 另有补救路径。默认 sliding window、保留预算比例 0.3,也支持 all;生成摘要后以“摘要+保留尾部”替换 active message IDs,向完整 transcript 追加 compaction 记录而非直接删除原历史。压缩失败或压后仍超窗有全量摘要等退路;system prompt 加工具定义本身超过窗口则无法靠历史摘要解决。L7
这种方案延长连续运行寿命,但摘要是有损信息;需要靠保留的消息历史和记忆文件补检,不能等同无限上下文。local 查历史以 transcript 全文匹配为主,Cloud message search 接口支持 fts/vector/hybrid;检索到的结果只有经工具读取后才进入当前上下文。L8
3. 持久 Memory:当前核心是 Git MemFS
MemFS 把 agent 的 Git memory repository 投影成真实本地 checkout:API agent 常见目录 ~/.letta/agents/<agent-id>/memory,local backend 为其 storage root 下 memfs/<agent-id>/memory。memory 与 memory_apply_patch 小修改工具会自动 commit;直接文件修改须显式提交,远端同步在后续 harness 同步时完成。local prompt compiler 用 git ls-tree HEAD、git show HEAD:<path> 读取已提交版本,证明未提交工作区内容不会直接成为核心提示。L9
须区分两代布局:MemFS v1/local 使用 system/*.md 作为核心记忆;其它文件主要投影目录索引,内容按需读取。当前代码另支持云端 MemFS v2:若非local且存在根 MEMORY.md,根级 Markdown 是 core memory,子目录要求自己的 MEMORY.md,skill 独立;所以“所有版本都用 system/”和“所有版本都用根 MEMORY.md”均不准确。v2 的客户端格式检测、读写验证和提示模板可见,云端 prompt compiler 的实现此次未核实。官方 MemFS 页面仍主要展示 v1,详细实现优先引用固定源码。L10
MemFS 默认没有向量索引。普通 Read/Grep/文件搜索按路径、描述和 Markdown 链接查找;官方另提供 memfs-search mod,可选语义/混合模式依赖 QMD。该可选文件检索与 Cloud 对话消息向量搜索是两种能力。旧 V1 的 archival memory 向量存储并非当前创建 agent 的默认工具集:creation builder 显式关闭 include_base_tools,仅默认挂服务端 web_search/fetch_webpage,local工具运行时传入。因此不能写成“CLI 默认把所有记忆 embedding 存入向量库”。L8、L11
同一 agent 的 MemFS 跨 conversation 复用;conversation 的窗口独立。agent 以ID划分本地目录,sharing 需显式附加 shared-memory repository;这是状态归属设计,并非宣称跨agent读取在任何权限模式下绝对不可能。项目 skills > agent MemFS skills > 全局 skills > bundled skills;发现阶段提供名称/描述,完整内容按需加载,agent-owned skills 可随云端记忆跨机器迁移。L9、L11
4. Agent loop:harness与后端交替推进
可核查调用链为交互 use-conversation-loop.processConversation 或 headless 的迭代循环 → sendMessageStream → backend conversation stream → 收集assistant/tool/approval/stop事件。API 模式中,服务端可处理自身工具并继续推理;本地工具产生 requires_approval 后由客户端分类为自动允许、拒绝或需用户输入,执行 executeApprovalBatch → tools manager → 以 approval 结果作为下一次输入继续。当前云端内部多step调度只从协议边界可见,不能以退休 V1 源码作“当前实现”证据;local backend 的 provider executor 则在同仓库可审阅。L6、L12
本地工具批次按资源调度:标记为可并发的只读工具和 Task 可一起执行;写工具按目标资源分组,同资源串行、不同资源可并行,结果按原始调用顺序回传。客户端等待审批并不意味着整个工具批次必然串行。executeApprovalBatch
正常终止、取消、错误、max_steps 都有分支;headless 特别避免在回传 approval 前强制max_steps,以免让后端永久停在等待审批。SDK自动重试默认关闭以避免状态重放,外层有共享恢复策略:429/5xx/网络故障按预算延迟重试,busy时尝试续接已有stream,审批ID失配重新取后端状态;鉴权、无额度等错误不会一律无限重试。子agent通过独立headless子进程运行,有新建隔离context、fork继承上下文以及调用已有agent的路径;reflection属于受限memory scope的专用子agent。它们隔离上下文预算,不代表与主agent的工作目录天然没有共享副作用。L12
综合判断(推断):Letta Code 的差异化是把跨会话身份、可提交记忆、后台经验整理和按需召回组合成持续工作的agent;该机制具备“写入—保留—再次使用”闭环,但“不断学习必然变好”仍需要具体任务、检索命中和记忆质量的实测。
源码导航
L1 当前/历史边界:Letta当前README。
L2 backend默认与部署:resolver、settings默认、官方self-hosting。
L3 学习意图与触发:根MemFS prompt、官方memory/dreaming。
L4 reflection实际开关:post-turn入口、Cloud cutover处理;默认值见E2。
L5 reflection提炼、写入、完成:reflection-v2提示、worktree finalization、success checkpoint。
L6 API消息边界:request builder与SDK重试、backend代理接口、官方compact API。
L7 local上下文压缩:预算与threshold、默认策略、摘要切换active IDs且追加历史、fallback。
L8 检索边界:官方MemFS无默认vector、Cloud search endpoint、local transcript search。
L9 持久化和已提交注入:memory工具自动提交、local compiler读HEAD、memory路径与作用域。
L10 MemFS两代布局:检测规则、local编译system目录。
L11 默认工具与skills:创建工具集、禁用base tools、skills来源优先级。
L12 loop、恢复、子agent:交互循环、headless approval执行与回传、max_steps的approval边界、重试分类、子agent spawn。
OpenClaw
1. 自主学习:当前版本已有两条默认自动闭环
事实:不能沿用“只有记笔记、没有标准自主学习”的旧结论。 第一条是 memory-core 的 Dreaming:默认启用,默认每天 03:00 的托管 cron sweep;依次 light(整理去重候选)→REM(主题反思、强化信号)→deep(评分门槛后巩固长期记忆)。深层晋升要求分数、召回次数、不同查询数量同时达标;untrusted/system 源先被代码排除,会话衍生候选只接受 interactive。模型在确定性门槛内选择 additions/merges/supersessions,接受前校验来源、旧条目保留比例与 bootstrap 容量;改写有 preimage、内容哈希检查,失败回退 append promotion。DREAMS.md 是人工审阅输出,不反过来当新学习来源。O1O2
第二条是核心 Skill Workshop 的 self-learning。skills.workshop.autonomous.mode 与 approvalPolicy 都默认 auto,不是额外安装社区技能才有。已用技能的即时修复、完工后的 detached experience review、每周 collection review构成过程知识沉淀。经验复盘要求单轮至少 10 次 model iterations、前台完成或中断但非 provider/prompt error、runtime 报告实际模型和 skill_workshop 可用、静默30秒且无活动agent;排除 cron/heartbeat/memory/overflow/hook/subagent/review,源码还排除 compacted === true。复盘读取固定完成位置的证据,最多一次技能变更;只能写本agent的 workshop-skills,经过 proposal→hash binding→scanner→apply,可留 pending 或 quarantine。新会话复用更新技能,正在运行的 skill snapshot 不被热替换。propose 只生成提案,off 关闭自动捕获。O3
边界/推断: 这是外部记忆与程序性技能更新,不是参数训练;有自动学习工作流,不等于保证学习正确。Memory flush 只是压缩前把未存上下文追加到日记,最终巩固由 dreaming负责。Heartbeat/cron是调度机制,不天然等于学习;默认 heartbeat 本身不做记忆维护。Workshop还提供显式评估插件hook,但“评价→反复修订→停止条件”的外部优化控制器并未内嵌,不能宣称标准无限自优化。O4
2. 长上下文:pruning、compaction、flush分工
事实: pruning针对旧 toolResult,不概括普通对话。当前客户端投影视图会写入隐藏 openclaw.cache-ttl marker,因此可跨Gateway重启恢复,原工具结果不改写;“永远仅内存、不持久化”已过时。非Anthropic默认关闭;Anthropic auth可播种智能默认。直接Anthropic API-key请求走服务端tool-result clearing,其余符合条件路径在TTL过期且上下文占用约30%后soft trim,仍约50%且有足量内容则hard clear;最近3轮与初始用户消息之前内容受保护。O5
Compaction默认开启,接近窗口预算或provider overflow触发,旧对话摘要持久化、保留近期尾部;分割时保持tool call/result配对。当前新配置默认safeguard,有摘要质量校验与有限纠正;不合格不写入。客户端阈值核心是 contextWindow−reserve;提前flush再减softThreshold,使用新鲜token观测,必要时读transcript推算。默认flush要求可写workspace,仅追加 memory/YYYY-MM-DD.md,禁止改MEMORY/DREAMS/SOUL/AGENTS;无待存内容可NO_REPLY。O6O7
Flush失败/重试耗尽不会重置会话;必要compaction失败保留原历史并报错,不能写成“自动清空重启”。摘要模型未显式覆盖时可临时使用配置的fallback链,取消或质量校验失败不切模型;overflow compaction后可重试原turn,重试会重置流缓冲防重复输出。Stop后停止后续恢复/重试,已完成compaction不回滚。原生Codex等runtime拥有自己的压缩策略,不能把内置runtime全部细节套到所有harness。子agent通常独立context/token预算,也允许显式context: fork,并非绝不继承父历史。O7O11
3. 持久Memory:Markdown为内容源,SQLite为索引与状态
事实: memory-core默认索引MEMORY.md、现存USER.md、memory/*.md;MEMORY保存长期事实,USER保存偏好指令,日记保存细节,DREAMS供审阅。文件可人工读写,SQLite保存chunk、embedding、FTS、provenance与运行状态,因此不宜把“无隐藏状态”的产品说法扩写成“所有系统状态只有Markdown”。当前每agent主数据库是 ~/.openclaw/agents/<agentId>/agent/openclaw-agent.sqlite,会话与transcript也已迁入该库;JSONL/sessions.json属于旧迁移或归档,不再是默认热写源。O8
Builtin支持FTS5/BM25+向量hybrid,400-token chunk/80 overlap,文件变更debounce重索引;综合相关性、时间、importance后MMR去重(不是学习式reranker)。默认OpenAI embedding;有可用凭证才获得向量检索,否则关键词搜索。可显式Gemini、Voyage、Mistral、Ollama等,本地GGUF需官方llama.cpp provider,sqlite-vec是可选加速。O8
重大版本边界:QMD已移除,doctor迁移旧backend/qmd配置并保留extraPaths和原始记忆;当前builtin不带旧QMD的HyDE/cross-encoder reranking。这里“builtin唯一engine”仅指这条内置检索引擎,不是系统不能换memory plugin:官方文档仍列Honcho及需安装的memory-lancedb外部插件,后者通过plugins.slots.memory选用;memory-wiki为旁路知识层,非memory-core替代。O9
写入—复用路径:工作日记/flush/合格interactive transcript→带来源索引→dreaming→curated memory→预算内bootstrap与逐轮刷新;触发短语还可通过确定性lexical/vector匹配注入最多3条可信curated内容。Active Memory默认escalate:用户显式回忆意图且普通lane无强命中,才运行阻塞式检索子agent。跨会话记忆个人安装默认开,配置DM隔离时默认关;只限同agent已识别私聊,排除群聊、其他agent及元数据不足会话;不会扩大sessions_*权限。配置sources默认memory,但rememberAcrossConversations开启会加入sessions,不能仅凭sources默认值断言“不索引会话”。O10
4. Agent loop:已从“嵌入外部Pi”演进为自有runtime及可插拔harness
事实: 当期链路是 Gateway agent RPC校验与session解析、立即返回runId→agentCommand→runEmbeddedAgent→session lane再global lane→prepared model runtime/harness选择→session与prompt准备→模型/工具循环→事件桥接、流输出与持久化→终态。源码run-orchestrator的enqueueSession包enqueueGlobal,CLI eligible path也在入队后分发。不同session可并发,同session串行,SQLite activeWriterRunId提交栅栏阻止被替代run落过期transcript。O11
当前运行内核在自有 packages/agent-core(Agent/agent-loop)与 @openclaw/ai,第三方说明仅称部分实现改编自Pi/pi-mono且依赖pi-tui做TUI。应写“源自Pi的自有内核”,不再称当前运行loop依赖外部pi-coding-agent。另有embedded plugin harness codex/copilot与独立CLI backend,provider/model/runtime是不同层。内核Agent默认toolExecution parallel,显式sequential或某工具要求sequential会使批次串行;模型轮次仍按工具结果/steering/followup继续,不能把session串行误写成工具永远串行。O12
循环在无待处理tool/steering/followup时结束,error/abort/预算超时可终止;agent.wait超时仅结束等待,不取消执行。队列支持steer/followup/collect/interrupt,当前默认steer。子agent用独立session在后台运行,完成后通过有幂等key的parent handoff;父run活跃时先steer,无法接收则排同session lane。计算完成与结果送达是独立状态,送达重试有上限。Cron隔离turn由scheduler负责预算与清理;这些异步调度组件不等价学习系统。O11O12
源码导航
所有链接固定同一SHA;文档与源码发现冲突时以本节较具体源码/说明为准。
O1 Dreaming默认值和03:00频率;三阶段及巩固验证。
O2 代码:候选来源和interactive gate;托管cron实现。
O3 Workshop默认auto;复盘阈值和资格代码;完整学习流程。
O4 外部评估优化loop边界;默认heartbeat不维护memory。
O6 flush目标与只追加提示;默认启用与预算;提前阈值/过期计数处理。
O7 compaction、safeguard、恢复和失败保留历史。
O8 Builtin检索与SQLite位置、索引;Session SQLite与旧JSONL迁移。
O10 Memory信任层与双lane;跨会话默认与隔离;sources和权限边界。
O11 真实入队与runtime准备;RPC到loop及writer fence;子agent隔离、fork及异步交付。
O12 自有内核循环及终止;工具串并行决策;默认parallel;Pi来源声明;队列。
官方文档冲突与核查边界
- 未做模型行为/准确率/收益评测。扫描、来源门槛和hash并不证明记忆或skill内容正确。
- 同一 commit 的 self-learning 说明仍称每周 collection review 有整体备份及自动回滚,而更具体的 Workshop 恢复说明明确新实现按普通 Agent 文件编辑处理,没有 collection 整体事务或新备份。本文不承诺周 review 具备整体自动回滚;逐 skill proposal apply 的 rollback metadata 是不同层次的机制。
compaction.md末尾对照表仍将 pruning 写成仅内存,与 pruning 专页的持久投影标记说明不一致。本文采用后者:原始 toolResult 不改写,客户端投影可持久恢复。- 文档称 memory“无 hidden state”是面向用户内容的简化说法;SQLite 实际还保存来源、索引和 Dreaming 运行状态。
横向结论与可借鉴实现
以下是基于上述实现的工程判断,不是经过统一任务集验证的产品排名。
| 希望解决的问题 | 值得先读的实现 | 原因与边界 |
|---|---|---|
| 个人偏好、环境事实和经验步骤的轻量持久化 | Hermes MemoryStore、background review、skills 工具 |
文件简单、容量明确,能看到从复盘到复用的完整路径;常驻笔记容量小,较大知识库要靠技能/历史/外部 provider。 |
| 大材料、多步数据处理与可编程多 Agent | Prime REPL、host bridge、runLoop、AgentSession |
外置变量、独立子会话和宿主调度边界清楚;需要理解变量丢失、预算及异步结果交付。 |
| 可版本化、跨 conversation 的长期身份和知识 | Letta MemFS、reflection worktree、local prompt compiler | 能审查记忆 diff/提交与注入过程;必须区分 API/local 和 MemFS 版本,云端内部不能由客户端代码直接推断。 |
| 常驻多入口助理的记忆巩固与异步运行 | OpenClaw memory-core、Dreaming、Workshop、session lane | 来源过滤、分阶段巩固、队列与结果投递较完整;配置和状态层更多,需逐项确认实际启用的 runtime/plugin。 |
学习闭环:哪里已经实现,哪里还需实测
| 环节 | 已看到的代表实现 | 仍需验证的效果 |
|---|---|---|
| 提取经验 | Hermes 后台复盘;Prime review/refine;Letta reflection;OpenClaw Dreaming/experience review。 | 是否准确识别用户纠正与稳定规律,有无把偶然成功、工具输出或旧召回误当新知识。 |
| 控制写入 | 有界文件与技能保护;JSON schema/版本冲突;Git worktree/commit/merge;来源评分、hash、scanner。 | 结构合法、合并成功不代表事实正确;错误记忆能否被下一次反例修正。 |
| 后续复用 | 常驻短记忆;harness 摘要;核心 MemFS 与目录投影;混合检索和可信触发注入。 | 该用时能否命中、不相关时是否避免干扰;知识增多后效果是否退化。 |
| 效果反馈 | 人类纠正、后续任务结果、回滚与可配置 quality/evaluation hooks。 | 未完成四者统一的“新旧记忆 A/B → 独立任务评分 → 自动晋升”验证,不能凭已有 hooks 宣称持续提升。 |
建议用于下一轮实测的最小任务集
这些是后续验证方案,本次没有执行。
| 场景 | 测试方式 | 记录指标 |
|---|---|---|
| 偏好与事实更新 | A 会话给出事实,B 会话要求使用;再给出相反的新事实,C 会话检查是否采用新版本。Prime 分 local/global,Letta 分同/不同 agent。 | 写入位置、版本、召回来源、采用率、旧事实残留。 |
| 程序性学习 | 完成一次包含纠错的任务,再给同类但参数不同的任务;对照启用/关闭复盘的干净状态。 | 技能是否产生与调用、错误是否重复、成功率、token/耗时。 |
| 压缩后精确信息恢复 | 在早期埋入精确 ID、失败原因、禁止操作,触发多次压缩后要求继续任务。 | 摘要保留率、历史补检成功率、未检索即猜测比例。 |
| 跨进程恢复 | 分别关闭 UI、重启 worker/Gateway、恢复会话,检查目标、工具执行状态、子任务及外置数据。 | 状态丢失、重复副作用、子结果丢失或重复投递。 |
| 记忆纠错和隔离 | 写入带来源的错误结论,再明确纠正;测试群聊/个人、不同 agent/profile 和删除后的可见性。 | 活跃记忆与原始历史是否分别清理,隔离是否符合配置。 |
阅读资料时应避开的旧结论
- Letta:旧 V1 server 已退休;当前默认 API 与开源 local runtime 必须分开。旧 archival/recall 向量架构不能直接当作当前 MemFS 默认实现。当前仓库说明
- OpenClaw:本次快照已有默认 Dreaming 和 auto Workshop,内置 QMD 已移除;“当前完全依赖外部 Pi loop”“会话热写仍全是 JSONL”均不符合本次版本。具体来源见 O1–O12。
- Hermes:压缩比例不是所有模型统一 50%;memory 快照在压缩后会重载;搜索结果也有长度限制。具体来源见 H5、H9、H10。
- Prime:默认自动 refinement 只对满足条件的根会话启用,默认 local 不自动传播到新 session;REPL 状态也有序列化与尺寸边界。具体来源见 Prime Agent。
本文的“已实现”指在上述版本看到调用链、存储和默认配置,或明确标为官方文档描述;“判断”是这些机制的工程含义;效果与未公开后端细节均保留为待验证项。
本文作者: Uyouii
文章链接: https://uyouii.cool/posts/3f0ed6b/
版权声明: 本博客文章除特别声明外, 均采用署名4.0国际(CC BY 4.0)国际许可协议进行授权, 转载请注明出处