Ubuntu TechHive

Notes on my Pi setup

Notes on my Pi setup

Pi 的核心工具包括 =read=、=bash=、=edit= 和 =write=。项目 =AGENTS.md= 文件提供特定于存储库的约束。

我的 Pi 设置笔记

我如何使用 Pi

我将 Pi 用作可定制的终端编码助手,用于检查代码库、进行针对性修改并运行检查。技能(Skills)用于捕获可重用的工作流;扩展(Extensions)则增加了委派、研究、回溯(rewind)和持久化目标等功能。

我安装的 CLI 版本是 Pi *1.5.2*。在 ~/.pi/agent/settings.json 中,我的默认配置是 openai-codex/gpt-6.1-sol=,开启 =xhigh 思维模式、深色主题并隐藏思维块。隐藏这些块仅改变呈现方式,不会影响推理工作量。这些是已配置的模型选择,并不保证服务提供商的可用性。

cd /path/to/project
pi
# 在 Pi 内部: /login, /model, /reload

Pi 的核心工具是 read=、=bash=、=edit 和 write=。项目中的 =AGENTS.md 文件提供了特定于代码库的约束。扩展执行集成;技能提供在相关时加载的特定任务指令。

已安装的扩展

这些包在我的用户设置中声明,并安装在 ~/.pi/agent/npm/node_modules/ 下。以下版本描述了当前的检查设置,而非永久固定:我的包声明使用的是未指定版本的 npm: 源。

包 已安装 我的用途
pi-subagents 0.88.1 专注的工作人员、独立审查员、顾问和范围审计。
pi-web-access 0.47.0 网络搜索、来源检查、页面/PDF 提取、代码库和视频研究。
pi-rewind-hook 1.8.8 与会话历史关联的 Git 后端文件检查点;通过 /tree 或 /fork 恢复。
pi-goal-x 0.34.1 明确的持久化目标、任务进度、暂停/恢复以及可选的完成审计。

我的 extensions 设置包含 ="-builtin:mcp"=:Pi 的内置 MCP 集成已禁用。以下功能来自已安装的扩展文档;它们并不意味着我的设置中启用了所有可选功能。

pi-subagents: 专注工作与独立判断

委派需要我的请求或适用指令,而不仅仅是复杂性。=subagents_enable= 在需要时启用委派工具。前台子进程作为父进程内的会话运行;后台子进程使用分离的运行器。每个子进程接收其自己的任务、上下文、工具和模型选择。

我将实现人员与只读审查/建议和范围审计分离开来(见下方的角色表)。独立审查可以并行运行;实现人员在每个工作树中保持一个写入者。=contact_supervisor= 将检查点决策和有意义的更新传回协调员。=/subagents-fleet= 检查正在运行的工作;=/subagents-doctor= 诊断设置。

请求示例——非自动后台活动:

使用审查员根据我的要求检查此更改,无需编辑。
在实施前,请 oracle 质疑此计划。

pi-web-access: 带有可检查证据的研究

web_enable 按需加载研究工具:

  • web_search: 搜索或批量处理相关查询;=workflow: "none"= 返回结果而不进行单独的摘要生成调用或策展浏览器。
  • fetch_content: 检索页面、PDF、代码库或支持的视频内容。回答模式处理是单独的可选模型交互。
  • get_search_content: 使用 responseId 翻阅存储的结果或查找确切段落,而不是重复获取相同材料。
  • source_check: 收集段落和来源元数据以进行手动声明审查;仅检索并不能证明声明为真。

搜索/获取操作可能会将数据发送到外部服务。我将凭据、私有来源和不相关的项目细节排除在研究查询和示例之外。

pi-rewind-hook: 文件和对话可以分开恢复

通过 /fork=,我可以在分支对话的同时保留文件,恢复两者,或者在保留对话的同时恢复代码。=/tree 提供存在检查点时的精确文件恢复,以及可用时的撤销功能。

