Pi 怎样决定模型看见什么:AGENTS.md、SYSTEM.md 与 Skills 的加载边界
你在仓库根目录告诉 Agent:"修改后运行单测。"进入 services/payment/ 后,它又遵循 "禁止运行全量测试";调用数据库迁移 Skill 时,第三份说明要求先连接生产库做探测。 三条规则都真实存在,问题却不是"Prompt 写得够不够好",而是:本轮到底加载了哪些 资源、以什么顺序加载、它们是否可信,以及冲突发生时谁负责停止执行。
Pi v0.82.1 的 ResourceLoader 很适合拆开这条链。它把 System Prompt、Context Files、 Skills、Prompt Templates、Extensions 与 Session 分成不同对象,但不会自动替你解决 所有冲突。本文只有一条主线:Agent Context 应被管理为版本化资源集合,而不是一个 不断增长、无法追溯的字符串。

一、先区分"模型看见"和"Harness 执行"
一次模型调用前至少存在五层输入:
text
基础层:默认 System Prompt 或 SYSTEM.md
增量层:APPEND_SYSTEM.md
常驻项目层:全局与目录级 AGENTS.md / CLAUDE.md
按需能力层:Skill Index,以及任务匹配后读取的 SKILL.md
运行层:Tool Schema、Session Messages、Tool Results、Extension 动态修改
它们不能只按"都是 Markdown"归为一类。AGENTS 是每轮常驻的项目规则;Skill 通常先 暴露名称、描述与路径,正文在需要时才读取;Extension 则是进程直接执行的代码。前两者 主要形成 Prompt 风险,后者还具有任意代码执行与供应链风险。
因此,审计 Context 不能只导出最终字符串。至少要回答:来源路径是什么、当前 SHA 是 多少、作用域是什么、是否被加载、是否具有执行权限、加载发生在什么时候。

二、AGENTS 的发现顺序比文件内容更容易被忽略
固定 Tag 的 resource-loader.ts 在每个目录依次检查 AGENTS.md、AGENTS.MD、CLAUDE.md、CLAUDE.MD,命中第一个 普通文件后停止该目录的候选搜索。随后它先加入 agentDir 中的全局 Context,再从 cwd 一路向文件系统根查找目录文件,并用 unshift() 把祖先结果整理成"根目录到当前目录" 的顺序。
这带来三个非显然边界:
- 同一目录同时存在 AGENTS 与 CLAUDE 时,不是全部拼接,而是候选顺序靠前者获胜;
- 深层服务会同时继承多个祖先目录规则,隐藏冲突可能来自仓库外的上层目录;
- 源码遍历到文件系统根,并不等于文档中所有资源都以 Git Root 为边界。
所以"我只检查了当前目录的 AGENTS"不能证明本轮 Context 完整。生产 Harness 应在启动 日志中列出实际加载文件,而不是让操作者根据目录结构猜测。

三、SYSTEM 是替换基础层,APPEND_SYSTEM 是增量层
ResourceLoader 分别暴露 getSystemPrompt() 与 getAppendSystemPrompt()。固定源码在 reload 时先解析显式传入值,否则发现 SYSTEM 文件;Append 路径独立解析。SDK 还允许 用 systemPromptOverride、appendSystemPromptOverride 和 agentsFilesOverride 注入 虚拟资源。
这说明 SYSTEM 不是"更高优先级的 AGENTS"。它改变的是基础 Prompt 来源;AGENTS 仍是 另一类 Context Input。APPEND_SYSTEM 则适合保留默认工具说明,只增加语言、安全或交付 规则。若把整套默认 Prompt 复制进 APPEND,升级后就会同时背负重复规则与旧工具描述。
更重要的是,文件名不能替代调用链证据。自研 SDK 若传入自定义 ResourceLoader,标准 cwd/agentDir 发现规则就不再自动成立;SDK 文档明确说明,此时资源发现由调用方负责。

四、Skill 的节省来自渐进披露,不是"免费能力"
Skill 目录通常包含 SKILL.md、scripts、references 与 assets。启动时真正适合常驻的是 路由信息:名称、描述和文件位置;任务匹配后,再读取完整工作流和必要参考资料。这样能 把几十个低频流程从固定上下文移到按需上下文。
但渐进披露有两个代价。
第一,Description 变成路由接口。只写"Helps with PDFs"无法告诉模型何时必须加载、 支持哪些动作、有什么边界。一个可用描述至少包含"能力、触发条件、关键限制"。
第二,发现不等于执行。Skill 被扫描、出现在 Index、完整文件被读取、脚本被调用、结果 被验证,是五个不同事件。静态来源只能证明前面的机制存在;本文没有运行真实 Pi,也不 把"文档中支持 Skill"写成模型会稳定触发的实测结论。

