ARTICLE · 1241082
终端里的 Pi, 怎样变成自己的 AI 工具?
用 Pi 时,大多数人的操作是:打开终端,进入项目,输入需求,等它执行。
但如果你每次都做同一件事,例如审查暂存区、整理变更说明、分析错误日志,就不一定需要反复打开聊天界面、手动输入要求。
你可以把 Pi 接进脚本,也可以给它做一个网页入口,甚至嵌入自己的程序。
Pi 官方提供了 Print、JSON、RPC,以及 TypeScript SDK 等接入方式。
它们复用 Agent 的执行能力,区别主要在于:谁来提交任务、怎样获取结果,以及是否需要持续控制会话。

01先做一个能用的脚本
假设你经常让 Pi 审查暂存区。
平时需要打开 Pi,说明审查范围,再补充“不要修改文件”“只报告有依据的问题”。
这套操作可以先变成一条命令:
SHELL
gitdiff--cached |pi--print\--no-session\--no-tools\--no-extensions\"审查输入中的 diff。 只报告有明确依据的问题。 说明触发条件、影响和代码位置。 无法确认的内容单独列出。"这里关闭工具和自动加载的扩展,只分析传入的 diff。
它能检查局部问题,但缺少完整项目上下文,报告也应保留这个限制。
Print 模式会输出最终回复,然后退出。你可以把结果保存为报告,也可以让其他脚本继续处理。
到这一步,Pi 已经成为工作流中的一个组件:
Git 提供变更
↓
脚本提交任务
↓
Pi 返回审查意见
模型和认证需要提前配置好。具体参数以本机 pi --help 为准。
02要看执行过程,就接事件流
当任务需要读取项目、调用工具时,只拿最后的报告可能不够。
你还想知道它正在检查什么、哪个工具失败了、有没有反复重试。
这时可以使用 JSON 模式:
SHELL
pi--modejson\"检查当前项目的鉴权实现, 列出相关文件和调用关系"\>events.jsonl一个容易误解的地方是:
JSON 模式输出的是执行事件流,不是保证模型最终回答符合某个 JSON Schema。
你的程序可以从事件中提取文本、工具活动和错误,再做成进度展示。
如果业务要求报告必须包含这些字段:
FIELDS
file 文件路径line 问题行号severity 严重程度还需要另外约束输出并校验。
拿到结构化事件,只解决了“程序怎样观察执行”,没有自动解决“审查结论是否正确”。
03做自己的界面,用 RPC 控制 Pi
一次性脚本能完成不少工作。
但要做一个持续使用的界面,就会有新的需求:
任务执行中允许取消;
用户可以补充要求;
完成后能够继续追问;
切换项目时管理会话。
RPC 模式让 Pi 作为长期运行的子进程,由你的程序通过标准输入、输出与它通信:
SHELL
pi--moderpc--no-session程序向它发送请求。为方便阅读,下面将请求结构展开:
JSON
{"id": "review-1","type": "prompt","message": "审查当前项目的登录流程"}实际传输采用 JSONL:每条请求序列化成一行,以换行符结束。
随后,程序持续读取回复与执行事件,展示在自己的界面中。
这里有个值得提前处理的细节:
命令返回成功,只代表请求被接受或处理,不代表模型已经完成任务。
客户端需要继续消费事件。按照当前协议,需要判断本轮自动工作结束时,应关注 agent_settled。
同时,还要处理进程异常退出、超时和取消。
也就是说,RPC 给了你控制接口,界面的状态管理仍然由你负责。

三种接入方式,复用 Pi 的执行能力。
04程序本身用 TypeScript,可以直接嵌入 SDK
如果宿主程序使用 Node.js 或 Bun,可以通过 SDK 在进程内创建 Pi 会话,直接提交任务、订阅事件和获取结果。
下面是一个接口示例:从标准输入接收 diff,同时允许读取项目文件补充上下文。
TYPESCRIPT
import { readFileSync } from"node:fs";import {createAgentSession,SessionManager,} from"@earendil-works/pi-coding-agent";constdiff=readFileSync(0, "utf8");if (!diff.trim()) {thrownewError("没有待审查的 diff");}const { session } =awaitcreateAgentSession({cwd:process.cwd(),tools: ["read","grep","find","ls", ],sessionManager:SessionManager.inMemory(), });consttask= ["审查下面的 diff。","可读取项目文件核实上下文。","只报告有明确触发条件和影响的问题。","不要修改文件。","不确定的内容单独说明。",diff,].join("\n\n");try {awaitsession.prompt(task);constreport=session.getLastAssistantText();console.log(report);} finally {session.dispose();}SDK 接入后,可以进一步订阅工具执行、文本更新等事件,把过程展示出来。
不过,SDK 默认也会使用配置和发现的资源。做成共享服务前,需要明确控制资源加载、工作区、凭证和执行权限。
工具选择不能代替文件系统隔离。
05几种接入方式,怎么选?
Print:只需要最终结果
适合脚本运行一次,获取报告、摘要或变更说明。
JSON:需要观察执行过程
适合一次任务中,记录文本更新、工具活动和执行状态。
RPC:需要持续交互
适合自己的界面,由其他进程发送任务、读取事件、管理会话。
SDK:需要嵌入程序
适合在 Node.js 或 Bun 中直接管理 Agent,使用 TypeScript 方法与事件接口。
不必一开始就做完整客户端。
一个固定范围、固定要求、结果方便检查的脚本,往往就能省下重复操作。
等到确实需要进度展示、继续追问或会话管理,再增加界面。
真正值得做的定制,是把你反复处理的工作整理清楚:
输入从哪里来?允许操作什么?什么结果需要人工检查?
Pi 负责执行,你的工具负责把这些要求变成一条可重复使用的流程。















































































