Pi 的 JSON Event Stream 模式:用 `pi --mode json` 消费结构化 Agent 事件流
2026/9/12 5:08:17 网站建设 项目流程

Pi 的 JSON Event Stream 模式:用pi --mode json消费结构化 Agent 事件流

【免费下载链接】scientific-agent-skillsTurn any AI agent into an AI Scientist. The #1 Agent Skills library for science, used by 190,000+ scientists worldwide. 165 ready-to-use validated skills plus 100+ scientific databases covering biology, chemistry, medicine, and drug discovery. Compatible with Cursor, Claude Code, Codex, Pi, Antigravity, and the open Agent Skills standard.项目地址: https://gitcode.com/GitHub_Trending/cl/scientific-agent-skills

导读

本文围绕 Pi(一个极简终端编码代理工具,安装包为@earendil-works/pi-coding-agent)的JSON Event Stream 模式展开,讲解如何通过pi --mode json "prompt"让 Pi 以"一次性提示"方式运行,并将整个会话过程中产生的全部 Agent 事件以 JSON Lines(JSONL)形式输出到 stdout。读完本文,你将掌握 JSON 模式的适用场景、完整的事件类型体系(会话级事件与基础 Agent 事件)、线性的增量式输出格式(message_update的 delta-only 设计),以及如何用jq等标准命令行工具过滤、消费这些事件流。对于需要双向控制的场景,本文也会给出与 RPC 模式、SDK 的取舍建议。


一、JSON 模式是什么:一次性脚本管道的首选

Pi 提供四种运行模式,JSON 模式是其中专门为"一次性、单向、脚本化"场景设计的形态:

  • 交互模式(TUI)pi,面向日常对话;
  • 打印模式pi -p "prompt",打印结果后退出;
  • JSON Event Stream 模式pi --mode json "prompt",所有会话事件以 JSONL 逐行输出到 stdout;
  • RPC 模式pi --mode rpc,通过 stdin/stdout 的 JSONL 协议实现双向控制。

JSON 模式的定位在 SKILL.md 中有明确表述:"Prefer JSON mode for one-shot command-line pipelines that only need streamed events, not bidirectional control",即只适合一次性提示、只需要读取流式事件、不需要反向控制的命令行管道。它不具备 RPC 模式的双向通信能力——RPC 模式可以接收promptsteerabortbash等命令,而 JSON 模式只能"发一个提示,收一串事件"。

基本用法

pi --mode json "Your prompt"

一行命令即可把 Agent 会话的所有事件推送到 stdout。配合2>/dev/null丢弃日志、jq过滤事件类型,就能快速构建无侵入的 Agent 观测管道:

pi --mode json "List files" 2>/dev/null | jq -c 'select(.type == "message_end")'

这条命令是 json.md 中给出的典型示例:仅提取每条消息的最终结果(message_end),屏蔽掉中间的text_delta增量噪音。


二、输出格式:首行会话头 + 逐行事件流

JSON 模式的输出遵循严格的"首行头 + 事件流"结构。

会话头(session header)

输出流的第一行是会话元数据:

{"type":"session","version":3,"id":"uuid","timestamp":"...","cwd":"/path"}

该行对应会话文件的 header 条目(见 session-format.md):version为会话格式版本(当前为 3),id是会话 UUID,timestamp为创建时间,cwd为工作目录。注意 header 与后续事件不同——它没有id/parentId字段,仅承载元数据。

事件流示例

随后事件按发生顺序逐行输出,每行一个独立 JSON 对象:

{"type":"agent_start"} {"type":"turn_start"} {"type":"message_start","message":{"role":"assistant","content":[]}} {"type":"message_update","usage":{},"assistantMessageEvent":{"type":"text_delta","contentIndex":0,"delta":"Hello"}} {"type":"message_end","message":{}} {"type":"turn_end","message":{},"toolResults":[]} {"type":"agent_end","messages":[]}

一个典型的会话生命周期大致为:agent_startturn_startmessage_start→(若干message_update)→message_endturn_endagent_end。若 Agent 调用了工具,中间还会插入tool_execution_start/tool_execution_update/tool_execution_end事件。


三、事件类型全景:会话级事件 + 基础 Agent 事件

JSON 模式下的事件使用JsonAgentSessionEvent类型,它与 Pi 内部的AgentSessionEvent基本一致,唯一区别是流式消息更新(message_update)省略了累积快照

