Ubuntu TechHive

Pi Coding Agent - Architecture and Hands-on Guide

Pi Coding Agent - Architecture and Hands-on Guide

Pi 是一个极简、可扩展的 AI 编程代理,主要在终端中运行。

Pi 编码代理 - 架构与实践指南

什么是 Pi 编码代理?

Pi 是一个极简、可扩展的 AI 编码代理,主要在终端中运行。

它允许开发者使用大语言模型 (LLM) 与其本地开发环境进行交互。

Pi 可以:

  • 阅读并理解现有代码。
  • 创建新文件和应用程序。
  • 修改现有代码。
  • 执行终端命令。
  • 运行测试并调试错误。
  • 管理对话历史。
  • 连接到不同的 LLM 提供商。
  • 通过自定义工具和技能扩展其功能。
  • 通过 MCP 集成外部服务。

Pi 是“代理工具包”(Agent Harness) 的一个示例。

什么是代理工具包?

代理工具包是围绕语言模型构建的软件基础设施,使其能够执行操作。

该工具包负责:

  • 构建模型的上下文。
  • 与 LLM 通信。
  • 为 LLM 提供工具。
  • 执行请求的工具调用。
  • 将工具结果返回给模型。
  • 管理对话和会话。
  • 控制执行生命周期。

LLM 提供推理能力。

工具包提供了将这种推理转化为行动的环境。

Pi 与传统聊天机器人的区别

传统聊天机器人通常遵循以下模式:

flowchart LR
    A["用户"] --> B["提示词"]
    B --> C["LLM"]
    C --> D["响应"]

AI 编码代理增加了一个执行环境:

flowchart TD
    A["用户"] --> B["Pi 代理"]
    B --> C["LLM"]
    C --> D{"需要工具吗?"}
    D -->|是| E["执行工具"]
    E --> F["返回结果"]
    F --> C
    D -->|否| G["最终响应"]

示例:

聊天机器人: “这是计算费用的 Python 代码。”

Pi: “我创建了 Python 文件,执行了程序,运行了测试,并修复了一个错误。”

重要的区别在于与实际环境进行交互的能力。

Pi 的设计理念

Pi 遵循极简主义哲学。

它不将所有可能的功能作为核心实现的一部分,而是强调可扩展性。

其指导思想是:

“让 Pi 适应你的工作流程,而不是反过来。”

核心原则

极简主义:

  • 保持核心相对精简。
  • 避免不必要的抽象。
  • 基于现有的操作系统工具构建。

可扩展性:

  • 创建自定义工具。
  • 构建扩展。
  • 使用可重用的技能。
  • 连接外部服务。

模型独立性:

  • 使用不同的 LLM 提供商。
  • 在同一环境中切换模型。
  • 比较模型行为。

透明度:

  • 观察模型响应。
  • 检查工具执行情况。
  • 查看修改内容。
  • 检查会话历史。

Pi 不需要什么

基本的 Pi 设置不需要:

  • 向量数据库。
  • 独立的编排服务器。
  • Kubernetes。
  • Docker。
  • 复杂的多代理框架。
  • 自定义后端应用程序。

对于基本演示,终端、受支持的 LLM 和本地目录就足够了。

Pi 架构概述

Pi 包含多个逻辑层。

高层架构

flowchart TB
    USER["开发者"]

    subgraph PI["Pi 编码代理"]
        UI["终端界面"]
        CORE["代理运行时"]
        CONTEXT["上下文管理器"]
        SESSION["会话管理器"]
        TOOLS["工具执行"]
        EXT["扩展 / 技能"]
        API["LLM API 抽象"]
    end

    subgraph MODELS["LLM 提供商"]
        OPENAI["OpenAI"]
        ANTHROPIC["Anthropic"]
        GOOGLE["Google"]
        LOCAL["本地模型"]
    end

    subgraph SYSTEM["开发环境"]
        FILES["文件系统"]
        BASH["Shell"]
        GIT["Git"]
        TESTS["测试"]
    end

    USER <--> UI
    UI <--> CORE

    CORE <--> CONTEXT
    CORE <--> SESSION
    CORE <--> TOOLS
    CORE <--> API

    EXT --> CORE

    API <--> OPENAI
    API <--> ANTHROPIC
    API <--> GOOGLE
    API <--> LOCAL

    TOOLS <--> FILES
    TOOLS <--> BASH
    TOOLS <--> GIT
    TOOLS <--> TESTS

这是一个概念架构,展示了主要职责,而不是每个内部依赖项。

Pi 的内部包

Pi 是作为一系列 TypeScript 包开发的。

pi-ai

用于与不同 LLM 提供商协作的统一接口。

