Gemini CLI 记忆机制解析:Agent 如何通过 GEMINI.md 与分层 Markdown 记忆文件持久化知识
Gemini CLI 将持久化事实、用户偏好和项目细节的存储方式设计得极为"朴素":不依赖数据库或专属存储 API,而是让 Agent 直接用文件编辑工具写入分层组织的 Markdown 记忆文件。本篇围绕 Memory 工具文档 展开,结合仓库源码说明记忆的路由规则、加载机制、冲突优先级与 /memory 命令体系,读完你可以掌握如何让 Agent 跨会话记住偏好、项目架构决策与常用配置。
一、记忆的本质:直接编辑 Markdown 文件
Gemini CLI 的 Memory 能力(见 docs/tools/memory.md)核心设计如下:
-
存储(Storage):Agent 使用
write_file或replace(edit)工具直接编辑 Markdown 文件,不存在独立的save_memory工具。这一点在系统提示词的源码中得到直接印证——packages/core/src/prompts/snippets.ts 中注入给模型的指令明确写道:You persist long-lived project context by editing markdown files directly with edit or write_file. There is no save_memory tool.同时它还提示模型:所有已加载的
GEMINI.md内容和私有项目MEMORY.md索引"已经在你的上下文里",编辑前无需重复读取。 -
加载(Loading):存储的事实会自动进入分层上下文系统(hierarchical context system),在后续所有会话中随系统提示词一起注入。
-
格式(Format):持久化指令应保持简洁,并且避免把同一事实在多个记忆层级间重复——每条事实只允许"住在"一个层级的一个文件里。
二、记忆路由:四类记忆文件与"一条事实只落一层"规则
文档指出,Agent 会把记忆路由到恰当的 Markdown 文件:共享的项目指令写入仓库中的 GEMINI.md,私有项目笔记写入项目专属的私有记忆目录,跨项目的个人偏好写入全局 ~/.gemini/GEMINI.md。源码中这条路由规则写得更为完整,共有四个层级(见 snippets.ts 的 toolUsageRememberingFacts):
| 记忆层级 | 文件位置 | 用途 | 是否提交到仓库 |
|---|---|---|---|
| 项目指令 | ./GEMINI.md |
团队共享的架构、约定、工作流等仓库级指引 | 是(committed and shared) |
| 子目录指令 | 如 ./src/GEMINI.md |
作用域限定在项目某一部分的指令 | 是 |
| 私有项目记忆 | ~/.gemini/tmp/<project-hash>/memory/(MEMORY.md 索引 + 同目录 *.md 笔记) |
仅属于当前用户的本机配置、机器特定说明、私有工作流 | 否(明确标注 "private, not committed to repo") |
| 全局个人记忆 | ~/.gemini/GEMINI.md |
跨项目个人偏好(所有项目通用的测试框架偏好、语言偏好、代码风格默认值) | 不适用 |
源码给出的路由判定规则(routing rules)是记忆正确落位的关键:
- 用户表述团队共享约定、架构规则或仓库级工作流("our project uses X"、"the team always Y")→ 更新相应的
GEMINI.md,不要同时写进私有记忆目录或全局个人记忆文件; - 用户表述本机专属配置、机器相关说明或私有工作流("on my machine"、"do not commit this")→ 保存到私有项目记忆目录,不要写进
GEMINI.md或全局记忆; - 用户表述跨项目个人偏好("I always prefer X"、"in general I like Z")→ 更新全局个人记忆文件
~/.gemini/GEMINI.md,同样不要写入GEMINI.md; - 一条事实若可能属于多个层级,先询问用户再写入;
- 绝不在层级之间复制或镜像同一事实,也不要在各层级文件之间添加交叉引用。
这个"单归属"设计有其工程动机:记忆文件会注入每个会话的系统提示词,跨层重复既浪费上下文 token,又会在规则更新时产生不一致。
私有记忆目录的索引结构
在私有记忆目录内部还有一层索引约定:MEMORY.md 是同目录笔记文件的索引——简短事实直接写进 MEMORY.md;内容较多的笔记(多段落、流程、字段)则放在同目录的 *.md 文件中,MEMORY.md 里只放一行指针。这一点有源码路径常量佐证:packages/core/src/tools/memoryTool.ts 定义了 DEFAULT_CONTEXT_FILENAME = 'GEMINI.md' 与 PROJECT_MEMORY_INDEX_FILENAME = 'MEMORY.md',其中 getProjectMemoryIndexFilePath() 返回 <project memory dir>/MEMORY.md,getGlobalMemoryFilePath() 返回 ~/.gemini/GEMINI.md。而私有记忆目录本身由 packages/core/src/config/storage.ts 的 getProjectMemoryTempDir()(<project temp>/memory)提供,按项目标识隔离。
此外,提示词还明确禁止把瞬时会话状态存入这些文件:代码改动摘要、bug 修复记录、任务级发现都不该写入,因为这些文件会被加载进每个会话,必须保持"瘦"。
三、加载机制:分层记忆如何进入上下文
存储侧的"写文件"只是起点,加载侧的注入路径是 Memory 能力成立的关键。Gemini CLI 使用分层上下文系统(hierarchy system),加载顺序见 docs/cli/gemini-md.md:
- 全局上下文文件:
~/.gemini/GEMINI.md,为所有项目提供默认指令; - 环境/工作区上下文文件:CLI 在配置的工作区目录及其父目录中搜索
GEMINI.md; - 即时(JIT)上下文文件:当工具访问某文件/目录时,CLI 自动扫描该目录到可信根(trusted root)之间的
GEMINI.md,让模型只在需要时才发现特定组件的细粒度指令。
从源码结构看,加载结果被组织为 HierarchicalMemory 结构——packages/core/src/config/memory.ts 定义 global、extension、project、userProjectMemory 四个可选字符串字段。渲染进系统提示词时,renderUserMemory 会将其包装为带语义的 XML 标签:
<loaded_context>
<global_context>…</global_context>
<user_project_memory>…(标注 "Private Project Memory Index (private, not committed to repo)")…</user_project_memory>
<extension_context>…</extension_context>
<project_context>…</project_context>
</loaded_context>
冲突优先级由 mandateConflictResolution 注入提示词:当指令互相矛盾时,遵循 <project_context>(最高)> <extension_context> > <global_context>(最低)。同时提示词声明:上下文指令可覆盖系统提示词中的默认行为(技术栈、风格、工作流、工具偏好),但不能覆盖安全、安全完整性相关的核心强制条款(Core Mandates)。
对私有记忆目录中的兄弟笔记文件,加载是"按需"的:MEMORY.md 每次会话都注入,而同目录的其他 *.md 文件只有在 MEMORY.md 按名引用时才会被运行时 Agent 通过 read_file 读取——这也是 packages/core/src/commands/memory.ts 中 augmentWithAutoPointers 逻辑存在的意义:应用私有记忆补丁时,若新创建了未被 MEMORY.md 引用的兄弟笔记,系统会自动追加一行指针条目,保证新文件"可被发现"。
四、实战:教 Agent 记住事实
日常使用中,你无需手写配置文件,只需在对话里自然表达(场景示例源自 docs/cli/tutorials/memory-management.md):
Remember that I prefer using 'const' over 'let' wherever possible.
Agent 会据此编辑对应的记忆 Markdown 文件(按上面的路由规则选择层级),事实在未来会话中自动加载。
Save the fact that the staging server IP is 10.0.0.5.
之后再次提问时无需重复背景:
Write a script to deploy to staging.
→ Agent Response: "I'll write a script to deploy to 10.0.0.5..."
文档归纳的典型用例包括:持久化用户偏好(如"我偏好函数式编程")、保存项目级架构决策、存储常用别名或系统配置。
五、检查与管理:/memory 命令
指令文件增多后,你需要知道 Agent 到底在遵循什么。docs/reference/commands.md 中的 /memory 命令用于管理 AI 的指令上下文(来自 GEMINI.md 文件加载的分层记忆):
/memory show:打印当前加载的、拼接后的全部指令文本(来自所有GEMINI.md文件与已保存的记忆)。源码实现在 showMemory,它调用flattenMemory(config.getUserMemory())展平分层记忆并附上文件计数,输出的正是模型在会话开始时收到的原始文本——非常适合排查"为什么 Agent 忽略了某条规则";/memory reload:强制重新扫描并加载所有配置位置的GEMINI.md。对应 refreshMemory,它在刷新MemoryContextManager后会调用config.updateSystemInstructionIfInitialized(),即重新生成系统提示词——这意味着运行中编辑GEMINI.md后执行该命令即可立即生效。
六、最佳实践
- 保持聚焦:
GEMINI.md的内容要简洁、可执行、与代码生成直接相关; - 善用否定式约束:明确告诉 Agent"不要做什么"(如 "Do not use class components")通常比模糊的正面指令更有效;
- 定期审查:周期性检查各层
GEMINI.md,移除过时规则; - 一事一归属:每条持久化事实只写入一个层级,跨层重复会稀释上下文并制造规则冲突;
- 临时状态不落盘:会话摘要、修复记录等不应写入记忆文件,它们会被加载进每个会话;
- 模块化拆分:大型
GEMINI.md可用@file.md语法从其他文件导入(支持相对与绝对路径),详见 docs/reference/memport.md;上下文文件名本身也可通过settings.json的context.fileName配置为数组形式(如["AGENTS.md", "CONTEXT.md", "GEMINI.md"])。
七、小结
Gemini CLI 的记忆机制把"持久化"这一 Agent 领域的常见难题还原为最直接的形态:分层 Markdown 文件 + 文件编辑工具 + 严格的单归属路由规则。写入靠 write_file/replace,读取靠分层上下文自动注入,管理靠 /memory show|reload,而源码中 packages/core/src/tools/memoryTool.ts、packages/core/src/config/memory.ts、packages/core/src/commands/memory.ts 与 packages/core/src/prompts/snippets.ts 完整支撑了这套从"记住"到"每次会话都带着"的闭环。理解四层级路由与"绝不跨层复制"原则,是正确使用该机制的核心。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0624
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00