五、Project Trust 不是 Context 防火墙
固定版本 reload 流程会先处理 Project Trust 与可执行 Extension 集合,再解析最终资源。 但 AGENTS 加载路径本身没有按 projectTrusted 过滤 Context Files。即使项目 Extension 没有被允许执行,仓库内规则仍可能进入模型 Context。
这不是说 AGENTS 等同恶意代码,而是说明两个门槛解决不同问题:
text
Project Trust:控制项目级可执行资源与设置是否进入 Runtime
Context 审计:控制不可信文字是否能诱导模型调用高风险 Tool
因此还需要 Tool allowlist、最小权限、网络与凭据隔离、外部写入审批。把 Trust 弹窗当作 完整 Sandbox,会把 Prompt Injection 与执行权限混成一个问题。

六、Context 污染不只表现为 Token 太多
污染至少有三种:
- Token Pollution:低频百科内容每轮常驻,挤压任务与代码证据;
- Instruction Conflict:全局、祖先、项目、Skill 和 Extension 提供相反动作;
- Stale Context:命令、目录或架构曾经正确,但当前版本已改变。
最危险的是第三种。模型看到一条语气确定的旧命令,通常不会主动怀疑它已经失效。 AGENTS 应保留高频、高风险和无法从代码自动发现的规则;发布手册、事故流程与云平台细节 更适合放进按需 Skill 或普通文档。可由脚本检查的目录、命令和版本,不应靠模型记忆。
七、给 Context 建一张预算表
可以按加载成本与风险把资源分成四档:
| 层级 | 典型内容 | 加载策略 | 必须记录 |
|---|---|---|---|
| L0 基础 | System、Tool 核心边界 | 每轮常驻 | 版本、SHA、工具集合 |
| L1 项目 | AGENTS、架构禁区、验证命令 | 按目录常驻 | 来源路径、作用域、校验日期 |
| L2 按需 | Skill 正文、专业参考资料 | 任务触发后加载 | 触发原因、读取文件、版本 |
| L3 可执行 | Extension、Skill Script、外部写入 | 审批后执行 | 权限、输入、输出、退出码、证据 |
这张表的目标不是追求最少 Token,而是把高频规则留在前面,把低频知识按需加载,把 可执行资源放到审批和证据之后。短任务可以只使用 L0/L1;数据库迁移、发布或外部写入 才需要进入 L2/L3。

八、真正可复现的是 Resource Snapshot Ledger
同一个 Session 稍后恢复时,磁盘上的 AGENTS、Skill 和 Extension 可能已经改变。只保存 对话 JSONL,不能重建当时的资源环境。一个最小 Ledger 可以是:
yaml
run_id: RUN-20260811-001
cwd: /workspace/service
resources:
- kind: context_file
path: /workspace/AGENTS.md
sha256: "..."
scope: ancestor
trusted_as: prompt_input
- kind: skill
path: /workspace/.agents/skills/db/SKILL.md
sha256: "..."
loaded: true
trigger: "database migration"
- kind: extension
path: /workspace/.pi/extensions/audit.ts
sha256: "..."
execution_authorized: false
结束任务时再记录哪些资源真正参与了模型请求和工具执行。发生冲突时,系统应输出来源, 让人决定,而不是让模型在沉默中"综合"。高风险动作还应把批准绑定到 Resource Snapshot 与当前 Artifact SHA;任一项变化都让批准失效。

九、落地时先做四个测试
不必先建设全能 Context Platform。一个垂直 Harness 可以从四项回归开始:
- Discovery Test:给定 cwd,加载文件集合和顺序是否固定;
- Collision Test:父子规则、同名 Skill、重复 Prompt 是否产生可见诊断;
- Disclosure Test:无关任务不加载 Skill 正文,相关任务能记录加载证据;
- Permission Test:文字资源不能绕过 Tool、网络和外部写入审批。
再加一条成本指标:分别统计常驻资源、按需资源和 Tool Schema 的输入占用,不用总 Token 掩盖某个常驻文件的膨胀。只有当加载集合、执行权限与结果证据都能重放,Context Engineering 才从"提示词管理"变成可维护的 Harness 能力。

十、边界与更简单的替代方案
小型仓库、短任务和只读问答不需要完整 Ledger。一个短 AGENTS、固定 Tool Set 和明确的 人工确认已经足够。复杂治理的成本包括资源哈希、冲突诊断、缓存失效和审计存储。
但只要任务跨目录、跨 Session、会执行脚本或会写外部系统,最小快照就开始有价值。Pi 给出的关键启发不是某个特定文件名,而是把"基础 Prompt、常驻规则、按需能力和可执行 扩展"拆成不同资源。真正决定质量的不是 Context 越多越好,而是:当前任务只加载必要 资源;每条资源有来源和版本;每次执行有权限和证据。