znlgis 博客

GIS开发与技术分享 — GDAL · GeoServer · PostGIS · QGIS · OpenLayers · Cesium · FreeCAD · NPOI

第五章:配置体系全解

本章全面解析 Pi 的配置体系:从全局到项目的两层配置文件、模型与思考、UI 与显示、会话压缩、重试策略、资源加载、CLI 参数覆盖,以及完整的配置示例和迁移指南。读完本章,你将能够精确控制 Pi 的每一个可配置行为。

5.1 配置体系概述

Pi 的设计哲学之一是 “零配置即可用,但每个细节都可控”。初次安装后,你不需要手动写任何配置文件就能开始编码;当你希望深度定制时,Pi 提供了一个清晰、分层的配置体系。

5.1.1 两层配置

Pi 的配置分为两个层级:

层级 路径 加载时机 作用范围
全局配置 ~/.pi/agent/settings.json 每次启动 所有项目
项目配置 .pi/settings.json(项目根目录) 项目被信任后 当前项目

全局配置是”底配置”——它定义了你的 Pi 在所有项目中的默认行为:使用哪个模型供应商、深色还是浅色主题、重试多少次,等等。

项目配置是”覆盖层”——当你进入一个特定项目,Pi 允许你为这个项目定义独立配置:可能这个项目需要不同的模型、更长的超时时间、或者一套不同的扩展和技能。

5.1.2 项目信任机制

Pi 默认不会自动加载项目级配置。原因很简单:从 GitHub 克隆一个仓库后,git pull 会同步 .pi/settings.json——你不会希望一个来历不明的项目自动覆盖你的全局配置。

当你首次在一个含有 .pi/settings.json 的项目中启动 Pi 时,TUI 顶部会显示一条提示:

⚠ 此项目包含 .pi/settings.json,是否信任并加载?(y/n)

确认后,Pi 会在项目的 .pi/ 目录下写入一个 .trust 标记文件,此后每次进入该项目都会自动加载项目配置。你也可以通过 defaultProjectTrust 配置项(见 5.3.4)改变这一行为。

5.1.3 配置合并规则

当两层配置同时存在时,合并规则为:

  1. 全局配置打底:未在项目配置中出现的字段,沿用全局值。
  2. 项目配置覆盖:项目配置中显式声明的字段覆盖全局对应字段。
  3. 数组字段追加(部分字段):像 extensionsskills 这类资源列表,项目配置中的条目追加到全局配置之后,而非替换。
  4. 数组字段替换(部分字段):像 enabledModels 这类功能性列表,项目配置完全替换全局配置。

具体哪些字段追加、哪些替换,会在后续各节中逐一说明。

5.1.4 /settings 交互式设置界面

Pi 的 TUI 内置了一个交互式设置界面。输入斜杠命令 /settings,你会看到:

┌──── Pi Settings ───────────────────────────────────────────┐
│                                                             │
│  当前配置文件: ~/.pi/agent/settings.json                     │
│                                                             │
│  [1] 模型与供应商 ........................................................... ▸ │
│  [2] UI 与显示 .............................................................. ▸ │
│  [3] 会话与压缩 ............................................................ ▸ │
│  [4] 重试策略 ................................................................. ▸ │
│  [5] 资源加载 ................................................................. ▸ │
│  [6] 其他设置 ................................................................. ▸ │
│                                                             │
│  [S] 保存并退出      [Q] 放弃修改                            │
│                                                             │
└─────────────────────────────────────────────────────────────┘

每个子菜单对应 settings.json 的一个分类,用方向键和回车即可修改。/settings 的本质是将 JSON 配置”可视化”,避免手写 JSON 时的格式错误。不过,如果你喜欢直接编辑文件,Pi 也完全支持——手动编辑 settings.json 后,Pi 会在下次启动时自动加载,无需重启(/reload 命令也可以做到热重载)。


5.2 模型与思考配置

模型相关配置是 Pi 配置体系中最核心的部分之一。它决定了 Pi 在每次对话中调用哪个供应商的哪个模型,以及模型是否启用”思考”(thinking / extended reasoning)功能。

5.2.1 defaultProvider

"defaultProvider": "anthropic"

指定 Pi 默认使用的模型供应商。Pi 支持的供应商列表见第四章:模型供应商与认证体系,常见的值包括:

供应商
"anthropic" Anthropic(Claude 系列)
"openai" OpenAI(GPT 系列)
"google" Google(Gemini 系列)
"deepseek" DeepSeek
"mistral" Mistral AI
"groq" Groq
"openrouter" OpenRouter(聚合网关)
"xai" xAI(Grok)

如果你在项目配置中覆盖了 defaultProvider,Pi 会在该项目中始终使用你指定的供应商。

5.2.2 defaultModel

"defaultModel": "claude-sonnet-4-20250514"

指定 Pi 默认使用的模型 ID。模型 ID 的格式取决于供应商,例如:

