第三章. Gemini Cil Memport:模块化的上下文管理

第三章. Gemini Cil Memport:模块化的上下文管理

本章将深入讲解 Gemini CLI 的 Memport 机制,这是一个让项目上下文管理变得模块化、可维护的核心功能。学完本章,你将能够构建清晰的上下文架构,让 AI 更准确地理解你的项目规范。

3.1. 为什么需要 Memport

如果你用过 Claude Code,应该对 CLAUDE.md 这个文件不陌生。这是 Claude Code 用来存储项目上下文的地方,你可以在里面写项目规范、编码风格、常用命令等信息,Claude 会在每次对话时读取这些内容。

但问题来了:当项目变大、团队成员增多时,CLAUDE.md 很容易膨胀到几千行。我见过最夸张的一个项目,CLAUDE.md 有 5000 多行,包含了 API 文档、数据库表结构、前端组件规范、部署流程等等。维护起来非常痛苦,而且它是单文件结构,无法模块化,多人协作时经常出现版本冲突。

Gemini CLI 用Memory Import Processor上下文导入处理器,允许模块化组织项目上下文解决了这个问题。Memport 允许你用 @./file.md 语法在 GEMINI.md 中导入其他文件,就像 ES6 模块那样组织上下文。

一个真实的痛点场景

假设你在开发一个电商系统,项目上下文包含:

  • 团队编码规范(200 行)
  • API 接口定义(800 行)
  • 数据库表结构(500 行)
  • 前端组件库规范(300 行)
  • 部署流程(150 行)

如果全部塞进一个 GEMINI.md,这个文件会有 1950 行。当你只想修改 API 接口定义时,需要在这 1950 行中找到对应的位置,非常低效。而且如果两个人同时修改不同的部分,Git 合并时会很麻烦。

用 Memport,你可以这样组织:

1
2
3
4
5
6
7
8
.gemini\
├── GEMINI.md (主入口,只有50行)
└── context\
├── team-conventions.md (200行)
├── api-schema.md (800行)
├── database-schema.md (500行)
├── component-library.md (300行)
└── deployment.md (150行)

GEMINI.md 只需要 5 行:

1
2
3
4
5
6
7
# 电商系统项目上下文

@.\context\team-conventions.md
@.\context\api-schema.md
@.\context\database-schema.md
@.\context\component-library.md
@.\context\deployment.md

这样,每个文件职责清晰,修改时不会互相干扰。


3.2. Memport 的基础语法

Memport 的语法非常简单,就是在 Markdown 文件中使用 @ 符号引用其他文件。

基础导入

.gemini\GEMINI.md 中写入:

1
@.\context\api-schema.md

Gemini CLI 启动时,会自动读取 context\api-schema.md 的内容,并将其注入到上下文中。

相对路径规则

Memport 支持多种路径格式:

路径格式含义示例
@.\file.md当前目录@.\api.md
@..\file.md父目录@..\shared\utils.md
@.\sub\file.md子目录@.\context\api.md
@\absolute\path\file.md绝对路径@D:\docs\api.md

Windows 路径中的反斜杠 \ 在 Markdown 中不需要转义。直接写 @.\context\api.md 即可。

嵌套导入

被导入的文件本身也可以包含导入语句,形成嵌套结构。

比如 team-conventions.md 中可以写:

1
2
3
4
5
# 团队编码规范

@.\code-style.md
@.\naming-rules.md
@.\git-workflow.md

然后在主 GEMINI.md 中只需要:

1
@.\context\team-conventions.md

Gemini CLI 会递归解析所有导入,最终形成一个完整的上下文树。


3.3. 安全机制:防止循环引用

Memport 内置了三层安全机制,防止你把自己绕晕。

机制 1:循环引用检测

假设你不小心写了这样的配置:

file-a.md

1
@.\file-b.md

file-b.md

1
@.\file-a.md

这就形成了循环引用。Gemini CLI 会在解析阶段检测到这个问题,并报错:

1
2
Error: Circular import detected
file-a.md -> file-b.md -> file-a.md

CLI 会立即中断启动,不会陷入死循环。

机制 2:最大导入深度

Memport 限制了最大导入深度,默认是 5 层。这意味着你不能无限嵌套导入。

比如这样的结构是允许的:

1
2
3
4
5
6
GEMINI.md
-> level1.md
-> level2.md
-> level3.md
-> level4.md
-> level5.md

但如果 level5.md 再导入 level6.md,就会报错:

1
Error: Maximum import depth (5) exceeded

为什么要限制深度?因为过于复杂的嵌套结构会让 AI 迷失。AI 需要理解上下文的层次关系,如果嵌套太深,AI 可能会混淆不同层级的信息。

机制 3:路径验证

Memport 会验证导入的文件路径是否合法。有两个检查点:

  1. 文件是否存在:如果引用的文件不存在,会报错并显示完整路径。
  2. 路径是否越权:Memport 会确保导入的文件在项目根目录及以下,防止越权读取系统文件。

比如你写了:

1
@..\..\..\..\Windows\System32\config\sam

Gemini CLI 会拒绝这个导入,并报错:

1
Error: Import path outside project root is not allowed

这是一个安全保护机制,防止恶意或错误的配置泄露敏感信息。


3.4. 三层上下文加载机制

Gemini CLI 启动时会按顺序加载三层上下文,每一层都有不同的作用域和优先级。

第一层:全局上下文

位置:C:\Users\你的用户名\.gemini\GEMINI.md

这是用户级的全局配置,适用于所有项目。你可以在这里写一些通用的偏好设置。

比如我的全局 GEMINI.md 是这样的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
## 代码质量标准
### 代码质量
- 遵循项目现有的模式
- 保持导入风格和命名约定一致
- 每个函数/类只负责一项职责
- DRY(不要重复自己)
- YAGNI(你不会需要它)
### 测试
- 测试所有公开函数
- 测试边界情况和错误条件
- 模拟外部依赖项
- 目标覆盖率 80% 以上
### 错误处理
- 使用恰当的 try-catch 块
- 提供清晰的错误消息
- 平稳降级
- 不要泄露敏感信息
## 核心原则
**渐进式进展**
- 小而可测试的改动
- 频繁提交可运行的代码
- 在之前工作的基础上推进(子任务)
**基于证据的**
- 在实施前研究 3 个以上类似模式
- 与项目风格完全匹配
- 用现有代码进行验证
**实用主义**
- 选择乏味的解决方案而非巧妙的代码
- 简单胜过复杂
- 适应项目实际情况
**上下文连续性**(多任务):
- 利用简历保持一致性
- 维持既定模式
- 测试子任务之间的集成
## 执行清单
- [ ] 清晰理解目的和任务
- [ ] 审阅背景文件,找出 3 个以上模式
- [ ] 检查规则模板和约束条件
**在进行中**
- [ ] 完全遵循现有模式
- [ ] 与编写代码同步编写测试
- [ ] 每次更改后运行测试
- [ ] 逐步提交可运行的代码
**完成之后**
- [ ] 所有测试通过
- [ ] 覆盖率达到目标
- [ ] 构建成功
- [ ] 所有预期交付成果均已达成

这些规则会应用到我所有的项目中。

第二层:项目上下文

位置:项目根目录\.gemini\GEMINI.md

这是项目级的配置,只适用于当前项目。你可以在这里写项目特定的规范。

比如一个 React 项目的 GEMINI.md

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 电商前端项目

## 技术栈
- React 18 + TypeScript
- Zustand (状态管理)
- TailwindCSS (样式)
- React Query (数据获取)

## 项目结构
- src\components\ - 可复用组件
- src\pages\ - 页面组件
- src\stores\ - Zustand状态
- src\api\ - API封装
- src\types\ - TypeScript类型定义

## 编码规范
- 使用函数组件 + Hooks
- 状态管理优先使用Zustand
- 样式使用TailwindCSS,避免写CSS文件
- API调用必须使用React Query

@.\context\api-schema.md
@.\context\component-library.md

第三层:本地上下文

位置:当前工作目录\GEMINI.md

这是最细粒度的上下文,只适用于当前子目录。适合用于特定模块的说明。

比如在 src\payment\ 目录下创建 GEMINI.md

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 支付模块

这个目录包含所有支付相关的代码。

## 重要提示
- 这个模块涉及敏感数据处理
- 所有金额计算必须使用Decimal类型,禁止使用Number
- 支付接口调用必须有重试机制
- 所有支付日志必须脱敏

## 文件说明
- PaymentService.ts - 支付服务主逻辑
- PaymentTypes.ts - 支付相关类型定义
- PaymentUtils.ts - 支付工具函数

上下文合并规则

这三层上下文会按顺序合并,后加载的内容会覆盖先加载的内容。

假设全局上下文说:“使用 any 类型是允许的”,但项目上下文说:“禁止使用 any 类型”,那么最终 AI 会遵循项目上下文的规则。

合并顺序:

1
2
3
4
5
全局上下文 (优先级最低)
↓ 覆盖
项目上下文 (优先级中等)
↓ 覆盖
本地上下文 (优先级最高)

这种设计让你可以在全局设置通用规则,在项目中设置项目特定规则,在子模块中设置模块特定规则,灵活且不冲突。


3.5. 本节小结

我们在本节学习了 Memport 的模块化上下文管理机制。核心要点:

Memport 的三大优势

  1. 模块化:将大文件拆分成多个小文件,职责清晰
  2. 可维护:修改某个模块不影响其他模块
  3. 可复用:通用规范可以在多个项目间共享

三层上下文加载

层级位置作用域优先级
全局~\.gemini\GEMINI.md所有项目
项目项目根\.gemini\GEMINI.md当前项目
本地当前目录\GEMINI.md当前目录

安全机制

  • 循环引用检测
  • 最大深度限制(5 层)
  • 路径越权保护

速查代码

1
2
3
4
5
6
7
8
9
10
11
12
# 主 GEMINI.md
@.\context\api-schema.md
@.\context\coding-standards.md

# 查看加载的上下文
> /memory show

# 重新加载上下文
> /memory refresh

# 临时添加记忆
> /memory add 这次对话中,优先使用函数式编程

下一节,我们将学习 MCP 集成,了解如何通过 Model Context Protocol 扩展 Gemini CLI 的能力边界。