乐于分享
好东西不私藏

技术扫描-OpenClaw Agent Runtime,Pi Agent 分析

技术扫描-OpenClaw Agent Runtime,Pi Agent 分析

XYDT

Co-Claw

随着 AI Agent 从对话迈向能够执行代码、操作文件、调用工具的自主智能体,Agent 框架正陷入过度复杂化的困境:动辄上万 token 的系统提示词、数十个内置工具、难以观测的子 Agent 黑盒,复杂度在堆叠,可观测性却在消失。如何构建一个既足够强大,又能被开发者完全理解和掌控的 Agent 运行时?

本文将从 Pi Agent 的极简主义设计哲学出发,深度拆解其不足千行代码的核心运行时、双层循环的精密控制流、以及三层嵌套的生命周期事件系统;揭示如何统一 LLM 消息与自定义事件,双队列机制如何优雅处理用户干预,以及不做什么为何比做什么更重要。通过对比 Claude Code、Codex 等主流框架的设计选择,带你全景俯瞰一个回归本质的 Agent 架构实践。

一、OpenClaw Agent Core 概览
1. OpenClaw和Pi Agent的关系

OpenClaw并没有自己构造一个agent loop,相反它把Agent相关的事情都交给了Pi Agent,或者说OpenClaw整体来看就是Pi Agent套壳,Pi Agent对外暴露的包是:

  • @mariozechner/pi-coding-agent(高级SDK)

  • @mariozechner/pi-agent-core (Agent Runtime)

  • @mariozechner/pi-ai (LLM API)

OpenClaw向Pi Agent提供了System Prompt, Tools, SessionManager(做一些零碎的控制),然后订阅Pi Agent运行过程中的一系列事件,处理流式文本和工具事件并分发给gateway。

Pi Agent是个非常简洁的Code Agent,只有Read, Edit, Write, Bash四个基础工具,并且Bash工具还被OpenClaw给替换了,其他工具都是在OpenClaw中提供的。

2. OpenClaw 内部的结构
3. 用户新增skill之后,整个更新链路
二、Pi-AI介绍
1. 概览

https://github.com/badlogic/pi-mono/tree/main

一共包含7个package:

2. Pi-AI 项目整体架构
3. pi-agent-core 的Agent Loop

可以看到其Agent Loop 仍为传统的ReAct 模式

4. 工具集
  • 默认:read, bash, edit, write(4个)

  • 可选:grep, find, ls(3个)

  • 总计:7个内置工具

  • 可扩展:通过扩展系统添加自定义工具

三、Pi Agent优势

核心哲学:"An autonomous agent is just an LLM + tools + a loop." ——Mario Zechner

1. Pi 的反直觉立场(PiAgent仍采用ReAct架构(Reasoning + Acting))

在当前 Agent 框架生态中,大多数项目在做加法:更多工具、更长提示词、更复杂的规划链、更多子 Agent。Pi 的创作者 Mario Zechner 认为这是一条弯路。他的核心论点是:

"前沿模型已经被 RL 训练得足够理解'编码 Agent'是什么。你不需要10,000 token的系统提示词。"

这不是空谈。Pi 在 Terminal-Bench 2.0 上使用 Claude Opus 4.5 进入了排行榜前列,与 Codex、Cursor、Windsurf 等拥有复杂工具链的 Agent 竞争——而 Pi 的系统提示词 + 工具定义加起来 不到 1000 token。
2. 架构分层:5 个文件构成的运行时

pi-agent-core 的全部源码只有 5 个文件、约 1,500 行代码:

3. 类型系统:少即是多
3.1 最晚转换策略

这是整个设计最精妙的抽象:

// 空接口 —— 通过 Declaration Merging 扩展

export interface CustomAgentMessages {

   // Empty by default - apps extend via declaration merging

}

// AgentMessage = LLM 消息 + 自定义消息

export type AgentMessage = Message | CustomAgentMessages[keyof CustomAgentMessages]

为什么不直接用 LLM 的 Message 类型? 因为真实应用中存在大量"非 LLM 消息":

