PI Agent 技术文档
PI Agent 技术文档
概述
PI Agent(Pi Coding Agent)是由 Earendil Inc. 开发的开源 AI 编码智能体工具包,官网为pi.dev,源码托管在 GitHub(earendil-works/pi),采用 MIT 许可证。它是一个极简的终端编码智能体框架(agent harness),核心理念是”小而可扩展”——保持核心尽可能精简,通过 TypeScript 扩展、技能、提示模板、主题和 Pi 包来实现功能定制。
项目架构
PI Agent 采用 npm workspaces 管理的 monorepo 结构,包含以下四个核心包`@earendil-works/pi-ai` ,`@earendil-works/pi-agent-core`,`@earendil-works/pi-coding-agent`,`@earendil-works/pi-tui`
此外,Slack/聊天自动化相关代码托管在独立仓库 earendil-works/pi-chat,会话存储后端使用独立的 packages/session-backend-sqlite(基于 SQLite,含迁移系统)。
核心功能
1. 多模型支持
PI Agent 支持 15 个以上的 LLM 提供商,包括 Anthropic、OpenAI、Google、Azure、Bedrock、Mistral、Groq、Cerebras、xAI、Hugging Face、Kimi For Coding、MiniMax、NVIDIA、OpenRouter、Ollama 等。认证方式支持 API 密钥和 OAuth,支持在会话中通过 /model 或 Ctrl+L 切换模型,通过 Ctrl+P 循环切换常用模型。
2. 会话管理
会话以树形结构存储,支持分支、回溯和合并。通过 /tree 命令可以导航到任意历史节点继续对话,所有分支存储在单一文件中。支持导出为 HTML(/export)或上传到 GitHub Gist 生成可分享链接(/share)。
3. 上下文工程(Context Engineering)
– **AGENTS.md**:项目指令文件,从 `~/.pi/agent/`、父目录和当前目录自动加载
– **SYSTEM.md**:可按项目替换或追加系统提示
– **Compaction(上下文压缩)**:接近上下文窗口上限时自动压缩旧消息,支持自定义压缩策略
– **Skills(技能)**:按需加载的能力包,渐进式披露,不占用提示缓存
– **Prompt Templates(提示模板)**:可复用的 Markdown 文件,通过斜杠命令展开
– **Dynamic Context(动态上下文)**:扩展可以在每轮前注入消息、过滤历史记录、实现 RAG 或长期记忆
4. 扩展系统
扩展是访问工具、命令、键盘快捷键、事件和完整 TUI 的 TypeScript 模块。项目内置 50+ 个扩展示例,包括:
-
子智能体(sub-agent) -
计划模式(plan mode) -
权限门控(permission gate) -
SSH 执行 -
沙箱隔离 -
MCP 集成 -
自定义编辑器、状态栏、覆盖层
5. 四种运行模式
| 模式 | 说明 |
|——|——|
| **Interactive(交互模式)** | 完整的终端 TUI 体验 |
| **Print/JSON** | `pi -p “query”` 用于脚本,`–mode json` 输出事件流 |
| **RPC** | 通过 stdin/stdout 的 JSON 协议,用于非 Node.js 集成 |
| **SDK** | 以库方式嵌入应用程序 |
6. 安全与隔离
PI Agent 默认不以权限限制运行,而是提供多种容器化方案:
– **Gondolin 扩展**:保留认证信息,将工具路由到本地 Linux 微虚拟机
– **Plain Docker**:在容器中运行完整 PI 进程
– **OpenShell**:在策略控制的沙箱中运行
7. 供应链安全
项目对 npm 依赖采用严格审查策略:精确版本锁定、依赖锁定文件校验、CI 自动安全审计、生命周期脚本白名单等。
API 接口与编程集成
SDK 核心 API
import { createAgentSession, ModelRuntime, SessionManager } from ”@earendil-works/pi-coding-agent”;import { getModel } from ”@earendil-works/pi-ai”;// 配置模型运行时const modelRuntime = await ModelRuntime.create();// 创建会话const { session } = await createAgentSession({model: getModel(”anthropic”, ”claude-opus-4-5”),modelRuntime,sessionManager: SessionManager.inMemory(),});
// 基本提示await session.prompt(”What files are in the current directory?”);// 带图片await session.prompt(”What's in this image?”, {images: [{ type: ”image”, source: { type: ”base64”, mediaType: ”image/png”, data: ”...” } }]});// 流式期间发送队列消息await session.steer(”Stop and do this instead”); // 打断剩余工具await session.followUp(”After you're done, also check X”); // 完成后追加
session.subscribe((event) => {switch (event.type) {case ”message_update”:// 助手流式输出break;case ”tool_execution_start”:console.log(`Tool: ${event.toolName}`);break;case ”agent_end”:console.log(”Agent finished”, event.messages);break;}});
// 访问当前对话状态const state = session.agent.state;console.log(state.messages); // 对话历史console.log(state.model); // 当前模型console.log(state.tools); // 可用工具// 等待 Agent 处理完毕await session.agent.waitForIdle();
会话管理 API
// 内存会话(不持久化)const { session } = await createAgentSession({sessionManager: SessionManager.inMemory(),});// 持久化会话const { session } = await createAgentSession({sessionManager: SessionManager.create(process.cwd()),});// 继续最近会话const { session } = await createAgentSession({sessionManager: SessionManager.continueRecent(process.cwd()),});// 列出会话const sessions = await SessionManager.list(process.cwd());// 树导航const result = await session.navigateTree(targetId);
自定义工具
import { defineTool } from ”@earendil-works/pi-coding-agent”;import { Type } from ”typebox”;const statusTool = defineTool({name: ”status”,label: ”Status”,description: ”Get system status”,parameters: Type.Object({}),execute: async () => ({content: [{ type: ”text”, text: `Uptime: ${process.uptime()}s` }],details: {},}),});
扩展系统
import { DefaultResourceLoader, createEventBus } from ”@earendil-works/pi-coding-agent”;const loader = new DefaultResourceLoader({cwd: process.cwd(),extensionFactories: [{name: ”my-extension”,factory: (pi) => {pi.on(”agent_start”, () => console.log(”Agent starting”));pi.registerTool(myTool);},},],});await loader.reload();
RPC 模式
# 作为子进程运行pi --mode rpc --no-session
通过 stdin/stdout 的 JSONL 协议与 PI Agent 通信,适合从 Python、Go 等其他语言集成。
资源加载机制
DefaultResourceLoader 负责发现和管理扩展、技能、提示、主题和上下文文件:
– **全局路径**:`~/.pi/agent/`
– **项目路径**:`.pi/`(当前工作目录下)
– **扩展发现**:`~/.pi/agent/extensions/` 和 `.pi/extensions/`
支持通过 agentsFilesOverride、skillsOverride、promptsOverride 等钩子进行程序化定制。
安装与使用
# npm 全局安装npm install -g --ignore-scripts @earendil-works/pi-coding-agent# 或通过安装脚本curl -fsSL https://pi.dev/install.sh | sh# 在项目中运行pi
设计哲学
PI Agent 的核心设计理念是“Primitives, not Features”——它不提供内置的子智能体、权限弹窗、计划模式或后台 Bash,因为这些功能可以通过扩展系统构建。这种设计让核心保持极简,同时给予用户完全的控制权来定制符合自己工作流的行为。
项目作者总结道:”Change the harness, not your workflow.”——如果需要某个命令、工具、提供商或 UI 调整,直接让 PI 自己构建并定制。
社区与生态
– **文档**:[pi.dev/docs/latest](https://pi.dev/docs/latest)
– **社区包市场**:[pi.dev/packages](https://pi.dev/packages)
– **Discord 社区**:[discord.gg/3cU7B4UPx](https://discord.com/invite/3cU7B4UPx)
– **GitHub Issues**:[earendil-works/pi/issues](https://github.com/earendil-works/pi/issues)
– **会话共享**:通过 `pi-share-hf` 工具将会话上传到 Hugging Face
– **RFC 规划**:[rfc.earendil.com](https://rfc.earendil.com/keyword/pi/)
本文档基于 PI Agent 官方文档和 GitHub 仓库信息编写,信息更新至 2026 年 7 月。
夜雨聆风