MemoryLake
返回全部文章
Tutorial2026 年 8 月 24 日·11 分钟阅读

如何让 Cursor 记住你项目的文件结构 (2026)

针对这个问题的常见解决方法是将目录树粘贴到规则文件中。但 Cursor 和 Claude Code 都建议你不要这样做。

Cursor 在规则中应避免的事项清单中包括:“避免重复代码库中已有的内容:指向规范示例,而不是复制代码”,其最佳实践也指出:“引用文件而不是复制其内容——这可以保持规则简短,并防止它们随着代码更改而过时。”Claude Code 的 /doctor 检查则更进一步,主动建议修剪这些内容:它会“削减 Claude 可以从代码库中推导出的内容,例如目录布局、依赖项列表和架构概述,并保留与工具默认设置不同的陷阱、基本原理和约定。”

两个开发商独立地表达了同一个观点:目录树是可以推导出来的,所以不要把宝贵的常驻上下文浪费在它上面。这就留下了一个真正的问题——如果粘贴结构是错误的,为什么 Cursor 总是把文件放错地方?

官方文档中记录了三个原因,每个原因的解决方法都不同。本文将涵盖这三个原因,以及应该存储什么来代替目录树。这一症状背后的机制请参见为什么 Cursor 会忘记你的文件结构。如果你的问题不仅仅是结构问题——比如规则在不同会话之间根本无法加载——请先阅读跨会话携带 Cursor 上下文

为什么 Cursor 会搞丢文件位置

你的部分目录树被故意排除在索引之外

这是首先需要检查的一点,也是最让人感到意外的一点,因为没有任何提示。

Cursor 会遵守你的忽略文件。根据文档:“Cursor 会自动遵守你的 .gitignore 规则。被 git 忽略的文件也会被 Cursor 的索引忽略。”除此之外,.cursorignore 还增加了“超出 .gitignore 范围的其他排除项”,并且 Cursor “默认已经忽略了 .env 文件、.git/ 和锁文件”。

结果非常直接:“被忽略的文件无法被索引,也无法被 Agent 访问。”因此,如果你的自动生成 API 客户端、第三方 SDK 或构建输出目录被 git 忽略了(通常确实如此),Agent 根本无法看到这部分结构。它并不是忘记了这些文件在哪里,而是它从未看到过它们。

这里有一个微妙的细节,解释了真正令人困惑的行为。“终端命令和 MCP 工具在 Cursor 的文件访问控制之外运行,因此它们可能仍然能够读取被忽略的文件。”所以,同一个 Agent 在运行 ls 后可能知道某个目录存在,但随后却无法通过搜索在其中找到任何内容。这种不一致性看起来就像是“健忘”。

没有存储的地图——结构每次都是重新发现的

Cursor 关于 @ 提及的指南比看起来更有启发性。在“当你清楚哪些文件相关时”使用它们,并且:“如果你不确定哪些文件重要,请跳过它——Agent 会通过自己的搜索找到相关文件。”

这就是其设计。Agent 会根据每个请求定位它需要的内容,而不是在消息之间保留项目地图。除非有规则规定或你手动附加,否则布局信息不会在对话轮次之间持久存在。Cursor 直接解释了为什么需要持久化:“大语言模型在补全之间不保留记忆。规则在提示词级别提供了持久、可复用的上下文。”

因此,“记住我的文件结构”并不是你没找到的某种记忆设置。这是一个关于你持久化了什么内容以及如何持久化的问题。

你编写的关于结构的规则没有加载

如果你确实编写了放置规则但它被忽略了,这几乎总是以下四种情况之一,Cursor 的常见问题解答(FAQ)指出了前两种:“检查规则类型。对于 Apply Intelligently,确保定义了描述。对于 Apply to Specific Files,确保文件模式与引用的文件匹配。”

