为什么您的 kilo.jsonc 不是完整的列表
Kilo 当前的规则模型是显式的,且其自身运行良好。项目规则“通过项目 kilo.jsonc 文件中的 instructions 键进行配置”,其中“每个条目指向一个文件路径或 glob 模式”。全局规则在全局配置中使用相同的键,“通常位于 ~/.config/kilo/kilo.jsonc”。
加载顺序遵循数组:“规则按照它们在 kilo.jsonc 中的 instructions 数组中出现的顺序加载”,先是全局配置,然后是项目配置。优先级解析则相反——“对于冲突的指令,项目级指令优先于全局指令”。您甚至可以在不删除规则的情况下将其搁置,因为“JSONC 支持 // 注释”。
这是一个清单(manifest),清单是一个很好的设计。以下所有内容都是清单之外的东西。
Glob 条目放弃了顺序。 文档直接指出:“由 glob 模式匹配的文件按文件系统顺序加载。”由于数组位置是您唯一的优先级控制手段,像 .kilo/rules/*.md 这样的单个条目会将其匹配的所有内容从有序列表转换为无序列表。文档中的示例配置将一个特定文件与覆盖同一目录的 glob 配对,这看起来很方便,但却悄悄剥夺了您决定哪条规则胜出的能力。
遗留目录在未被列出的情况下也会加载。 这是最让人头疼、耗费数天时间的问题:
“如果您的项目中存在.kilocode/rules/目录,其内容将自动包含以实现向后兼容。要完全迁移,请移动您的规则文件并在kilo.jsonc中引用它们。”
请将此视为一个实际运行的行为,而不仅仅是一个说明。Kilo 将其目录从 .kilocode/ 重命名为了 .kilo/,但旧目录仍然会加载——自动加载,在您的数组中没有条目,在优先级表中也没有位置。经历过早期版本的仓库会有一个并行运行的第二规则树,而您正在阅读的 kilo.jsonc 却对此只字未提。
每个目录下的 AGENTS.md 文件在访问文件时被注入。 Kilo 支持子目录中的 AGENTS.md,并精确描述了该机制:“当 Agent 读取该目录中的文件时,每个目录下的 AGENTS.md 文件会被动态加载——它们不会在会话开始时预先加载。当 Agent 读取 src/backend/ 中的文件时,会发现相应的 AGENTS.md,并将其内容作为 <system-reminder> 标签注入到对话中。”
这是一个很好的功能。但这也意味着,您有效的指令集会在对话过程中根据 Agent 恰好打开了哪些文件而发生变化,而仅覆盖根文件的优先级表并没有说明这些注入的优先级排在何处。
根目录的 AGENTS.md 无法关闭。 “AGENTS.md 本身无法单独禁用——如果存在,它总是会被加载。要覆盖其指令,请使用更高优先级的来源,例如 instructions 配置键或特定于 Agent 的提示词。” AGENTS.md 和 AGENT.md 也是“Kilo Code 中的写保护文件”,因此“AI Agent 在没有用户明确批准的情况下无法修改这些文件”。这有利于安全,并且在您要求 Agent 整理它们之前,这一点非常值得了解。
文件名的大小写敏感方式常常让人感到意外。 Kilo 警告道:“文件名必须是大写(AGENTS.md),不能是小写(agents.md)。”按优先级顺序支持的名称依次为 AGENTS.md,然后是 AGENT.md。其他 Agent 在这方面有所不同——有些将这两种大小写视为等效——因此共享仓库应统一标准化为大写。
旧的 memory bank(记忆库)仍然有效。 Kilo 的弃用通知指出“Kilo Code 的 memory bank 功能已被弃用,取而代之的是 AGENTS.md”,并紧接着补充道:“现有的 memory bank 规则将继续有效。”需要注意的是状态指示器——“遗留的 Memory Bank 状态指示器(如 [Memory Bank: Active] 和 [Memory Bank: Missing])仍可能出现,但并不能保证在所有客户端或模式下都出现。”这个警告非常关键:该徽章仅限于支持它的客户端和模式,因此请将其视为提示而非最终答案,并通过实际行为进行验证。
这些加起来就是您数组之外的五个来源。这正是大多数“我的规则没有生效”报告的实际原因,而且这是一个配置问题,而不是模型问题——正如我们在为什么 Agent 会忽略您的指令文件中所区分的那样。
人们尝试的其他方法
阅读 kilo.jsonc 并信任它。 这是最常见的方法,但从结构上来说是错误的。该数组只是众多输入之一,而那两个静默的输入——遗留目录和每个目录下的注入——恰恰是配置文件无法向您展示的。
添加一个宽泛的 glob 来捕获所有内容。 ".kilo/rules/**/*.md" 保证了不会遗漏任何内容,但由于 glob 匹配按“文件系统顺序”加载,因此放弃了整个集合的顺序。您用一个不完整的列表换来了一个无序的列表。
立即删除 .kilocode/。 目标正确,但第一步这样做很冒险。这些文件可能已经生效了几个月,您所依赖的某些行为可能正是来自它们。将它们移出加载路径并进行审查,然后再做决定。
将所有内容放入 AGENTS.md。 它排名第三,无法禁用,且是其他工具读取的格式。但它不接受 frontmatter,也不支持条件加载,因此单个根文件会成为每个任务的常驻上下文(always-on context)。常驻预算问题与我们在编码 Agent 实际上在阅读什么中探讨的问题相同。
将规则转化为技能(skills)。 技能是按需加载的,这听起来像是免费的条件限制,而 Kilo 对选择机制的运作方式坦率得令人惊讶:“Agent(LLM)根据技能的 description 字段决定是否使用该技能。没有关键字匹配或语义搜索——Agent 会根据所有可用的技能描述评估您的请求,并确定是否有某个技能‘清晰且明确地适用’。”必须始终遵守的约定无法在相关性判断中幸存——这就是为什么技能不能替代规则,也不能替代记忆(memory),正如我们在为什么 Agent 的技能不是记忆中所论证的那样。
解决方案:构建一个有序列表,然后证明它是完整的列表
共三个步骤。第三步是人们常常跳过的一步,但它也是唯一能捕获静默来源的一步。
步骤 1:盘点 Kilo 可以加载的每个路径
在更改任何内容之前,遍历仓库并记录每个位置存在的内容。
从已声明的集合开始:项目 kilo.jsonc 中的 instructions 数组,以及 ~/.config/kilo/kilo.jsonc 中的相同键。手动将每个 glob 展开为其匹配的实际文件名(按文件系统顺序),以便您可以看到 Kilo 将使用的顺序。
然后是未声明的集合。检查项目中任何地方是否存在 .kilocode/rules/——通知中说的是“目录”(复数),所以也要检查子目录。检查 .kilo/rules/memory-bank/ 和遗留的 .kilocode/rules/memory-bank/。查找树中的每个 AGENTS.md 和 AGENT.md,而不仅仅是根目录下的,并记录每个文件管辖的目录。如果您使用 CLI,还要检查 .claude/ 和 .agents/,因为读取这些是“为了与其他工具兼容”;如果您想排除外部技能目录,可以使用 KILO_DISABLE_EXTERNAL_SKILLS 环境变量将其关闭。
您现在有了一个列表。它会比您的 kilo.jsonc 更长,而其中的差异正是您之前不知道正在运行的内容。
步骤 2:将列表合并为一个已声明的有序数组
为每个项目决定一个去处,然后使数组与实际情况相符。
必须始终适用的仓库级约定放入根目录的 AGENTS.md 中——它无法被禁用,其他工具也会读取它,并且它具有写保护,防止 Agent 意外编辑。保持简短;它是常驻的。
需要明确排序的规则作为单独的文件放入 .kilo/rules/ 中,每个文件在项目 instructions 数组中通过完整路径列出。按您期望的顺序每行顺序列出一个。不要在这里使用 glob——glob 恰恰会丢弃您的排序。
特定于目录的指南放入每个目录下的 AGENTS.md 文件中,这是 Kilo 文档中记录的唯一一种根据 Agent 工作位置加载内容的机制。
个人偏好放入全局 kilo.jsonc 数组中,请记住全局配置的优先级为 4,低于项目数组和根目录的 AGENTS.md。
然后清空遗留路径。将 .kilocode/rules/ 的内容移到加载路径之外的某个地方(例如 docs/ 子目录),然后仅通过数组中的显式路径重新添加您真正需要的内容。对于 memory bank 也是如此:Kilo 自身的迁移说明是“检查 .kilo/rules/memory-bank/(或遗留的 .kilocode/rules/memory-bank/)中的内容”,并“将该内容移入项目的 AGENTS.md 文件中”。移动仍然正确的部分;删除描述旧版本代码库的部分。
步骤 3:通过反证法而非阅读来证明列表
配置文件无法针对其未提及的文件进行自我验证。因此,直接测试边界。
在您设定的最低优先级来源的底部放一条故意显得不寻常且无害的指令——比如一个您在其他情况下绝不会使用的、显眼的变量命名约定。要求 Agent 编写一个简短的函数。如果该约定出现了,说明该来源正在加载,且其上方的任何内容都没有与其发生冲突。
然后反向测试。在您认为没有加载的来源中放入一条直接矛盾的指令——例如在清空遗留的 .kilocode/rules/ 路径之前放入。再次询问。如果矛盾的版本胜出,说明该路径是有效的,且其优先级高于您认为权威的路径。Kilo 不会显现指令源之间的冲突,因此反证测试是查看解析结果的唯一方法;通用模式在检测记忆冲突中有所介绍。
从拥有自己 AGENTS.md 的子目录中重复一次该测试,因为每个目录下的文件只有在 Agent 读取该目录下的文件时才会被注入。从仓库根目录运行测试将无法触发它们。
在 MemoryLake 中进行设置
合并能为您带来一个有序列表。但它不会告诉您为什么某一行会出现在其中——而一条没有记录原因的规则,在下一次清理时往往是第一个被丢弃的。
MemoryLake 保存了这些原因:哪条规则是因为哪次事件而存在的、尝试过并拒绝了什么,以及哪些约束来自人而不是代码。它位于 instructions 数组之外,因此重新排序、重命名和目录迁移都不会导致其丢失。从这里开始。
步骤 1:创建 API 密钥
为仓库创建一个工作区并生成一个 API 密钥。将其作用域限定在仓库,而不是 Kilo,这样下一次工具迁移就只是配置更改,而不是重写。