职责:

  • 模型请求。
  • 模型响应。
  • 流式传输。
  • 提供商特定的集成。
  • 工具调用表示。

pi-agent-core

代理运行时。

职责:

  • 代理执行循环。
  • 工具调用。
  • 代理状态。
  • 消息处理。
  • 执行事件。

pi-coding-agent

编码代理应用程序。

职责:

  • CLI。
  • 编码工具。
  • 会话。
  • 上下文文件。
  • 扩展。
  • 技能。
  • 用户配置。

pi-tui

终端用户界面组件。

职责:

  • 终端渲染。
  • 输入处理。
  • 交互式组件。
  • 显示代理活动。

包关系

flowchart TD
    USER["开发者"]
    TUI["pi-tui"]
    CODING["pi-coding-agent"]
    CORE["pi-agent-core"]
    AI["pi-ai"]
    LLM["LLM 提供商"]

    USER <--> TUI
    TUI <--> CODING
    CODING <--> CORE
    CORE <--> AI
    AI <--> LLM

    CODING --> FS["工具"]
    CODING --> SESSION["会话"]
    CODING --> EXT["扩展"]

相同的代理基础设施也可以通过非交互式界面使用。

Pi 的工作原理

Pi 遵循用户、代理运行时、语言模型和工具之间的重复交互循环。

这通常被称为“代理循环”。

第 1 步 - 用户提交请求

示例:

“创建一个跟踪费用的 Python 应用程序。”

Pi 通过其终端界面接收此请求。

第 2 步 - 上下文组装

在联系 LLM 之前,Pi 会准备上下文。

这可能包括:

  • 系统指令。
  • 用户请求。
  • 活动对话历史。
  • 可用工具。
  • 来自 AGENTS.md 的项目指令。
  • 技能描述。
  • 相关文件内容。
  • 模型配置。

活动会话分支决定了包含哪些历史消息。

第 3 步 - 模型请求

Pi 将准备好的请求发送给选定的 LLM 提供商。

LLM 可以生成:

  • 自然语言文本。
  • 结构化工具调用。
  • 两者的组合。

工具请求示例:

工具:write 文件:expenses.py 内容:Python 源代码

LLM 不会直接写入文件。

它请求 Pi 执行该操作。

第 4 步 - 工具执行

Pi 接收请求的工具调用。

工具执行器执行该操作。

示例:

  • 读取文件。
  • 写入文件。
  • 修改代码。
  • 执行 shell 命令。

然后 Pi 捕获结果。

第 5 步 - 返回工具结果

输出返回给代理运行时。

示例:

工具:bash 命令:python expenses.py

结果: Traceback: NameError …

结果成为 LLM 可用上下文的一部分。

第 6 步 - 继续或完成

LLM 可能会决定:

  • 调用另一个工具。
  • 修改代码。
  • 运行额外的测试。
  • 提供最终答案。

Pi 在需要更多执行时重复此过程。

这种交互是代理行为的基础。

完整的代理循环图

flowchart TD
    START["用户请求"]
    CTX["构建上下文"]
    CALL["调用 LLM"]
    RESPONSE["接收模型响应"]
    DECISION{"工具调用?"}
    EXEC["执行工具"]
    RESULT["收集工具结果"]
    FINISH["最终响应"]

    START --> CTX
    CTX --> CALL
    CALL --> RESPONSE
    RESPONSE --> DECISION

    DECISION -->|是| EXEC
    EXEC --> RESULT
    RESULT --> CALL

    DECISION -->|否| FINISH

时序图

sequenceDiagram
    autonumber
    actor User
    participant Pi as Pi 代理
    participant LLM
    participant Tools
    participant OS as 操作系统

    User->>Pi: 创建一个费用跟踪器
    Pi->>Pi: 组装上下文
    Pi->>LLM: 发送提示词和工具定义

    LLM-->>Pi: 请求 write 工具
    Pi->>Tools: 写入 expenses.py
    Tools->>OS: 创建文件
    OS-->>Tools: 成功
    Tools-->>Pi: 工具结果

    Pi->>LLM: 使用结果继续
    LLM-->>Pi: 请求 bash 工具
    Pi->>Tools: 运行 Python 程序
    Tools->>OS: 执行命令
    OS-->>Tools: 输出
    Tools-->>Pi: 执行结果

    Pi->>LLM: 继续
    LLM-->>Pi: 最终响应
    Pi-->>User: 任务完成

为什么这很重要

三个职责是分离的:

  1. LLM: 生成推理并提出行动建议。
  2. 代理工具包: 协调执行并管理上下文。
  3. 工具: 在环境中执行操作。

这种架构也是许多其他 AI 代理实现的基础。

