深色模式
07 · 扩展机制:extensions / skills / prompt-templates / themes / packages
Pi 的设计哲学(来自 README):"minimal, extensible agent harness that you can make your own." 所有可定制能力都通过扩展机制分发。本篇讲清楚这套机制怎么学、怎么读源码。 配套文档(
packages/coding-agent/docs/):extensions.mdskills.mdprompt-templates.mdthemes.mdpackages.md。
1. 五种可定制资源
| 资源 | 是什么 | 加载点(源码) |
|---|---|---|
| Extension(扩展) | TS 模块,factory 函数注册工具/命令/快捷键/provider/事件处理器/渲染器/TUI | coding-agent/core/extensions/*(loader.ts / runner.ts / types.ts / wrapper.ts / virtual-modules.ts) |
| Skill(技能) | 按需加载的指令 + 配套文件 | coding-agent/core/skills.ts |
| Prompt template(提示词模板) | 可复用的消息文本,展开用户输入 | coding-agent/core/prompt-templates.ts |
| Theme(主题) | 终端颜色/样式 | coding-agent/modes/interactive/theme/* + config.ts:getThemesDir |
| Pi package(包) | 把以上资源打包,经 npm 或 git 分发 | coding-agent/core/package-manager.ts + docs/packages.md |
2. Extension 系统(核心)
定义方式(durable 与 coding-agent 共用 DSL)
来自 pi-durable/src/harness/define.ts(被 coding-agent 复用):
defineExtension(extension):类型化一个扩展。defineTool({ name, description, parameters, execute }):定义一个工具(args 来自parametersschema,details 来自返回)。section(key, render, options?):一个系统提示词_section_,可被扩展包裹/改写。hook(task, handlers):给具名任务挂钩子。wrapTool(tool, wrapper)/wrapSection(key, wrapper):在所选扩展内包裹某工具/section。
加载与运行(coding-agent/core/extensions/)
loader.ts:发现并加载扩展(支持jiti-loader.ts动态加载 TS/JS,virtual-modules.ts处理虚拟模块)。runner.ts+wrapper.ts:执行扩展 factory、应用 wrap、把注册结果接到 agent 运行时。types.ts:所有Extension*类型(ExtensionFactory/ExtensionContext/ExtensionAPI/ExtensionHandler/ExtensionCommandContext/ExtensionUIContext等)。index.ts从core/index.ts统一导出defineTool/defineExtension/ 各事件类型(BeforeAgentStartEvent/AgentStartEvent/TurnStartEvent/ToolCallEvent/SessionTreeEvent/SessionCompactEvent...)。
学习重点:先读
core/index.ts的扩展导出,再看extensions/loader.ts如何把磁盘上的扩展变成运行时注册表,最后看extensions/mcp/这个"真·扩展"示例(把 MCP 服务器变成 Pi 工具)。
3. Skills / Prompt Templates / Themes
- Skills(
skills.ts):技能是"按需指令",模型可在合适时机调用;与扩展的区别是技能偏内容/指引,扩展偏能力/代码。 - Prompt templates(
prompt-templates.ts):用户输入进 agent 前先经模板展开(如选中文件、图片、粘贴文本、shell 输出可成为消息内容)。 - Themes(
modes/interactive/theme/,含light.json/dark.json/theme-controller.ts/theme-schema.ts/theme-tokens.ts):终端配色,用户可放自定义主题到config.ts:getCustomThemesDir()。
4. Pi Packages(分发)
core/package-manager.ts+core/pi-manifest.ts:解析piConfig、安装/解析包。docs/packages.md:如何把一个扩展+技能+主题打成 Pi package,经 npm 或 git 分享。- 仓库内示例:
packages/coding-agent/examples/extensions/*(custom-provider-anthropic、gitlab-duo、gondolin、sandbox、with-deps)与examples/plugins/pi-example-plugin/——学扩展的最佳素材,直接对照源码看 factory 怎么写。
5. 阅读清单
docs/extensions.md+docs/skills.md+docs/themes.md+docs/packages.md(总览)。pi-durable/src/harness/define.ts—— 扩展 DSL 的"词表"。coding-agent/core/index.ts(extensions导出段)—— 运行时暴露的扩展 API 全貌。coding-agent/core/extensions/loader.ts+runner.ts—— 从磁盘到运行时的加载链路。coding-agent/extensions/mcp/—— 真实扩展范例。packages/coding-agent/examples/extensions/custom-provider-anthropic/—— 最小可运行扩展。
6. 自测
defineTool与pi-ai里的AgentTool是什么关系?扩展定义的工具最终怎么进 agent 的tools列表?- 一个 Pi package 经 npm 安装后,loader 如何发现并加载它?
wrapTool/wrapSection在什么场景下比"自己重写一个扩展"更合适?- skill 与 extension 的本质区别是什么?