// Anthropic
"defaultModel": "claude-sonnet-4-20250514"

// OpenAI
"defaultModel": "gpt-4.1"

// DeepSeek
"defaultModel": "deepseek-chat"

// Google
"defaultModel": "gemini-2.5-pro-exp-03-25"

// OpenRouter
"defaultModel": "anthropic/claude-sonnet-4"

注意:如果你切换了 defaultProvider,请务必同时检查 defaultModel 是否对该供应商有效。一个供应商不认识的模型 ID 会在首次 API 调用时触发错误,Pi 会在 TUI 中直接显示具体报错信息。

5.2.3 defaultThinkingLevel

"defaultThinkingLevel": "medium"

控制 Pi 是否启用模型的 思考/扩展推理(extended reasoning) 能力。并非所有模型都支持思考(例如 GPT-4o 不支持,Claude 3.5 Sonnet 之后的模型支持,DeepSeek-R1 支持),Pi 会在运行时自动检测:如果模型不支持思考,该设置会被静默忽略。

可选值:

含义 适用场景
"off" 关闭思考 简单任务:查资料、改一行配置、拼写纠正
"minimal" 最小思考 中等任务:改一个函数、调整 CSS、写注释
"low" 低强度思考 稍复杂:重构一个模块、写单元测试
"medium" 中等思考 日常编码:实现一个完整功能、跨文件重构
"high" 高强度思考 困难任务:架构决策、性能优化、复杂 Bug 排查
"xhigh" 极强思考 极高难度:安全审计、算法设计、大型系统设计

最佳实践:日常编码建议设为 "medium"。简单的一行修改可以用 /thinking off 临时关闭;遇到棘手 Bug 时用 /thinking high 临时提升——这两个斜杠命令可以在会话中动态切换,不影响配置文件。

5.2.4 thinkingBudgets

"thinkingBudgets": {
  "off": 0,
  "minimal": 1024,
  "low": 2048,
  "medium": 4096,
  "high": 8192,
  "xhigh": 16384
}

自定义每个思考级别的 token 预算上限。这个字段是可选的——不写就用 Pi 的内置默认值(如上表)。

什么时候需要自定义?举个例子:Claude Opus 的思考能力非常强,但 4096 token 的”中等思考”可能不够它完整推演一个跨文件的架构改动,你可以把 medium 调到 8192。相反,如果你用的模型思考能力一般、给定太多 token 只是浪费钱,可以把 high8192 下调到 4096

5.2.5 模型与思考完整示例

{
  "defaultProvider": "anthropic",
  "defaultModel": "claude-sonnet-4-20250514",
  "defaultThinkingLevel": "medium",
  "thinkingBudgets": {
    "off": 0,
    "minimal": 1024,
    "low": 2048,
    "medium": 4096,
    "high": 8192,
    "xhigh": 16384
  }
}

5.3 UI 与显示配置

5.3.1 theme

"theme": "dark"

控制 Pi TUI 的颜色主题。内置选项:

效果
"dark" 深色主题(默认)
"light" 浅色主题
"high-contrast" 高对比度主题(无障碍友好)

你也可以指定自定义主题名称——Pi 会从 ~/.pi/themes/ 和项目 .pi/themes/ 目录中加载 .json 主题文件。例如,如果你写了一个 ~/.pi/themes/solarized.json,就可以设置:

"theme": "solarized"

自定义主题文件的编写方式见 5.6.5

5.3.2 externalEditor

"externalEditor": "code --wait"

当你使用 /editor 命令(打开外部编辑器编辑当前提示词,或编辑某段多行内容)时,Pi 会调用这里指定的命令。默认值是系统 $EDITOR 环境变量(通常是 vimnanonotepad)。

常用设置:

// VS Code
"externalEditor": "code --wait"

// Vim
"externalEditor": "vim"

// Neovim
"externalEditor": "nvim"

// Emacs
"externalEditor": "emacs"

// Sublime Text
"externalEditor": "subl --wait"

// JetBrains (需要安装命令行工具)
"externalEditor": "idea --wait"

注意--wait 标志至关重要——它告诉编辑器以”阻塞模式”打开,Pi 会等待你关闭文件后再继续。不加 --wait 的话,Pi 可能在你还未保存时就读取了文件。

5.3.3 quietStartup

"quietStartup": false

默认 false。设为 true 后,Pi 启动时不再显示版本号、模型信息、供应商状态等启动头部信息,直接进入对话。

这个选项在以下场景特别有用:

  • 脚本化调用:通过 SDK 嵌入或 RPC 模式启动 Pi 时,减少控制台噪音。
  • Alacritty / tmux 分屏:屏幕空间有限,不想被启动信息占满。
  • 个人偏好:你只是单纯不想每次都看那些信息。

5.3.4 defaultProjectTrust

"defaultProjectTrust": "ask"

