作为龙虾(OpenClaw)早期的实现基座, 开源AI Agent项目“pi”,正被越来越多人所提及. 其优雅简洁的设计以及便捷的扩展能力让你可以轻松的基于它进行二次创作而快速地得到自己独有的Agent. 尤其在各路主流Coding Agent内置了各种臃肿上下文的情况下(比如在claude code输入一个hello则动辄携带上万token的提示词), 清爽简洁的pi则看起来别具一格.而从agent设计入门和借鉴的角度, pi也是再好不过的一个参考项目.废话不多说, 本篇从全局出发一窥pi的设计思想和整体架构.从v0.80.3开始, pi逐渐调整架构, 拆分出更多细分职责的包. 然而旧版本在包划分上更简洁易于理解. 本篇先使用v0.80.3以前版本来分析.下篇将分析最新版本.1. 概览pi主要是用TypeScript开发, 是一个 monorepo4个npm包按依赖方向自下而上堆叠层包名角色能否独立运行L1earendil-works/pi-ai多 provider 统一 LLM 流式 API可被其它包引用L2earendil-works/pi-agent-core通用 Agent 运行时循环 / 状态 / 工具 / Session可提供 SDKL3earendil-works/pi-tui终端 UI 与差分渲染可提供组件库L4earendil-works/pi-coding-agent交互式 CLI 应用main.ts 模式分发最终运行入口用户执行的pi命令 L4 启动依次调用 L2 驱动 AgentAgent 通过 L1 调用大模型最终通过 L3 在屏幕渲染消息。2. 依赖方向图依赖关系L4 同时依赖 L2、L3、L1L2 与 L3 都依赖 L1。方向单向下层不知道上层。关键约束依赖方向是单向的下层永远不知道上层的存在。这让pi-agent-core可以脱离 CLI 被任何宿主SDK、测试、第三方应用使用。3. 各模块职责pi-ai屏蔽各 LLM providerAnthropic / OpenAI / Google / Bedrock / Mistral / Cloudflare / Vertex / GitHub Copilot / OpenAI Codex 等的协议差异对外只暴露streamSimple(model, context, options)。内置fauxprovider 用于测试。pi-agent-core与 UI / CLI / 应用场景无关的通用 Agent 运行时。提供低层 Agent Loop流式 工具调用循环、高层 AgentHarnessSession 集成 Compaction Skills、状态机、工具协议。pi-tui通用 TUI 库。TUI类提供组件树 键盘事件 差分渲染Editor、Input、Markdown等是可复用组件。无任何 Agent 业务逻辑。pi-coding-agent把上述三者组装成用户可用的 CLI。负责 CLI 解析、SessionManager、扩展系统、内置工具、多种运行模式interactive / print / json / rpc。4. 启动链路从pi命令到第一次回复以下时间线描述一次pi启动在 4 个包之间发生了什么。4.0 启动总览粉L4 / 蓝L2 / 黄L1。虚线是事件回流方向与实线反向。步骤 1CLI 入口L4packages/coding-agent/src/main.ts:477pi-coding-agentexport async function main(args: string[], options?: MainOptions)main()是CLI入口函数由 dist 编译后的dist/cli.js调用。入口函数顺序执行解析参数 → 决定模式 → 加载配置 → 构建 runtime → 分发到模式。步骤 2参数解析与模式分发L4main.ts:497-509.pi-coding-agentconst parsed parseArgs(args); // cli/args.tslet appMode resolveAppMode(parsed, process.stdin.isTTY);appMode类型为interactive | print | json | rpc由命令行参数和 stdin 是否是 TTY 共同决定。步骤 3创建 SessionManagerL4main.ts:250-322pi-coding-agent根据--fork/--session/--resume/--no-session等参数决定是新建、分叉、恢复还是纯内存 Session。核心 APISessionManager.inMemory(cwd) // 纯内存不落盘SessionManager.open(path, dir) // 打开已有 JSONLSessionManager.forkFrom(path) // 从已有分叉步骤 4构建 Agent Session runtimeL4 ↔ L2packages/coding-agent/src/core/sdk.ts:204pi-coding-agentexport async function createAgentSession(options)这是 SDK 入口。它做 5 件事解析cwd、agentDir、authStorage、modelRegistry。恢复历史SessionsessionManager.buildSessionContext()。解析模型options → 历史 → 配置 → provider 默认。实例化Agent来自 L2 pi-agent-core。构造AgentSession封装 Agent 与 SessionManager。关键代码sdk.ts:331-394agent new Agent({initialState: { systemPrompt: , model, thinkingLevel, tools: [] },convertToLlm,streamFn: async (model, context, options) { return streamSimple(model, context, { ... }); },transformContext, steeringMode, followUpMode, ...});步骤 5Agent 启动首轮对话L2packages/agent/src/agent.ts:386-400pi-agent-coreprivate async runPromptMessages(messages: AgentMessage[]) {await this.runWithLifecycle(async (signal) {await runAgentLoop(messages,this.createContextSnapshot(),this.createLoopConfig(),(event) this.processEvents(event), // ← emit 回调signal,this.streamFn, // ← streamSimple);});}Agent 持有_state状态机调用runAgentLoop驱动 LLM 与工具循环。详见后续对Agent Loop的详解。步骤 6流式调用 LLML1packages/ai/src/stream.tspi-aistreamSimple(model, context, options)根据model.api在api-registry.ts查找对应provider实现返回AssistantMessageEventStream。provider 屏蔽 HTTP/SSE/WebSocket 差异。步骤 7事件回流到 UIL4 → L3agent.ts:509-556Agent 层 agent-session.ts:460-510Coding Agent 层pi-agent-core / pi-coding-agentLLM 流式事件经processEvents更新 Agent 状态然后通过subscribe()传递给AgentSession._handleAgentEvent再转发给InteractiveMode最终由TUI差分渲染到屏幕。详见后续消息传递分发链路详解。5. 端到端数据流从用户按键到屏幕像素的完整调用链每个箭头都是一次跨层调用。6. 关键模块职责映射职责所在包关键文件说明CLI 入口pi-coding-agentmain.ts:477解析参数、决定模式、调用 createAgentSessionSession 持久化pi-coding-agentsession-manager.ts条目树 JSONL 读写扩展系统pi-coding-agentcore/extensions/扩展加载、事件总线、生命周期内置工具pi-coding-agentcore/tools/read / write / edit / bash / grep / find / ls交互模式pi-coding-agentinteractive-mode.ts主循环、事件订阅、UI 协调Agent 状态机pi-agent-coreagent.ts_state 状态、steering/followUp 队列Agent Looppi-agent-coreagent-loop.tsrunAgentLoop / runLoop / 流式处理Agent Harnesspi-agent-coreharness/agent-harness.ts高层封装Session Compaction Skills通用 Sessionpi-agent-coreharness/session/JSONL/Memory repo、buildContextCompactionpi-agent-coreharness/compaction/上下文压缩 / 分支摘要流式 APIpi-aistream.tsstreamSimple 统一入口Provider 注册pi-aiapi-registry.ts按 api 类型查找 Provider模型元数据pi-aimodels.tsmodels.generated.ts 静态索引OAuthpi-aiutils/oauth/Claude / ChatGPT / Copilot OAuthTUI 主类pi-tuitui.ts组件树 键盘事件循环编辑器pi-tuicomponents/editor.ts输入框 历史 自动补全差分渲染pi-tuitui.ts:extractSegments...按行比较仅重绘差异行7. 设计原则单向依赖L1 ← L2 ← L3 ← L4禁止反向。下层不知道上层存在pi-agent-core可被任意宿主复用。事件流而非命令流Agent Loop 通过emit(event)推送事件监听器按订阅顺序处理。UI 端订阅 → Coding Agent 层订阅 → Agent 处理 状态。协议式工具调用LLM 返回的tool_use块被解析为AgentTool调用工具执行结果以toolResult消息回写上下文。Session 与 State 解耦Agent 的_state是运行时内存SessionManager是 JSONL 持久层二者通过 AgentSession 桥接并双写。扩展点优先于硬编码扩展系统提供tool_call、before_agent_start、input、tool_result等钩子业务能力大多可由扩展覆盖。可测试的 Provider 边界pi-ai内置fauxprovider所有上游代码都可以在零成本下测试。