Pi 中的工具

Pi 的极简编码配置使用四个基本工具。

read

读取文件内容。

提示词示例:

“读取 app.py 并解释其结构。”

write

创建或覆盖文件。

提示词示例:

“创建一个打印 Hello TechHive 的 Python 程序。”

edit

修改现有文件。

提示词示例:

“修改程序以接受用户名。”

bash

执行 shell 命令。

提示词示例:

“运行程序并显示结果。”

工具执行示例

flowchart TD
    A["用户:修复错误"]
    B["LLM 分析请求"]
    C["read:检查代码"]
    D["edit:修复代码"]
    E["bash:运行测试"]
    F{"测试通过?"}
    G["最终响应"]

    A --> B
    B --> C
    C --> D
    D --> E
    E --> F
    F -->|否| B
    F -->|是| G

根据版本和配置,可能提供额外的内置工具和扩展。

上下文管理和会话

什么是上下文?

上下文是为模型请求提供给 LLM 的信息。

它可能包括:

  • 当前用户请求。
  • 对话历史。
  • 工具结果。
  • 系统指令。
  • 项目指令。
  • 技能描述。
  • 引用的文件内容。

Pi 不会自动将存储库中的每个文件加载到 LLM 上下文中。

它根据会话和配置的资源选择并组装上下文。

AGENTS.md

AGENTS.md 是一个项目指令文件。

示例:

# 项目指令

此项目用于编码代理研讨会。

准则:
- 使用 Python。
- 首选标准库。
- 保持代码简单。
- 编写可读的函数。
- 为新功能添加测试。
- 解释重大更改。

这些指令有助于指导代理在项目中的行为。

会话

Pi 维护对话会话。

会话可以包括:

  • 用户消息。
  • 助手消息。
  • 工具调用。
  • 工具结果。
  • 模型更改。
  • 上下文压缩事件。

持久会话使用 JSONL 文件。

会话分支

Pi 支持基于树的对话结构。

flowchart TD
    A["开始会话"]
    B["创建应用程序"]
    C["添加数据存储"]

    D["CSV 方法"]
    E["SQLite 方法"]

    F["测试 CSV"]
    G["测试 SQLite"]

    A --> B
    B --> C
    C --> D
    C --> E
    D --> F
    E --> G

分支允许从早期的对话状态探索替代方法。

上下文压缩

长时间的对话可能会超过模型的上下文窗口。

Pi 可以总结较旧的上下文,以减少未来模型请求中发送的信息量。

命令:

/compact

压缩有助于管理上下文大小,但可能会丢失旧消息中的一些细节。

原始会话条目可以保留在存储的会话历史记录中。

模型提供商

Pi 可以与多个 LLM 提供商协作。

示例:

  • OpenAI。
  • Anthropic。
  • Google。
  • 其他受支持的提供商。
  • 配置的本地模型。

模型独立性

flowchart TD
    USER["开发者"]
    PI["Pi 代理"]
    API["统一模型接口"]

    USER --> PI
    PI --> API

    API --> A["OpenAI"]
    API --> B["Anthropic"]
    API --> C["Google"]
    API --> D["本地模型"]

优势:

  • 灵活性。
  • 模型比较。
  • 提供商选择。
  • 成本优化。
  • 实验。

模型功能和兼容性可能有所不同。

扩展 Pi

无需修改核心即可自定义 Pi。

AGENTS.md

项目特定的指令。

提示词模板

用于重复活动的重用提示词。

示例:

  • 代码审查。
  • 文档。
  • 测试生成。
  • 重构。

技能

用于专门工作流程的可重用指令和支持资源。

示例:

  • Python 测试工作流程。
  • 部署工作流程。
  • 文档生成。
  • API 开发。

扩展

基于 TypeScript 的自定义。

扩展可以:

  • 定义自定义工具。
  • 注册命令。
  • 响应生命周期事件。
  • 集成外部服务。
  • 自定义交互行为。

MCP 集成

MCP 代表模型上下文协议 (Model Context Protocol)。

它为应用程序访问外部工具和资源提供了一种标准化方式。

现代 Pi 版本提供内置的 MCP 支持。

集成示例:

  • GitHub。
  • 数据库。
  • 内部应用程序。
  • 远程服务。

扩展架构

flowchart TD
    PI["Pi 代理"]

    PI --> A["AGENTS.md"]
    PI --> B["提示词模板"]
    PI --> C["技能"]
    PI --> D["扩展"]
    PI --> E["MCP"]

    D --> F["自定义命令"]
    D --> G["自定义工具"]
    D --> H["事件处理程序"]

    E --> I["外部服务"]

Pi 执行模式

Pi 支持多种界面。

