AGENTS.md 项目规则 · 逐目录的指令,深者优先
怎么把「这个项目的约定」喂给模型?grok 沿目录树收集 AGENTS.md(兼容 CLAUDE.md、.cursor/rules),拼成一条 system-reminder。这一章看它的发现顺序、深者优先、尊重 gitignore、目录信任门槛,以及为什么它不进 system prompt。
AGENTS.md 项目规则 · 逐目录的指令,深者优先
Part 4 从最轻量的扩展讲起:项目规则文件。你想让模型「记住这个项目的约定」(用什么框架、别碰哪些目录),就写进 AGENTS.md。grok 的处理在 prompt/agents_md.rs。
发现:一路从 home 收到 cwd
read_agents_config_with_paths 按顺序收集:
~/.grok/(全局,实为$GROK_HOME,连同其下的rules/)最先;~/.claude/、~/.cursor/(兼容,受 compat 开关控制:每家分agents(具名文件)和rules(规则目录)两个开关,默认全开);- cwd → git 根的目录链,但收集后反转成「根 → cwd」——让更深的文件优先级更高(子目录的规则覆盖父目录)。这条链统一由
repo.rs的RepoDirChain生成;若 git 根恰好是$HOME(dotfiles 仓库),它会被丢掉,按「不在仓库里、只看 cwd」处理。
认的文件名很宽:AGENTS.md、AGENT.md、CLAUDE.md、CLAUDE.local.md 等(同一目录命中几个就读几个);还扫规则目录 .grok/rules/、.claude/rules/、.cursor/rules/ 下的 *.md(不递归,按文件名排序)。—— 又是「兼容既有生态」:你的 CLAUDE.md、Cursor 规则,grok 直接读。
会话中途读、列、改到这条链以外的目录时,AgentsMdTracker 还会沿路找那里的指令文件,但只把路径提醒给模型,读不读由它决定。
一个和 Skills 的对比:AGENTS.md 发现尊重 .gitignore(被忽略的不收;只看仓库根的 .gitignore 和全局 excludes,仓库外的文件永远算未忽略),而 skills 目录不过滤 gitignore。两个看似相似的「沿目录树发现」子系统,在这一点上刻意不同——读源码时这种细微差异最容易被忽略,却常常是有意为之。
目录信任:先问「信不信这个仓库」
发现之前还有一道闸:read_agents_config_with_paths 带一个 project_trusted 参数,目录未受信任时(既没加 --trust,也没在交互中授权),整条项目链一个文件都不读,只加载 home 层。folder_trust.rs 的模块注释把理由写得很直白:AGENTS.md / CLAUDE.md、.grok/skills 和 .mcp.json 一样,都是攻击者能随仓库一起分发的文件,里面的命令、自动批准规则或 agent 指令若被自动采纳,就是「一键 RCE / 绕过策略」。
渲染:一条 system-reminder
收集到的文件不是直接拼进 system prompt,而是 render_agents_md 拼成一个 <system-reminder> 块:开头一句前缀,然后每个文件一段 ## From: {路径},注明「从仓库根到当前目录排序,深者优先」。规则目录里的 *.md 会剥掉 YAML frontmatter(AGENTS.md 这类具名文件原样保留);路径和正文里出现的 <system-reminder 标签还会被 neutralize_reminder_tags 转义成 <,防止不可信的 AGENTS.md 提前闭合或伪造外层框架。
还记得 system prompt 那章的设计吗?——AGENTS.md 故意不进 system prompt,而是作为一条独立的合成用户消息(打标 ProjectInstructions,注释写明「一旦放下就不再替换」,否则会打破 KV 缓存前缀)注入。原因是 system prompt 要字节稳定才能命中 KV 缓存,而项目规则每个项目不同、还可能变。把「稳定的身份」和「多变的项目规则」分两路走,是这套设计的精髓。
一个例外是内置的 Plan agent:它不注入这条 reminder,而是把同一批文件渲染进首条用户消息的 <rules> 段(仓库内的文件记为 always_applied_workspace_rule,home 下的记为 user_rule,前面再插一条浏览器验证规则)。格式换了,但仍走用户消息、不碰 system prompt。
和《从 LLM 到 Coding Agent》对照
对照 context-injection,以及你熟悉的 Claude Code 的 CLAUDE.md:最小实现里,项目指令可能就是往 system prompt 里塞一段。grok 的增量是:沿目录树分层发现、深者优先、尊重 gitignore、兼容多家格式、未受信目录一律不读,还为了缓存把它从 system prompt 里拆出来。下一章看更强的扩展:Skills。
上一篇:并行 worktree · 下一篇:Skills