为什么规范文件不会自动加载
Aider 的规范文档清晰地描述了这一机制。您编写一个简单的 Markdown 文件,然后:
"最好使用/read CONVENTIONS.md或aider --read CONVENTIONS.md来加载规范文件。这样它会被标记为只读,并且如果启用了提示词缓存(prompt caching),它也会被缓存。"
这句话中包含了两个特性,而且都是刻意设计的。将文件标记为只读意味着智能体(agent)不会尝试去修改它——规范文件是输入,而不是工作产出。缓存它则意味着在支持提示词缓存时,您无需在每次对话交互中重复支付 Token 费用。
关键在于动词。是您去加载(load)它。Aider 文档中记载的规范机制是一个需要您显式读取的文件,而不是它会自动寻找的文件名。并不会因为存在 CONVENTIONS.md 文件就触发自动发现步骤。
这一点值得准确说明,因为很容易被误解——而且这与工具发现了您的文件却忽略它的情况不同。为什么智能体会忽略你的指令文件 介绍了那种情况;而当前这种情况更简单,因为根本就没有加载任何内容,谈不上忽略。
Aider 并非对您的代码库一无所知。它会在每次请求时自动构建并发送一个仓库地图(repository map):
"Aider 使用您整个 Git 仓库的简明地图,其中包含最重要的类和函数,以及它们的类型和调用签名。"
"Aider 会在用户提出每次修改请求时,将仓库地图与请求一起发送给大语言模型(LLM)。"
因此,模型在接收请求时已经对您的代码结构有了真实的了解。但它没有掌握的是您的规范——其原因在于结构设计,而非疏忽。仓库地图是基于代码生成的。它可以展示某个模块存在以及它的调用签名是什么。但它无法展示您在八个月前否决了某个备选库,因为被否决的库并不在仓库中,无法被映射。这种区别正是规范文件存在的全部意义所在。
官方文档中包含了一个对比示例,使这一效果更加具体:在读取了规范文件的情况下,生成的函数使用了首选的 HTTP 客户端并包含了类型提示。而在没有读取的情况下,相同的请求生成的代码使用了另一个库且没有类型提示——文档中将其描述为"在小型 Python 脚本中可能更常见。" 相同的模型,相同的提示词,不同的结果,完全是因为这一个文件。
人们尝试的其他替代方法
在每个会话开始时手动输入 /read CONVENTIONS.md。 这确实有效,也是正确的第一步。但这也是一种习惯,而习惯在您匆忙的日子里往往会失效——而这些日子恰恰是规范被违反并合并到代码库中的时候。
将规范直接粘贴到提示词中。 这只在单次交互中有效。它不是只读的,因此文件可能会被智能体修改;它没有被缓存,因此您需要重复为此付费;而且下周您粘贴的内容可能又不一样了。
使用 /add 而不是 /read 来添加规范文件。 这比看起来要糟糕得多。/add 会将文件作为可编辑文件放入聊天中。文档的建议明确指出了只读路径,并且还有一个值得牢记的相关提示:不要 /drop(丢弃)在启动时添加的只读文件。一个智能体可以编辑的规范文件,最终必然会被编辑。
将规范写在主源文件顶部的注释块中。 这样规则就存在于它所约束的代码内部,它只能随这一个文件移动,仓库地图会很乐意包含这段注释,而您的其他十二个模块却永远看不到它。
把所有内容都塞进规范文件中。 这是相反的失败案例,也是几个月后更常见的情况。一个规范文件如果膨胀到包含每个架构决策、每次事故复盘和每个被否决的方案,那么在每个会话中都会被完整加载。虽然它是只读且被缓存的,成本尚可承受——但您现在正在将大量固定的上下文消耗在仅适用于极少数请求的内容上。
解决方案:让文件自动加载,并保持精简
只需三个步骤。第一步是两行配置的修改;另外两步则能让您一劳永逸。
步骤 1:在项目的配置文件中添加 read
Aider 文档提供了一种使其自动化的方法:
"您还可以在 .aider.conf.yml 配置文件中配置 Aider 始终加载您的规范文件"该字段是 read,它可以接受单个文件名或文件名列表。单个规范文件对应一个条目;如果您除了规范文件之外,还有比如始终希望可用的 Schema 引用,则可以使用列表。
您将配置文件放在哪里非常重要,因为 Aider 会搜索三个位置:
"Aider 将在以下位置寻找此文件:您的用户主目录、Git 仓库的根目录、当前目录。如果上述文件存在,它们将按此顺序加载。最后加载的文件将具有最高优先级。"
将 read 条目放在 Git 仓库根目录 的配置中,而不是您的用户主目录中。原因有二。首先,这是唯一随项目移动的位置,因此团队成员和 CI 无需任何配置即可获得相同的行为。其次,在主目录配置中设置 read 条目会指向一个在您打开的每个仓库中可能并不存在的文件名——指向项目本地文件的全局设置是一个陷阱,随时会在您克隆下一个仓库时暴露出来。
因为最后加载的文件具有最高优先级,所以仓库根目录的配置也可以干净地覆盖您在全局设置的任何内容,这通常正是您所期望的。
步骤 2:决定文件中保留什么,并移出其余内容
既然该文件在每个会话中都会无条件加载,那么它的大小就成了一项永久性的成本。这改变了其中应该包含的内容。
保留那些对每次请求都适用且足够简短、可以作为规则陈述的内容:首选的库、类型提示要求、命名规范、测试命令。这些都是指令,而规范文件是存放指令的绝佳容器。
移出所有属于历史背景的内容。解释导致选择该库的事故段落很有价值——这是该规则在评审中得以保留的原因——但它不需要在每次对话的提示词中都出现。对数据模型的冗长解释、发布清单以及关于为什么三个模块结构奇特的说明也是如此。
测试标准很简单:如果一句话回答了 "我该怎么做",它就属于规范文件。如果它回答了 "为什么",它就应该放在智能体在被问及可以查找的地方。编程智能体实际上在阅读什么 是一个非常有用的交叉参考,因为这种划分适用于每个具有始终加载指令文件的工具。
Aider 自身对该文件的建议(来自文档指向的社区规范)也秉承了相同的精神——关于偏好的简短、具体的陈述。
步骤 3:为“为什么”提供一个智能体可以查询的归宿
这一步可以防止规范文件重新膨胀。一条没有记录原因的规则,是一条没人会删除也没人会捍卫的规则,因此文件只会变得越来越长。
推理过程需要是可检索的,而不是始终加载的,并且它需要能够跨越不同的工具。Aider 是一个具有独特机制的终端原生工具,许多团队将其与 IDE 助手配合使用。如果推理过程存在于只有 Aider 读取的 CONVENTIONS.md 中,那么您工具链的另一半就永远看不到它——明年当您使用其他工具时,您也看不到它。将项目文档转化为 AI 记忆 介绍了如何在不从头重写的情况下,将现有的书面材料转化为这种形式。
在 MemoryLake 中进行设置
MemoryLake 将您规范背后的推理过程保存在任何单一工具之外,并通过 MCP 或 API 提供给任何发起请求的智能体。您的 CONVENTIONS.md 仍保留在原处,Aider 继续按照其自身文档描述的方式加载它;共享层只保存那些否则会使该文件膨胀的内容。
步骤 1:创建 API 密钥
生成密钥并在大约 30 秒内发出您的第一次请求。在执行上述步骤 2 之前完成此操作,这样在您精简文件时,就有地方可以存放每个原因。