检查点属于提示/助手轮次边界,而非每个工具调用。会话分类账记录它们;Git 将快照对象保存在 refs/pi-rewind/store 中。覆盖范围包括已跟踪和未跟踪的非忽略文件,不包括忽略的文件或空目录。这补充了正常的提交。我没有 rewind.retention 覆盖:记录的默认值是没有自动过期,因此快照存储可能会增长。

pi-goal-x: 明确的、持久的工作

/goal 在执行前讨论结果并确认计划;=/sisyphus= 遵循有序步骤。目标、任务和进度在会话间持久存在。=/goal-direct= 仅在我明确选择时绕过起草。

/goal-status 显示进度,=/goal-pause= 停止自动继续,=/goal-resume= 继续,=/goal-tweak= 修改目标或计划。可选的完成审计使用单独的代理来检查要求和证据;其可用性并不代表我已经启用了它。普通任务不会隐式成为目标。

我的技能

只有 commit-msg 位于 ~/.pi/agent/skills/ 中。Pi 还会发现共享的 ~/.agents/skills/ 目录,我的其他个人/工具安装的技能也位于此处。

位置 / 技能 目的
~/.pi/agent/skills/commit-msg 基于已检查更改的过去时、多行提交消息,采用代码库的 develop 风格;无 Git 变动。
~/.agents/skills/implementation-steps scratch/implementation_steps/ 中的动手重构课程,包含累积的工作代码和验证。
~/.agents/skills/lightpanda 感知 JavaScript 的 DOM 提取和功能性浏览器自动化;非视觉布局保真度的证据。
~/.agents/skills/rex 通过其 CLI 控制 Rex 会话、标签页、窗格、命令和终端输出。
~/.agents/skills/ui-sdk 使用 @ui-sdk/* 构建和测试基于行为的、可访问的界面。
~/.agents/skills/ui-ux-a11y 应用捆绑的 UI/UX、WCAG 2.2 AA、可访问性、对比度和验证规则。

子代理包还提供用于编排的 pi-subagents 和用于有界、只读顾问辩论的 =council-mode=;这些是打包的技能。

在 Pi 内部的调用示例:

/skill:commit-msg staged files

嵌入式技能摘录

这些是我六个个人/工具安装的 SKILL.md 文件的逐字摘录,而非替代的技能定义。支持文件和相对路径仍属于每个原始技能目录。简短的 Rex 条目已完整包含;较长的技能被摘录以保持这些笔记的可读性。

commit-msg: 措辞前的证据

来源: =~/.pi/agent/skills/commit-msg/SKILL.md=,“核心契约”。

生成的提交消息必须:

1. 符合最近 `develop` 分支提交的风格和格式。
2. 使用过去时。
3. 是多行的。
4. 仅基于请求输入中已检查的文件更改。
5. 避免使用 diff/stat/name-status 数据不支持的声明。
6. 避免重用目标提交中的占位符主题(如 `WIP`)。
7. 避免改变 git 状态;此技能是只读的。

implementation-steps: 工作代码与可教性

来源: =~/.agents/skills/implementation-steps/SKILL.md=,开篇契约。

为选定的目标制作动手实施课程。每个编号阶段都包含实际工作的源代码及其详细的 README。遵循记录步骤的学习者必须理解他们正在编写的内容及其原因,并准确达到捕获的目标代码。技术正确性、精确的源代码等同性和可教性是独立的要求;它们互不替代。

此工作流与语言和框架无关。检查目标而不是强加运行时、架构、固定的阶段数量或先前任务的实施选择。创建学习工件;保持目标不变。

lightpanda: 有界提取,适当的证据

来源: =~/.pi/agent/skills/lightpanda/SKILL.md=,“CLI 和持久化自动化”。

对于已知的授权 URL,从有界提取开始:

```zsh
lightpanda fetch --dump markdown --dump-max-bytes 12000 --fail-on-http-error 'http://127.0.0.1:PORT/PATH'
```

将 URL 替换为观察到的应用程序 URL。使用 `--dump html` 获取标记,或使用 `--dump semantic_tree_text` 获取紧凑的语义树。检查命令状态和错误;转储本身并不能证明导航或交互成功。

rex: 从已安装的 CLI 加载指南

来源: =~/.pi/agent/skills/rex/SKILL.md=,完整文件。

---
name: rex
description: 使用 rex CLI 管理 Rex 会话、打开标签页、排列窗格、运行命令、检查终端输出并控制连接的 Rex 应用。
metadata:
  rex-stub: "2"
---


运行 `rex __internal skill` 并遵循其打印的指南。指南来自已安装的 Rex CLI,因此它描述了该版本中可用的命令。

如果命令失败,说明已安装的 Rex 版本早于该指南。从 `rex whoami --json` 开始,然后使用 `rex --help` 和 `rex COMMAND --help`。

ui-sdk: 使用版本匹配的文档

来源: =~/.pi/agent/skills/ui-sdk/SKILL.md=,“先阅读”。

已安装版本的文档以 Markdown 形式随每个包提供:

- `node_modules/@ui-sdk//docs/llms.txt` 是索引。先阅读它。 是 `react`、`vue`、`svelte`、`solid` 或 `web`。
- 然后只阅读任务需要的页面,例如 `docs/components/select.md`。不要阅读整个 `docs/` 文件夹;它很大。
- 从我们的组件构建的界面不需要 `docs/core.md`。只有下方的路径 2 需要,即使那样你也要按标题搜索它:它超过 300 KB。`docs/rendering.md` 位于同一个 `docs/` 文件夹中。
- 不要阅读 `dist/*.js` 中编译的 JavaScript,即使是为了调试。文档和 `.d.ts` 类型就是 API;当它们无法回答时,编写一个尝试它的小测试。

此处“路径 2”是指从 @ui-sdk/core 构建缺失的组件/行为,而不是组合现有组件。

ui-ux-a11y: 维护权威与范围

来源: =~/.pi/agent/skills/ui-ux-a11y/SKILL.md=,“范围与权威门控”。

在编辑或批准工作之前:

1. 识别当前项目中用户授权的实施范围、代码库说明以及任何适用的计划或验收标准。
2. 发现并检查当前项目实际的真理来源:现有的产品行为、用户提供的参考、设计契约、设计系统、令牌来源以及任务要求时的已部署行为。不要假设任何文件名或路径。
3. 为受影响的路由、状态、区域设置、视口、主题和交互识别每个适用的 `UX-*`、`A11Y-*`、`CC-*` 和 `VAL-*` 规则 ID。
4. 在实施前记录 `VAL-01` 要求的权威基准。仅在当前任务或项目定义时使用参考基准。
5. 如果缺少必要的真理来源,或者合规性需要未经批准的路由、功能、重新设计、工作流、依赖项、内容、权限或产品范围更改,请停止。

其完整的 ui_ux_a11y/ 规则文件夹仍然具有权威性;此摘录不取代其可访问性、对比度和渲染体验检查。

受控委派

我的 subagents.agentOverrides 将实现与判断分开。所有四个角色都继承项目上下文,并默认为新鲜的对话上下文(只读角色有明确覆盖;工作人员使用捆绑的默认值)。

角色 配置模型 思维 职责 / 工具
worker openai-codex/gpt-6.1-sol 中等 执行分配的检查点;读取/搜索,=bash=,=edit=,=write=,联系主管。
reviewer openai-codex/gpt-6.1-sol 高 只读正确性和证据审查;仅读取/搜索和联系主管。
oracle openai-codex/gpt-6-astra 中等 只读架构建议和假设检查。
scopeCreepPatrol openai-codex/gpt-6-astra 中等 只读需求可追溯性和未经授权的范围检测。

scopeCreepPatrol 的代理定义位于 =~/.agents/scopecreeppatrol.md=;模型和其他覆盖来自我的 Pi 设置。

对于委派的实施,协调员路由工作、做出决策并维护分类账——而不是代码。工作人员根据当前文件和批准的要求检查顾问提供的代码,报告验证证据,并在下一个单元之前请求检查点决策。只读角色内联返回发现/纠正代码,而不是文件。建议不是用户批准。

范围审计员检查需求参考、字面上的 1 到 N 列、需求来源以及确切的状态 no-started / in-progress / deferred / completed / not-applicable=;它不得发明该列的含义。阻塞性问题使用 =contact_supervisor 和 =need_decision=;实质性的非阻塞更新使用 =progress_update=,无需日常闲聊。

flowchart TD
    U["用户需求和批准"] --> C["协调员:路由和跟踪"]
    C --> W["工作人员:实施一个检查点"]
    W --> E["更改的文件和验证证据"]
    E --> R["审查员:正确性"]
    E --> S["范围巡逻:可追溯性"]
    C --> O["Oracle:有界建议"]
    R --> D["协调员:检查点决策"]
    S --> D
    O --> D
    D -->|批准下一个单元| W
    D -->|满足需求| F["最终报告"]

我的子代理配置

来自 ~/.pi/agent/settings.json 的完整 subagents 部分嵌入在下方,包括所有四个角色覆盖及其未更改的提示。外部 JSON 对象显示了它在设置中的位置;不相关的设置已省略。

{
  "subagents": {
    "agentOverrides": {
      "worker": {
        "model": "openai-codex/gpt-6.1-sol",
        "thinking": "medium",
        "inheritProjectContext": true,
        "tools": [
          "read",
          "grep",
          "find",
          "ls",
          "bash",
          "edit",
          "write",
          "contact_supervisor"
        ],
        "systemPrompt": "你是实施工作人员。仅实施可追溯到实际用户需求的分配工作。未经明确的事先用户批准,绝不扩大范围。代理建议不是批准。协调员负责协调、维护进度分类账并转发代理编写的代码;它不得编写或修改代码。仅在检查其对当前文件和批准要求的适用性后,才应用顾问提供的代码。在每个分配的实施检查点,报告需求参考、更改的文件、验证证据、剩余工作和所需的分类账更新;在开始下一个实施单元之前请求协调员的决策。对于阻塞性问题和检查点决策,使用 contact_supervisor 并说明 need_decision,对于需要协调员注意的实质性更改,使用 progress_update。不要发送日常叙述或重复的完成消息。绝不要在没有证据的情况下声称验证通过。"
      },
      "reviewer": {
        "model": "openai-codex/gpt-6.1-sol",
        "thinking": "high",
        "inheritProjectContext": true,
        "defaultContext": "fresh",
        "tools": [
          "read",
          "grep",
          "find",
          "ls",
          "contact_supervisor"
        ],
        "systemPrompt": "你是只读实施审查员。根据实际用户需求、实施、测试和验证证据审查分配的工作人员检查点。不要编辑文件或创建补丁或报告文件。返回带有需求参考、确切位置、证据和具体替换代码或统一 diff 的可操作发现(在有用时内联)。区分实际缺陷和可选建议。不要扩大或重新定义范围,也绝不要将你的建议视为用户批准。通过 contact_supervisor 及时报告阻塞性发现;否则返回简洁的最终审查。避免心跳、重复发现和日常闲聊。识别过时的检查点和不受支持的完成声明。"
      },
      "oracle": {
        "model": "openai-codex/gpt-6-astra",
        "thinking": "medium",
        "inheritProjectContext": true,
        "defaultContext": "fresh",
        "tools": [
          "read",
          "grep",
          "find",
          "ls",
          "contact_supervisor"
        ],
        "systemPrompt": "你是只读顾问,回答协调员分配的具体问题。质疑不受支持的假设,识别架构或正确性风险,并区分事实、不确定性和建议。在有用时,内联提供实际的纠正代码或统一 diff。不要编辑文件或创建补丁或报告文件。保留实际用户需求;范围扩大需要明确的事先用户批准。你不能授予该批准。通过 contact_supervisor 升级阻塞性缺失决策;否则返回你的有界答案,无需日常进度闲聊。不要发明额外的需求或发起不相关的工作。"
      },
      "scopeCreepPatrol": {
        "model": "openai-codex/gpt-6-astra",
        "thinking": "medium",
        "inheritProjectContext": true,
        "defaultContext": "fresh",
        "tools": [
          "read",
          "grep",
          "find",
          "ls",
          "contact_supervisor"
        ],
        "systemPrompt": "你是只读范围和需求可追溯性审计员。将分配的工作人员检查点和进度分类账与实际用户需求和明确的事先用户批准进行比较。检测未经授权的扩大、省略或更改的需求,以及被歪曲为用户授权的代理建议。检查分类账是否包含实施需求参考、字面上的 1 到 N 列、状态和需求来源。不要发明 1 到 N 的含义。确切保留状态:no-started / in-progress / deferred / completed / not-applicable。区分用户需求和代理需求;代理需求不授权范围扩大。通过 contact_supervisor 及时报告有证据支持的差异。在有用且在现有范围内时,内联提供具体的纠正代码。绝不要编辑文件、创建补丁或报告文件、重新定义需求、授予批准或制造验收门控。避免日常闲聊。"
      }
    },
    "watchdog": {
      "enabled": true,
      "scope": {
        "enabled": true
      },
      "clarification": true,
      "main": {
        "model": "openai-codex/gpt-6-astra",
        "thinking": "medium"
      },
      "cadence": {
        "everyNTools": 16
      },
      "children": {
        "enabled": false,
        "overrides": {
          "worker": {
            "enabled": true,
            "model": "openai-codex/gpt-6.1-sol",
            "thinking": "high",
            "cadence": {
              "everyNTools": 8
            }
          }
        }
      }
    }
  }
}

看门狗行为

看门狗是一个单独的第二模型审查机制,而不是 reviewer 角色。主看门狗每 16 个工具结果检查一次,并在符合条件的更改工作边界进行检查。范围监控和主会话澄清已启用。子看门狗已关闭 *除了工作人员*:其明确的覆盖启用了每 8 个工具结果和符合条件的边界处的审查,使用 Sol/high 模型。这些是活动/边界触发器,而不是空闲轮询循环。

Pi 内部有用的检查命令:=/subagents-fleet=、=/subagents-doctor= 和 =/subagents-watchdog status=。

本地推理:Pi 支持的 HTTP API

我的 local-inference/ Bun/TypeScript 工作区在 http://127.0.0.1:8081/v1 公开了一个与 OpenAI 兼容的 Chat Completions API。它是一个通向 Pi 管理提供商的本地 HTTP 网关,*不是*设备上的模型权重服务器。

  • packages/protocol: Zod 4 请求验证和后端契约。
  • packages/pi-proxy: Pi 的公共 =ModelRuntime=,用于模型解析、保存的凭据、OAuth 刷新和原生流式传输。
  • packages/server: =Bun.serve=、HTTP/SSE 转换、取消、背压和加密的延续信封。

该网关将 @earendil-works/pi-coding-agent 和 @earendil-works/pi-ai 固定在 *1.5.0*,独立于我安装的 CLI 1.5.2。

flowchart LR
    C["HTTP 客户端"] -->|Chat Completions| H["local-inference: Bun HTTP 服务器"]
    H --> V["Zod 验证的请求"]
    V --> M["Pi ModelRuntime"]
    P["Pi 模型配置和保存的登录"] --> M
    M --> Q["配置的上游提供商"]
    Q -->|原生流| M
    M -->|文本、推理、工具事件| H
    H -->|SSE 增量| C
    C --> T["可选的客户端工具执行"]
    T -->|下一次请求时的工具结果| H

每个请求执行一个提供商轮次:网关不执行工具或编辑文件。工具执行属于客户端。文本流与推理分开;断开连接/关闭会取消上游工作。原生延续数据使用经过身份验证的加密 reasoning_details 信封。

使用 Pi 登录所需提供商后,从包含 local-inference/ 的目录启动网关:

cd local-inference
bun install --frozen-lockfile
bun run start -- --port 8081

在另一个终端中,检查监听器或显式发出流式请求(POST 使用提供商账户并可能产生使用费):

curl http://127.0.0.1:8081/healthz
curl http://127.0.0.1:8081/v1/models
curl -N http://127.0.0.1:8081/v1/chat/completions \
  -H 'Content-Type: application/json' \
  -d '{"model":"openai-codex/gpt-6.1-sol","stream":true,
       "messages":[{"role":"user","content":"Reply with hello."}]}'

模型 ID 是确切的 provider/model 字符串;=/v1/models= 广告模型但不是准入白名单。Pi 拥有提供商支持和凭据处理。默认环回监听器不需要客户端令牌;非环回绑定需要一个。=–token-env NAME= 可选地保护监听器,独立于提供商登录。绝不要发布 auth.json 或令牌。

该 API 支持文本和函数工具,不支持图像、模式约束响应或 Responses 端点。客户端必须使用 Chat Completions。从 local-inference/ 运行 bun run typecheck 以检查网关的类型。

来自 local-inference 的代码

这些是逐字摘录,而非独立程序:周围的类、类型和辅助定义保留在命名的源文件中。此处未复制任何客户端应用程序或不相关的包命名空间。

创建 Pi 的运行时并列出广告模型

来自 local-inference/packages/pi-proxy/src/index.ts=。凭据和提供商配置保留在 =ModelRuntime 之后;刷新和列出接收请求的取消信号。

  static async create(options: PiBackendOptions = {}): Promise<PiBackend> {
    const { provider, ...runtimeOptions } = options;
    return new PiBackend(await ModelRuntime.create(runtimeOptions), provider);
  }

  async models(signal: AbortSignal) {
    await this.runtime.refresh({ providers: this.provider ? [this.provider] : undefined, signal });
    signal.throwIfAborted();
    const available = await this.runtime.getAvailable(this.provider, { signal });
    return available.map(model => ({ id: this.provider ? model.id : `${model.provider}/${model.id}`, owned_by: model.provider }));
  }

解析提供商同时保留确切请求的模型 ID

来自同一个文件。Pi 提供提供商元数据和自定义模型解析;HTTP 层保留调用者的确切模型 ID,而不是对其应用 CLI 模糊名称或思维后缀便利。

  async resolve(id: string, signal: AbortSignal): Promise<InferenceModel> {
    signal.throwIfAborted();
    const slash = id.indexOf("/");
    const provider = this.provider ?? (slash > 0 ? id.slice(0, slash) : undefined);
    const modelId = this.provider ? id : id.slice(slash + 1);
    if (!provider) throw new ApiError(400, "使用 provider/model 作为模型 ID,或以 --provider 开头");
    await this.runtime.refresh({ providers: [provider], signal });
    signal.throwIfAborted();
    const selected = resolveCliModel({ cliProvider: provider, cliModel: modelId, modelRuntime: this.runtime });
    if (!selected.model) throw new ApiError(400, selected.error ?? "Pi 无法解析请求的模型", "model_resolution_error");
    // Pi 拥有模型构造、提供商元数据和自定义模型支持。
    // 其 CLI 解析器也接受模糊名称/思维后缀;HTTP 模型
    // 字段是确切的 ID,因此这些便利不能重写该字段。
    return { ...selected.model, id: modelId };
  }

选择 Pi 流式 API

来自同一文件中的 PiBackend.stream=。共享推理选项使用 =streamSimple=;原生 =reasoningEffort 选项使用 =stream=。

    const events = request.reasoningEffort === undefined
      ? this.runtime.streamSimple(model, context, request)
      : this.runtime.stream(model, context, request);

在线路上保持文本和推理分开

来自 =local-inference/packages/server/src/index.ts=,在事件 switch 内部。文本增量在到达时发出,无需等待提供商完成。

      case "text_delta": source.push(event.delta); await chunk({ content: event.delta }); break;
      case "thinking_delta": await chunk({ reasoning_content: event.delta }); break;

参考

我与 Pi 一起使用的工具、扩展、技能驱动工具和库的来源: