为什么 Copilot CLI 的指令行为与编辑器不同
首先来看这个列表。GitHub 关于 CLI 自定义指令的页面命名了八种位置。在用户级别,"$HOME/.copilot/copilot-instructions.md" 保存 "适用于跨仓库的用户级指令",而 $HOME/.copilot/instructions/**/*.instructions.md 保存 "模块化用户级指令"。在仓库中,有用于 "仓库级指令" 的 .github/copilot-instructions.md、模块化的 .github/instructions/**/*.instructions.md 文件,以及三个智能体指令文件:AGENTS.md、CLAUDE.md 和 GEMINI.md。对于 CLAUDE.md,表格补充道:"Copilot CLI 也会使用 .claude/CLAUDE.md。"
然后是它查找的位置。"除非下表另有说明,否则 Copilot CLI 会在标准位置中发现仓库和智能体指令文件:仓库根目录、当前工作目录、它们之间的中间目录,以及它正在处理的文件路径中嵌套的任何目录。" 有一个例外值得记住:模块化仓库指令是 "在标准位置中发现,但不在中间目录中发现。"
接着是它如何组合它们。这是最重要的一句话:"当存在多个适用的用户级和仓库指令文件时,Copilot CLI 会组合它们的指令。它会删除完全相同的用户级 copilot-instructions.md、仓库级和智能体指令的重复副本,但没有定义这些文件之间的通用优先级顺序。避免冲突的指令。"
这与许多人对 Copilot 指令的看法不同。编辑器和 github.com 文档描述了个人、特定路径、仓库级、智能体和组织指令之间的排名,详见哪个 Copilot 指令文件胜出,以及在何处。而 CLI 页面描述的是带有去重功能的组合,并明确指示要避免冲突。如果你的 AGENTS.md 说了这一套,而你的 CLAUDE.md 说了另一套,CLI 文档不会告诉你它会遵循哪一个——它会告诉你不要让自己陷入那种境地。
人们尝试的其他方法
将个人 AGENTS.md 放在主目录中。 CLI 文档中记录的用户级位置是 copilot-instructions.md 以及 $HOME/.copilot 内部的模块化指令文件夹。放在它们旁边的 AGENTS.md 不在文档记录的列表中。添加额外 AGENTS.md 文件的文档记录途径有所不同,将在步骤 2 中介绍。
在会话进行中编辑指令文件并期望更改立即生效。 GitHub 的页面指出:"你对自定义指令文件所做的更改不会立即在活动的 CLI 会话中可用。" 你需要退出并恢复会话,或者启动一个新会话。这是编辑过的 AGENTS.md 似乎被忽略的最常见原因。
从你的主目录引用共享文件。 CLI 支持在 .github/copilot-instructions.md、AGENTS.md 和 CLAUDE.md 中使用 @ 引用,但是 "绝对路径和以 ~/ 开头的路径不会被加载。" 指向 ~/notes/conventions.md 的一行代码不会起任何作用。
在 GEMINI.md 或模块化文件中使用 @ 引用。 "文件引用在 GEMINI.md 或 *.instructions.md 文件中不会被展开。" 引用将保持为字面文本。
在每个包中都放入模块化指令文件夹。 在单体大仓库(monorepo)中,为每个层级提供其专属的 .github/instructions 文件夹是很自然的想法。然而,如果你在某个包内启动会话,仓库根目录与该包之间的文件夹就成了中间目录。GitHub 的表格指出,模块化仓库指令是在标准位置中发现的 "但不在中间目录中发现",这比 AGENTS.md 的规则更窄。这些中间文件夹中的模块化文件夹会被跳过,而同一文件夹中的 AGENTS.md 则会被读取。
手动保持三个智能体文件同步并寄希望于此。 许多仓库都带有 AGENTS.md、CLAUDE.md 和 GEMINI.md,因为不同的工具读取不同的文件。CLI 会读取所有这三个文件。完全相同的副本会被删除;略有不同的副本则会全部包含在内。这种偏差问题与调和冲突的 CLAUDE.md 层中描述的问题相同。
解决方法:查看 CLI 加载了什么,为每个事实安排一个归宿,然后将个人文件放在 CLI 查找的位置
目标是建立一个指令集,其中每个事实只出现一次,每个文件都在文档记录的位置,并且你可以确认会话实际加载了什么。
步骤 1:询问 CLI 它为此会话发现了什么
GitHub 为此专门记录了一个命令:"使用 /instructions 命令查看为当前会话发现的指令文件,并启用或禁用单个文件。"
在你通常工作的目录中运行它并记下列表。然后从子目录中再次运行它。因为发现范围涵盖了仓库根目录、工作目录以及它们之间的目录,所以在目录树深处启动的会话可以获取到根目录下会话获取不到的文件。特定路径的文件增加了另一个变量:它们 "仅在它们的 applyTo 值与 Copilot CLI 正在处理的文件匹配时才被包含。"
将该列表与你的预期进行对比。通常会出现三样东西:一个没人记得的 CLAUDE.md 或 .claude/CLAUDE.md,一个嵌套在子文件夹中的 AGENTS.md,以及一个之前被某人禁用的文件。GitHub 明确指出,禁用的文件不会被包含:"你使用 /instructions 禁用的指令文件不会被包含。"
如果你在会话期间编辑了这些文件中的任何一个,请记住该列表反映的是会话开始时的状态。在得出结论之前,请退出并恢复,或者启动一个新会话。
步骤 2:为每个事实安排一个归宿,然后正确放置个人文件
现在决定每个文件的用途。对于与多个智能体一起使用的仓库,一个可行的划分如下:
AGENTS.md 保存共享的、与工具无关的事实:构建和测试命令、约定、约束。它是每个智能体都会读取的文件,包括 Copilot CLI。
.github/copilot-instructions.md 保存任何特定于 Copilot 的内容(如果有的话)。
CLAUDE.md 和 GEMINI.md 要么仅保存特定于这些工具的内容,要么指向 AGENTS.md。请记住,@ 引用在 CLAUDE.md 中会被展开,但在 "GEMINI.md 中不会被展开",因此指针模式适用于前者而不适用于后者。Claude Code 如何处理同一对文件在 Claude Code 的 AGENTS.md 默认设置中有所介绍。
从除其归宿之外的所有地方删除重复的事实。CLI 会删除完全相同的副本,但几乎相同的副本才是导致矛盾的原因。
对于个人指令,请使用文档记录的用户级文件:$HOME/.copilot/copilot-instructions.md,或 $HOME/.copilot/instructions/ 下的模块化文件。如果你保留了一个希望每个仓库都能看到的个人 AGENTS.md,GitHub 记录了一个用于附加目录的变量:"在 COPILOT_CUSTOM_INSTRUCTIONS_DIRS 中列出的目录" 提供 "附加的 AGENTS.md 和 *.instructions.md 文件。用逗号分隔多个目录。" 将你的个人 AGENTS.md 放在它自己的目录中,并列出该目录。
如果你使用非默认的 Copilot 主目录,请注意:"如果你设置了 COPILOT_HOME 环境变量,Copilot CLI 将使用该目录而不是 $HOME/.copilot 来存放这两个用户级指令位置。"
步骤 3:启动新会话并确认结果
退出,启动一个全新的会话,然后再次运行 instructions 命令。现在列表应该符合你的计划:一个共享的智能体文件、来自文档记录位置的个人指令,并且没有你不期望的内容。
然后测试行为。向 CLI 提一个问题,其答案取决于现在仅存在于一个文件中的事实。如果答案正确,说明配置成功。如果不对,请检查是否涉及具有狭窄 applyTo 模式的特定路径文件,因为这些文件仅在匹配的文件处于处理状态时才适用。
同样值得在你实际工作最多的子目录中重复整个检查。在包文件夹中嵌套了 AGENTS.md 的单体大仓库中,在该包内部启动的会话与在根目录下启动的会话会获得不同的指令集,根据发现规则,这两者都是正确的。了解你处于哪一个会话中可以解释大多数 "它昨天还遵守规则" 的报告。
每当有人添加新智能体的指令文件时,请重复此检查。仓库会悄悄地累积这些文件,而 CLI 会在不被要求的情况下读取每一个新文件。
在 MemoryLake 中进行设置
步骤 2 中的整理会产生一个简短的事实列表,无论哪个智能体读取它们,这些事实对项目都是成立的。MemoryLake 是一个保存该列表的地方,这样它就不再依赖于某个给定工具今年碰巧读取哪个文件名。
You write the entries yourself, in your own words. Nothing is read out of, written to, or deleted from your .copilot folder, your repository's instruction files, or any vendor's store.
步骤 1:创建 API 密钥
登录并从控制面板生成一个密钥。该密钥允许智能体读取你编写的条目,无论该智能体是读取 AGENTS.md、CLAUDE.md 还是两者都不读取。