交互式

启动终端界面。

pi

打印模式

执行提示词并打印其响应。

pi -p "解释 Python 装饰器"

JSON 模式

流式传输结构化代理事件。

pi --mode json -p "解释这个项目"

RPC 模式

通过标准输入和输出使用 JSONL 消息控制 Pi。

SDK

在 TypeScript 应用程序中嵌入 Pi 代理功能。

flowchart TD
    CORE["Pi 代理运行时"]

    CORE --> A["交互式 TUI"]
    CORE --> B["打印 / JSON"]
    CORE --> C["RPC"]
    CORE --> D["TypeScript SDK"]

    A --> E["开发者"]
    B --> F["自动化脚本"]
    C --> G["外部应用程序"]
    D --> H["自定义代理应用程序"]

安装和最小化设置

安装 Pi

macOS / Linux:

curl -fsSL https://pi.dev/install.sh | sh

Windows PowerShell:

irm https://pi.dev/install.ps1 | iex

使用 npm 的替代方案:

npm install -g --ignore-scripts @earendil-works/pi-coding-agent

npm 安装需要 Node.js 22.19 或更高版本。

验证安装

pi --version

创建项目

mkdir pi-techhive-demo
cd pi-techhive-demo
git init

启动 Pi

pi

配置身份验证

在 Pi 内部:

/login

选择受支持的提供商并进行身份验证。

然后:

/model

选择要使用的模型。

基本命令

命令 用途
/login 验证模型提供商身份
/model 选择模型
/thinking 设置思考级别
/settings 打开设置
/new 开始新会话
/resume 恢复会话
/session 会话信息
/tree 导航对话历史
/fork 从较早的消息分支
/compact 压缩上下文
/mcp 管理 MCP 服务器
/reload 重新加载资源
/export 导出会话
/share 分享会话
/quit 退出 Pi

在终端界面中输入 / 以发现已安装版本中可用的命令。

实践演示:费用跟踪器

创建项目目录

mkdir expense-tracker
cd expense-tracker
git init
pi

探索项目

提示词:

检查当前目录。

解释存在哪些文件。

不要修改任何内容。

概念: 文件系统探索和读取操作。

生成应用程序

提示词:

创建一个简单的 Python 费用跟踪器。

要求:
- 添加费用。
- 列出费用。
- 计算总费用。
- 将费用存储在 CSV 文件中。
- 仅使用 Python 标准库。

保持实现简单。

概念: 代码生成和文件创建。

执行程序

提示词:

运行应用程序。

创建三个示例费用。

验证总数计算是否正确。

概念: Shell 执行和结果观察。

添加自动化测试

提示词:

使用 Python unittest 创建单元测试。

测试费用创建和总数计算。

运行测试并修复任何错误。

概念: 自主测试和迭代修正。

扩展应用程序

提示词:

添加按类别对费用进行分组的功能。

显示每个类别的总数。

更新测试并运行它们。

概念: 代码修改和上下文保留。

探索会话管理

命令:

/session /tree /model

概念: 会话历史、分支和模型切换。

安全注意事项

Pi 可以使用其运行进程可用的权限执行命令。

它不一定在每次工具调用之前请求批准。

推荐做法:

  • 在专用的项目目录中工作。
  • 在修改重要代码之前使用 Git。
  • 避免暴露凭据。
  • 检查生成的代码。
  • 查看外部扩展。
  • 不要在公共演示中使用敏感数据。
  • 对不受信任的任务使用容器或沙箱。
  • 在分享会话内容之前进行检查。

AI 编码代理不能替代安全和代码审查实践。

Pi 与其他工具的比较

Pi

极简、可扩展的编码代理工具包。

优势:

  • 自定义。
  • 多个 LLM 提供商。
  • 工具执行。
  • 会话管理。
  • 可扩展性。

Claude Code

具有集成开发工具和工作流程集的编码代理。

Codex CLI

旨在与代码库、终端命令和开发工作流程配合使用的编码代理。

LangChain / LangGraph

用于开发自定义 LLM 应用程序和代理工作流程的框架。

Pi 主要是一个即用型且可扩展的代理工具包,而不是通用的工作流程图框架。

关键要点

  1. Pi 是代理工具包,而不是 LLM。
  2. LLM 提出行动建议;Pi 协调执行。
  3. 代理循环支持多步任务执行。
  4. 工具允许 Pi 与开发环境进行交互。
  5. 上下文和会话保持对话的连续性。
  6. Pi 不绑定到单一 LLM 提供商。
  7. 扩展和技能支持自定义。
  8. 极简架构仍然可以支持复杂的代理工作流程。
  9. 人工监督和适当的隔离仍然很重要。