找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

4664

积分

0

好友

621

主题
发表于 5 天前 | 查看: 22| 回复: 0

Claude Code 源码泄露的事,大家应该都知道了。npm 包里多带了一个 .map 文件,512,000 行 TypeScript 就这么公开了。

研究完它的源码后,我们的结论是:Claude Code 的记忆系统,比想象中初级。

它确实做了不少工作,分了好几层,甚至搞了一个让 agent 做梦的机制来整理记忆。听起来很高级。但扒开来看,本质上还是在一个 agent 的沙盒里打转,记忆出不去,也活不长。

下面一层一层拆开来说。

01 Claude Code 记忆拆解

第一层:CLAUDE.md,用户写给 agent 的规矩

CLAUDE.md 是一个 Markdown 文件,用户自己写,放在项目根目录下。内容可以是任何你想让 Claude 记住的规矩:代码风格约定、项目架构说明、测试命令、部署流程。这个大家用过的应该都比较熟悉了。

每次会话开始时,Claude Code 会把这个文件完整加载进 context。文件越短,Claude 遵守得越好。

它支持三个作用域:项目级的 CLAUDE.md 放在项目根目录,个人级的放在 ~/.claude/CLAUDE.md,组织级的放在企业配置里。

第二层:Auto Memory,agent 自己记笔记

CLAUDE.md 解决了用户主动告诉 agent 的问题,但很多有价值的信息是在对话过程中冒出来的,用户不会专门去写。

Auto Memory 就是干这个的:Claude 在工作中自己判断哪些信息值得记下来,写进一个独立的记忆目录里。

Claude 会把值得记住的东西分成四类:user 类型记录用户的角色和偏好,feedback 类型记录用户的纠正和确认,project 类型记录项目相关的决策和背景,reference 类型记录外部资源的位置。

这些记忆存在 ~/.claude/projects/<项目路径>/memory/ 目录下。每条记忆是一个独立的 Markdown 文件,带 frontmatter 标注类型和描述。入口文件是 MEMORY.md,起索引作用,每行不超过 150 个字符,只存指针,不存内容。

每次会话开始时,MEMORY.md 的前 200 行会被注入 context。真正的知识分散在各个话题文件里,按需加载。

大概长这样:

~/.claude/projects/-Users-me-myproject/memory/
├── MEMORY.md                  ← 索引文件,每行一个指针
├── user_role.md               ← “后端工程师,熟悉 Go,React 新手”
├── feedback_testing.md        ← “集成测试必须跑真实数据库,不要 mock”
├── project_auth_rewrite.md    ← “auth 重构是因为合规要求,不是技术债”
└── reference_linear.md        ← “pipeline bug 在 Linear INGEST 项目里追踪”

MEMORY.md 内容示例(每行 ≤150 字符):
- [User role](user_role.md) — 后端工程师,Go 熟练,React 新手
- [Testing rule](feedback_testing.md) — 集成测试不要 mock 数据库
- [Auth rewrite](project_auth_rewrite.md) — 合规驱动,非技术债
- [Bug tracker](reference_linear.md) — pipeline bug 看 Linear INGEST

这里有一个设计细节值得注意:Claude 被明确要求不要信任自己的记忆。泄露的系统提示词里写得很直白,大意是「记忆只是提示,行动前先去读真实文件做核实」。在模型幻觉率还在两位数的阶段,这种怀疑自己的策略反而很实用。

第三层:Auto Dream,让 agent 做梦整理记忆

记忆写入的问题解决了,但跑了几十次会话之后,MEMORY.md 越来越乱。

矛盾的条目堆积起来就会出现:“昨天的 bug”类似这样的表述写进记忆后,过一周就没人知道是哪天了。于是,已经被重构掉的函数还留在记忆里,文件越来越长,越来越脏。

Auto Dream 模拟的是人脑在睡眠中做的事:整理和巩固记忆。

它扫描现有记忆文件,翻阅历史会话记录,找到用户的反馈和反复提到的话题,然后做整合:把相对时间换成绝对日期,合并矛盾条目,剔除过时内容,最终把 MEMORY.md 控制在 200 行以内。

触发条件两个同时满足:距离上次整合超过 24 小时,且积累了 5 次以上新会话。也可以手动输入“dream”触发。整个过程跑在后台的子 agent 里,不阻塞主会话。

机器人梦境中自动整理记忆示意图

第四层:KAIROS,泄露代码里还没上线的野心

前面三个都是已经上线或正在灰度的功能。泄露的代码里还藏着一个更大的东西。

KAIROS 在源码中出现了超过 150 次。这是一个后台守护进程模式,想把 Claude Code 从被动响应的工具变成主动观察的自治体。

KAIROS 维护 append-only 的日志文件,持续记录观察、决策和行动。它在固定间隔收到 <tick> 信号,自行决定是该主动做点什么,还是保持安静。设计里有一个 15 秒的阻塞预算,任何会打断用户工作超过 15 秒的操作都会被推迟。

KAIROS 内部整合了 autoDream,但走得更远。它不只在会话间隙做记忆整理,而是把整个观察-思考-行动的循环搬到了后台。代码里可以看到它的系统提示词开头:“# Dream: Memory Consolidation — You are performing a dream, a reflective pass over your memory files.”

不过 KAIROS 目前被一个编译时 feature flag 控制,没有出现在任何公开版本里。更像是 Anthropic 对下一步方向的探索。

02 这套体系的天花板在哪?

回头看这四层,用过一段时间就会发现几个绕不过去的问题:

  • 200 行硬上限MEMORY.md 最多 200 行,25KB。项目跑几个月,记忆就开始互相挤占,老的被新的顶掉。
  • 只有 grep 检索。记忆的查找靠 grep 关键词匹配,没有语义理解。你记得讨论过“部署时端口冲突的问题”,但记忆里写的是“修改 docker-compose 的 port mapping”,grep 搜不到。
  • 细节容易丢。Auto Memory 记的是 agent 自己觉得重要的东西,粒度很粗。具体的代码片段、调试过程、讨论的上下文,大部分会被丢掉。
  • 层层修补的复杂度。CLAUDE.md 不够加 Auto Memory,Auto Memory 乱了加 Auto Dream,Dream 不够又搞 KAIROS。每一层都是在补上一层的问题,越叠越复杂,但根上的限制没变。
  • 跨工具不通用。记忆锁在 Claude Code 一个工具里。换到 OpenCode、Codex CLI,从零开始。
  • 终究是短期记忆。不管做不做梦,本质还是会话粒度的东西。「上周讨论的 Redis 配置最后怎么处理的」「三个月前的 auth 重构到哪一步了」,这类长跨度的回溯基本无望。

单智能体记忆隔离示意图:三个智能体被隔板分开,成为信息孤岛

这不是 Claude Code 的设计失误。单 agent、会话粒度、本地存储,架构走到这里,天花板就在这。

03 memsearch:记忆应该比任何一个 agent 都活得更长

这是我们做 memsearch 的核心想法。agent 会换,工具会换,但你在项目里积累的知识不应该跟着消失。memsearch 把记忆从 agent 里抽出来,放到一个独立的持久层。agent 来来去去,记忆一直在。

memsearch项目主页,展示其作为跨平台AI编程代理语义记忆工具

整体架构:

┌─────────────────────────────────────────┐
│         Agent Plugins (用户层)           │
│  Claude Code · OpenClaw · OpenCode · Codex│
└──────────────────┬──────────────────────┘
                   ↓
┌──────────────────┴──────────────────────┐
│       memsearch CLI / Python API         │
│            (开发者层)                     │
└──────────────────┬──────────────────────┘
                   ↓
┌──────────────────┴──────────────────────┐
│    Core: Chunker → Embedder → Milvus     │
│            (引擎层)                       │
└──────────────────┬──────────────────────┘
                   ↓
┌──────────────────┴──────────────────────┐
│     Markdown Files (Source of Truth)      │
│          (持久存储层)                     │
└─────────────────────────────────────────┘

最上面是四个主流 agent 平台【Claude Code · OpenClaw · OpenCode · Codex】的插件,负责自动捕获对话。中间是 CLI 和 Python API,给开发者做自定义集成。底下是 Milvus 向量索引加 Markdown 持久存储。

四个平台各自接入,但往下走都是同一套 core。

安装:两条命令搞定

Claude Code 用户在 marketplace 里装就行:

/plugin marketplace add zilliztech/memsearch
/plugin install memsearch

全程不需要配置任何东西。

