阅读源码: CLaude Code 如何实现Agent Memory (上)
阅读源码 CLaude Code 如何实现Agent Memory 上一、数据模型封闭四类一文件一记忆封闭的四类分类法记忆被约束在一个四值枚举里memoryTypes.ts:14-19user、feedback、project、reference。这不是随意的标签而是一道内容闸门——WHAT_NOT_TO_SAVE_SECTION明确排除代码模式、架构、git 历史、debug 方案、CLAUDE.md已有内容、临时任务状态即使用户明确要求保存也适用。设计意图很清楚只存“读代码、跑 git 都推导不出来”的东西。这是整个系统控制记忆数量的第一道、也是最重要的一道防线。其中user类型记忆名称用户/名称说明存放有关用户身份岗位、目标、工作职责以及知识储备的相关信息。完善的用户记忆可以让你后续的交互行为适配用户的使用习惯与思考角度。读写该类记忆目的是充分了解用户本身明确如何针对性地为用户提供帮助。举个例子你和资深软件工程师、初次接触编程的学生开展协作时沟通方式应当有所区分。谨记所有记录都应当以便于服务用户为宗旨不要记录带有负面主观评价、或是和双方工作无关的用户信息。存储时机当你获知用户的岗位、使用偏好、工作职责、知识水平等任意细节时/存储时机使用方式在工作需要结合用户个人情况、思维习惯时启用。例如用户需要你讲解某段代码你的回答需要贴合用户的实际情况输出对他最有用的内容依托用户已经掌握的专业知识帮助他搭建知识框架。/使用方式示例用户我是一名数据科学家正在调研项目现有的日志方案 助手[保存用户记忆用户为数据科学家当下正在研究可观测性、日志相关内容] 用户我已经有十年Go语言开发经验但我第一次接触该仓库的React前端部分 助手[保存用户记忆用户精通Go语言初次接触React以及本项目前端讲解前端知识时可以多用后端相关类比进行说明]/示例feedback类型记忆名称反馈/名称描述用户针对你的工作方式给出的指导包含需要规避的操作以及需要沿用的习惯。读写该类记忆十分关键能够让你后续的工作风格保持统一适配项目的协作要求。 失误经验与成功经验都需要记录倘若你只保存用户的纠正意见虽然可以规避过往错误但会淡忘用户已经认可的处理方案行事也容易变得过度保守。/描述存储时机当用户纠正你的处理思路例如“不要这样”“别做X”或是认可你非常规的方案可行例如“正是如此”“很好继续这么做”、默许你的特殊选择。 纠正指令十分显眼而肯定类提示往往较为隐晦需要多加留意。 以上两种场景都要记录适用于后续对话的信息尤其是那些出乎意料、无法从代码直接看出的要求同时记下背后缘由方便之后处理边界场景。/存储时机使用方式依靠该类记忆规范自身工作习惯无需用户反复重申相同要求。/使用方式内容格式开头写明行为准则随后书写**原因**用户给出的理由大多是过往事故或是个人偏好再写明**适用方式**该条规范的生效场景。 知晓背后动机可以灵活处理各类边界情况而非死板遵守规则。/内容格式示例用户测试代码不要使用数据库模拟环境。上个季度我们吃过亏模拟测试运行正常但线上数据库迁移却失败了 助手【保存反馈记忆集成测试必须连接真实数据库禁止使用模拟库。原因此前模拟环境和线上环境存在差异掩盖了迁移故障】 用户不要每次回复末尾总结操作我可以自行查看代码变更记录 助手【保存反馈记忆用户偏好简洁回答禁止在文末添加总结】 用户没错本次采用合并式PR是正确的拆分多个PR只会造成无效的重复工作 助手【保存反馈记忆该模块的代码重构用户倾向使用单个合并PR而非拆分大量小型PR该方案得到用户认可属于通过的决策而非纠错】/示例一条记忆 一个文件每条记忆是一个带 YAML frontmatter 的.md文件文件名称约定为{类型}_{主题}.md---name:语义名description:一句话描述用于判断相关性type:user|feedback|project|reference---正文feedback/project 要求写成 规则 **Why:****Howto apply:**MEMORY.md 是索引不是记忆MEMORY.md是入口索引每条一行指针- [Title](file.md) - hook无 frontmatter指令反复强调“Never write memory content directly into MEMORY.md”。它和主题文件是两个东西。二、存储一个扁平的、不分类型的池子四种类型共用同一个目录没有user/、feedback/子目录。scanMemoryFiles过滤只看.md和非MEMORY.md不看 typeformatMemoryManifest把 type 当成行首标签[type]拼进一个混编清单召回选择器在所有类型里一起挑不按类型配额。type 真正起作用只有两处写入侧的正文结构指令feedback/project要写 Why/How to apply和触发时机user学到角色时、feedback用户纠正/确认时。这是给模型的写作指导不是流程上的分区。唯一的“物理分开”出现在 team 模式按private/team两个目录路由且user/feedback都偏private、project/reference偏team。但即便如此user和feedback仍在一起——分开的是“它俩”和“偏 team 的另两类”不是四种类型各自独立。这个“扁平不分类型”的选择是后面盲区的根源之一。三、写入两个互斥的写手“改还是建”由模型定两个写手写手 A主 agent 自己。它的系统提示里始终带着完整的 save 指令任何时候它觉得该记就能直接用 Write/Edit 写。当用户说“记住 X”时会直接调用tools指令要求立刻存储这个记忆。写手 B后台 extractMemories。它在每个 query loop 结束模型给出最终回复、不再调工具时由handleStopHooks触发分叉主对话共享 prompt cache从这轮对话里提炼持久事实。有门控只有在主线程agentId检查跳过子 agent、feature flag、auto memory 开着的情况下才存储。consthowToSaveskipIndex?[## How to save memories,,Write each memory to its own file (e.g., user_role.md, feedback_testing.md) using this frontmatter format:,,...MEMORY_FRONTMATTER_EXAMPLE,,- Keep the name, description, and type fields in memory files up-to-date with the content,- Organize memory semantically by topic, not chronologically,- Update or remove memories that turn out to be wrong or outdated,- Do not write duplicate memories. First check if there is an existing memory you can update before writing a new one.,]:[## How to save memories,,Saving a memory is a two-step process:,,**Step 1** — write the memory to its own file (e.g., user_role.md, feedback_testing.md) using this frontmatter format:,,...MEMORY_FRONTMATTER_EXAMPLE,,**Step 2** — add a pointer to that file in \${ENTRYPOINT_NAME}\. \${ENTRYPOINT_NAME}\ is an index, not a memory — each entry should be one line, under ~150 characters: \- [Title](file.md) — one-line hook\. It has no frontmatter. Never write memory content directly into \${ENTRYPOINT_NAME}\.,,- \${ENTRYPOINT_NAME}\ is always loaded into your conversation context — lines after${MAX_ENTRYPOINT_LINES}will be truncated, so keep the index concise,- Keep the name, description, and type fields in memory files up-to-date with the content,- Organize memory semantically by topic, not chronologically,- Update or remove memories that turn out to be wrong or outdated,- Do not write duplicate memories. First check if there is an existing memory you can update before writing a new one.,]互斥防重复两者互斥。hasMemoryWritesSinceextractMemories.ts:121-148检查主 agent 这轮是否已往 auto-mem 路径写过文件写过就跳过 extract、只推进游标。注释说得很直白主 agent 提示词本来就有 save 指令它自己写了再 fork 一遍就冗余了。“改还是建”——代码不做判断模型做这是“模型即档案员”信念最集中的体现。代码里没有“if 文件存在则 Edit else Write”的硬规则。代码只做两件事喂数据extract 进来时scanMemoryFiles扫现有记忆formatMemoryManifest拼成一行一个的清单喂给 fork agent。给指令Check this list before writing - update an existing file rather than creating a duplicate Do not write duplicate memories. First check if there is an existing memory you can update before writing a new one.然后模型拿这轮对话提炼出的事实去对照清单里每条的[类型] 文件名 (时间): 描述自己判断有相关主题文件就 Edit没有就 Write。hasMemoryWritesSince只判断“主 agent 写没写过”用于互斥不判断改 vs 建至于怎么找下方四会讲。fork 的两轮策略fork复制一份当前对话的上下文另起一个独立的 agent 去跑子任务但这份副本和原对话共享缓存因为 Edit 工具要求先 Read 过同一文件extract agent 的执行模式被设计成两轮prompts.ts:39turn 1 并行 Read 所有“可能要改”的候选文件不是全部是它看清单挑的子集turn 2 并行 Write/Edit。先批量读、再批量写且只读候选。四、召回没有向量只有一次小模型的判断两条召回路径路径 AMEMORY.md 始终在系统提示里。loadMemoryPrompt构建系统提示时同步读MEMORY.md截断到 200 行/25KB 后拼进去。这是“始终在场”的部分。路径 B相关记忆动态注入。每次用户请求且超过一个词触发findRelevantMemories选 ≤5 条相关记忆作为system-reminder附件注入。这是“按需召回”。扫描原语scanMemoryFiles两条路径的下游、以及 extract 的清单都依赖同一个扫描原语scanMemoryFilesmemoryScan.ts:35-77。它做四件事递归 readdir → 过滤.md排除MEMORY.md→ 并行读每个文件前 30 行 frontmatter → 按mtimeMs降序截取前 200 个。一个设计精髓值得学习单遍优化。readFileInRange内部本来就要读取文件内容才知道文件大小按行读顺带把元信息里的mtimeMs一起返回。于是“读内容顺带拿 mtime→ 排序 → 截断”一轮搞定省掉一次单独的查询文件元信息轮。清单formatMemoryManifest每个 MemoryHeader 被压成一行memoryScan.ts:84-94- [feedback] feedback_testing.md (2026-02-10T08:13:22.000Z): 测试别 mock 数据库注意这里只有 filename description type 时间没有 frontmatter 的 name。200 个文件 × 一行本身就是个紧凑清单。选择器一次 Sonnet 判断selectRelevantMemoriesfindRelevantMemories.ts:77-141是召回的核心也是“模型即档案员”信念的另一半。没有向量检索、没有词频打分、没有 embedding。它做的是拿用户 query 清单 最近用过的工具列表调一次 sideQuery用比主循环更小更快的 Sonnet 模型系统提示要求“up to 5确信有用才选不确定就别选可以返空”输出强制 JSON schema{ selected_memories: [filename...] }max_tokens: 256。最后用validFilenames过滤掉小模型幻觉出来的不存在文件名。“最多 5”不是代码截断是系统提示里写“up to 5”让模型自己控制代码只在attachments.ts:2231-2234有个.slice(0, 5)兜底。一个精妙的细节recentTools一并传给选择器让它避开正在用的工具的参考文档那是噪音但保留那些工具的“坑/警告”类记忆——正在用时恰恰是坑最要紧的时候。mtimeMs贯穿排序与新鲜度mtimeMs是文件系统给的“内容最后修改时间毫秒戳”读文件时顺带拿到。它干四件事排序新在前、截 200、清单里显示 ISO 时间、算新鲜度提示“47 days ago”、给老记忆加“引用前请核实”警告。新鲜度文案在附件创建时算好固化不在渲染时现算避免Date.now()让“3 天前”变“4 天前”打碎 prompt cache。五、如何防止记忆爆炸七层截断且压缩会重置“动态注入”听起来危险——岂不是会把记忆越塞越多直到提示词爆炸系统用七层防护卡死从索引到单条到累计层限制代码位置1. 索引截断MEMORY.md 最多 200 行 / 25KBmemdir.ts:35-382. 扫描上限最多扫 200 个文件每个只读前 30 行memoryScan.ts:21-223. 选择上限Sonnet 最多选 5 条输出 ≤256 tokenfindRelevantMemories.ts:20-234. 单条截断每条最多 200 行 / 4KB超了截断并提示“用 FileRead 看完整文件”attachments.ts:269, 2775. 单轮总量5 × 4KB 20KB/轮attachments.ts:271-2736. 会话累计累计 60KB 后停止预取attachments.ts:288 (MAX_SESSION_BYTES)7. 去重已注入过的不重注模型已用 FileRead 读过的不注alreadySurfacedreadFileState第 6 层尤其巧妙collectSurfacedMemories扫消息历史算累计字节所以压缩天然重置它——旧附件被压缩删掉后计数归零又能重新注入。第 4 层截断不丢文件而是截一部分因为选择器已经判定它最相关frontmatter 开头通常就是关键。结语核心信念与它的代价通观全篇每个机制都在印证同一个信念▎ 代码不做判断只做三件事——喂数据、给指令、设边界。判断全部留给模型。“改还是建”代码喂 manifest 去重指令模型判断。“相关不相关”代码喂一行一行的清单Sonnet 判断。“该不该存”代码给四类分类 排除规则模型判断。“陈旧不陈旧”代码给mtimeMs 验证提示模型判断。边界防护则是硬的七层截断防爆、Promise.allSettled容错、hasMemoryWritesSince互斥、validFilenames防幻觉、路径校验防遍历。这个设计的收益是零基础设施——无向量库、无 schema 迁移、无类型分区、无专用索引引擎全靠文件系统 一次小模型调用且能随模型能力进化而自动变强模型更聪明召回和抽取就更好。这是一个清晰的权衡用模型的判断力换基础设施的简洁用“控制记忆数量”换“不必建大规模检索系统”。理解了这个权衡就理解了这套记忆系统每一个设计选择背后的逻辑脉络。在我们设计agent memory的过程中cc的一些设计思路还是很值得学习的。以上内容为阅读源码的学习心得如有错误或建议欢迎批评与指正。end

相关新闻

网盘直链下载助手终极指南:告别限速,八大网盘高速下载全解析

网盘直链下载助手终极指南:告别限速,八大网盘高速下载全解析

网盘直链下载助手终极指南:告别限速,八大网盘高速下载全解析 【免费下载链接】Online-disk-direct-link-download-assistant 一个基于 JavaScript 的网盘文件下载地址获取工具。基于【网盘直链下载助手】修改 ,支持 百度网盘 / 阿里云盘 / 中…

2026/8/11 3:18:20 阅读更多 →
Make MakeFile 快捷键工具

Make MakeFile 快捷键工具

make 和 Makefile 是软件开发中极其核心的构建自动化工具。简单来说,你告诉它“我想生成目标文件A”,它就会根据你写的规则(Makefile)自动推导出需要执行哪些命令(比如编译、链接)来生成A。 一个最经典的入…

2026/8/11 3:18:20 阅读更多 →
测试02测试02测试02测试02测试02测试02测试02

测试02测试02测试02测试02测试02测试02测试02

测试02测试02测试02测试02测试02测试02测试02

2026/8/11 3:18:20 阅读更多 →

最新新闻

UE5角色面部动画:Anim Curves驱动BlendShape全流程解析

UE5角色面部动画:Anim Curves驱动BlendShape全流程解析

1. 项目概述:从概念到实现的桥梁最近在做一个独立游戏的角色面部动画,目标是让角色能做出像《苏珊的微笑》那样细腻、富有感染力的表情。直接手K每一帧动画?那工作量简直不敢想。在UE5里,我发现了一套高效且强大的工作流&#xff…

2026/8/11 7:44:42 阅读更多 →
C++函数模板:从泛型编程基础到高级应用实战

C++函数模板:从泛型编程基础到高级应用实战

1. 从“硬编码”到“泛型思维”:为什么我们需要函数模板? 干了这么多年C,我见过太多新手和老手在同一个问题上反复“造轮子”:写一个比较两个整数大小的函数,再写一个比较两个浮点数大小的,然后又要处理字符…

2026/8/11 7:44:42 阅读更多 →
Electron应用接入Microsoft Store:实现订阅与永久许可证的完整指南

Electron应用接入Microsoft Store:实现订阅与永久许可证的完整指南

1. 项目概述:从独立分发到官方商店的跨越 如果你和我一样,用 Electron 开发过桌面应用,那你肯定经历过这个阶段:吭哧吭哧写完了代码,用 electron-builder 或 electron-forge 打包成 .exe 或 .msi ,…

2026/8/11 7:44:42 阅读更多 →
华为思科生成树协议(STP/RSTP/MSTP)跨厂商对接实战与排错指南

华为思科生成树协议(STP/RSTP/MSTP)跨厂商对接实战与排错指南

1. 项目背景与核心挑战最近在帮一个客户做网络架构的整合,他们之前一部分核心交换机用的是思科,后来扩容和边缘接入层采购了一批华为设备,结果在生成树协议(STP)的对接上出了点“小麻烦”。网络时不时出现环路告警&…

2026/8/11 7:44:42 阅读更多 →
电机定子电压方程与电磁转矩控制解析

电机定子电压方程与电磁转矩控制解析

1. 电机定子电压方程解析1.1 基本方程推导三相交流电机的定子电压方程是分析电机运行特性的基础。以同步旋转坐标系(dq坐标系)为例,定子电压方程可表示为:u_d R_s*i_d dψ_d/dt - ω_e*ψ_q u_q R_s*i_q dψ_q/dt ω_e*ψ_d其…

2026/8/11 7:44:42 阅读更多 →
企业AI项目算法选型7大避坑指南与实战经验

企业AI项目算法选型7大避坑指南与实战经验

1. 企业AI创新中的算法选型挑战最近三年,我作为AI应用架构师参与了17个企业级AI项目的落地实施。在这些项目中,算法选型环节总是最容易出现问题的关键节点。很多企业投入大量资源采购算力、组建团队,却在算法选型这个基础环节栽了跟头。算法选…

2026/8/11 7:43:42 阅读更多 →

日新闻

如何用Video2X实现专业级视频画质提升:AI视频增强完整指南

如何用Video2X实现专业级视频画质提升:AI视频增强完整指南

如何用Video2X实现专业级视频画质提升:AI视频增强完整指南 【免费下载链接】video2x A machine learning-based video super resolution and frame interpolation framework. Est. Hack the Valley II, 2018. 项目地址: https://gitcode.com/GitHub_Trending/vi/v…

2026/8/11 0:00:02 阅读更多 →
前后端分离项目中控制台与接口工具数据差异排查指南

前后端分离项目中控制台与接口工具数据差异排查指南

1. 问题现象解析:控制台与Apifox的数据差异 最近在调试一个前后端分离项目时,遇到了一个典型问题:后端服务在本地开发环境控制台能正常输出查询数据,但通过Apifox测试时却返回空结果。这种"控制台有数据,接口工具…

2026/8/11 0:00:03 阅读更多 →
AI编程实战:从Claude Code踩坑到游戏开发入门

AI编程实战:从Claude Code踩坑到游戏开发入门

1. 从“AI能帮我做游戏”到“AI让我重新学编程”最近身边不少朋友,尤其是一些非技术背景、但对游戏开发有浓厚兴趣的朋友,都在问我同一个问题:“听说现在用Claude Code这种AI编程工具,小白也能做游戏了,是真的吗&#…

2026/8/11 0:00:03 阅读更多 →

周新闻

5分钟告别提取码焦虑:baidupankey如何智能破解百度网盘资源锁

5分钟告别提取码焦虑:baidupankey如何智能破解百度网盘资源锁

5分钟告别提取码焦虑:baidupankey如何智能破解百度网盘资源锁 【免费下载链接】baidupankey 在线查询网盘提取码(维护中 rm repo) 项目地址: https://gitcode.com/gh_mirrors/ba/baidupankey 你是否曾经在深夜寻找一份重要资料&#x…

2026/8/11 1:08:05 阅读更多 →
如何快速生成中国车牌图片:Python开源工具完整指南

如何快速生成中国车牌图片:Python开源工具完整指南

如何快速生成中国车牌图片:Python开源工具完整指南 【免费下载链接】chinese_license_plate_generator 中国车牌生成器 项目地址: https://gitcode.com/gh_mirrors/ch/chinese_license_plate_generator 中国车牌生成器是一个基于Python的开源项目&#xff0c…

2026/8/11 1:08:05 阅读更多 →
收藏!小白程序员轻松入门大模型,从Harness工程开始实践

收藏!小白程序员轻松入门大模型,从Harness工程开始实践

文章强调学习大模型不应只关注模型本身,而应重视模型外的系统搭建,即Harness。提出AgentModelHarness的实用公式,详细介绍Harness的四个层次:持久化层、执行层、控制层和观察与验证层。文章还探讨了上下文工程、工具设计、AGENTS.…

2026/8/11 1:08:05 阅读更多 →

月新闻

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南 【免费下载链接】BaiduNetdiskPlugin-macOS For macOS.百度网盘 破解SVIP、下载速度限制~ 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduNetdiskPlugin-macOS 还在为百度网盘macOS版的龟速下…

2026/8/10 17:07:33 阅读更多 →
终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 还在为网易云音乐下载的NCM格式文件无法在其他播放器播放而烦恼吗?ncmdump解密工具帮你轻松解决这个困…

2026/8/11 1:08:06 阅读更多 →
HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

AgentCard 智能体卡片:为英语学习 App 打造桌面级学习助手适用平台:HarmonyOS 7.0 (API 26 Beta)一、引言 HarmonyOS 7.0(API 26 Beta)新增了 AgentCard 智能体卡片能力,这是继 HMAF(鸿蒙智能体框架&#x…

2026/8/10 17:07:33 阅读更多 →