控制 Pi 对包含 .pi/settings.json 的项目的默认行为:

行为
"ask" 每次进入新项目都询问(默认,推荐)
"always" 自动信任所有项目配置
"never" 永不加载项目级配置,即使已信任也忽略

安全建议:保持 "ask"。只有当你 100% 确定所有经手的项目都是可信的(例如,你只在自己的项目中使用 Pi),才考虑切换为 "always""never" 适合需要严格隔离的场景——比如你在审查恶意代码库,不希望任何项目配置影响 Pi 的行为。

5.3.5 UI 与显示完整示例

{
  "theme": "dark",
  "externalEditor": "code --wait",
  "quietStartup": false,
  "defaultProjectTrust": "ask"
}

5.4 会话与压缩配置

Pi 的每一次对话都是一个”会话(session)”。随着对话进行,消息历史越长,发送给模型的 context 就越大——直到超出模型的上下文窗口上限。届时,Pi 需要通过压缩(compaction)把长历史精简为一段摘要,为后续对话腾出空间。

5.4.1 为什么需要压缩

假设你正在用 Pi 重构一个大型项目。对话已经进行了 30 轮:你让它读了 8 个文件、改了 12 处代码、排查了 3 个 Bug、讨论了 2 个架构方案。原始对话历史轻松超过 20000 token。如果模型上下文窗口是 200K token,还能撑一阵;如果是 128K 或更少,很快就满了。

压缩做的事情是:用一个专门的摘要调用,把”已完成、不再需要细节”的那部分历史压缩成一段结构化摘要(”用户要求重构 user-service.ts,已完成:1. 提取 validateEmail 函数……2. 修复 login 接口的 race condition……”),释放出来的 token 空间用于新一轮对话。

5.4.2 compaction.enabled

"compaction": {
  "enabled": true
}

是否启用自动压缩。默认 true

  • true:当 token 预算接近上限时,Pi 自动触发压缩。
  • false:关闭自动压缩。上下文超出窗口上限时,最旧的对话会被直接丢弃(truncation),而不是压缩成摘要。不推荐,除非你有特殊理由。

5.4.3 compaction.reserveTokens

"compaction": {
  "reserveTokens": 16384
}

压缩后为模型响应预留的 token 数。默认 16384

Pi 的工作方式是:在发送上下文给模型之前,确保有至少 reserveTokens 个 token 的空间留给模型输出。如果剩余空间不足,就触发压缩腾出空间。

这个值不宜设得太低——如果模型的输出被 token 限制截断,你会得到一个不完整的代码块或半截回答。16384 是一个合理默认值,允许模型输出约 12000~16000 个中文字符。如果你经常让模型生成大量代码(例如一次性重写整个文件),可以考虑调到 32768

5.4.4 compaction.keepRecentTokens

"compaction": {
  "keepRecentTokens": 20000
}

压缩时保留的最近对话 token 数。默认 20000

压缩不是把整个历史都压掉——最近几轮对话包含当前的上下文脉络,不能被压缩。keepRecentTokens 指定了”从最新消息往回数,保留多少 token 不被压缩”。

举个例子:总共 60000 token 历史,reserveTokens = 16384keepRecentTokens = 20000。Pi 会计算:

上下文窗口 - reserveTokens - keepRecentTokens = 可压缩的历史部分

只压缩”最早的那段历史”,保留”最近的 20000 token”原样不动。这意味着压缩后,模型依然能看到你最近几轮的完整对话细节,只是丢失了早期已经完成的那些任务的详细记录(变成了摘要)。

5.4.5 压缩策略

Pi 的压缩策略可以用一句话概括:宁可多压一点,也不能让模型输出被截断

压缩本身也是一次 API 调用(通常是调用一次模型,把旧历史作为输入,要求模型生成摘要),因此:

  1. 压缩调用会消耗少量 token(通常 500~2000 token 用于摘要本身)。
  2. 压缩使用的模型是你的 defaultModel
  3. 如果你设置了 defaultThinkingLevel: "high",压缩调用也会使用高强度思考——但其实没必要。Pi 内部会将压缩调用的思考级别强制设为 "minimal",你不需要额外配置。

如果你希望在特定项目中关闭压缩(例如,你正在进行一个短对话,不担心 token 超出),可以在项目 .pi/settings.json 中覆盖:

{
  "compaction": {
    "enabled": false
  }
}

5.4.6 会话与压缩完整示例

{
  "compaction": {
    "enabled": true,
    "reserveTokens": 16384,
    "keepRecentTokens": 20000
  }
}

5.5 重试机制配置

API 调用偶尔会失败——超时、限流、网络抖动、供应商临时故障。Pi 内置一套指数退避重试机制,确保这些瞬时故障不会打断你的工作流。

5.5.1 retry.enabled

"retry": {
  "enabled": true
}

是否启用自动重试。默认 true

