Pi Agent 101|08|Context Files and Skills
Pi 把 AGENTS.md、skills、prompt templates 和 active tools 共同编译进动态 system prompt。
先说人话:System prompt 不是写死在墙上的一句口号,而是每次开工前临时整理出来的“工作说明”。
当前项目有什么规矩、能用哪些工具、有哪些 skills、用户装了哪些扩展,这些都会影响模型该怎么工作。Pi 把它们编译成这一轮 session 的提示。
Agent 的 system prompt 不应该是一段固定字符串。真正运行时,它取决于当前工作目录、项目规则、用户安装的 skills、prompt templates、active tools、extension 贡献的工具说明,以及用户配置。Pi 把这些资源统一装载,再生成当前 session 的 system prompt。

这张图的重点是:system prompt 不是一段固定文本,而是由运行环境动态组装出来的工作说明。项目规则、skills、prompt templates、active tools、extensions 和用户当前目录,都会改变模型应该如何行动。
这也是为什么 Context Files and Skills 不只是“提示词工程”。它解决的是 agent 如何把长期规则、项目习惯和可复用操作手册带进每一次运行。
给基础读者的慢速版地图
Agent 需要知道“这个项目有什么规矩”和“遇到某类任务该怎么做”。Context files 像项目墙上的长期说明;Skills 像工具箱里的任务手册;Prompt templates 像常用快捷指令。它们共同决定模型在这一轮任务里能获得哪些背景知识。
读图说明:这张图把“三种资源”拆成五个连续位置。先不要记术语,先看每一格负责什么,以及上一格的结果怎样交给下一格。
读图说明:这张图把“加载顺序”拆成五个连续位置。先不要记术语,先看每一格负责什么,以及上一格的结果怎样交给下一格。
读图说明:这张图把“Skill 使用”拆成五个连续位置。先不要记术语,先看每一格负责什么,以及上一格的结果怎样交给下一格。
读图说明:这张图把“错误来源”拆成五个连续位置。先不要记术语,先看每一格负责什么,以及上一格的结果怎样交给下一格。
读图说明:这张图把“好的资源”拆成五个连续位置。先不要记术语,先看每一格负责什么,以及上一格的结果怎样交给下一格。
这组图的目的不是替代正文,而是给读者一个低门槛入口:先形成整体画面,再回到正文理解为什么这些边界必须存在。
读完这一篇,你应该能看懂什么
- 理解 context files、skills、prompt templates、tool snippets 的区别
- 看清为什么 system prompt 要随 active tools 动态重建
- 学会把“可发现资源”和“直接注入上下文”分开
和主流产品怎么对应
Claude Code 会读项目规则,Cursor 会把工作区、打开文件和 IDE 状态放进上下文,Codex CLI 也要处理当前 repo 的指令和可用工具。差别在产品外观,底层问题一样:system prompt 不能是一段固定口号,它要跟当前项目现场一起变。
OpenClaw 的场景更复杂。一次 channel 消息进入系统后,可能要叠加用户配置、plugin 提供的资源、provider 能力和当前会话状态。Pi 这一篇讲的,就是这些东西进入模型前应该怎么分层。
先把问题说清楚
- AGENTS.md / CLAUDE.md:项目级规则和上下文
- Skills:模型可发现的任务说明书索引
- Prompt templates:slash 风格的 prompt macro
- Tool snippets/guidelines:当前 active tools 的使用说明
- Extensions:动态声明更多资源、工具和 hook
Skills 不是工具。它们更像“按需读取的说明书”:system prompt 里只放 name、description、location,让模型在任务匹配时读取完整 skill。
AGENTS.md、Skills、Prompt templates 怎么选
很多人第一次做 agent 时,会把所有规则都塞进 system prompt。这样很快会失控。更好的做法是分清三类东西:长期规则、可复用方法、一次性 prompt 模板。
- 机制:AGENTS.md / CLAUDE.md
- 适合放什么:项目长期规则、代码风格、测试命令、禁止事项
- 怎么触发:进入项目时自动加载
- 安全边界:影响整个项目,别写一次性任务细节
- 例子:“不要直接跑全量 e2e;改 TS 后跑 check”
- 机制:Skill
- 适合放什么:某类任务的操作手册
- 怎么触发:模型按描述发现,或用户显式调用
- 安全边界:通常先作为索引出现,不必全文塞进上下文
- 例子:“如何发布 Ghost 文章”“如何做 PR review”
- 机制:Prompt template
- 适合放什么:常用的一次性指令模板
- 怎么触发:用户输入 slash command
- 安全边界:只是字符串展开,不执行代码
- 例子:/review $ARGUMENTS、/fix $1
放到“修复失败测试”的例子里:项目测试规则应该在 AGENTS.md;“系统性 debug 的四步法”适合做 skill;“请按这个格式总结失败原因”适合做 prompt template。三者都能影响模型,但用途完全不同。
规则冲突时怎么办
动态 system prompt 还会遇到一个现实问题:不同来源可能冲突。比如 AGENTS.md 说“不要跑全量 e2e”,某个 skill 的步骤却包含“先跑完整 e2e”。Pi 这类 harness 不应该让模型自己猜谁更重要,而应该在 prompt 结构里明确优先级:系统和安全规则最高,用户当前指令其次,项目规则约束当前 repo,skill 只是可复用方法,template 只是一次性展开文本。
实际执行时,可以把 skill 里的步骤理解成"建议流程",而不是越过项目规则的授权。如果 skill 和项目规则冲突,runtime 应该要求模型遵守更贴近当前工作区和安全边界的规则,必要时让用户确认。具体落地通常是两手:system prompt 里把安全规则放在最前面、用更强的措辞,让模型在意图层面就倾向于遵守;同时在 tool_call hook 里对违反安全边界的操作做硬拦截。prompt 约束模型意图,hook 约束模型行为。
Active tools 与 prompt 同步
Pi 区分“所有已注册工具”和“当前激活工具”。只有 active tools 会进入 agent.state.tools,也只有当前工具的 prompt snippets / guidelines 应该进入 system prompt。
这是一个很实用的设计:工具越多,prompt 越容易变成噪声。工具说明必须跟当前能力同步,而不是把所有可能能力一次性塞给模型。
Prompt templates 是轻量扩展
Prompt template 是 markdown 文件,支持 $1、$@、$ARGUMENTS 等参数替换。它不执行代码,只做字符串展开,所以安全边界比 extension 更简单。
对用户来说,/review、/fix、/test 这类可复用 prompt 不一定需要写 TypeScript extension;template 就够了。
可迁移的边界
如果自己做 harness,system prompt 不要写成一整块静态字符串。它应该由当前工作目录、项目规则、skills 索引、prompt templates、active tools 和 extensions 动态组成。这样模型看到的规则才会跟真实运行环境一致。
为什么规则要分层
项目规则适合写长期约束,比如测试命令、代码风格、不要跑某些危险操作。Skills 适合写某类任务的操作手册,比如发布文章、做 PR review、处理某个工具链。Prompt templates 适合写一次性常用指令,比如 review、fix、summarize。
这几类东西如果混在一起,系统会很快变乱。把一次性任务写进项目规则,会污染所有后续运行;把复杂工作流写成 template,会缺少触发条件和步骤;把工具说明硬塞进全局 prompt,又会让模型看到与当前 active tools 不匹配的能力。
好的 Context 系统应该让模型少猜
模型最怕的是上下文里有过期规则、冲突规则和不存在的工具。AgentSession 这层的价值,是在运行前把当前可用工具、当前目录规则、已发现 skills 和扩展注入统一整理。
用户看到的是“agent 更懂这个项目”,底层其实是 context files、skills、templates 和 tool prompt 共同完成的运行前装配。
这里的取舍
- 取舍:Skills
- Pi 的倾向:索引化,不直接全文注入
- 可迁移原则:可发现资源不等于当前上下文
- 取舍:Templates
- Pi 的倾向:字符串宏
- 可迁移原则:低风险扩展不需要完整插件系统
- 取舍:Tool prompt
- Pi 的倾向:随 active tools 动态生成
- 可迁移原则:模型说明必须匹配真实可用能力
- 取舍:Resource loading
- Pi 的倾向:集中化
- 可迁移原则:extensions/skills/prompts/themes 不要散落加载
如果你在读 OpenClaw
如果你在读 OpenClaw,这一篇对应项目规则、skills、prompt resources 和 plugin 提供的上下文。上层产品越复杂,越不能把 system prompt 写死。它应该由当前 workspace、用户配置、可用能力和扩展资源一起生成。
源码里真正能看到的资源装配
Pi 的上下文不是启动时写死的一段 system prompt,而是由资源加载器动态装配。项目规则、全局规则、skills、prompt templates、主题、扩展提供的资源、active tools 的说明,都会共同影响模型这一轮看到的工作规则。
Context files 和 Skills 的区别很重要。项目规则适合自动进入 system prompt,告诉模型这个项目长期遵守什么。Skills 默认更像“可发现的任务手册索引”:模型先知道有哪些 skill、它们适合什么任务,需要时再读取完整内容。用户也可以显式调用某个 skill,把它全文展开进这次任务。
Prompt templates 又是另一层,它更像轻量命令宏。适合常用一次性指令,而不是长期项目规则或复杂操作手册。
为什么这不是简单提示词工程
真实 agent 的上下文管理要解决的是“规则从哪里来、什么时候生效、会不会冲突”。当前目录不同,项目规则不同;active tools 不同,工具说明也应该不同;扩展启用后,可能带来新的资源和 hook;用户显式调用 skill 时,模型看到的任务说明又会改变。
如果这些都靠手写一段固定 prompt,系统很快会出现上下文错配:prompt 里说能用的工具实际没有启用,旧项目规则污染新项目,一次性任务细节变成长期规则。
Context Files and Skills 这篇要表达的是:agent 的 system prompt 应该反映真实运行环境,而不是一份静态说明书。
阅读时可以用的三问
第一,这条规则应该放在哪里。长期项目规则、任务操作手册、一次性 prompt template、工具说明和 extension 行为,生命周期完全不同。
第二,模型是否知道当前真正可用的能力。Prompt 里说有某个工具,但 runtime 没启用,是最危险的上下文错配。
第三,规则冲突时谁优先。用户当前指令、项目规则、skill 步骤、系统安全边界要有明确层级,否则 agent 会在长任务里摇摆。
如果只记住一句话
system prompt 应该由当前工作环境生成,而不是永远写死。
小结
一句话:system prompt 不该是写完就忘的死文本。它应该像项目现场的一份活说明书,知道当前目录、可用工具、项目规则和这次任务真正需要的技能。该出现的出现,不该塞进去的别塞。