type WithoutPartial<T> = T extends { partial: unknown } ? Omit<T, "partial"> : T; type JsonAgentSessionEvent = | Exclude<AgentSessionEvent, { type: "message_update" }> | { type: "message_update"; usage: Usage; assistantMessageEvent: WithoutPartial<AssistantMessageEvent> };

AgentSessionEvent是基础AgentEvent与会话级事件的并集。

会话级事件

事件类型载荷
queue_update{ steering: readonly string[], followUp: readonly string[] },只要任一队列发生变化即触发
compaction_start{ reason: "manual" \| "threshold" \| "overflow" }
compaction_end{ reason, result: CompactionResult \| undefined, aborted, willRetry, errorMessage? }
auto_retry_start{ attempt, maxAttempts, delayMs, errorMessage }
auto_retry_end{ success, attempt, finalError? }
summarization_retry_scheduled{ attempt, maxAttempts, delayMs, errorMessage }
summarization_retry_attempt_start{ source: "branchSummary" }{ source: "compaction", reason }
summarization_retry_finished无额外载荷

其中compaction_startreason三值与 compaction.md 中的触发机制一一对应:manual/compact手动触发)、threshold(上下文超阈值自动压缩)、overflow(溢出恢复)。compaction_endwillRetry为 true 表示溢出压缩成功后会自动重试原提示词。

基础 Agent 事件

  • agent_startagent_end(后者携带messages);
  • turn_startturn_end(后者携带messagetoolResults);
  • message_start(携带message)、message_update(携带usageassistantMessageEvent)、message_end(携带message);
  • tool_execution_start(携带toolCallIdtoolNameargs)、tool_execution_update(在前者基础上增加partialResult)、tool_execution_end(携带resultisError)。

需要说明:RPC 模式下的完整事件清单还包含agent_settledbash_execution_updateextension_error等(见 rpc.md),且 RPC 的message_update同样采用 delta-only 设计——这一设计在 JSON 模式下被严格化:JSON 模式的JsonAgentSessionEvent直接通过类型层面剔除了partial字段。


四、核心设计:为什么message_update是 delta-only

JSON 模式最值得理解的设计决策是message_update记录的增量(delta)性质

  1. 省略累积message字段:常规事件流中message_update会携带当前累积的完整消息对象,JSON 模式将其省略;
  2. 省略assistantMessageEvent.partial:增量事件本身不再包含累积的 partial 快照。

这样做的直接收益是流大小保持线性——无论生成多长的回复,每个增量记录只携带新增的一小段文本,而不是反复传输越来越大的累积快照。

组装实时文本的规则

由于累积快照被省略,消费方需要自己"拼装"实时内容:

  • 通过assistantMessageEvent中的contentIndex定位内容块(文本、思考内容或工具调用参数各有独立的内容块索引);
  • 通过delta字段累积增量文本;
  • 对于工具调用,需要缓存toolcall_delta.delta,因为只有toolcall_end.toolCall才持有完整调用(RPC 文档对此有同样的说明,见 rpc.md);
  • 最终以message_end中携带的message作为权威的最终消息

usage 字段的语义

message_update顶层的usage字段携带最新一次累积的、由供应商上报的用量。它有一个值得注意的边界:当供应商只在生成完成时才上报用量时,中间过程的usage可能一直是 0。因此不要依赖流式过程中的 usage 数值做实时统计,应等待message_end或会话结束后的权威数据。

Usage对象的结构在 session-format.md 中有精确定义:包含inputoutputcacheReadcacheWritetotalTokens,以及同样含四字段加totalcost


五、与 RPC 模式的分工:何时不用 JSON 模式

json.md 文档结尾给出了明确的边界:"For bidirectional control, use RPC instead of JSON mode."

二者的定位对比如下:

维度JSON 模式RPC 模式
命令pi --mode json "prompt"pi --mode rpc
方向单向(一次提示 → 事件流)双向(stdin 发命令,stdout 收事件)
典型场景一次性脚本管道、日志观测IDE 集成、自定义 UI、跨语言客户端
增量事件delta-only(无partial同样 delta-only
会话持久化默认与普通会话一致可用--no-session实现无状态子进程

在 SKILL.md 的"Build-On-Pi Defaults"中给出了更细的三级选择建议:

  • Node/TypeScript 进程内应用(需要类型安全、直接状态访问、自定义工具/扩展)→ 首选SDKcreateAgentSession()/createAgentSessionRuntime());
  • 非 Node.js 客户端或需要进程隔离→ 首选RPCpi --mode rpc --no-session起步,按需加会话标志);
  • 一次性命令行管道、只需要流式事件→ 首选JSON 模式