其他平台也一样简单。OpenClaw 一条命令:openclaw plugins install clawhub:memsearch。Python API 用 uv 或 pip:

uv tool install "memsearch[onnx]"

自动记忆,全量记忆,按需回忆

装好之后,memsearch 通过 shell hook 接入 agent 的生命周期。

自动记忆,全量记忆。 每轮对话结束时,对话被 Haiku 模型自动总结要点,被追加到当天的记忆 Markdown 文件,再异步向量化进索引。后台完成,用户无感。且不会漏任何对话轮次,历史所有操作都有记忆,永不遗忘。

记忆召回通过 skill 机制触发。 memsearch 注册了一个 memory-recall skill,Claude 可以主动调用,也可以在判断用户问题需要历史上下文时被动触发。skill 跑在 fork 出来的子 agent 里(context: fork),不会把搜索工具的定义塞进主会话的 context,零 token 开销。

memsearch系统交互流程图:展示会话开始、每次用户提示、异步停止三个阶段的完整流程

记忆文件的目录结构长这样:

.memsearch/
└── memory/
    ├── 2026-03-28.md    ← 每天一个文件
    ├── 2026-03-29.md
    ├── 2026-03-30.md
    └── 2026-04-01.md

一天一个 Markdown 文件。打开就能读,编辑器能直接改。想迁移?复制文件夹。想版本管理?git 跟踪。

向量索引只是缓存层,Markdown 才是 source of truth。 索引丢了随时重建。数据不会锁死在某个工具里。

检索:不只是向量搜索

Claude Code 的记忆检索靠 grep。记忆少的时候够用,多了就不行了。

memsearch 走混合搜索。语义向量抓相近的内容,BM25 抓精确关键词,RRF 做融合排序。

你问「上周那个 Redis 超时怎么解决的」,语义搜索能理解意图。你说「搜一下 handleTimeout」,BM25 精确命中函数名。两条路互补。

recall 被触发后,子 agent 内部会从 L1 往 L3 逐层下探。Claude 在每一层看到的东西大概是这样:

L1:语义搜索

子 agent 先跑 memsearch search,从 Milvus 里召回最相关的结果:

┌─ L1 搜索结果 ─────────────────────────────────┐
│                                                │
│  #a3f8c1 [score: 0.85] memory/2026-03-28.md    │
│  > 部署时 Redis 端口冲突,默认 6379 被占用,    │
│    改用 6380,同时更新了 docker-compose...       │
│                                                │
│  #b7e2d4 [score: 0.72] memory/2026-03-25.md    │
│  > auth 模块重构完成,JWT 换成 session token,  │
│    原因是移动端对 token 刷新支持不好...          │
│                                                │
│  #c9f1a6 [score: 0.68] memory/2026-03-20.md    │
│  > 数据库索引优化,在 users 表加了复合索引,    │
│    查询时间从 800ms 降到 50ms...                 │
│                                                │
└────────────────────────────────────────────────┘

每条结果带 chunk_hash、相关性分数、来源文件,内容截断到 200 字。大多数时候到这一层就够了。

L2:上下文展开

如果 L1 的预览不够用,子 agent 拿 chunk_hash 跑 memsearch expand a3f8c1,拉出完整段落:

┌─ L2 展开结果 ─────────────────────────────────┐
│                                                │
│  ## 2026-03-28 部署问题排查                     │
│                                                │
│  Redis 端口冲突排查过程:                       │
│  1. docker-compose up 后 Redis 容器启动失败     │
│  2. 宿主机 6379 被另一个 Redis 实例占用         │
│  3. 改 docker-compose.yml: “6380:6379”         │
│  4. 更新 .env: REDIS_PORT=6380                 │
│  5. config/database.py 连接字符串同步修改       │
│                                                │
│  注意:只影响本地开发环境,生产环境不受影响。   │
│                                                │
│  [source: memory/2026-03-28.md  lines: 42-55]  │
└────────────────────────────────────────────────┘

不用截断,完整上下文,所有细节都在。

L3:原始对话

极少数情况下需要看当时到底聊了什么。子 agent 跑 memsearch transcript <path> --turn <uuid>,拉出原始对话记录:

┌─ L3 原始对话 ─────────────────────────────────┐
│                                                │
│  [user] docker-compose up 跑不起来,Redis 报   │
│         端口冲突,帮我看看怎么回事              │
│                                                │
│  [agent] 检查了宿主机端口占用情况...            │
│          运行 lsof -i :6379 发现...             │
│          建议修改映射端口为 6380...              │
│          (tool_call: Bash “lsof -i :6379”)      │
│          (tool_call: Edit “docker-compose.yml”) │
│                                                │
│  [user] 好了,还有别的地方要改吗?              │
│                                                │
│  [agent] 还需要更新 .env 和 database.py...      │
│                                                │
└────────────────────────────────────────────────┘

用户的提问、agent 的回复、调用了哪些工具,一个不漏。

三层从轻到重,子 agent 自己判断需要下探到哪一层,最后把整理好的结果返回主会话。省 token,不丢信息。

跨 agent 共享:真正的永久记忆

这是 memsearch 和 Claude Code 记忆最本质的区别。

Claude Code 的记忆锁在自己一个工具里。你用 OpenCode、OpenClaw、Codex CLI,得各自从零开始。MEMORY.md 存在本地,绑定单个用户、单个 agent,天然就是一座孤岛。

memsearch 目前支持四个主流 coding agent:Claude Code、OpenClaw、OpenCode、Codex CLI。它们共享同一套 Markdown 记忆格式,和同一个 Milvus collection。

不管从哪个 agent 写入的记忆,其他 agent 都能搜到。

多工具协同开发截图:展示Claude Code、OpenCode、Codex CLI和OpenClaw四个工具窗口同时工作

举两个实际场景。

第一个:你在 Claude Code 里花了一下午搞清楚项目的部署流程,踩了几个坑。对话被自动总结、索引。第二天切到 OpenCode 继续开发,问「昨天部署时那个端口冲突怎么解决的」。OpenCode 直接搜到昨天在 Claude Code 里的记忆,给你正确答案。

第二个:团队协作。把 Milvus 后端指向 Zilliz Cloud,多个开发者在不同机器上、用不同 agent,读写同一份项目记忆。新人加入,不用翻几个月的 Slack 和文档,agent 自己就知道项目的历史上下文。

这些事情,Claude Code 的记忆体系做不到。

给开发者的接口

如果你不只是用现成的 agent 插件,而是自己搭 agent 工具,memsearch 提供了 CLI 和 Python API 两种方式。

CLI 可以直接在终端操作记忆:

# 索引 markdown 文件
memsearch index ./memory
# 搜索记忆
memsearch search “Redis 端口冲突”
# 展开某条记忆的完整内容
memsearch expand a3f8c1
# 启动文件监视,自动索引变动
memsearch watch ./memory
# 压缩老记忆
memsearch compact

Python API 几行代码就能接进任何框架:

from memsearch import MemSearch

mem = MemSearch(paths=[“./memory”])
await mem.index()                      # 索引 markdown
results = await mem.search(“Redis config”) # 混合搜索
await mem.compact()                    # 压缩老记忆
await mem.watch()                      # 文件变动自动索引

底层用 Milvus 做向量数据库。本地跑用 Milvus Lite,零配置。云端协作接 Zilliz Cloud,有免费层。自托管 Docker 也行。

嵌入模型默认用 ONNX,CPU 跑,不用 GPU 不用调 API。想换 OpenAI 或 Ollama 随时切。

尾声

Claude Code 的记忆设计有它的价值。KAIROS 和 autoDream 的思路也值得关注。

但单 agent 内部的记忆优化,走到头也就是这样了。记忆应该比任何一个 agent 都活得更长。通过独立的向量存储层和开源统一的记忆协议,或许才是打破智能体“记忆孤岛”的关键一步。

希望这份基于源码的分析,以及对跨平台记忆方案 memsearch 的介绍,能给大家在构建更“持久”的 AI 编程工作流时带来一些启发。关于 AI 编程、向量数据库以及各种工程实践的更多讨论,也欢迎来 云栈社区 交流。

memsearch 紫色云朵Logo




上一篇:元思维:最小可治理单元如何解决复杂AI系统的混乱问题?
下一篇:Kubernetes PV PVC 回收策略实战:删除 PVC 后 PV 保留还是删除?
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2026-4-7 15:54 , Processed in 0.702289 second(s), 43 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2026 云栈社区.

快速回复 返回顶部 返回列表