规则的前置元数据(frontmatter)表格值得牢记,因为没有设置任何字段的规则并不是损坏的规则——它是一个手动规则。设置 alwaysApply: true 时,它是“始终包含。忽略 Globs 和描述。”设置 alwaysApply: false 并带有 globs 时,它是“当匹配的文件在上下文中时自动附加。”有描述但没有 globs 时,“Agent 会读取描述并在相关时拉入规则。”两者都没有时,它是“仅当你在聊天中 @ 提及该规则时才包含。”

然后是扩展名陷阱:“.cursor/rules 中的普通 .md 文件会被规则系统忽略,因为它没有前置元数据来指定 descriptionglobsalwaysApply。如果你更喜欢纯 Markdown,请改用 AGENTS.md。”

最后是位置。规则会保存在你打开的文件夹的 .cursor/rules 中。如果你将 monorepo 的子目录作为项目打开,那么你的规则范围就仅限于该子目录。

粘贴的目录树不出一周就会出错

即使它成功加载,它也会失效。目录列表是你可以放入常驻文件中失效最快的东西,而过时的目录树比没有目录树更糟糕:它会主动引导 Agent 走向已经移动的路径。这正是 Cursor 所说的规则“随着代码更改而过时”的意思,也是为什么建议引用而不是复制的原因。

开发者们尝试过的方法

tree -L 3 的输出粘贴到常驻规则中。 它能加载,在最初几天很准确,然后就开始误导。规则内容“包含在模型上下文的开头”,因此你每条消息都在为此付费。

只写一句“项目是按功能组织的”就结束了。 话虽没错,但无法执行。它没有告诉 Agent 新文件应该放在哪里。

在每次聊天中手动重新附加文件夹。 有效,这就是如何停止向 AI 重复解释上下文中描述的循环。

取消忽略目录以便 Cursor 可以看到它们。 有时正确,但通常不推荐——文档列出了忽略这些内容的原因,包括“大型生成文件会减慢索引速度”以及“敏感信息和凭据排除在 AI 上下文之外更安全”。

将结构规则设置为 Apply Intelligently。 听起来很合理,但它把决定权交给了你花五秒钟写出的描述。描述模糊,规则就无法生效。

要求 Agent 在每个会话中重新扫描代码库。 昂贵且重复,同样的模式也出现在如何阻止 Claude Code 重新读取你的代码库中。

解决方案:存储放置规则,而不是目录树

改变一下思路,这个问题就会变得容易解决:你不需要 Cursor 记住文件在哪里。你希望它知道新文件应该放在哪里,以及为什么。前者是可以推导出来的,而且容易过时;后者是一种约定,能够长期有效。

Cursor 自己的文档在没有明说的情况下证明了这一点。它自动附加规则的示例(范围限定为 globs: src/components/**/*.tsx)包含诸如“将样式共同放置在组件旁边的模块 CSS 文件中”和“保持组件在 200 行以内。当文件超过该行数时,将子组件提取到同一目录中”等行。这些就是放置规则。示例中并没有目录树。

四个步骤。

在编写任何内容之前,先审计忽略文件。 对照 Agent 总是搞错的目录,检查 .gitignore.cursorignore。如果某个文件夹确实应该可见——例如已提交的 schema 目录、你提交的生成客户端——这是一个单行修复,任何规则都无法替代。

编写由 globs 限定范围的放置约定。 每个区域一个规则,通过模式进行附加,以便在你该区域工作时加载。使用文档中记录的 glob 形式:src/** 表示 src/ 下的所有内容,src/**/*.tsx 表示组件,需要两个模式时使用逗号分隔的模式,如 docs/**/*.md, docs/**/*.mdx。说明文件应该放在哪里以及应该如何命名,而不是当前存在什么。

使用嵌套的 AGENTS.md 进行结构化范围限定。 在任何子目录中放置一个,它就会“在处理该目录或其子目录中的文件时自动应用”,其指令“与父目录合并,更具体的指令优先”。没有前置元数据,无需维护 glob,而且文件就放在它所描述的代码旁边——因此在布局发生变化时,它更有可能得到更新。

