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