内存导入处理器
内存导入处理器是一项功能,允许您通过使用 @file.md 语法导入其他文件中的内容来模块化您的 GEMINI.md 文件。
概述
此功能使您能够将大型 GEMINI.md 文件分解为更小、更易于管理、可在不同上下文重用的组件。导入处理器支持相对路径和绝对路径,并内置了安全功能,以防止循环导入并确保文件访问安全。
语法
使用 @ 符号后跟要导入文件的路径:
# 主 GEMINI.md 文件
这是主要内容。
@./components/instructions.md
更多内容。
@./shared/configuration.md支持的路径格式
相对路径
@./file.md- 从同一目录导入@../file.md- 从父目录导入@./components/file.md- 从子目录导入
绝对路径
@/absolute/path/to/file.md- 使用绝对路径导入
示例
基本导入
# My GEMINI.md
欢迎来到我的项目!
@./get-started.md
## 特性
@./features/overview.md嵌套导入
导入的文件本身也可以包含导入,从而创建嵌套结构:
# main.md
@./header.md
@./content.md
@./footer.md# header.md
# 项目标题
@./shared/title.md安全功能
循环导入检测
处理器会自动检测并防止循环导入:
# file-a.md
@./file-b.md
# file-b.md
@./file-a.md <!-- 这将被检测并阻止 -->文件访问安全
validateImportPath 函数确保只允许从指定目录导入,防止访问允许范围之外的敏感文件。
最大导入深度
为防止无限递归,有一个可配置的最大导入深度(默认为:5 级)。
错误处理
文件丢失
如果引用的文件不存在,导入将优雅地失败,并在输出中显示错误注释。
文件访问错误
权限问题或其他文件系统错误将得到妥善处理,并显示相应的错误消息。
代码区域检测
导入处理器使用 marked 库来检测代码块和内联代码跨度,确保这些区域内的 @ 导入被正确忽略。这提供了对嵌套代码块和复杂 Markdown 结构的稳健处理。
导入树结构
处理器返回一个导入树,显示导入文件的层次结构,类似于 Claude 的 /memory 功能。这有助于用户通过显示哪些文件被读取以及它们的导入关系来调试 GEMINI.md 文件中的问题。
示例树结构:
内存文件
L 项目:GEMINI.md
L a.md
L b.md
L c.md
L d.md
L e.md
L f.md
L included.md该树保留了文件导入的顺序,并显示完整的导入链以供调试。
与 Claude Code 的 /memory (claude.md) 方法的比较
Claude Code 的 /memory 功能(如 claude.md 中所示)通过连接所有包含的文件来生成一个扁平的、线性的文档,始终用清晰的注释和文件名标记文件边界。它不明确显示导入层次结构,但 LLM 会收到所有文件内容和文件名,这足以在需要时重建层次结构。
注意:导入树主要用于开发过程中的清晰性,与 LLM 的消费关系有限。
API 参考
processImports(content, basePath, debugMode?, importState?)
处理 GEMINI.md 内容中的导入语句。
参数:
content(string):要处理导入的内容basePath(string):当前文件所在目录的路径debugMode(boolean, 可选):是否启用调试日志记录(默认为 false)importState(ImportState, 可选):用于循环导入预防的状态跟踪
返回: Promise<ProcessImportsResult> - 包含已处理内容和导入树的对象
ProcessImportsResult
interface ProcessImportsResult {
content: string; // 已处理的、已解析导入的内容
importTree: MemoryFile; // 显示导入层次结构的树结构
}MemoryFile
interface MemoryFile {
path: string; // 文件路径
imports?: MemoryFile[]; // 直接导入,按导入顺序排列
}validateImportPath(importPath, basePath, allowedDirectories)
验证导入路径,以确保它们是安全的并且在允许的目录内。
参数:
importPath(string):要验证的导入路径basePath(string):用于解析相对路径的基本目录allowedDirectories(string[]):允许的目录路径数组
返回: boolean - 导入路径是否有效
findProjectRoot(startDir)
通过从给定的起始目录向上搜索 .git 目录来查找项目根目录。实现为一个 异步 函数,使用非阻塞文件系统 API 来避免阻塞 Node.js 事件循环。
参数:
startDir(string):开始搜索的目录
返回: Promise<string> - 项目根目录(如果未找到 .git,则为起始目录)
最佳实践
- 为导入的组件使用描述性的文件名
- 保持导入层级浅 - 避免深度嵌套的导入链
- 记录您的结构 - 维护导入文件的清晰层次结构
- 测试您的导入 - 确保所有引用的文件都存在且可访问
- 尽可能使用相对路径 以提高可移植性
故障排除
常见问题
- 导入不起作用:检查文件是否存在且路径是否正确
- 循环导入警告:检查您的导入结构是否存在循环引用
- 权限错误:确保文件可读且位于允许的目录内
- 路径解析问题:如果相对路径未正确解析,请使用绝对路径
调试模式
启用调试模式以查看导入过程的详细日志记录:
const result = await processImports(content, basePath, true);