跳转到内容

内存导入处理器

内存导入处理器是一项功能,它允许您通过使用 @file.md 语法从其他文件导入内容,来模块化您的 GEMINI.md 文件。

此功能使您能够将大型的 GEMINI.md 文件分解为更小、更易于管理的组件,这些组件可以在不同的上下文中重复使用。导入处理器支持相对路径和绝对路径,并内置了防止循环导入和确保文件访问安全的安全特性。

使用 @ 符号,后面跟着您想要导入的文件的路径:

# Main GEMINI.md file
This is the main content.
@./components/instructions.md
More content here.
@./shared/configuration.md
  • @./file.md - 从同一目录导入
  • @../file.md - 从父目录导入
  • @./components/file.md - 从子目录导入
  • @/absolute/path/to/file.md - 使用绝对路径导入
# My GEMINI.md
Welcome to my project!
@./get-started.md
## Features
@./features/overview.md

导入的文件本身可以包含导入,从而创建嵌套结构:

main.md
@./header.md @./content.md @./footer.md
header.md
# Project Header
@./shared/title.md

处理器会自动检测并防止循环导入:

file-a.md
@./file-b.md
# file-b.md
@./file-a.md <!-- This will be detected and prevented -->

validateImportPath 函数确保只允许从指定目录导入,防止访问允许范围之外的安全敏感文件。

为了防止无限递归,有一个可配置的最大导入深度(默认:5级)。

如果引用的文件不存在,导入将优雅地失败,并在输出中带有错误注释。

权限问题或其他文件系统错误会被优雅地处理,并伴有适当的错误信息。

【翻译】 导入处理器使用 marked 库来检测代码块和内联代码跨度,确保这些区域内 @ 的导入被正确忽略。这提供了对嵌套代码块和复杂 Markdown 结构的健壮处理。

处理器返回一个导入树,显示了导入文件的层次结构,类似于 Claude 的 /memory 功能。这有助于通过显示哪些文件被读取以及它们的导入关系来帮助用户调试他们的 GEMINI.md 文件问题。

示例树结构:

Memory Files
L project: 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) 方法的比较

Section titled “与 Claude Code 的 /memory (claude.md) 方法的比较”

Claude Code 的 /memory 功能(如在 claude.md 中所见)通过连接所有包含的文件产生一个扁平的线性文档,始终用清晰的注释和路径名标记文件边界。它没有明确地呈现导入层次结构,但 LLM 接收所有文件内容和路径,这对于在需要时重构层次结构是足够的。

[!NOTE] 导入树主要用于开发期间的清晰度,对 LLM 消费的相关性有限。

processImports(content, basePath, debugMode?, importState?)

Section titled “processImports(content, basePath, debugMode?, importState?)”

处理 GEMINI.md 内容中的导入语句。

参数:

  • content (string):要处理导入的内容
  • basePath (string):当前文件所在的目录路径
  • debugMode (boolean, 可选):是否启用调试日志记录(默认:false)
  • importState (ImportState, 可选):循环导入预防的状态跟踪

返回值: Promise<ProcessImportsResult> - 包含处理后的内容和导入树的 Object

interface ProcessImportsResult {
content: string; // The processed content with imports resolved
importTree: MemoryFile; // Tree structure showing the import hierarchy
}
interface MemoryFile {
path: string; // The file path
imports?: MemoryFile[]; // Direct imports, in the order they were imported
}

validateImportPath(importPath, basePath, allowedDirectories)

Section titled “validateImportPath(importPath, basePath, allowedDirectories)”

验证导入路径,确保它们是安全的且位于允许的目录内。

参数:

  • importPath (字符串):要验证的导入路径
  • baseDir (字符串):解析相对路径的基础目录
  • allowedDirs (字符串[]): 允许的目录路径数组

返回值: 布尔值 - 导入路径是否有效

从给定的起始目录向上搜索 .git 目录以找到项目根目录。作为一个 异步 函数实现,使用非阻塞文件系统 API,以避免阻塞 Node.js 事件循环。

参数:

  • startDir (字符串):开始搜索的目录

返回值: Promise<string> - 项目根目录(如果找不到 .git,则为起始目录)

  1. 使用描述性文件名 导入组件
  2. 保持导入路径浅显 - 避免深层嵌套的导入链
  3. 记录你的结构 - 维护清晰的导入文件层次结构
  4. 测试你的导入 - 确保所有引用的文件存在且可访问
  5. 尽可能使用相对路径 以提高可移植性
  1. 导入不工作:检查文件是否存在且路径是否正确
  2. 循环导入警告:检查导入结构是否存在循环引用
  3. 权限错误:确保文件可读且位于允许的目录内
  4. 路径解析问题:如果相对路径解析不正确,请使用绝对路径

启用调试模式以查看导入过程的详细日志记录:

const result = await processImports(content, basePath, true);