夜雨聆风学习资料网

ARTICLE · 1241082

终端里的 Pi, 怎样变成自己的 AI 工具?

终端里的 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 负责执行,你的工具负责把这些要求变成一条可重复使用的流程。

相关学习资料