步骤 2:上传您的第一批记忆
在合并的步骤 1 期间执行此操作,此时您正在阅读那些您之前不知道正在加载的文件。对于在 .kilocode/rules/ 中找到的每条规则,在决定是否保留它之前,记录下编写它的原因——因为以后做这种判断要困难得多。添加仍然准确的 memory bank 内容,并记录您删除了哪些部分以及原因。

步骤 3:连接您的 AI 和 Agent
在您使用的各个界面上连接 Kilo Code;VS Code 插件和 CLI 共享优先级表,但在外部目录上有所不同,因此两者都应该读取相同的决策集。如果您仍在同一个仓库上运行 Cline,也请将其连接——两者共享规则文件的历史遗产,而共享层可以防止它们发生偏离。

这在实践中改变了什么
“我的规则没有生效”变成了一个 5 分钟的检查,而不是耗费一整个下午。因为您有了一份盘点清单,所以问题在于已知来源中哪一个胜出了,而不是是否存在某些未知文件。
排序变得真实有效。用显式路径替换 glob 意味着数组位置确实决定了优先级,因此冲突会有一个您可以指出的、可预测的答案。
遗留目录不再是第二个事实来源。一旦 .kilocode/rules/ 被清空,优先级表加上您的每个目录下的 AGENTS.md 映射就是完整的全貌。
并且原因在清理后得以保留。合并在设计上就是要删除文件的。删除规则没有问题;但如果删除了关于它为什么存在的唯一记录,那么六个月后就会再次发生同样的争论。
Kilo Code 规则文件的最佳实践
显式列出路径,而不是使用 glob。在 instructions 数组中每行一个文件虽然更冗长,但这是控制顺序的唯一方法。将 glob 保留给顺序确实无关紧要的目录。
注释掉而不是删除。JSONC 注释允许您搁置一条规则,并附上关于为什么要搁置它的说明,这比直接缺失一行能提供更多信息。
保持根目录的 AGENTS.md 简短。它无法被禁用且总是会被加载,因此每一行都是永久的上下文成本。将任何特定于区域的内容推送到每个目录下的文件中。
标准化为大写 AGENTS.md。Kilo 要求大写,且不同工具对大小写敏感性的处理不尽相同,因此对于共享仓库,大写是零成本的选择。
不要信任 memory bank 状态指示器。Kilo 表示它们“仍可能出现,但并不能保证在所有客户端或模式下都出现”。请改用反证法进行验证。
在任何依赖项或版本升级后,重新运行反证测试。向后兼容路径正是版本发布之间最容易发生变化的东西,而这里的静默变化看起来就像是模型变差了——这也是我们在Cline 遗忘项目上下文(关于 Kilo 所分叉的工具)中涵盖的许多误诊背后的原因。如果您仍计划进行该迁移,从 Cline 迁移 to Kilo Code 涵盖了文件映射;本指南则是关于您迁移到那里之后该怎么做。
结论
Kilo Code 的 instructions 数组是一个真正的清单,而清单是正确的思路。问题在于 Kilo 的三种加载行为位于其之外:遗留的 .kilocode/rules/ 目录会自动加载,每个目录下的 AGENTS.md 文件会在 Agent 读取其附近的文件时被注入,而 CLI 会读取来自其他工具的兼容性目录。
合并意味着显式命名每个路径,清空您未命名的路径,然后通过反证法进行测试——因为配置文件无法审计它从未提及的来源。这样做一次,优先级表就会成为您项目的准确描述,而不再是片面的描述。