Skip to content

系统提示构建

源码版本v0.73.1

system-prompt.ts 是 pi 默认系统提示的拼装车间。一个文件、一个 buildSystemPrompt 函数,把工具列表、guidelines、pi 文档路径、项目上下文文件、技能、日期、cwd 拼成最终 prompt 字符串。createAgentSession 不直接调它——它由 AgentSession 在每次 prompt 前根据当前激活工具重新构建,保证工具增减后 prompt 同步更新。

职责

  1. 拼默认 prompt:buildSystemPrompt 不带 customPrompt 时走默认路径,生成「You are an expert coding assistant operating inside pi」开头的完整提示。见 packages/coding-agent/src/core/system-prompt.ts:28-80packages/coding-agent/src/core/system-prompt.ts:131-171
  2. custom prompt 路径:customPrompt 提供时跳过默认模板,只追加 contextFiles、skills、日期、cwd。见 packages/coding-agent/src/core/system-prompt.ts:53-80
  3. 工具列表与 guidelines:根据 selectedTools 决定哪些工具可见,根据工具组合动态生成 guidelines(如 bash+grep 同时存在时建议优先用 grep)。见 packages/coding-agent/src/core/system-prompt.ts:89-129
  4. prompt snippet 注入:每个工具的 promptSnippet 是一行简短描述,拼进「Available tools」列表,LLM 据此判断工具用途。见 packages/coding-agent/src/core/system-prompt.ts:89-92
  5. 技能附加:formatSkillsForPrompt 把可见技能(非 disableModelInvocation)拼成 <available_skills> XML 段落。见 packages/coding-agent/src/core/system-prompt.ts:162-165
  6. 文档自指引:prompt 里写明 pi 自身文档路径(readme、docs、examples),并指示 LLM 在用户问 pi 时去读这些文件。见 packages/coding-agent/src/core/system-prompt.ts:141-147

设计动机

为什么不让 AgentSession 直接持有 prompt 字符串?因为工具集是动态的——用户可以在 session 中途 /tools 增减工具,扩展也可以注册新工具。如果 prompt 是静态字符串,工具变化后 LLM 还会按旧 prompt 调用已禁用的工具。buildSystemPrompt 每次调用都重新生成,保证 prompt 与当前激活工具集严格对齐。

为什么要区分默认 prompt 和 custom prompt 路径?默认 prompt 是 pi 官方调优的版本,包含工具列表、guidelines、文档自指引;custom prompt 是用户或扩展提供的完全自定义版本,只想追加 contextFiles 和 skills。两条路径共享 contextFiles、skills、日期、cwd 的追加逻辑,但默认路径多出 toolsList 和 guidelines 的拼装。

guidelines 动态化值得一提:如果同时启用 bash 和 grep/find/ls,prompt 会建议「Prefer grep/find/ls tools over bash for file exploration (faster, respects .gitignore)」;如果只有 bash 没有 grep/find/ls,则建议「Use bash for file operations like ls, rg, find」。这让 LLM 在不同工具集下都能选到高效路径。

关键文件

guidelines 动态生成,通过 set 去重:

typescript
// packages/coding-agent/src/core/system-prompt.ts:105-129
const hasBash = tools.includes("bash");
const hasGrep = tools.includes("grep");
const hasFind = tools.includes("find");
const hasLs = tools.includes("ls");

if (hasBash && !hasGrep && !hasFind && !hasLs) {
	addGuideline("Use bash for file operations like ls, rg, find");
} else if (hasBash && (hasGrep || hasFind || hasLs)) {
	addGuideline("Prefer grep/find/ls tools over bash for file exploration (faster, respects .gitignore)");
}

for (const guideline of promptGuidelines ?? []) {
	const normalized = guideline.trim();
	if (normalized.length > 0) {
		addGuideline(normalized);
	}
}

// Always include these
addGuideline("Be concise in your responses");
addGuideline("Show file paths clearly when working with files");

默认 prompt 末尾追加日期和 cwd,位置故意放最后让 LLM 注意到:

typescript
// packages/coding-agent/src/core/system-prompt.ts:167-171
if (hasRead && skills.length > 0) {
	prompt += formatSkillsForPrompt(skills);
}

// Add date and working directory last
prompt += `\nCurrent date: ${date}`;
prompt += `\nCurrent working directory: ${promptCwd}`;

return prompt;

数据流

prompt 构建流程:

边界与失败

小结

buildSystemPrompt 是 prompt 拼装车间,根据当前工具集动态生成 guidelines,custom 与默认两条路径共享 contextFiles/skills/日期/cwd 追加逻辑。技能系统的加载和格式化看 技能系统,消息转换看 消息类型与 convertToLlm,工具集本身看 工具集 read/bash/edit/write/grep/find/ls