Pi Coding Agent 入门教程
Pi 是一个运行在终端里的 AI 编码 Agent,类似于 Claude Code、OpenAI Codex CLI 这类工具。
Pi 的官方理念是:"There are many agent harnesses but this one is yours"(Agent 工具很多,但这个是你自己的)。
你给 Pi 一句话,它就能在你的项目目录里读文件、写文件、跑命令,循环调用大模型直到完成任务。
核心理念是用最小的内核加极强的可扩展性,让你把工具改造成适合自己的样子,而不是反过来去适应工具。

Pi 包含什么
Pi 不是一个单独的程序,而是一套由四个 npm 包组成的工具链。
普通用户只需安装最上层的 @earendil-works/pi-coding-agent,就能得到一个开箱即用的命令行 Agent。
适合谁用
Pi 特别适合以下场景和人群:
- 偏好终端工作流、不想在 IDE 和命令行之间来回切换的开发者
- 想要一个可以深度定制、甚至让 Agent 自己改写自己的工具的进阶用户
- 需要同时接入多家大模型(Anthropic、OpenAI、Google 等)的人
- 想把 Agent 能力嵌入到自己程序里的开发者(通过 SDK 或 RPC 模式)
注意:Pi 默认以你的用户权限运行,没有内置沙箱。在不受信任的代码仓库上使用前,请先阅读本文的「安全须知」章节。
核心设计哲学:原语而非功能
理解 Pi 的设计哲学,你会明白它为什么故意「不内置」很多其他 Agent 都有的功能。
Pi 把这个理念叫做 Primitives, Not Features(提供原语,而非功能)。
故意不内置的功能
下面这些功能,Pi 都没有内置,而是让你按需通过扩展或外部工具来实现:
| 不内置的功能 | Pi 的替代方案 |
|---|---|
| MCP 协议集成 | 把工具写成带 README 的 CLI,或装一个 MCP 扩展 |
| 子 Agent(subagents) | 用 tmux 开多个会话,或自己写扩展 |
| 权限确认弹窗 | 放进容器里跑,或自己写确认流程扩展 |
| 计划模式(plan mode) | 把计划写到文件里,或写扩展 |
| 内置待办事项 | 用一个 TODO.md 文件,或装扩展 |
| 后台 bash | 用 tmux 获得完整可观测性 |
为什么要这样做
Pi 认为这些功能在不同团队里需求差异巨大,强行内置反而会让工具变得臃肿且难以贴合实际工作流。
所以它的做法是:保留一个干净的最小内核,把所有「功能」都变成可安装、可编写、可分享的扩展、技能、提示模板和主题。
甚至你可以直接让 Pi 帮你把这些功能写出来,写完用 /reload 重载,立刻就能用。
这句话值得记住:Adapt Pi to your workflows, not the other way around(让 Pi 适应你的工作流,而不是你适应 Pi)。
架构与核心包
Pi 由四个层级分明的包组成,上层依赖下层。
你平时用的 pi 命令,只是最上层那个包提供的入口。
四个核心包
| 包名 | 作用 | 何时会单独用到 |
|---|---|---|
@earendil-works/pi-coding-agent | 交互式编码 Agent CLI,用户直接安装使用的入口 | 绝大多数情况只需这个 |
@earendil-works/pi-agent-core | Agent 运行时,负责工具调用循环和状态管理 | 想自己搭一个非编码类的 Agent 时 |
@earendil-works/pi-ai | 统一的多厂商 LLM API(OpenAI、Anthropic、Google 等) | 只想用一个统一接口调多家模型时 |
@earendil-works/pi-tui | 终端 UI 库,支持差分渲染 | 想写自己的终端应用时 |
四种运行模式
Pi 不只能交互式运行,它提供了四种模式来适配不同场景:
| 模式 | 说明 | 典型场景 |
|---|---|---|
| Interactive(交互式) | 完整的终端 UI 体验 | 日常编码、对话式开发 |
| Print / JSON | pi -p "提问" 一次性输出;--mode json 输出事件流 | 脚本自动化、管道处理 |
| RPC | 通过 stdin/stdout 的 JSON 协议通信 | 非 Node 程序集成 |
| SDK | 作为库嵌入到你的应用里 | 在自家产品里集成 Agent 能力 |
安装
Pi 提供多种安装方式,覆盖 macOS、Linux 和 Windows。
最常见的是用 npm 全局安装,也可以用官方的一键脚本。
方式一:一键脚本(推荐新手)
macOS 和 Linux 用户用 curl:
curl -fsSL https://pi.dev/install.sh | sh
Windows 用户用 PowerShell:
powershell -c "irm https://pi.dev/install.ps1 | iex"
方式二:npm 全局安装
如果你已经装了 Node.js,用包管理器全局安装即可。
注意那个 --ignore-scripts 参数:它会跳过依赖的安装期生命周期脚本,Pi 正常使用不需要这些脚本,加上更安全。
# npm 安装 npm install -g --ignore-scripts @earendil-works/pi-coding-agent # pnpm 安装 pnpm add -g --ignore-scripts @earendil-works/pi-coding-agent # bun 安装 bun add -g --ignore-scripts @earendil-works/pi-coding-agent
验证安装
安装完成后,查看版本号确认是否成功:
pi --version
例如:
$ pi --version 0.80.6
卸载
卸载方式取决于你当初用什么装的:
# curl 装的或 npm 装的 npm uninstall -g @earendil-works/pi-coding-agent # pnpm 装的 pnpm remove -g @earendil-works/pi-coding-agent # bun 装的 bun uninstall -g @earendil-works/pi-coding-agent
注意:卸载 Pi 不会删除你的配置。设置、凭证、会话记录、已安装的 Pi 包都保留在
~/.pi/agent/目录里,需要手动清理。
配置模型 Provider
Pi 本身不包含大模型,它需要你提供至少一个模型供应商(Provider)的访问凭证。
配置方式有两种:订阅登录,或 API Key。
方式一:订阅登录(最省事)
如果你已经有 Claude Pro/Max、ChatGPT Plus/Pro 或 GitHub Copilot 订阅,可以直接登录复用。
启动 Pi 后运行 /login,然后选择供应商即可:
# 启动 pi pi # 在 pi 里执行登录命令 /login
可选的订阅供应商有三种:
| 供应商 | 要求 | 说明 |
|---|---|---|
| Claude Pro / Max | Anthropic 订阅 | 第三方工具用量按 Token 计费,不占订阅额度 |
| ChatGPT Plus / Pro(Codex) | OpenAI 订阅 | OpenAI 官方通过 Codex for OSS 认可 |
| GitHub Copilot | Copilot 订阅 | 若提示模型不支持,需在 VS Code 里先启用对应模型 |
登录后凭证会存进 ~/.pi/agent/auth.json,过期会自动刷新。退出登录用 /logout。
方式二:API Key(最灵活)
用环境变量传入 API Key 是最通用的方式。比如用 Anthropic 的 Key:
# 设置环境变量后启动 export ANTHROPIC_API_KEY=sk-ant-... pi
你也可以在 Pi 里运行 /login 并选择 API Key 类型的供应商,把 Key 持久化存进 auth.json。
常见供应商的环境变量
Pi 支持 15 家以上的供应商,下面列出最常见的几家:
| 供应商 | 环境变量 | auth.json 里的键名 |
|---|---|---|
| Anthropic | ANTHROPIC_API_KEY | anthropic |
| OpenAI | OPENAI_API_KEY | openai |
| Google Gemini | GEMINI_API_KEY | |
| DeepSeek | DEEPSEEK_API_KEY | deepseek |
| Groq | GROQ_API_KEY | groq |
| Mistral | MISTRAL_API_KEY | mistral |
| xAI | XAI_API_KEY | xai |
| OpenRouter | OPENROUTER_API_KEY | openrouter |
| Hugging Face | HF_TOKEN | huggingface |
提示:
auth.json里的凭证优先级高于环境变量。如果两处都配了,以auth.json为准。
auth.json 的结构
如果你想手动管理凭证,可以直接编辑 ~/.pi/agent/auth.json。这个文件创建时会被设为 0600 权限(仅当前用户可读写):
{
"anthropic": { "type": "api_key", "key": "sk-ant-..." },
"openai": { "type": "api_key", "key": "sk-..." },
"google": { "type": "api_key", "key": "..." }
}
Key 字段还支持三种高级写法,方便从密码管理器或环境变量里取值:
| 写法 | 含义 | 示例 |
|---|---|---|
"!命令" | 以感叹号开头,执行该命令并取 stdout 作为 Key | "!op read 'op://vault/item/cred'" |
"$变量名" | 取环境变量的值 | "$MY_ANTHROPIC_KEY" |
| 纯字面量 | 直接当作 Key 使用 | "sk-ant-..." |
云平台供应商
如果你用的是云上的模型服务,Pi 也支持 Azure OpenAI、Amazon Bedrock、Google Vertex AI、Cloudflare 等。
这些通常需要额外配置端点、区域或部署名。以 Azure OpenAI 为例:
# Azure OpenAI 所需的环境变量 export AZURE_OPENAI_API_KEY=... export AZURE_OPENAI_BASE_URL=https://your-resource.ai.azure.com # 可选:API 版本与部署名映射 export AZURE_OPENAI_API_VERSION=2024-02-01 export AZURE_OPENAI_DEPLOYMENT_NAME_MAP=gpt-4o=my-gpt4o
配置 DeepSeek 供应商
Pi 通过 models.json 支持自定义供应商,配置文件地址:
- Linux / macOS:~/.pi/agent/models.json
- Windows:%USERPROFILE%\.pi\agent\models.json
先在 DeepSeek 开放平台获取 API Key:https://platform.deepseek.com/api_keys。
{
"providers": {
"deepseek": {
"baseUrl": "https://api.deepseek.com",
"api": "openai-completions",
"apiKey": "$DEEPSEEK_API_KEY",
"models": [
{
"id": "deepseek-v4-pro",
"name": "DeepSeek V4 Pro",
"contextWindow": 1000000,
"maxTokens": 384000,
"input": ["text"],
"reasoning": true,
"cost": {
"input": 1.74,
"output": 3.48,
"cacheRead": 0.145,
"cacheWrite": 0
},
"compat": {
"requiresReasoningContentOnAssistantMessages": true,
"thinkingFormat": "deepseek",
"reasoningEffortMap": {
"minimal": "high",
"low": "high",
"medium": "high",
"high": "high",
"xhigh": "max"
}
}
},
{
"id": "deepseek-v4-flash",
"name": "DeepSeek V4 Flash",
"contextWindow": 1000000,
"maxTokens": 384000,
"input": ["text"],
"reasoning": true,
"cost": {
"input": 0.14,
"output": 0.28,
"cacheRead": 0.028,
"cacheWrite": 0
},
"compat": {
"requiresReasoningContentOnAssistantMessages": true,
"thinkingFormat": "deepseek",
"reasoningEffortMap": {
"minimal": "high",
"low": "high",
"medium": "high",
"high": "high",
"xhigh": "max"
}
}
}
]
}
}
}
设置环境变量:
Linux / Mac 用户:
export DEEPSEEK_API_KEY="<你的 DeepSeek API Key>"
Windows 用户:
$env:DEEPSEEK_API_KEY="<你的 DeepSeek API Key>"
进入项目目录并执行 pi 命令:
cd /path/to/my-project pi
输入 /model 打开模型切换器,选择 deepseek,然后选择 DeepSeek-V4-Pro 或 DeepSeek-V4-Flash。
更多配置选项请参阅:https://github.com/earendil-works/pi/blob/main/packages/coding-agent/docs/models.md。
凭证解析顺序
当 Pi 需要某个供应商的凭证时,按以下顺序依次查找,找到即用:
| 优先级 | 来源 |
|---|---|
| 1(最高) | 命令行 --api-key 参数 |
| 2 | auth.json 里的条目(API Key 或 OAuth 令牌) |
| 3 | 环境变量 |
| 4 | models.json 里自定义供应商的 Key |
第一次运行
配置好凭证后,进入你的项目目录,直接运行 pi 启动。
# 进入项目目录 cd /path/to/project # 启动 pi pi
启动后,直接输入一句话并回车,比如让它分析这个仓库:
Summarize this repository and tell me how to run its checks.
Pi 会自动读取文件、运行命令,然后给出总结和检查方式。
项目信任提示
如果当前目录或上层目录里有 .pi 配置、扩展、技能等项目级资源,Pi 在交互式启动时会先问你信不信任这个项目。
这是为了防止一个仓库在你不知情时静默加载它的扩展或修改设置。
注意:信任决策保存在
~/.pi/agent/trust.json。非交互模式(-p、--mode json)不会弹窗,默认按全局设置里的defaultProjectTrust处理。
Agent 是怎么工作的
你每发一条消息,Pi 就会启动一个 agent 循环。理解这个循环,就理解了 Pi 的工作方式。
核心是中间那个 turn 循环:模型每轮可能调用工具,Pi 执行工具把结果塞回上下文,再让模型继续,直到模型不再调用工具、给出最终回复。
四个内置工具
Pi 默认只给模型四个工具,覆盖了编码最核心的读写和执行能力。
| 工具 | 作用 | 是否默认启用 |
|---|---|---|
read | 读取文件内容 | 是 |
write | 创建或覆盖文件 | 是 |
edit | 对文件做局部补丁修改 | 是 |
bash | 运行 shell 命令 | 是 |
grep | 搜索文件内容 | 否(需通过工具选项开启) |
find | 按条件查找文件 | 否(需通过工具选项开启) |
ls | 列出目录内容 | 否(需通过工具选项开启) |
控制可用工具
你可以通过命令行参数精确控制模型能用哪些工具。
这在需要限制 Agent 能力时很有用,比如只让它审查代码而不许改动:
# 只读模式:只允许读取和搜索类工具 pi --tools read,grep,find,ls -p "审查这段代码" # 禁用某个工具,其余保留 pi --exclude-tools ask_question # 关闭所有内置工具,只保留扩展提供的工具 pi --no-builtin-tools -e ./my-extension.ts # 完全禁用工具,纯对话 pi --no-tools -p "解释一下这个概念"
提醒:Pi 在你的当前工作目录里运行,能修改你的文件。建议配合 git 等版本控制使用,方便随时回滚。
用 AGENTS.md 给项目下指令
AGENTS.md 是 Pi 的项目指令文件,告诉模型这个项目有什么规矩、怎么跑、要注意什么。
它的作用类似于 Claude Code 的 CLAUDE.md——而且 Pi 同时支持这两种文件名。
写一个 AGENTS.md
在项目根目录创建 AGENTS.md,写上你希望模型遵守的规则:
# 项目指令 - 改完代码后运行 `npm run check`。 - 不要在本地跑生产环境的数据库迁移。 - 回答尽量简洁。
Pi 从哪里加载指令
Pi 在启动时会从多个位置加载指令文件,按范围从大到小:
| 位置 | 作用范围 | 说明 |
|---|---|---|
~/.pi/agent/AGENTS.md | 全局 | 对你所有项目生效的通用指令 |
父目录的 AGENTS.md | 项目级 | 从当前目录向上逐层查找 |
当前目录的 AGENTS.md | 项目级 | 最具体、优先级最高的指令 |
文件名用 AGENTS.md 或 CLAUDE.md 都行,Pi 都会识别。
修改系统提示
AGENTS.md 是在默认系统提示之外追加的指令。如果你想更彻底地控制,可以替换整个系统提示。
在项目里放 .pi/SYSTEM.md 会替换默认系统提示;放 .pi/APPEND_SYSTEM.md 则是追加(全局对应 ~/.pi/agent/ 下的同名文件)。
注意:改了指令文件后,记得在 Pi 里运行
/reload重载,或者重启 Pi,新指令才会生效。
交互模式常用操作
交互模式是 Pi 最常用的形态,掌握几个关键操作就能高效使用。
引用文件:@
在编辑器里输入 @,会弹出项目文件的模糊搜索,选中后文件内容会作为上下文发给模型。
你也可以在命令行启动时直接带上文件:
# 启动时带上一个文件 pi @README.md "总结一下这个文件" # 带上多个文件一起审查 pi @src/app.ts @src/app.test.ts "一起审查这两个文件"
运行 shell 命令:!
在编辑器里以 ! 开头输入命令,会直接运行并把输出发给模型:
# 运行命令,输出会进入模型上下文 !npm run lint # 两个感叹号:运行但不把输出加进模型上下文 !!npm run build
切换模型与思考强度
Pi 支持中途切换模型和思考强度,适配不同任务的复杂度。
| 操作 | 快捷键 / 命令 | 说明 |
|---|---|---|
| 打开模型选择器 | /model 或 Ctrl+L | 从所有可用模型里挑一个 |
| 切换思考强度 | Shift+Tab | 在 off / minimal / low / medium / high / xhigh / max 之间循环 |
| 循环收藏模型 | Ctrl+P / Shift+Ctrl+P | 在你预先圈定的几个模型间快速切换 |
启动时也可以直接指定模型和思考强度:
# 指定厂商和模型 pi --provider openai --model gpt-4o "帮我重构" # 用 厂商/模型 的写法 pi --model openai/gpt-4o "帮我重构" # 用 名称:思考强度 的简写 pi --model sonnet:high "解决这个复杂问题" # 限定可在 Ctrl+P 里循环的模型 pi --models "claude-*,gpt-4o"
输入与编辑技巧
| 操作 | 方式 | 说明 |
|---|---|---|
| 多行输入 | Shift+Enter(Windows Terminal 用 Ctrl+Enter) | 在一条消息里换行 |
| 路径补全 | Tab | 补全文件路径 |
| 粘贴图片 | Ctrl+V(Windows 用 Alt+V) | 也支持把图片拖进终端 |
| 复制回复 | Ctrl+X | 复制最后一条助手消息 |
| 外部编辑器 | Ctrl+G | 打开 $VISUAL / $EDITOR 编辑长文本 |
边跑边插话
Agent 在工作时,你不用干等,可以随时插入消息。
| 按键 | 行为 | 适用场景 |
|---|---|---|
| Enter | 转向消息:当前工具跑完后立刻送达,打断剩余工具 | 发现方向跑偏,及时纠正 |
| Alt+Enter | 后续消息:等 Agent 完全跑完再送达 | 想追加一个新需求 |
| Escape | 中止当前工作,把排队消息还原回编辑器 | 想停下来重新组织 |
提示:Windows Terminal 里 Alt+Enter 默认是全屏切换,转向和后续消息的按键可以在设置里通过
steeringMode和followUpMode改。
常用斜杠命令速查
在编辑器里输入 / 就会弹出命令补全。下面是最常用的一批斜杠命令。
| 命令 | 功能 |
|---|---|
/login / /logout | 管理 OAuth 或 API Key 凭证 |
/model | 切换模型 |
/scoped-models | 设置哪些模型参与 Ctrl+P 循环 |
/settings | 调整思考强度、主题、消息送达方式等 |
/resume | 从历史会话里选一个继续 |
/new | 开一个新会话 |
/name <名称> | 给当前会话起个显示名 |
/session | 查看会话文件、ID、消息数、Token 用量和花费 |
/tree | 跳到会话树的任意节点,从那里继续 |
/fork | 从某条历史消息分叉出一个新会话 |
/clone | 把当前分支复制成一个新会话 |
/compact [提示] | 手动压缩上下文,可带自定义指令 |
/copy | 复制最后一条助手消息到剪贴板 |
/export [文件] | 把会话导出为 HTML 或 JSONL |
/import <文件> | 从 JSONL 文件导入并恢复会话 |
/share | 上传为私有 GitHub Gist,生成可分享的 HTML 链接 |
/reload | 重载快捷键、扩展、技能、提示、主题和上下文文件 |
/trust | 保存当前项目的信任决策 |
/hotkeys | 显示所有快捷键 |
/changelog | 查看版本更新历史 |
/quit | 退出 Pi |
会话管理:树形历史
Pi 的会话不是一条直线,而是一棵树。
这意味着你在任意一个历史节点分叉,都不会丢失原来的分支,所有分支都存在同一个会话文件里。
会话存在哪里
会话自动保存到 ~/.pi/agent/sessions/,按工作目录归类。
从命令行恢复或浏览历史会话:
# 继续最近一次会话 pi -c # 浏览并选择一个历史会话 pi -r # 给会话起个名字,方便日后查找 pi --name "my task" # 打开指定的会话文件或 ID pi --session <path|id> # 临时会话,不保存 pi --no-session
在会话树里导航
用 /tree 可以打开会话树视图,跳到任意历史节点继续。
从这里继续会产生一条新分支,原来的分支保持不变。
分叉与克隆
| 命令 | 行为 | 区别 |
|---|---|---|
/fork | 从某条更早的用户消息分叉出新会话 | 从历史中间某个点重新开始 |
/clone | 复制当前活跃分支成新会话 | 在当前最新状态基础上开一份副本 |
压缩上下文
当对话变长、接近模型的上下文上限时,Pi 会自动把较早的消息压缩成摘要。
你也可以主动用 /compact 触发,还能附带一句自定义指令告诉它压缩时保留什么重点:
# 在 pi 里手动压缩,并要求保留最近改动 /compact 重点保留最近的改动和错误处理
导出与分享
把会话导出成 HTML 方便存档或展示:
# 导出为 HTML 文件 /export my-session.html # 上传为私有 GitHub Gist,得到分享链接 /share
非交互模式与集成
Pi 不只能交互式对话,它还能作为命令行工具、事件流、RPC 服务和 SDK 库来用。
一次性提问:print 模式
用 -p 让 Pi 回答完就退出,适合在脚本里调用:
# 直接提问 pi -p "总结一下这个代码库" # 配合管道,把内容喂给 Pi cat README.md | pi -p "总结这段文字" # 带图片提问 pi -p @screenshot.png "这张图里是什么?"
事件流:JSON 模式
--mode json 会把所有事件以 JSON 行的形式输出,方便程序解析:
# 输出 JSON 事件流 pi --mode json -p "列出 src 下所有 .ts 文件"
进程集成:RPC 模式
--mode rpc 通过 stdin/stdout 走 JSON 协议,适合非 Node 的程序(比如 Python、Go)来驱动 Pi。
导出已有会话
不启动新会话,直接把一个已有会话文件导出成 HTML:
# 把会话文件导出为 HTML pi --export session.jsonl output.html
SDK 模式
如果你要在自己的 Node 应用里嵌入 Pi 的能力,可以用 SDK 模式把它当作库引入。
这是比 RPC 更紧密的集成方式,详见官方文档的 SDK 章节:https://pi.dev/docs/latest/sdk。
扩展 Extensions
扩展是 Pi 可扩展性的核心。它就是一个 TypeScript 模块,能订阅生命周期事件、注册自定义工具、添加命令和快捷键。
扩展通过 jiti 加载,所以直接写 TypeScript 即可,无需编译。
扩展放在哪里
| 位置 | 作用范围 |
|---|---|
~/.pi/agent/extensions/*.ts | 全局,所有项目生效 |
.pi/extensions/*.ts | 项目级,仅当前项目生效 |
也可以是子目录形式(扩展名/index.ts),或带 package.json 的完整包。
一个最小扩展示例
下面这个扩展演示了三件事:启动时通知、拦截危险命令、注册一个自定义工具和一个命令。
// 文件路径:~/.pi/agent/extensions/my-extension.ts
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
import { Type } from "typebox";
// 扩展导出一个默认工厂函数,接收 ExtensionAPI
export default function (pi: ExtensionAPI) {
// 1. 监听 session_start 事件:会话启动时弹个通知
pi.on("session_start", async (_event, ctx) => {
ctx.ui.notify("扩展已加载!", "info");
});
// 2. 监听 tool_call 事件:拦截危险的 bash 命令
pi.on("tool_call", async (event, ctx) => {
if (event.toolName === "bash" && event.input.command?.includes("rm -rf")) {
// 弹确认框,用户拒绝就阻止执行
const ok = await ctx.ui.confirm("危险操作!", "允许执行 rm -rf 吗?");
if (!ok) return { block: true, reason: "被用户阻止" };
}
});
// 3. 注册一个自定义工具,模型可以调用它
pi.registerTool({
name: "greet",
label: "打招呼",
description: "按名字向某人打招呼",
parameters: Type.Object({
name: Type.String({ description: "要打招呼的名字" }),
}),
async execute(toolCallId, params, signal, onUpdate, ctx) {
return {
content: [{ type: "text", text: `你好,${params.name}!` }],
details: {},
};
},
});
// 4. 注册一个斜杠命令 /hello
pi.registerCommand("hello", {
description: "打个招呼",
handler: async (args, ctx) => {
ctx.ui.notify(`你好 ${args || "world"}!`, "info");
},
});
}
写完后用 -e 参数临时加载测试:
# 临时加载一个扩展来测试 pi -e ./my-extension.ts
扩展能做什么
扩展的能力远不止上面这些,它几乎能介入 Pi 工作流的每个环节:
| 能力 | 对应方法 | 典型用途 |
|---|---|---|
| 注册自定义工具 | pi.registerTool() | 让模型调用你的业务接口 |
| 注册命令 | pi.registerCommand() | 添加自己的斜杠命令 |
| 注册快捷键 | pi.registerShortcut() | 绑定自定义快捷键 |
| 拦截工具调用 | tool_call 事件 | 权限确认、命令改写 |
| 修改上下文 | context 事件 | 过滤历史、注入 RAG 内容 |
| 注入消息 | pi.sendMessage() | 动态补充上下文 |
| 注册供应商 | pi.registerProvider() | 接入私有模型网关 |
| 自定义 UI | ctx.ui 系列 | 对话框、状态栏、组件 |
提示:Pi 仓库里有 50 多个示例扩展,涵盖子 Agent、计划模式、权限门、SSH 执行、沙箱等,是学习扩展开发的最好参考。
技能 Skills
技能是另一种可复用的能力包,和扩展的区别在于:技能主要是给模型看的指令和脚本,按需加载。
Pi 实现了 Agent Skills 标准,所以也能直接用 Claude Code、OpenAI Codex 等工具的技能。
技能的工作方式
技能采用渐进式披露(progressive disclosure)的原则。
启动时 Pi 只把每个技能的名字和描述放进系统提示;当任务匹配时,模型才用 read 工具加载完整的技能说明。
这样既能装很多技能,又不会一开始就把上下文撑满。
技能放在哪里
| 位置 | 作用范围 |
|---|---|
~/.pi/agent/skills/ | 全局 |
~/.agents/skills/ | 全局(跨工具共享) |
.pi/skills/ | 项目级(需项目被信任) |
.agents/skills/ | 项目级(跨工具共享) |
技能的结构
一个技能就是一个包含 SKILL.md 的目录,其余文件随意组织:
my-skill/
├── SKILL.md # 必需:前置信息 + 指令
├── scripts/ # 辅助脚本
│ └── process.sh
├── references/ # 按需加载的详细文档
│ └── api-reference.md
└── assets/
└── template.json
SKILL.md 的写法
SKILL.md 顶部是前置信息(frontmatter),下面是给模型的指令正文:
--- name: my-skill description: 这个技能做什么、什么时候用。要写具体。 --- # My Skill ## Setup 首次使用前运行一次: ```bash cd /path/to/skill && npm install ``` ## Usage ```bash ./scripts/process.sh <input> ```
前置信息里最重要的两个字段:
| 字段 | 是否必填 | 说明 |
|---|---|---|
name | 必填 | 最多 64 字符,只能用小写字母、数字、连字符 |
description | 必填 | 最多 1024 字符,决定模型何时加载这个技能,要写得具体 |
提醒:
description写得好不好,直接决定模型会不会在正确时机用上这个技能。写「处理 PDF 文件,提取文本和表格、填表单、合并多个 PDF」远好过写「帮助处理 PDF」。
手动调用技能
模型不一定会主动加载技能。你可以用 /skill:名称 强制加载并执行:
# 加载并执行技能 /skill:brave-search # 带参数加载技能 /skill:pdf-tools extract
Pi 包管理
扩展、技能、提示模板、主题都可以打包成 Pi 包,通过 npm 或 git 分享安装。
Pi 内置了一套包管理命令,让你像装插件一样扩展能力。
安装与卸载
# 从 npm 安装一个包 pi install npm:@foo/pi-tools # 从 git 仓库安装 pi install git:github.com/badlogic/pi-doom # 项目本地安装(加 -l) pi install npm:@foo/pi-tools -l # 卸载 pi remove npm:@foo/pi-tools
更新与查看
| 命令 | 功能 |
|---|---|
pi list | 列出已安装的包 |
pi update | 只更新 Pi 自身 |
pi update --all | 更新 Pi 和所有包 |
pi update --extensions | 只更新包,不动 Pi 本体 |
pi update --extension <源> | 更新指定的某个包 |
pi config | 启用或禁用包里的各项资源 |
安全须知
安全是使用 Pi 前必须了解的部分。Pi 的安全模型和很多 Agent 工具不同,需要你主动配合。
没有内置沙箱
Pi 不包含内置沙箱,它以启动它的用户身份运行,拥有该用户的全部权限。
内置工具可以读写文件、运行 shell 命令;扩展是 TypeScript 模块,权限和 Pi 进程一样。
这是有意为之:Pi 要在本机源码上工作、调用项目工具链、融入开发环境,一个不完整的进程内沙箱会让人误以为是安全边界,实际却仍依赖宿主的 shell、文件系统和凭证。
重要:真正的隔离必须来自操作系统或容器/虚拟化边界,而不是 Pi 内部。
项目信任
项目信任决定 Pi 是否加载项目级的设置、资源、扩展和包。
当一个目录里存在 .pi/settings.json、.pi/extensions、.pi/skills、.pi/SYSTEM.md 等内容时,Pi 会要求先信任才能加载。
| 信任级别 | 行为 | 设置方式 |
|---|---|---|
ask(默认) | 交互式询问;非交互模式忽略项目资源 | settings.json 的 defaultProjectTrust |
always | 始终信任项目资源 | 同上,或用 -a / --approve |
never | 从不信任,忽略项目资源 | 同上,或用 -na / --no-approve |
信任决策保存在 ~/.pi/agent/trust.json,按目录路径记录,最近的父目录决策优先。
注意:项目信任只是「输入加载守卫」,它防止仓库静默改你的设置或扩展,但不能让不可信的代码、提示或模型输出变得安全。仓库文件、注释、文档里的提示注入是本地 Agent 固有的风险,Pi 无法可靠阻止。
处理不可信或无人值守的任务
对于不受信任的仓库、需要密切监控的生成代码、或无人值守的自动化,官方建议把 Pi 放进隔离环境里跑。
推荐做法:
- 把整个
pi进程放进容器、虚拟机或远程沙箱 - 只挂载 Agent 应该访问的工作区路径
- 除非必要,不要挂载宿主的
~/.pi/agent(里面有你的凭证和会话) - 只传最少必要的 API Key,或用短期凭证
- 任务不需要联网时,限制网络访问
- 把结果复制回可信系统前,先审查 diff 和输出
提醒:如果你把宿主工作区以读写方式挂载进容器,容器内的写入仍会改到宿主文件。要更强地防范误写,用只读挂载,或把文件复制进出沙箱。
资源与社区
官方资源
- GitHub 仓库:github.com/earendil-works/pi
- 官网:pi.dev
- 官方文档:pi.dev/docs/latest
- npm 包:@earendil-works/pi-coding-agent
