如何扩展 Pi Agent
你最近可能经常听到"Pi"——它最初驱动了 OpenClaw,可能是有史以来增长最快的智能体项目。
开箱即用的 Pi 刻意保持极简——只有四个工具:bash、read、write、edit。没有子智能体、没有团队、没有 MCP。其他一切都由你自己添加,通过让 Pi 成为 Pi 的那个核心系统:扩展(extensions)。
1、扩展系统
你可以自定义几乎所有东西:工具、钩子、模型提供商、会话管理、命令,以及终端 UI 本身。Pi 了解自己的扩展 API,因此你经常无需编写代码。告诉 Pi"把天气信息放到我的提示输入框里",它就会读取扩展文档,编写小部件,然后重新加载。
扩展是钩入运行时的 TypeScript 文件。Claude Code 也有钩子,所以区别在于覆盖面。Pi 通过三个对象暴露了几乎所有的接缝:
- pi.* 注册新能力:registerTool、registerCommand、registerShortcut、registerProvider(你自己的 LLM)、sendUserMessage、setActiveTools。
- pi.on(event) 响应整个生命周期:input、session_start、before_agent_start、tool_call、tool_result、context、before_provider_request、session_before_compact。
- ctx.* 访问活跃会话:ctx.ui、ctx.sessionManager、ctx.cwd、ctx.model。
同时,/reload 提供热重载,让你可以在使用智能体的同时重写它自己的运行时。
示例 - TUI 自定义: 我可以重新皮肤化我的 pi TUI——只需在 session_start 时调用一次 ctx.ui.setHeader(...)。或者在提示输入框上方添加天气信息
我重新皮肤化了 UI。我用《硅谷》中的 Jian Yang 的 ASCII 艺术替换了 Pi 内置的标题:眼镜、叼着的香烟、飘散的烟雾、随机引语。只需在 session_start 时调用一次 ctx.ui.setHeader(...)。虽然只是装饰,但终端 UI 像其他一切一样属于你。
示例 - 终端中的 DOOM: 你甚至可以在智能体工作时玩 DOOM。有人将其作为一个包发布在 pi.dev/packages/pi-doom,一个完整的 TUI 游戏挂载在你的编码会话中,太疯狂了。
真实示例 - pi-hypa: 将工具 token 减少 80~96%。@hypabolic/pi-hypa 直接钩入清理 bash 命令输出。
例如,如果 pi 运行 git log --stat -200,它会清理不必要的噪音,如 diff、subject、comments,只保留 commit,这通常可以减少 80~98%。它透明地拦截 Pi 的正常 bash 工具,因此智能体从未请求压缩,也从未看到 34k token 的噪音。
还有一个由其他人构建的 pi 扩展目录,你几乎可以找到任何 claude code 或 CodeX 的可用功能
pi-mcp-adapter pi-subagents
pi-chrome @narumitw/pi-plan-mode
@amaster.ai/pi-computer-use @juicesharp/rpiv-ask-user-question
@quintinshaw/pi-dynamic-workflows @juicesharp/rpiv-todo
@narumitw/pi-goal · pi-btw · pi-ask-user
1、如何构建扩展
构建 Pi 扩展实际上非常简单,以下是一些示例:
1)注入上下文。让智能体无需任何工具调用即可感知 Git:
pi.on("before_agent_start", (event, ctx) => {
return { systemPrompt: event.systemPrompt + "\n\n" + gitSummary() };
});
问"我在哪个分支?不使用任何工具",它已经知道了。
2)添加一个工具。让智能体读取你的剪贴板:
pi.registerTool({
name: "read_clipboard",
description: "Read what's currently in the clipboard",
execute: async () => ({ content: [{ type: "text", text: await clipboard.read() }] }),
});
通过这个,Pi 可以访问一个新工具 'read_clipboard'
3)权限门控
我在团队的共享智能体上运行这个,因为不是每个人都应该看到所有东西。在提示到达智能体之前,一个廉价的 Haiku 调用会根据 PERMISSION.md 策略对其进行分类,然后允许或拒绝:
import { complete } from "@earendil-works/pi-ai";
pi.on("input", async (event, ctx) => {
const policy = await readPolicy(ctx.cwd);
if (!policy) return { action: "continue" };
const { decision, reason } = await classify(ctx, policy, event.text); // Haiku
if (decision === "denied") {
ctx.ui.notify(`Blocked by PERMISSION.md: ${reason}`, "error");
return { action: "handled" }; // skip the agent entirely
}
return { action: "continue" };
});
我设置策略如"只有 Jason 可以查看收入数据",然后以其他人身份问"六月的收入是多少?"Pi 在它到达智能体之前就阻止了,并在 UI 中显示了原因。
2、使用 Pi SDK 构建真实的 AI 应用
大多数人忽略了 Pi 不仅仅是一个 CLI。它是五个包:pi-ai(调用任何模型,支持 Claude 和 Codex 订阅 OAuth)、pi-agent(核心循环)、pi-coding-agent(Claude Code SDK 等价物,包含工具、会话、压缩、扩展)、TUI 和编排器。整个智能体可以折叠成一个函数调用。
以下是大约 15 行的智能体,没有 UI:
import { createAgentSession, SessionManager } from "@earendil-works/pi-coding-agent";
const { session } = await createAgentSession({
sessionManager: SessionManager.inMemory(),
});
session.subscribe((event) => {
if (event.type === "message_update" && event.assistantMessageEvent.type === "text_delta") {
process.stdout.write(event.assistantMessageEvent.delta); // stream to your UI
}
});
await session.prompt("Look at the files here and tell me what this project is.");
运行 npx tsx 并观察它流式传输,使用你现有的 Pi 认证(你的 Claude 订阅,文件中没有 API 密钥)。将同一个会话包装在 WebSocket 中,你就有了一个托管的聊天智能体,每个浏览器标签页一个会话。
对于产品,你可以用资源加载器和自己的工具来限定每个会话:
const resourceLoader = new DefaultResourceLoader({
cwd, // where the agent WORKS (a per-user sandbox)
agentDir: getAgentDir(), // config/auth root, stays on the host
noExtensions: true, noSkills: true, // deny ambient pickup, allow only what you pass
extensionFactories: [guardrail], // policy as code (e.g. block dangerous bash)
});
await resourceLoader.reload();
const { session } = await createAgentSession({
sessionManager: SessionManager.inMemory(),
customTools: [getMrr], // your product's own capabilities
resourceLoader,
});
我正是用这个结构构建了 Posia,一个启动和运营业务的自主智能体。从本地转向 Web 托管只需一个调整:Pi 的默认设置假设本地文件系统,会话以 JSONL 形式存储,工具在宿主机上运行。
对于多租户后端,你可以运行 SessionManager.inMemory(),通过镜像 session.subscribe 将你自己的数据库作为真实数据源,并通过每个用户的沙箱重新代理 bash、read 和 write。
原文链接:Pi agent 101 - How to extend and build your own harness
汇智网翻译整理,转载请标明出处