嵌套规则采用“根规则先出现、局部规则后出现”的分层模型。Codex 不在 Runtime 内解释每条自然语言规则谁覆盖谁,而是保留来源路径和稳定顺序,让更靠近 cwd 的说明在模型输入中位于后部,并在作用域变化时整体替换当前项目规则快照。
作用域是一条目录链
根目录 AGENTS.md 作用于整条项目路径;子目录文档只在 cwd 落入该子树时出现。工作目录从 frontend/ 切换到 backend/ 后,先前 frontend 文档不再适用,World State 必须发送替换说明。
每个加载项保留环境 ID、路径 URI 和正文。渲染时,Host User Instructions 与项目文档之间使用显式分隔符;多份项目文档也按发现顺序组成一份可识别上下文。
def assemble_agents_context(user_rules, docs):
parts = []
if user_rules:
parts.append(user_rules.text)
for doc in docs: # root -> cwd
parts.append(render_source(doc.environment_id, doc.path, doc.text))
return "\n\n--- project-doc ---\n\n".join(parts)
总预算按读取顺序消费
project_doc_max_bytes 是所有发现文档共享的总预算,不是每文件上限。读取根文档后扣除字节,继续读取下一层;最后一份超过剩余量时只保留前缀,预算归零后停止。这样内存与 Prompt 成本有硬上界,但越靠后的局部规则可能被截断。
async def read_with_total_budget(fs, paths, limit):
loaded, remaining = [], limit
for path in paths:
if remaining == 0:
break
data = await fs.read(path)
kept = data[:remaining]
loaded.append((path, kept))
remaining -= len(kept)
if len(kept) < len(data):
warn_truncated(path, len(data), len(kept))
return loaded
这是明确的实现权衡:根规则优先获得预算,保证全局安全约束不容易被局部大文件挤掉;代价是团队必须控制上层文档长度,给局部规则留下空间。
缓存和失效
AgentsMdManager 缓存与环境选择关联的加载结果。环境选择未变时可以复用;cwd 或环境组合变化后重新发现。缓存的是已解析加载结果,不改变 World State 的差异语义:新旧正文不同就渲染替换,无内容则渲染撤销。
源码与测试锚点
codex-rs/core/src/agents_md.rs:总预算、来源项和拼接顺序。codex-rs/core/src/agents_md_manager.rs:环境选择缓存。codex-rs/core/src/context/world_state/agents_md.rs:替换与撤销文本。codex-rs/core/src/agents_md_tests.rs:嵌套顺序和截断行为。
评论
登录后即可评论