5.5.2 retry.maxRetries

"retry": {
  "maxRetries": 3
}

最大重试次数。默认 3。超出此次数后,Pi 将在 TUI 中显示错误信息并将控制权交还给你——你可以手动重试(输入 /retry)或换一种提问方式。

5.5.3 retry.baseDelayMs

"retry": {
  "baseDelayMs": 2000
}

指数退避的基础延迟(毫秒)。默认 2000(2 秒)。

Pi 的重试延迟公式为:

延迟 = baseDelayMs × 2重试次数 + 随机抖动

具体来说,默认配置下的实际延迟序列为:

重试次数 延迟(约)
第 1 次 2~3 秒
第 2 次 4~6 秒
第 3 次 8~12 秒

加上随机抖动(±25%)是为了避免多个并发的重试请求同时打到供应商(”thundering herd”问题)。

5.5.4 retry.provider.timeoutMs

"retry": {
  "provider": {
    "timeoutMs": 120000
  }
}

单次 API 请求的超时时间(毫秒)。默认 120000(2 分钟)。

这是网络层面的超时——包括了 DNS 解析、TCP 连接、TLS 握手、请求发送和响应接收的全过程。如果供应商在 2 分钟内没有返回任何字节,Pi 会判定该次请求失败并触发重试。

如果你的网络环境不稳定(例如通过代理访问、跨国访问),可以考虑调高这个值:

"retry": {
  "provider": {
    "timeoutMs": 300000
  }
}

5.5.5 retry.provider.maxRetryDelayMs

"retry": {
  "provider": {
    "maxRetryDelayMs": 30000
  }
}

单次重试的最大延迟上限(毫秒)。默认 30000(30 秒)。

当指数退避公式计算出的延迟超过这个值时,会被截断为这个值。防止在 maxRetries 较大时出现”等几分钟才重试”的极端情况。

5.5.6 重试机制完整示例

{
  "retry": {
    "enabled": true,
    "maxRetries": 3,
    "baseDelayMs": 2000,
    "provider": {
      "timeoutMs": 120000,
      "maxRetryDelayMs": 30000
    }
  }
}

5.6 资源加载配置

Pi 的可扩展性在很大程度上依赖于”资源加载”——你可以引入 npm 包、TypeScript 扩展、技能文件、提示模板和主题文件来定制 Pi 的行为。这一节详细说明资源加载相关的所有配置字段。

5.6.1 packages

"packages": [
  "my-pi-tools@1.0.0",
  "git+https://github.com/user/pi-custom-skill.git"
]

一个字符串数组,每项是一个包引用。Pi 支持两种包引用格式:

格式 示例 说明
npm 包 "my-pi-tools@1.0.0" 通过 npm registry 安装的包。@version 可选,不写则取 latest
Git 仓库 "git+https://github.com/user/pi-custom-skill.git" 直接指向一个 Git 仓库(需要是公开可访问的,或你有 SSH 权限)

Pi 在启动时会自动解析 packages 数组,下载并加载每个包中注册的扩展、技能、提示模板和主题。关于包的编写和分发细节,见第十章:Pi 包管理与分发

包引用中的版本号强烈建议标注。不标版本意味着”总是用最新版”——如果包作者发布了一个不兼容的更新,你的 Pi 可能在下一次启动时突然行为异常。

数组合并规则:项目配置中的 packages 追加到全局配置之后。

5.6.2 extensions

"extensions": [
  "~/.pi/extensions/my-tools.js",
  "./tools/ci-helper.ts"
]

一个 TypeScript / JavaScript 文件路径数组,指定 Pi 启动时需要加载的扩展文件。扩展是 Pi 最强大的定制手段——你可以在扩展中定义新工具、注册生命周期钩子、注入自定义系统提示等。详细开发方法见第九章:Extensions 扩展开发

路径支持:

前缀/格式 解析规则 示例
~ 开头 展开为用户主目录 "~/.pi/extensions/my-tools.ts"
./ 开头 相对于当前工作目录 "./tools/ci-helper.ts"
其他 相对于 Pi 配置文件所在目录

数组合并规则:项目配置中的 extensions 追加到全局配置之后。这意味着项目的扩展在全局扩展之后加载——你可以利用这个顺序实现”先全局基础,再项目覆盖”的效果。

5.6.3 skills

"skills": [
  "~/.pi/skills/typescript-best-practices/SKILL.md",
  "~/.pi/skills/git-workflow/SKILL.md",
  "./.pi/skills/project-conventions/SKILL.md"
]

一个路径数组,指向要加载的技能文件SKILL.md)。技能是 Pi 的核心能力之一——每个技能文件包含一段结构化的提示词,告诉模型”如何完成某类特定任务”。详见第八章:Skills 技能系统

数组合并规则:项目配置中的 skills 追加到全局配置之后。