应用层通过 Declaration Merging 扩展自定义消息类型,编译器自动推断联合类型。内部所有逻辑(压缩、分支、UI 渲染)都基于 AgentMessage 运转,仅在调用 LLM 的瞬间才通过 convertToLlm() 过滤为 Message[]

这就是 Zechner 所称的"最晚转换"(late conversion)策略。

3.2 AgentEvent — 细粒度的生命周期事件

export type AgentEvent =

    | { type: "agent_start" }

    | { type: "agent_end"; messages: AgentMessage[] }

    | { type: "turn_start" }

    | { type: "turn_end"; message: AgentMessage; toolResults: ToolResultMessage[] }

    | { type: "message_start"; message: AgentMessage }

    | { type: "message_update"; message: AgentMessage; assistantMessageEvent: AssistantMessageEvent }

    | { type: "message_end"; message: AgentMessage }

    | { type: "tool_execution_start"; toolCallId: string; toolName: string; args: any }

    | { type: "tool_execution_update"; toolCallId: string; toolName: string; args: any; partialResult: any }

    | { type: "tool_execution_end"; toolCallId: string; toolName: string; result: any; isError: boolean };

三层嵌套的生命周期:Agent > Turn > Message/Tool。每一层都有 start/end 事件,构成完整的可观测性——这正是 Zechner 反复强调的:

"Claude Code 的 Plan Mode 会 spawn 一个子 Agent,你对子 Agent 内部的运作零可见性。这是黑盒中的黑盒。"

4. 核心循环:双层 While 的精密设计

4.1 入口:agentLoop vs agentLoopContinue

两个入口函数体现了一个重要区分:

agentLoopContinue 的存在让 重试 变得优雅:出错后不需要重新构造 prompt,直接 continue() 即可从当前上下文继续。

4.2 双层循环结构

这是 runLoop() 的完整控制流——它是理解 Pi Agent 的关键:

5. Agent 类:状态容器 + 消息队列
5.1 两种队列模式
Agent 类引入了思考周到的队列机制:

// Steering mode: "all" = 一次性发送全部 | "one-at-a-time" = 每次只发一条

private steeringMode: "all" | "one-at-a-time";

private followUpMode: "all" | "one-at-a-time";

为什么需要 one-at-a-time? 考虑这个场景:用户在 Agent 工作时快速发送了 3 条修正。one-at-a-time 模式让 Agent 逐条处理,每条都能得到充分响应,而不是一股脑收到 3 条然后只回应最后一条。

5.2 prompt() vs continue() vs steer() vs followUp()

6. Proxy Stream:带宽优化的客户端重建
这个模块为 Web 应用场景设计(浏览器 → 代理服务器 → LLM)。核心创新是 带宽优化:服务器不传输 partial 字段(完整的局部消息对象),仅传输轻量的 delta 事件:

ProxyAssistantMessageEvent 比原始 AssistantMessageEvent 轻得多——没有 partial 字段,仅包含 contentIndex + delta 等最小信息。客户端通过 processProxyEvent() 逐步重建完整消息。

7. 设计哲学总结

7.1 "不做什么"比"做什么"更重要

7.2 核心设计原则

7.3 写给开发者:何时借鉴 Pi 的设计

适合的场景:

  • 你的 Agent 需要高可观测性 → 学习 Pi 的三层事件系统

  • 你在构建编码/CLI Agent → 学习"4 工具 + bash"的极简策略

  • 你需要跨 Provider 会话迁移 → 学习 convertToLlm的最晚转换模式

  • 你需要用户中途干预 → 学习 Steering/FollowUp 双队列机制

  • 你需要保持内置工具的简单,必要, 学习减少内置工具,外部工具可插拔,让Agent自己写工具

不适合的场景:

  • 你需要复杂的多 Agent 编排 → Pi 的设计理念与此相悖

  • 你需要严格的安全沙箱 → Pi 明确选择了"YOLO by default"

  • 不迷信MCP→把 MCP 调用暴露为 CLI 接口的工具。够用就行,不需要内置到核心。

公司官网:www.xydigit.com
服务电话:400 830 8588

服务邮箱:XYDT@xydigit.com

XYDT

关注我们

微信号XYDigit