pi System Prompt 构成详解

pi 的 system prompt 采用分层拼装机制,启动时按固定顺序叠放各层,最终拼接为发送给 LLM 的完整系统提示。

拼装顺序

┌─────────────────────────────────────────────┐
│  ① 基础系统提示 (pi 内置)                     │
│     角色、工具说明、行为准则、文档路径           │
│     ↓ 可被替换                                │
│  ② SYSTEM.md (如存在)                        │
│     完全替换①,而非追加                        │
│     ~/.pi/agent/SYSTEM.md 或 .pi/SYSTEM.md    │
│     ↓                                        │
│  ③ APPEND_SYSTEM.md (如存在)                  │
│     追加在②之后                                │
│     ↓                                        │
│  ④ 上下文文件                                 │
│     AGENTS.md / CLAUDE.md 全部拼接            │
│     来源:全局 + 沿目录树向上收集                │
│     ↓                                        │
│  ⑤ 技能列表 (XML)                             │
│     仅名称 + 描述,遵循 Agent Skills 规范       │
│     ↓                                        │
│  ⑥ 最终 System Prompt → 发送给 LLM            │
└─────────────────────────────────────────────┘

工具 Schema 不在 system prompt 中

工具定义(read、write、edit、bash 及扩展注册的自定义工具)作为 API 请求的 tools 参数单独传递,不进入 system prompt 正文。system prompt 中只包含工具的简要描述说明。


各层详解

① 基础系统提示

pi 内置的角色定义块,包含:

② SYSTEM.md — 完整替换

如果 ~/.pi/agent/SYSTEM.md 或 .pi/SYSTEM.md 存在,会彻底接管系统提示,基础提示被丢弃。

CLI 等价:--system-prompt <text>

适用场景:想要完全自定义 agent 角色和行为时。

③ APPEND_SYSTEM.md — 追加

在系统提示末尾追加内容(不论基础提示是否被 SYSTEM.md 替换)。

CLI 等价:--append-system-prompt <text>

适用场景:添加通用指令、输出格式要求等,不影响核心角色。

④ 上下文文件 — 全部拼接

pi 从 ~/.pi/agent/AGENTS.md 开始,沿着工作目录向上遍历(直到文件系统根或 git 仓库根),逐级收集沿途的 AGENTS.md 和 CLAUDE.md。所有找到的文件全部拼接(不是层级覆盖),包裹在 <project_context> 标签内。

拼接顺序(从上到下):

~/.pi/agent/AGENTS.md        ← 全局行为规范
祖先目录/AGENTS.md            ← 中间目录可能有也可能无
项目根/AGENTS.md              ← 项目特定指令

实际案例:一个典型的配置可能包含两层上下文文件:

层级 内容
全局 行为准则(Think Before Coding、Simplicity First、Surgical Changes、Goal-Driven Execution)、工具偏好(uv/uvx、bun/bunx)
项目 技能修改规则(只在 ./skills/ 中修改,不要在 ~/.pi/agent/skills/ 或 ~/.agents/ 中修改)

两者拼接后同时注入,agent 同时遵守全局规范和项目规则。

禁用:--no-context-files / -nc

⑤ 技能列表 — 渐进式披露

pi 扫描所有技能位置,提取每个技能的 name 和 description(来自 SKILL.md 的 YAML frontmatter),以 XML 格式注入系统提示:

<available_skills>
  <skill>
    <name>librarian</name>
    <description>Research open-source libraries with evidence-backed answers
    and GitHub permalinks...</description>
    <location>.../librarian/SKILL.md</location>
  </skill>
  <skill>
    <name>pi-subagents</name>
    <description>Delegate work to builtin or custom subagents with
    single-agent, chain, parallel, async, forked-context...</description>
    <location>.../pi-subagents/SKILL.md</location>
  </skill>
</available_skills>

关键设计:只注入名称和描述,不注入完整技能内容。完整 SKILL.md 由 agent 按需通过 read 工具加载。这是渐进式披露——用最小上下文成本让 agent 知道"有什么可用",需要时才获取详情。

调用方式:

技能来源优先级(低→高):


扩展对 System Prompt 的影响

扩展注册的工具会出现在工具的简要描述中(第①层),但工具的完整 schema(参数定义等)不进入 system prompt,而是放在 API 请求的 tools 参数中。

扩展注册的技能会出现在技能 XML 中(第⑤层)。

pi 包的安装来源决定其技能注入的路径:


查看实际 System Prompt

可以通过自定义扩展在交互式会话中查看拼装完成的 system prompt。

一个典型实现:

  1. 监听 before_agent_start 事件,获取 event.systemPrompt(这是拼接完成、即将发送的最终版本)
  2. 注册命令(如 /system-prompt),以全屏 TUI overlay 展示
  3. 对内容做语法染色:章节标题加粗高亮、XML 标签弱化、技能名称强调

事件回调获取的 systemPrompt 与 ctx.getSystemPrompt() 的区别:前者是事件触发时已拼装完成的快照,后者是实时调用构建。


设计理念总结

原则 体现
分层拼接 多源上下文文件全部合并,不做层级覆盖
可选替换 SYSTEM.md 可完全接管,不想接管就追加
渐进式披露 技能仅名称入 prompt,内容按需加载
工具分离 工具 schema 不进 system prompt,减少上下文占用
扩展驱动 基础提示极简,能力通过扩展/技能/包注入

总 Token 估算

一个典型的中等复杂度环境(全局 AGENTS.md + 项目 AGENTS.md + 2-3 个技能 + 若干扩展工具),system prompt 大约占用 4000-5500 token,在主流模型的 context window 中占比极小。