步骤 2:上传您的第一批记忆
逐行梳理规范文件。对于每条规则,写下它存在的原因——您否决的替代方案、背后的事故、迫使其制定的约束条件。这些段落将从规范文件中移出并放入此处。支持文档和文件也放在同一个地方。

步骤 3:连接您的 AI 和智能体
让 Claude、Codex、OpenClaw 以及您的其他智能体通过 MCP 或 API 进行访问。当有人询问为什么规范是这样时,返回的答案会附带其原因,而不仅仅是重复规则本身。

这在实践中带来了什么改变
第一个改变是周一早上的失败不再发生。在每个拥有该仓库的机器上,每个会话的第一条消息发送之前,规范文件就已经加载完毕,无需任何人刻意记住。
第二个改变是,只读和缓存成为了默认设置,而不是您必须正确输入的内容。这两个属性都来自文档中记载的 read 路径,一旦文件每次都加载,这两个属性就变得更加重要。
第三个改变是规范文件可以变得更小,而不是更大。每一条将其原理解释移入可查询存储的规则,都可以用一行字来陈述。一个简短的始终加载文件加上一个可查询的原因存储,绝对优于一个冗长的始终加载文件,而且它们包含的总信息量是相同的。
第四个改变体现在团队中有人不使用 Aider 的时候。规则保留在 Aider 读取它们的仓库中。而推理过程则保存在每个智能体都能访问的地方。两部分内容都不会被困在单一工具的格式中。
Aider 规范的最佳实践
使用 read,而不是 add。 只读是输入文件的正确姿态,也是文档所推荐的。这也意味着智能体不会悄悄重写您的规则。
将配置放在 Git 根目录下。 它随项目移动,并且比您的主目录配置具有更高的优先级,因为最后加载的文件获胜。
当您有多个始终开启的输入时,请使用列表。 read 字段接受列表,因此规范文件加上 Schema 引用可以各占一个条目,而不是合并成一个庞大的文件。
不要 /drop(丢弃)在启动时添加的只读文件。 Aider 的提示直接指出了这一点,在长时间的会话中清理聊天文件时,很容易不小心发生这种意外。
在文件中保留指令,将原因移出。 该文件在每次请求时都会加载。任何回答 "为什么" 的内容,在没人询问的交互中都会产生费用。
不要指望仓库地图来承载您的规范。 它是根据您的代码构建并在每次请求时发送的,这确实非常有用——但它只能反映仓库中包含的内容。被否决的库不会留下任何可供映射的痕迹。
将规范文件提交到 Git。 这很显而易见,但仍值得一说:一个只存在于一台笔记本电脑上的规范文件,只是披着团队外衣的个人偏好。
做好在您使用的每个其他工具中重复此操作的准备。 机制会有所不同——让智能体坚持你的编码风格 介绍了另一个工具实现相同工作的版本,而自主编程智能体的最佳记忆解决方案 则涵盖了所有这些工具底层的技术层。
结论
Aider 的规范机制是一个显式加载的只读文件,而不是通过约定自动发现的文件名,正是这单一的区别,导致在测试中有效的文件在日常使用中失效。解决方案已记录在文档中且非常简单:在 Git 仓库根目录的 .aider.conf.yml 中添加一个 read 条目,这使得每个拥有该仓库的人在每个会话中都能加载该文件,且该文件是只读并被缓存的。
需要权衡的部分是其中应该包含什么。因为该文件现在是无条件加载的,每一行都是永久性的成本——这恰好形成了一种合理的约束,促使您只保留现行的指令,并将推理过程移到智能体可以按需查询的地方。Aider 的仓库地图将继续告诉模型您的代码包含什么。而只有您才能告诉它,您的代码刻意不包含什么。