此外,JSON 模式与打印模式(pi -p)都适用于"跑一次拿结果"的场景,但 JSON 模式额外提供完整的事件级可观测性——你可以看到思考增量、工具调用过程、token 用量与压缩事件,而打印模式只给你最终文本。


六、实战:用 jq 消费 JSON 事件流

结合上述事件结构,可以构建若干高价值的消费管道。

只取助手最终消息

pi --mode json "List files" 2>/dev/null | jq -c 'select(.type == "message_end")'

message_endmessage字段是权威的最终消息(含文本、思考与工具调用块),适合作为"结果抽取"的入口。

监控工具调用序列

pi --mode json "Refactor this file" 2>/dev/null \ | jq -c 'select(.type == "tool_execution_start") | {tool: .toolName, args: .args}'

tool_execution_start携带toolCallIdtoolNameargs,可按toolCallId关联tool_execution_endresultisError,从而重建完整的工具调用闭环。

观测压缩与重试

pi --mode json "Process a large codebase" 2>/dev/null \ | jq -c 'select(.type | startswith("compaction") or startswith("auto_retry") or startswith("summarization_retry"))'

上下文超限触发压缩、溢出重试等生命周期事件(compaction_start/endauto_retry_start/endsummarization_retry_*)均可在此过滤下可见,便于评估长会话的上下文管理行为。

实时输出流式文本

利用 delta-only 设计,可以用jq把流式增量拼成实时文本:

pi --mode json "Write a haiku" 2>/dev/null \ | jq -r 'select(.type == "message_update" and .assistantMessageEvent.type == "text_delta") | .assistantMessageEvent.delta'

contentIndex+delta拼装即可;工具调用参数与思考内容同理,分别消费toolcall_deltathinking_delta增量。


七、补充:事件与会话格式的一致性

JSON 模式输出的事件结构与 Pi 的会话持久化格式同源。会话文件本身也是 JSONL(存储于~/.pi/agent/sessions/--<path>--/<timestamp>_<uuid>.jsonl),其中的消息类型与事件体系一一对应:

  • UserMessagerole: "user")、AssistantMessagecontent含 text/thinking/toolCall 块,stopReasonstop/length/toolUse/error/aborted)、ToolResultMessage(含isError)、BashExecutionMessageCustomMessage等七种消息共同构成AgentMessage联合类型;
  • 会话条目类型(sessionmessagemodel_changecompactioncustom等)通过id/parentId构成树结构。

理解这层同源性有两个实践价值:

  1. 事件语义即持久化语义:JSON 模式里看到的compaction_end.reasonmessage_end.message.stopReason,与落盘会话文件中对应条目的字段完全一致;
  2. 结果可跨模式续接:JSON 模式跑完的事件流,其最终message_endagent_end.messages中携带的消息对象,可直接对应到会话文件中的持久化消息,方便后续用/resume--session无缝续接。

更完整的会话文件格式、SessionManagerAPI 与解析建议(逐行读取、按entry.type分派、忽略未知类型以兼容未来版本)参见 session-format.md。


结语

pi --mode json是 Pi 四种运行模式中最适合脚本化消费的一种:它以"首行会话头 + 逐行 JSONL 事件流"的线性格式,把 Agent 的思考、文本生成、工具调用、上下文压缩与重试等全生命周期暴露为标准事件,并通过 delta-only 的message_update设计保证了流体积随生成长度线性增长。结合jq即可搭建轻量的 Agent 观测、结果抽取与自动化管道;一旦需求升级为双向控制(如流式打断、中途注入指令、执行 bash),则应迁移到 RPC 模式(见 rpc.md),进程内 Node/TypeScript 应用则优先考虑 SDK。

【免费下载链接】scientific-agent-skillsTurn any AI agent into an AI Scientist. The #1 Agent Skills library for science, used by 190,000+ scientists worldwide. 165 ready-to-use validated skills plus 100+ scientific databases covering biology, chemistry, medicine, and drug discovery. Compatible with Cursor, Claude Code, Codex, Pi, Antigravity, and the open Agent Skills standard.项目地址: https://gitcode.com/GitHub_Trending/cl/scientific-agent-skills

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询