重要提示:技能文件的内容会注入到系统提示中,占用 token 预算。不要加载用不上的技能文件——每多一个技能,模型的有效上下文就少一点。把项目专有的技能放在项目配置中,全局通用的放在全局配置中。

5.6.4 prompts

"prompts": [
  "~/.pi/prompts/code-review.md",
  "~/.pi/prompts/writing-style.md"
]

一个路径数组,指向要加载的提示模板文件。提示模板是纯文本文件,其内容会被追加到系统提示的末尾(在所有技能之后、在对话历史之前)。

提示模板的典型用途:

  • 代码风格规范:”始终使用 2 空格缩进。函数名使用 camelCase。导出函数必须包含 JSDoc 注释。”
  • 工作流约束:”每次改动前先解释你要做什么。改动后检查是否引入了 lint 错误。”
  • 行为偏好:”回复中文。使用简体中文。不要使用 emoji。”

数组合并规则:项目配置中的 prompts 追加到全局配置之后。

5.6.5 themes

"themes": [
  "~/.pi/themes/solarized.json",
  "~/.pi/themes/nord.json"
]

一个路径数组,指向要加载的自定义主题文件。每个主题文件是一个 JSON 文件,定义了 TUI 各元素的颜色。

主题文件的典型结构:

{
  "name": "solarized",
  "colors": {
    "background": "#002b36",
    "foreground": "#839496",
    "accent": "#268bd2",
    "error": "#dc322f",
    "warning": "#b58900",
    "success": "#859900",
    "userBubble": "#073642",
    "assistantBubble": "#002b36",
    "toolOutput": "#586e75",
    "dimmed": "#657b83"
  }
}

然后你在 theme 字段中引用它的 name

"theme": "solarized"

数组合并规则:项目配置中的 themes 追加到全局配置之后。

主题系统的完整定制指南(包括完整的自定义主题 JSON 结构、颜色字段详解、热重载机制)请见 第八章:Skills 技能系统 的 8.8 Themes 主题系统小节。

5.6.6 资源加载完整示例

{
  "packages": [
    "pi-tool-react@0.2.0",
    "git+https://github.com/user/pi-gitlab-tools.git"
  ],
  "extensions": [
    "~/.pi/extensions/shell-safety.ts",
    "./tools/project-utils.ts"
  ],
  "skills": [
    "~/.pi/skills/git-workflow/SKILL.md",
    "~/.pi/skills/code-review/SKILL.md",
    "./.pi/skills/project-conventions/SKILL.md"
  ],
  "prompts": [
    "~/.pi/prompts/coding-style.md"
  ],
  "themes": [
    "~/.pi/themes/solarized.json"
  ]
}

5.7 其他配置

5.7.1 httpProxy

"httpProxy": "http://127.0.0.1:7890"

HTTP 代理地址。当你处于需要代理才能访问模型供应商 API 的网络环境时(例如中国大陆访问 OpenAI API),设置此项。Pi 会将所有发出的 HTTP 请求通过此代理转发。

留空或不写此字段表示直连。

5.7.2 shellPath

"shellPath": "C:\\Program Files\\Git\\bin\\bash.exe"

自定义 Shell 路径。Pi 在执行 bash 工具时调用此处的 Shell 可执行文件。默认值取决于操作系统:

操作系统 默认 Shell
Linux /bin/bash,若不存在则 /bin/sh
macOS /bin/zsh,若不存在则 /bin/bash
Windows PowerShell(powershell.exe

在 Windows 上,如果你安装了 Git Bash 或 WSL,可以通过此字段让 Pi 使用类 Unix Shell:

// Windows + Git Bash
"shellPath": "C:\\Program Files\\Git\\bin\\bash.exe"

// Windows + WSL
"shellPath": "wsl.exe"

安全提示shellPath 指向的可执行文件必须是你信任的。Pi 不会对此路径做任何安全校验——它只是直接调用。

5.7.3 npmCommand

"npmCommand": "pnpm"

包管理命令。Pi 在安装 packages 中指定的 npm 包时,会使用这个命令。默认值为 "npm"

可选值取决于你系统上安装了什么:

包管理器
"npm" npm(默认)
"pnpm" pnpm
"yarn" Yarn Classic
"bun" Bun

5.7.4 enabledModels

"enabledModels": [
  "claude-sonnet-4-20250514",
  "claude-opus-4-20250514",
  "gpt-4.1",
  "deepseek-chat"
]

Ctrl+P 模型切换器中出现的模型列表。输入 Ctrl+P 后,Pi 会弹出一个模型选择菜单:

┌──── 切换模型 ────────────────────────────┐
│                                           │
│  · claude-sonnet-4-20250514               │
│    claude-opus-4-20250514                 │
│    gpt-4.1                                │
│    deepseek-chat                          │
│                                           │
│  ↑↓ 选择  Enter 确认  Esc 取消            │
│                                           │
└───────────────────────────────────────────┘

只有出现在此列表中的模型才能在 Ctrl+P 中快速切换。如果你的 defaultModel 不在此列表中,它依然会正常使用(defaultModelenabledModels 是独立的),只是你不能通过 Ctrl+P 切换到它之后再切回来——除非你把它也加入 enabledModels

数组合并规则:项目配置中的 enabledModels 完全替换全局配置中的值(不追加)。

5.7.5 steeringMode

"steeringMode": "auto"

消息投递模式。这个配置比较底层,通常不需要修改。它控制 Pi 在生成响应时如何与模型交互:

行为
"auto" 自动模式(默认)。Pi 自行决定投递策略。
"streaming" 强制流式。每条响应都通过 SSE 流式返回。
"batch" 强制批量。等模型完整生成后再一次性返回。

绝大多数情况下保持 "auto" 即可。只有在调试或特殊性能需求时才需要修改。

5.7.6 followUpMode

"followUpMode": "auto"

后续消息投递模式。控制 Pi 在模型返回后是否自动发送”后续消息”(follow-up)。同样通常不需要修改:

行为
"auto" 自动模式(默认)。
"always" 始终发送后续消息。
"never" 不发送后续消息。

5.7.7 其他配置完整示例

{
  "httpProxy": "http://127.0.0.1:7890",
  "shellPath": "C:\\Program Files\\Git\\bin\\bash.exe",
  "npmCommand": "pnpm",
  "enabledModels": [
    "claude-sonnet-4-20250514",
    "claude-opus-4-20250514",
    "gpt-4.1",
    "deepseek-chat"
  ],
  "steeringMode": "auto",
  "followUpMode": "auto"
}

5.8 CLI 参数覆盖

配置文件是”持久化”的配置。有时你只想临时改变某个设置——例如用 DeepSeek 跑一次,用完后切回原来的模型。Pi 提供了一套 CLI 参数和环境变量机制,让你无需改动 settings.json 就能覆盖配置。

5.8.1 配置优先级

从低到高,Pi 配置的优先级为:

内置默认值  <  全局 settings.json  <  项目 .pi/settings.json  <  环境变量  <  CLI 参数
  • 内置默认值:硬编码在 Pi 源码中的出厂设置。
  • 全局 settings.json:覆盖内置默认值。
  • 项目 .pi/settings.json:覆盖全局配置。
  • 环境变量:覆盖以上所有配置文件的对应字段。
  • CLI 参数:最高优先级,覆盖一切。

5.8.2 环境变量

Pi 支持通过以下环境变量覆盖对应的配置项:

环境变量 覆盖的配置字段 示例
PI_PROVIDER defaultProvider export PI_PROVIDER=deepseek
PI_MODEL defaultModel export PI_MODEL=deepseek-chat
PI_THINKING defaultThinkingLevel export PI_THINKING=high
PI_THEME theme export PI_THEME=light
PI_EDITOR externalEditor export PI_EDITOR="code --wait"
PI_PROXY httpProxy export PI_PROXY=http://127.0.0.1:7890
PI_SHELL shellPath export PI_SHELL=/bin/zsh
HTTPS_PROXY httpProxy(备选) export HTTPS_PROXY=http://127.0.0.1:7890

注意HTTPS_PROXYPI_PROXY 的备选——如果两个都设置了,PI_PROXY 优先。

环境变量在以下场景最常用:

  • CI/CD 管道:在 GitHub Actions 或 Jenkins 中运行 Pi 时,通过环境变量注入配置,无需创建配置文件。
  • 临时切换模型PI_MODEL=deepseek-chat pi 用 DeepSeek 启动 Pi,下次不加这个变量就恢复原模型。
  • 多机器的差异化设置.bashrc / .zshrc 中根据主机名设置不同的 PI_PROXY

5.8.3 --api-key

pi --api-key sk-ant-api03-xxxxxxxxxxxxx

临时覆盖 API Key。这个参数会覆盖 ~/.pi/agent/credentials.json 中存储的 API Key(凭证文件的详细说明见第四章)。

典型使用场景:

  • 你的 API Key 刚刚轮换,但不想立即写入凭证文件——先用 --api-key 测试一下新 Key 是否有效。
  • 借用同事的 API Key 做一个临时测试,用完即弃。
  • CI/CD 中通过 Secrets 注入 API Key,避免将凭证写入文件系统。

5.8.4 --tools--exclude-tools

# 只启用 bash 和 read 工具
pi --tools bash,read

# 排除只读搜索工具
pi --exclude-tools grep,find

--tools:白名单模式——只有列表中的工具对模型可见。所有其他工具(包括通过 extensions 注册的)都被隐藏。

--exclude-tools:黑名单模式——从工具列表中移除指定的工具。

两者可以同时使用(先应用白名单,再应用黑名单),但通常不会同时用——选一个就够了。

工具名称是工具在 Pi 内部的注册名(与你在 TUI 中看到的工具调用名称一致)。常见内置工具名:

工具名 功能
read 读取文件内容
write 创建或覆盖文件
edit 精确字符串替换编辑
bash 执行 Shell 命令
grep 正则表达式搜索文件内容(可选启用)
find 按 glob 模式查找文件(可选启用)
ls 列出目录内容(可选启用)

5.8.5 --no-builtin-tools--no-tools

# 禁用所有内置工具(扩展工具仍然可用)
pi --no-builtin-tools

# 禁用所有工具——只能是纯聊天模式
pi --no-tools
  • --no-builtin-tools:禁用 Pi 自带的 readwriteeditbash 四个核心工具。通过 extensions 注册的自定义工具仍然可用。
  • --no-tools:禁用所有工具(内置 + 扩展),Pi 变成纯对话模式,不能读写文件、不能执行命令。

这些参数在以下场景有用:

  • 你只想和 Pi 聊天、讨论方案,不希望它碰任何文件。
  • 测试一个新的 extension 工具时,不想被内置工具干扰。
  • 安全审查场景:让 Pi 在”只读对话”模式下分析代码。

5.8.6 -e / --extension

# 加载单个扩展文件
pi -e ./tools/my-experiment.ts

# 加载多个扩展文件
pi -e ./tools/a.ts -e ./tools/b.ts

临时加载一个或多个 TypeScript 扩展文件。这些扩展只在本次会话中有效——不会写入 settings.json

这是测试新扩展的标准工作流:

  1. 写出扩展的初始版本。
  2. pi -e ./tools/my-experiment.ts 启动 Pi 并加载它。
  3. 在对话中调用扩展注册的工具,观察行为是否正确。
  4. 迭代修改扩展文件,用 /reload 重新加载。
  5. 最终版本通过后,把它加入 settings.jsonextensions 数组中。

5.9 完整配置示例

5.9.1 全局配置:~/.pi/agent/settings.json

以下是一份完整的、用于日常编码的全局配置示例。它涵盖了本章介绍的所有配置分类,你可以把它作为起点,根据自己的需求删减或修改:

{
  "defaultProvider": "anthropic",
  "defaultModel": "claude-sonnet-4-20250514",
  "defaultThinkingLevel": "medium",
  "thinkingBudgets": {
    "off": 0,
    "minimal": 1024,
    "low": 2048,
    "medium": 4096,
    "high": 8192,
    "xhigh": 16384
  },

  "theme": "dark",
  "externalEditor": "code --wait",
  "quietStartup": false,
  "defaultProjectTrust": "ask",

  "compaction": {
    "enabled": true,
    "reserveTokens": 16384,
    "keepRecentTokens": 20000
  },

  "retry": {
    "enabled": true,
    "maxRetries": 3,
    "baseDelayMs": 2000,
    "provider": {
      "timeoutMs": 120000,
      "maxRetryDelayMs": 30000
    }
  },

  "packages": [
    "pi-tool-react@0.2.0"
  ],
  "extensions": [
    "~/.pi/extensions/shell-safety.ts",
    "~/.pi/extensions/git-helper.ts"
  ],
  "skills": [
    "~/.pi/skills/typescript-best-practices/SKILL.md",
    "~/.pi/skills/git-workflow/SKILL.md",
    "~/.pi/skills/code-review/SKILL.md"
  ],
  "prompts": [
    "~/.pi/prompts/coding-style.md"
  ],
  "themes": [
    "~/.pi/themes/solarized.json"
  ],

  "httpProxy": "",
  "shellPath": "",
  "npmCommand": "pnpm",
  "enabledModels": [
    "claude-sonnet-4-20250514",
    "claude-opus-4-20250514",
    "gpt-4.1",
    "deepseek-chat",
    "gemini-2.5-pro-exp-03-25"
  ],
  "steeringMode": "auto",
  "followUpMode": "auto"
}

说明httpProxyshellPath 留空表示使用系统默认(直连/系统默认 Shell)。中国大陆用户通常需要在此填写代理地址。

5.9.2 项目配置:.pi/settings.json

以下是一份典型的项目级配置。它覆盖了全局配置中的模型选择(该项目使用 GPT-4.1 而非 Claude Sonnet),并额外加载了项目专有的技能和提示模板:

{
  "defaultProvider": "openai",
  "defaultModel": "gpt-4.1",
  "defaultThinkingLevel": "low",

  "skills": [
    "./.pi/skills/api-design-conventions/SKILL.md",
    "./.pi/skills/database-migration/SKILL.md"
  ],
  "prompts": [
    "./.pi/prompts/repo-style-guide.md",
    "./.pi/prompts/commit-conventions.md"
  ],
  "extensions": [
    "./.pi/extensions/db-migrate-helper.ts"
  ],

  "compaction": {
    "reserveTokens": 32768
  }
}

分析一下这份配置的合并效果:

字段 全局值 项目值 最终生效
defaultProvider "anthropic" "openai" "openai"(覆盖)
defaultModel "claude-sonnet-4-20250514" "gpt-4.1" "gpt-4.1"(覆盖)
defaultThinkingLevel "medium" "low" "low"(覆盖)
theme "dark" 未设置 "dark"(沿用全局)
compaction.reserveTokens 16384 32768 32768(覆盖)
compaction.enabled true 未设置 true(沿用全局)
skills 3 个全局技能 2 个项目技能 5 个技能(追加)
prompts 1 个全局模板 2 个项目模板 3 个模板(追加)
extensions 2 个全局扩展 1 个项目扩展 3 个扩展(追加)

5.10 配置迁移

Pi 是一个活跃开发的项目。随着新版本发布,settings.json 的字段可能会新增、重命名、废弃或改变默认值。好消息是,pi update 命令会自动处理配置迁移。

5.10.1 pi update 自动迁移

pi update

当你运行 pi update 升级 Pi 到新版本时,升级脚本会:

  1. 检测 ~/.pi/agent/settings.json 的当前结构。
  2. 对比 新版本期望的结构。
  3. 自动迁移
    • 新增字段:插入默认值。
    • 重命名字段:自动改名并保留原值。
    • 废弃字段:在迁移日志中给出警告,但不删除(你可以手动清理)。
  4. 备份:迁移前自动备份原始 settings.jsonsettings.json.bak-<timestamp>

迁移过程中的日志会打印在终端上,类似这样:

[pi] 正在迁移配置文件...
[pi] ✓ 新增字段: thinkingBudgets (默认值)
[pi] ✓ 重命名字段: modelId → defaultModel (保留原值)
[pi] ⚠ 废弃字段: legacyTimeout 已不再使用,你可以从配置中手动删除
[pi] 配置迁移完成。备份已保存为 settings.json.bak-20250630-143022

5.10.2 版本升级注意事项

  1. 不要手动编辑备份文件后覆盖。迁移后的 settings.json 是 Pi 唯一识别的格式。如果你恢复了旧备份,Pi 会在下次启动时再次执行迁移——但如果有破坏性变更(breaking change),可能导致配置被错误解析。

  2. 项目级 .pi/settings.json 也会被迁移。在项目目录内运行 pi update 时,升级脚本会同时迁移项目配置。

  3. thinkingBudgets 是较晚引入的字段。如果你从早期版本升级,这个字段会被自动添加默认值。如果你之前通过其他方式(例如环境变量)控制了思考预算,迁移后可能需要手动调整这个字段。

  4. 扩展的 API 可能随版本变化。如果你维护了自定义扩展,升级 Pi 后请检查扩展调用的 API 是否仍然兼容。Pi 的扩展 API 遵循语义化版本,主版本号变化时可能存在不兼容变更。建议阅读 Pi 的 CHANGELOG 后再升级。

  5. 始终在升级前 git commit 你的工作,或者在升级后运行一次简单测试:”你好,列出当前目录的文件”。确保 Pi 的基本功能——文件读写、Shell 命令、模型调用——都能正常工作。


5.11 本章小结

本章我们完整剖析了 Pi 的配置体系:

  • 两层配置(全局 ~/.pi/agent/settings.json + 项目 .pi/settings.json)提供了”默认值 + 项目覆盖”的灵活性。
  • 项目信任机制确保了安全性——你不会在不知情的情况下加载他人的配置。
  • /settings 提供了交互式的可视化配置体验,同时也完全兼容手动编辑 JSON。
  • 模型与思考配置让你精确控制 Pi 的”智能水平”——从零思考到极强推理。
  • UI 与显示配置让你定制 Pi 的外观和行为——主题、编辑器、启动画面、信任策略。
  • 会话压缩是 Pi 在长对话中保持可用性的关键,理解 reserveTokenskeepRecentTokens 的含义能帮你避免模型输出被截断。
  • 指数退避重试机制确保瞬时故障不会打断你的工作流。
  • 资源加载packagesextensionsskillspromptsthemes)是 Pi 可扩展性的基石——每个数组都支持全局配置 + 项目追加。
  • CLI 参数覆盖让临时切换配置变得简单——环境变量和命令行参数优先级高于配置文件。
  • pi update 自动迁移让你无忧升级,备份机制确保出问题时可以回滚。

下一章:第六章:交互式TUI深入 将深入 Pi 的交互式 TUI——斜杠命令体系、键盘快捷键、会话管理、checkpoint/rollback、以及 profile 切换等日常使用中最高频的操作。


提示:如果你在配置中遇到任何问题,先运行 pi doctor 做一次诊断。它会把当前生效的所有配置(包含两层合并后的最终值)打印出来,并标注每条配置的来源(全局/项目/环境变量/CLI 参数),方便你快速定位问题。