Pi,最小化编码代理工具:扩展功能、技能、会话与安全性
为何一个配备四种工具且系统提示简短的小型终端编码工具能胜过那些功能繁杂的代理:安装、模型、会话树、扩展、技能以及沙箱环境。
像 Claude Code、Cursor 和 OpenCode 这样的终端编码工具已成为许多开发者日常工作中的常规部分,尤其是自 OpenAI 在 4 月将 Codex CLI 开源之后。Pi 是一款刻意设计得较为简洁的编码工具,它的诞生源于对这类工具的诸多不满:这些工具的功能总是在不断变化。
这种不满并非源于漏洞,而是这些工具本身在变化,随之模型行为也会改变。工程师们需要能够依赖的工具。虽然大语言模型本身并不可靠,但至少其周围的组件——包括工具、系统提示以及注入其中的所有内容——都可以做到确定性。
Claude Code和Codex会在后台为系统添加大量上下文信息,但界面上并不会显示这些内容,而这些隐藏的添加项会以细微的方式干扰工作流程。更新频率为每天一次,甚至一天多次。原本在早上九点还能顺畅运行的工作流程,到了十点就可能出问题,而到三点时又会表现得完全不同,尽管模型本身没有变化,只是使用的工具不同而已。几乎每个月都会有新功能推出,包括MCP、子代理、计划模式和后台执行等功能,越来越难以追踪后台到底发生了什么。
Pi的解决方案是一条设计原则:如果不需要,就不去实现。现有的工具会在用户看不见的地方注入上下文信息,用户因此无法了解实际情况。这就是这样的设计理念的由来。
极简主义的设计灵感何在
在开发Pi之前,其创造者Mario Zechner查看了Terminal Bench的排行榜,发现一个名为Terminus的编程框架格外突出。该框架仅为模型提供一种工具,即与tmux会话的接口。大型语言模型通过发送单个按键,并读取tmux返回的ANSI输出来完成任务。仅凭这一点,它几乎总能进入前三名,且常常夺得第一名。
这揭示了一个有用的直觉:如今的模型大多通过强化学习进行训练,因此它们已经了解什么是编程框架,无需再添加太多复杂功能。Pi正是将这一理念体现为一种极简却又可扩展的框架。
Pi的独特之处
Pi的独特之处在于它省略了其他编码工具视为标准的那些功能。以MCP为例:连接服务器后,每个会话开始时所有工具定义都会涌入上下文。而CLI工具则配有README文件,这些文件仅在需要时才会被读取和执行,因此没有理由持续占用上下文资源。
它拥有而其他工具所缺乏的特质
Pi是通过剔除不必要的功能来设计的,但它却具备Claude Code所没有的能力。扩展和包只需几条命令即可安装:
pi install npm:@foo/pi-tools
pi install git:github.com/user/repo
pi config # Enable or disable
扩展机制
扩展功能是基于从Pi包导入的API编写的:
import { ExtensionAPI } from "@mariozechner/pi-coding-agent";
扩展程序可以拦截诸如工具调用之类的事件。其中一个示例用于防止危险的shell命令:
export default function (pi: ExtensionAPI) {
pi.on("tool_call", async (event, ctx) => {
if (event.toolName === "bash"
&& event.input.command.includes("rm -rf")) {
const ok = await ctx.ui.confirm(
"Dangerous!", "Allow rm -rf?"
);
if (!ok) return { block: true, reason: "Blocked" };
}
});
}
1. 安装
安装只需一条命令:
npm install -g --ignore-scripts @earendil-works/pi-coding-agent
安装脚本也是一种选择:
curl -fsSL https://pi.dev/install.sh | sh
存在两种认证方式。一种使用 API 密钥:
# Use an API key
export ANTHROPIC_API_KEY=sk-ant-...
pi
另一种方式是重用您已有的订阅:
# Use an existing subscription
pi
/login # Select a provider
通过 /login,现有的订阅服务如 Anthropic Claude Pro 或 Max、OpenAI ChatGPT Plus 或 Pro(Codex)以及 GitHub Copilot 都可以直接使用。学习门槛极低:安装后即可开始与之对话,它就能正常工作。
2. 模型设置
Pi 支持超过 15 家大型语言模型提供商,主要包括:
- Anthropic
- OpenAI
- Google Gemini / Vertex
- DeepSeek
- xAI
- OpenRouter
- Amazon Bedrock
- Azure OpenAI
- Groq / Cerebras / Mistral など
在会话进行过程中切换模型是完全正常的:
/model # Model selection screen
Ctrl+L # Same as above
Shift+Tab # Switch thinking level (off–max)
可以在 ~/.pi/agent/models.json 中添加自定义提供者。任何与 OpenAI、Anthropic 或 Google 兼容的 API 只需通过配置即可使用,而 llama.cpp 等路由服务器则可用于加载本地模型。“无需绑定特定提供者”是 Pi 强调最多的优势之一。
3. 会话管理
会话以树形结构的 JSONL 文件形式存储在 ~/.pi/agent/sessions/ 目录下,每条消息都包含 id 和 parentId 字段。由于这种结构,单个文件即可支持所有相关操作:
pi -c # Continue the most recent session
pi -r # Select from previous sessions
/tree命令尤其有趣。你可以回到对话中的任意节点,然后从那里继续展开讨论。所有的对话历史都保存在同一个文件中,因此很容易说“我想回到半小时前的讨论状态”,然后真正实现这一操作。
/compact命令会汇总旧消息以压缩上下文信息。自动压缩功能默认处于开启状态,一旦上下文容量超出限制,它会自动恢复并重新尝试。
4. 详细解析扩展功能
在这里,Pi展现出了它真正的价值。自定义功能共有四层:
Extensions (TypeScript) → Tools, commands, UI, and event handling
Skills → Procedures/instructions written in Markdown
Prompt Templates → Reusable prompts
Themes → Display themes
来自 npm 或 git 的包是这样管理的:
pi install npm:@foo/pi-tools
pi install git:github.com/user/repo
pi list
pi update --all
扩展程序可以实现以下所有功能:
- 添加自定义工具,包括内置工具的替代品。
- 创建自定义子代理和计划模式。
- 实施权限控制与路径保护。
- 添加状态行、页眉和页脚等界面元素。
- 设置git检查点或自动提交功能。
- 集成MCP服务器。
- 如果愿意,还可以在等待时运行Doom游戏。
核心理念是:产品中其他所有功能,包括子代理、计划模式以及权限弹窗,都可以通过扩展程序来实现。因此其设计思路是保持核心部分尽可能简洁。
5. 技能
技能是以Markdown格式编写的功能包。遵循Agent Skills标准,包含一个SKILL.md文件的文件夹即构成一个技能。
<!-- ~/.pi/agent/skills/my-skill/SKILL.md -->
# My Skill
Use this skill when a user asks about X.
```
```text ## Steps 1. Perform this action. 2. Then perform that action. ```
可以通过 /skill:name 显式调用某个技能,当任务适合时,智能体也会自行加载它。关键的设计思路是让技能仅在需要时才进入上下文。与其将所有内容都塞进系统提示词中,不如在实际使用时再加载这些技能,这样系统提示词的长度就能保持在大约一千个标记左右。
6. Pi Web,浏览器界面
还有一个名为 Pi Web 的浏览器界面:
npx @agegr/pi-web@latest
其主要功能包括:
- 会话工作区,可按项目列出、恢复、重命名及删除过往对话。
- 两种分支方式:从某条消息开始新会话,或在当前会话中创建分支。
- 项目文件查看及 Git 差异显示功能。
- Git 工作树切换功能。
- 可在浏览器中设置提供者登录信息、模型、包及技能参数。
由于它与终端版本共享 ~/.pi/agent 设置及会话文件,因此在浏览器与终端之间切换十分便捷。
7. 内存
内存相关机制其实很简单。其设计理念是 Pi 并不需要独立的长期记忆数据库,而是采用了三种机制来实现相应功能:
1. The session itself is memory
The entire history is saved as JSONL and can be resumed at any time.
2. AGENTS.md / CLAUDE.md
Write project conventions, instructions, and commands in these files.
They are loaded at startup from global settings and the directory hierarchy.
3. Compaction
Long sessions are compressed by summarizing older parts.
However, the complete history remains in JSONL, so you can go back with /tree.
换句话说,已执行的操作会保存在会话中,而需要牢记的内容则保存在AGENTS.md文件中。通过扩展程序添加内存也是一种常见的衍生应用场景。
8. 确保安全
Pi没有内置的沙箱机制。读取、写入、编辑以及bash命令操作均以启动它的用户的权限来执行,扩展程序也是如此。这是有意为之——仅靠半成品的进程内沙箱只能提供看似安全的边界,因此官方立场是将真正的隔离功能交给操作系统以及容器或虚拟机层。不可信的代码库以及无人监控的运行过程应当放在隔离环境中。
一种方法是将整个Pi环境放入Docker中,这是最简单的方式:
# 1. Put the entire pi environment in Docker (simplest)
另一种方法是在主机上运行 Pi,仅将工具执行任务路由到本地的微型虚拟机:
# 2. Run pi on the host and route only tool execution
# to a local micro-VM (Gondolin)
pi -e ~/.pi/agent/extensions/gondolin
名为“项目信任”的功能添加了输入保护机制。它能防止仓库悄悄覆盖 Pi 的设置或扩展程序,且默认会对未经验证的项目要求确认。不过它无法完全防止命令注入,因此在处理不熟悉的代码或文档时需牢记这一点。
9. 编写自己的扩展程序
最简单的扩展程序仅由一个 TypeScript 文件构成。该文件用于注册一个工具:
export default function (pi: ExtensionAPI) {
pi.registerTool({
name: "deploy",
// Tool definition (input schema, execution logic)
});
它还可以添加命令或拦截工具调用:
pi.registerCommand("stats", {
// Custom command definition }); pi.on("tool_call", async (event, ctx) => {
// Intercept tool calls and process them
}); }
将文件放入所有项目的 ~/.pi/agent/extensions/ 目录,或单个项目的 .pi/extensions/ 目录,这样在 Pi 启动时它就会自动加载。如需临时测试,可使用 pi -e ./my-ext.ts。官方仓库中有大量示例:自动提交、git 检查点、MCP 集成以及自定义压缩功能。在 Pi 上,缺少某些功能是意料之中的事,通常的做法是自己添加或安装相关包。
Pi 给我们的启示
对于那些正在构建自己智能体的人来说,Pi 的设计决策能提供有价值的参考。不必选择功能齐全的包,先从四个工具和约一千个标记的系统提示语开始,再根据需求逐步添加其他功能。设计时应先考虑要删除什么,而非要添加什么。
相关阅读
- 代理工具架的五层结构及缺少它们时代码会如何出错——详细介绍了代理工具架在代码中执行规则的五个层面,从执行边界到上下文处理流程,以及相关研究能够证明和无法证明的内容。
- 实用指南:构建私有云编码代理——OpenCode与本地大语言模型的结合——提供了构建私有云编码代理的完整操作指南,包括合同规范、检查项以及供团队直接使用的代码模板。