针对特定需求显式附加文件夹。 当你清楚相关区域时,使用 @ 提及它:“@auth.ts@src/components/ 以包含文件或文件夹(选择文件夹后输入 / 可以导航到更深层)。”这是为了解决眼前的请求,而不是约定的替代方案。

这解决了加载和范围限定的问题。但这些方法都无法保留让布局合理化的核心部分——为什么边界划在这里,你尝试过并回退了哪些重构,哪个目录看起来像残留物但实际上不是。规则的推荐上限是 500 行,旨在指向而不是复制,因此结构背后的论据无处安放。

这正是 MemoryLake 所保存的:将你项目的持久知识保存在一个你的工具可以读取的层中,从而使规则保持简短,同时保留推理过程。设置只需三个步骤。

步骤 1:创建 API 密钥

登录 MemoryLake 并创建 API 密钥。一个凭据即可跨你连接的所有工具使用。

创建 MemoryLake API 密钥
创建 MemoryLake API 密钥

步骤 2:上传你的第一批记忆

简短的条目,每条记录一个主张。具体关于结构应该写些什么:

上传你的第一批记忆到 MemoryLake
上传你的第一批记忆到 MemoryLake

每种新东西应该放在哪里,以及原因。 “新的 API 处理器放在 src/api/handlers/ 中,每个路由一个文件,因为路由器会匹配该目录。”规则规定了位置;而原因则是阻止下个月出现看似合理但错误的替代方案的关键。

看起来随意但实际上并非如此的边界。 比如不能从另一个模块导入的模块,必须保持无框架的目录。目录树中没有任何内容能传达这种约束。

你已经拒绝的重构方案。 你尝试过的扁平结构,你刻意不设立的 utils/ 目录。每个新的 Agent 都会再次提出这些建议,而代码库中没有任何内容记录这一决策。

排除在索引之外的目录,以及其中的内容。 如果 generated/ 被 git 忽略了,写一行关于里面有什么以及它是如何生成的笔记,比取消忽略 40,000 个文件要有用得多。

步骤 3:连接你的 AI 和 Agent

连接你使用的工具。MemoryLake 可以通过 MCP 和 API 访问,因此支持 MCP 的原生 Agent(包括 Claude Code、Codex 和 OpenClaw)可以通过指向 MCP 服务器进行连接,而其他助手则通过 API 读取相同的记忆。你编写一次的放置约定,就是每个在代码库中工作的 Agent 所读取的相同约定。

通过 MCP 连接你的 AI 和 Agent
通过 MCP 连接你的 AI 和 Agent

三个坦诚的限制。MemoryLake 不会索引你的代码库,也不会编写你的 Cursor 规则——Cursor 自己的索引负责查找文件,而规则是你引导 Agent 的方式。它只保存你或你的 Agent 放入其中的内容,因此步骤 2 是手动的。而且这是上下文,而不是强制执行;如果某个放置规则确实必须遵守,Lint 规则或 CI 检查才是保证。

这在实践中带来了什么改变

“它把文件放错了地方”变成了两步检查。 目录被忽略了吗?规则的类型和模式正确吗?几乎总是其中之一。

你不再需要在每次添加文件夹时更新规则。 约定在重构中得以幸存,而目录列表则不能。

新贡献者会得到与 Agent 相同的答案。 编写好的放置约定既是入职文档,又恰好能引导模型。

索引排除项不再看起来像 Bug。 一旦你明白 .gitignore 会将文件移出 Agent 的访问范围,“它在 dist/ 中找不到任何内容”的报告就不再神秘了。

布局决策在工具之外依然存在。 无论阅读它的是 Cursor、Claude Code 还是 Codex,其推理过程都是相同的——这就是持久记忆的真正含义中所涵盖的形式。

Cursor 真正遵守的结构最佳实践

首先检查 .gitignore.cursorignore 被 git 忽略的文件会被 Cursor 的索引忽略,没有任何规则可以绕过这一点。

永远不要将目录树粘贴到常驻规则中。 它是可以推导出来的,不出一周就会过时,而且两个开发商都建议不要这样做。

