Pi Agent Core 更像一个 Agent Runtime
看 Pi Agent Core 的时候,最大的感受不是“这个库能调工具”,而是它把 Agent 当成了一种运行时。
这个差别看起来像措辞问题,实际上差很多。
如果你把 Agent 只当成“外面包一层 Prompt 的 LLM”,那你最关心的是模型接口和工具调用。如果你把它当成运行时,你会开始问另一组问题:
- 上下文怎么整理
- 中途能不能插控制消息
- 工具前后能不能挂逻辑
- 任务断了以后怎么继续
- UI 怎么知道它现在卡在哪
Pi Agent Core 比较有价值的地方,就是它开始认真回答这些问题。
它不是聊天封装,它在管理状态
Pi 里有一个很重要的选择:内部一直保留自己的消息模型,真正调模型之前才转成 provider 需要的格式。
这意味着系统内部不必一开始就被某个模型接口绑住。你可以在内部保留更丰富的状态:
- 用户消息
- 工具调用
- 工具结果
- 流式输出
- 中间控制信息
这件事听起来像实现细节,其实影响很大。越晚做 provider 适配,内部就越自由,运行时能力也越容易长出来。
它把上下文处理放到了前面
它把上下文处理单独拎出来,而不是和模型适配混在一起,这一点很重要。
这两件事常常被一锅炖:
- 一边裁剪历史
- 一边改 role
- 一边做摘要
- 一边适配 provider 协议
最后你很难说清楚某一步到底是在“治理上下文”,还是在“迎合模型接口”。
Pi 把这两类事情拆开以后,职责就顺了:
- 先处理内部上下文
- 再转成模型能吃的格式
这对长对话和复杂工具链都很重要。上下文治理一旦是临时拼上的,后面会越来越难改。
它的循环不是只会一直 call LLM
Pi 的 loop 设计也很像运行时,而不是单纯的对话封装。它不是机械地“调模型 -> 调工具 -> 再调模型”,而是把运行过程看成一个带控制面的循环。
这里最关键的是两种队列:
steeringfollowUp
steering 适合处理中途纠偏。任务还在跑,但你发现方向不对了,要马上插一条控制消息,让下一轮转过去。
followUp 适合处理尾部追加。当前任务本来快收了,你又补一句“顺手把这个也做掉”,那它更像下一轮的开始。
这两个队列一分开,很多事情就讲得通了。系统不是简单地“支持插话”,而是知道不同的插话该进哪个控制口。
它把“能继续跑”当成默认能力
现在看 Agent 系统,特别在意 continuation。
很多 Demo 只证明一件事:它能跑起来。实际项目里,更常见的问题是它跑一半断了,或者页面关了,或者工具超时了,或者下一轮还想接着刚才的状态继续干。
Pi 在设计上有一个很好的倾向:它考虑的是怎么接着跑,而不是每次都从头来。
这会直接改变系统气质。
只能从头开始的 Agent,更像一个智能脚本。能恢复、能续跑、能保留中间状态的 Agent,才更像任务系统。
工具前后留 Hook,这件事比看起来重要
Pi 在工具执行前后都预留了 Hook。这个做法很合理。
因为真实业务里,工具调用往往不是裸执行。你会想在前后加很多东西:
- 参数校验
- 权限判断
- 审计
- 风险拦截
- 返回值清洗
- 观测埋点
如果系统没有这些接口,最后所有业务逻辑都会被塞进工具本身,代码会很快粘成一团。
Hook 的意义不是“可扩展”,而是给安全、合规、运维这些现实问题留位置。
它也在认真对待可观测性
还有一点很重要:Pi 不只是跑任务,它还显式维护运行状态给外部看。
比如:
- 现在是不是在 streaming
- 当前有没有 pending tool call
- 错误是什么
- 已经积累了哪些消息
这些信息对 UI、调试器和上层 orchestration 都很重要。很多 Agent 看起来能用,一接到产品里就暴露出问题,原因就是过程对外几乎不可见。
用户不是只想知道“有没有结果”,他们还想知道“现在为什么卡住了”。
从 Pi 身上能拿走什么
如果把 Pi 这套思路收成几句话,可以这么记:
- Agent 不只是 Prompt 包装
- 上下文治理要前置
- 控制消息要有自己的通道
- 任务需要恢复能力
- 工具执行要能挂业务逻辑
- 运行状态要能被外部看见
这些东西加在一起,才更像一个 Runtime。
下一代 Agent 系统真正比拼的,未必是谁调模型调得更花,而是谁把运行时做得更稳。Pi Agent Core 至少把这件事摆到了台面上。