步骤 2:上传你的第一批记忆
添加步骤 2 中的共享事实,每个条目一个,并说明每个约束存在的原因。原因可以让下一个人决定某个规则是否仍然适用。

步骤 3:连接你的 AI 和智能体
将你的智能体指向该工作区。然后,相同的事实就可以在 CLI、编辑器以及不读取任何这些指令文件的工具中使用了。

这在实践中改变了什么
第一个区别是 "不读取 AGENTS.md" 变得可以诊断了。大多数情况证明是以下三种情况之一:文件在会话中途被编辑、它位于文档记录的位置之外,或者它被禁用了。instructions 命令会显示是哪一种情况。
第二个区别是冲突不再是无声的。因为 CLI 文档 "没有定义通用的优先级顺序",所以两个文件之间的矛盾无法通过你可以查阅的规则来解决。将每个事实保留在一个地方可以消除这个问题。
第三个区别是个人指令和团队指令干净地分离开来。个人偏好存放在你的主目录或列出的目录中;团队事实存放在仓库中。这也是在 VS Code 中设置 Copilot 记忆背后的划分方式,其中仓库范围的记忆和个人指令承担着不同的工作。
第四个区别是上下文保持精简。CLI 发现的每个文件都会组合到它工作所依据的内容中。更少、更清晰的文件意味着更少的重复,这也是Copilot 如何按请求组装上下文背后的相同考量。
Copilot CLI 指令文件的最佳实践
在调试行为之前运行 instructions 命令。 它会显示为当前会话发现的文件,这是唯一重要的列表。
编辑后重新启动。 指令更改会在你恢复会话或启动新会话时生效。
为每个事实保留一个归宿。 完全相同的副本会被删除;几乎相同的副本会全部包含在内,并可能相互矛盾。
使用文档记录的用户级位置。 $HOME/.copilot/copilot-instructions.md、模块化指令文件夹,或者在 COPILOT_CUSTOM_INSTRUCTIONS_DIRS 中列出的用于个人 AGENTS.md 文件的目录。
避免主目录引用。 以 ~/ 开头的路径不会被加载,并且引用在 GEMINI.md 或模块化文件中不会被展开。
将新的智能体文件视为对 Copilot 上下文的更改。 为另一个工具添加的 CLAUDE.md 也会被 CLI 读取。如果你正在工具之间移动指令,将 CLAUDE.md 迁移到 Copilot 涵盖了这种映射,而 为什么 Copilot 会遗忘代码库上下文 涵盖了指令文件无法容纳的内容。
结论
Copilot CLI 的指令处理非常宽容。It reads its own files, other agents' files, your personal files and any directories you list, from the repository root down to the file it is editing. GitHub 对所有这些都进行了清晰的记录。
它同样清晰记录的是,CLI 是组合而不是排序:它 "没有定义这些文件之间的通用优先级顺序",并要求你避免冲突。这把保持一致性的责任交给了你组织文件的方式。
检查会话发现了什么,为每个事实安排一个归宿,将个人文件放在 CLI 查找的位置,并在编辑后重新启动。将共享的事实保存在不受文件名约定限制的地方,这样向仓库添加下一个智能体就不需要去理清上一个智能体的头绪了。