使用 globs 限定结构规则的范围。 关于组件的规则应该在你打开组件时附加,而不是在每条消息上都附加。

对于每个目录的约定,优先使用嵌套的 AGENTS.md 更具体的指令优先,无需维护前置元数据,且文件就放在它所描述的内容旁边。

.cursor/rules 内部使用 .mdc,绝不要使用普通的 .md 放在那里的 .md 文件会被静默忽略。

编写命名约定,而不是文件列表。 “每个路由一个文件,以路由命名”比 handlers/ 的任何快照都更长寿。

针对眼前的任务,使用 @ 附加文件夹。 精准定位胜过寄希望于搜索能选中正确的区域。

将推理过程保留在规则之外。 边界存在的原因是让 Agent 能够处理你的约定未预料到的情况——这也是为什么 Agent 会忽略你编写的指令文件中的普遍问题。

结论

Cursor 不会在消息之间保留项目的地图,它也不应该这样做——Agent 每次都会通过自己的搜索找到相关文件,而规则是文档中记录的用于任何需要持久化的内容的机制。因此,当文件放错地方时,按顺序有三件事需要检查:目录是否被 .gitignore.cursorignore 排除,你的规则类型和 glob 模式是否真的导致它加载,以及规则是说明了文件应该放在哪里,还是仅仅描述了它们在哪里

最后一个是实质性的解决方案,也是 Cursor 和 Claude Code 的文档独立指向的方案:不要把常驻上下文浪费在工具可以推导出的内容上,也不要复制会过时的内容。编写放置约定,将其范围限定在它们管辖的目录中,并将布局背后的推理过程保存在每个工具都可以查询的地方。这样,新文件就会因为约定清晰易懂而被放在正确的地方,而不是因为你的目录树快照碰巧仍然准确。

常见问题

Cursor 会索引我的整个项目吗?

并非全部。Cursor 会自动遵守 .gitignore,因此被 git 忽略的文件会被排除在索引之外,而 .cursorignore 会添加进一步的排除项。Cursor 默认还会忽略 .env 文件、.git/ 和锁文件。被忽略的文件无法被索引,也无法被 Agent 访问,不过终端命令和 MCP 工具在这些控制之外运行,可能仍然可以读取它们。

我应该把我的目录结构放在 Cursor 规则中吗?

通常不建议。Cursor 的指南是引用文件而不是复制其内容,因为随着代码的更改,副本会过时,其应避免的事项清单中也包括重复代码库中已有的内容。相反,应该编写新文件放置位置的约定,并使用 globs 限定其范围。

为什么 Cursor 会把新文件放错目录?

三个常见原因:目标目录被忽略文件排除了,导致 Agent 看不到它;你的放置规则由于其类型、模式或扩展名而没有加载;或者你描述了现有的布局,而不是说明新文件应该放在哪里以及应该如何命名。

如何将规则的范围限定在一个目录中?

有两种方法。在 .mdc 规则的前置元数据中设置 globs 并将 alwaysApply 设为 false,当匹配的文件在上下文中时,它就会自动附加。或者在该子目录中放置一个 AGENTS.md——在处理该目录或其子目录中的文件时,它会自动应用,并与父目录的指令合并,更具体的指令优先。

我可以每次都手动附加文件夹吗?

可以,对于特定任务来说,这是正确的工具:输入 @ 并引用文件或文件夹,选择文件夹后使用 / 可以导航到更深层。但它不会持久存在。Cursor 自己的框架是大语言模型在补全之间不保留记忆,因此任何应该在下个会话中应用的内容都需要是规则或 AGENTS.md

我应该取消忽略目录以便 Cursor 可以看到它们吗?

只有当内容作为上下文确实有用时才这样做。文档中记录的忽略原因包括:大型生成文件会减慢索引速度、敏感信息排除在外更安全、二进制资产会增加噪音,以及第三方代码很少有用。对于确实重要的被排除目录,写一小段关于其中内容以及它是如何生成的笔记,通常比直接索引它更好。