- xk1282026-09-0520428
第三版以来又用了快一个月。第一次安装 Pi 的佬友可以先看前三版,这篇继续记录第三版之后的变化。
前三版
Pi 从零安装到入门配置:Windows 实战教程
Pi Windows 工作流第二版:从第一版配置升级到现在有哪些改变?
Pi Windows 工作流第三版:继续迭代
你也可以直接把四篇文章交给agent让它配置好
本版:编写于 2026 年 9 月 5 日,Pi
0.85.0。这次改动主要来自三件事:Pi 有了原生 PowerShell 工具;我换了一套上下文压缩方案;插件更新后,原有配置和本地扩展的部分需要对应调整。
项目 |
第三版 |
当前状态 |终端工具 |
通过bash工具和 shell 配置使用 PowerShell |
主会话和常规子代理显式使用原生powershell工具 |上下文 |
原生自动压缩、pi-ultra-compact、context-mode|
关闭原生自动压缩,移除 ultra-compact,改用 Magic Context;保留 context-mode |中文界面 |
pi-di18n接管部分内置工具显示 |
移除 pi-di18n,使用rpiv-i18n翻译接入它的扩展界面 |模型选择 |
Plan 角色写死模型,后台组件各自配置 |
Plan 角色已继承模型,Historian 用本地扩展同步;普通角色仍有固定供应商配置,下面一起说明如何改成跟随 |MCP |
Context7、DeepWiki 提前连接 |
两者改为按需连接,工具是否直接暴露另行配置 |通知 |
新增的通知插件 |
新增@pi-unipi/notify,使用 Windows 桌面通知 |本地扩展 |
plan-subagent-ceiling|
保留原扩展,新增magic-context-model-sync同步 Historian 的模型选择 |下面只展开说说上述这些影响工作流使用方式的变化。其他未提及就是没有改变。
原生 PowerShell:主会话、子代理、Plan 和权限一起调整
Pi
0.84.2加入defaultTools,0.84.3加入可选的原生powershell工具。这两项合起来,可以让模型看到的工具名和实际使用的终端一致。之前需要反复告诉模型:虽然工具叫 Bash,这里要按 PowerShell 的变量、引号和路径规则执行。现在主会话直接使用下面这份工具列表。
settings.json 中的当前终端配置```
{
"shellPath": "C:\\Program Files\\PowerShell\\7\\pwsh.exe",
"defaultTools": [
"read",
"powershell",
"edit",
"write",
"grep",
"find",
"ls"
]
}
``这里起工具选择作用的是defaultTools,不能只改shellPath。原生 PowerShell 工具优先找pwsh.exe`,没有时才回退到 Windows PowerShell。Pi 在 Windows 上默认仍选择 Bash,需要自己显式启用 PowerShell。另外,编辑器里的
!、!!仍走 Bash 入口。defaultTools也只选择内置工具。常规子代理也要改自己的工具列表。 主会话启用了 PowerShell,不会覆盖角色配置里已经写死的
tools。我在settings.json.subagents.agentOverrides里同步调整了普通角色,下面以 scout 和 worker 为例:常规子代理的 PowerShell 工具配置摘录```
{
"subagents": {
"agentOverrides": {
"scout": {
"tools": ["read", "grep", "find", "ls", "powershell", "contact_supervisor"]
},
"worker": {
"tools": ["read", "grep", "find", "ls", "powershell", "edit", "write", "contact_supervisor"]
}
}
}
}
``其他常规角色也使用powershell`。这里仅摘录工具字段,合并时保留原有的思考等级、上下文继承等配置;模型如何跟随供应商切换,放到后面的模型一节统一说。Plan 的工具选择单独配置。 我在
~/.pi/agent/pi-plan-mode.json的defaultPlanTools中加入powershell,原有读工具、subagent、FFF 和 MCP 条目继续保留,当前文件也仍保留bash。Plan 会对有效的bash/powershell工具应用有限命令策略,普通会话能执行的脚本不一定能通过 Plan 检查。这里的
safeSubcommands要按当前版本理解:命中自定义信任前缀后,Plan 会跳过整条命令的解析检查,无法起到只读保证。三个plan-*专用角色仍只保留read/grep/find/ls。权限插件也要认识新工具名。
权限继续使用
@gotgenes/pi-permission-system,在它的配置里补充:```
{
"shellTools": {
"powershell": {
"commandArgument": "command"
}
}
}
``把这段合并到~/.pi/agent/extensions/pi-permission-system/config.json,原有permission` 规则保留。因为命令规则写在
permission.bash下。shellTools告诉插件:名为powershell的工具也携带 shell 命令,命令正文在command参数里,要送进现有命令检查链路。只换工具名、不补这个映射,插件会把它当普通扩展工具处理。终端规则仍按 PowerShell 7 和 UTF-8 编写,避免在原生工具外再套一层 Bash 或
cmd。普通角色即使没有edit/write,也可能通过 PowerShell 写入文件;我自己的协作规则继续要求子代理只回传证据,由主线程修改文件。Magic Context:安装、配置和日常更新
前情提要 Pi 有没有压缩插件推荐?
虽然 OpenAI 那边引入了新的上下文压缩方式,但是 Pi 这边还没有跟进,观望一下。
我对上下文的需求是长会话里的整理和回读:旧调查可以从当前上下文移出,需要时还能找回原始消息;不需要把每次任务都积累成跨会话长期记忆。
第三版的组合是原生自动压缩、
pi-ultra-compact和context-mode。现在移除了pi-ultra-compact,安装@cortexkit/pi-magic-context。现在三个组件这样分工:
-
context-mode继续负责大段工具结果的外部索引和检索。- Magic Context 给消息打标签,通过
ctx_reduce排队移出不再需要的内容,Historian 在后台整理旧对话,需要原文时通过ctx_expand回读。- Pi 原生自动压缩关闭,由 Magic Context 管理这条自动整理路径。
首次安装,向导和手动安装二选一。
在 PowerShell 7 中运行官方向导:```
npx @cortexkit/magic-context@latest setup --harness pi
```--harness pi明确指定 Pi,避免同时装了其他宿主时选错目标。向导会注册 Pi 扩展、创建 Magic Context 配置,并询问 Historian、Dreamer、Sidekick 和 embedding 的模型选择。先在 Pi 里配置好可用的供应商和模型,再按自己的需要选择;我只保留会话整理,后面会关闭长期记忆等功能。如果不需要向导,也可以直接安装 Pi 包:```
pi install npm:@cortexkit/pi-magic-context
``这条会把扩展加入 Pi 的packages,但不会替你创建magic-context.jsonc`,需要自行准备。上面两个命令是两条安装路径,不用连续执行。记得移除你的其他记忆或上下文管理插件避免冲突,例如我的:```
pi remove npm:pi-ultra-compact
```压缩开关分别配置。 Pi 的原生自动压缩关闭,Magic Context 自己的压缩开启。在
~/.pi/agent/settings.json关闭 Pi 原生压缩配置,让 Magic Context 接管。Pi 的压缩配置```
{
"compaction": {
"enabled": false,
"reserveTokens": 65536,
"keepRecentTokens": 24000
}
}
``Magic Context 当前配置摘录``
{
"enabled": true,
"auto_update": true,
"language": "zh",
"cache_ttl": "5m",
"execute_threshold_percentage": 65,
"history_budget_percentage": 0.18,
"protected_tags": 24,
"compaction": {
"enabled": true
},
"smart_drops": false,
"caveman_text_compression": {
"enabled": false
},
"dreamer": {
"disable": true
},
"memory": {
"enabled": false
},
"todowrite": {
"enabled": false
},
"sidekick": {
"disable": true
},
"embedding": {
"provider": "off"
}
}
``这份文件在~/.config/cortexkit/magic-context.jsonc,不在.pi目录里。项目自己的.cortexkit/magic-context.jsonc` 还能覆盖用户配置。这里关闭了长期记忆、embedding、Dreamer、Sidekick 和 Magic Context 自带 Todo。任务列表继续由现有
rpiv-todo负责。Historian 的模型字段和跟随主会话的办法放到下一节,手动安装时也要补上那部分。上面的内容作参考。
日常更新 :
命令 |
更新范围 |pi update npm:@cortexkit/pi-magic-context|
只更新 Magic Context 的 Pi 扩展 |pi update --extensions|
更新扩展包 |pi update|
只更新 Pi 本体 |pi update --all|
更新 Pi 本体和扩展包 |虽然配置虽然写着
auto_update: true,但是现在 magic-context 只支持 OpenCode 插件侧的自动更新检查,不负责升级 Pi 包。Pi 这边仍使用第一条定向更新命令。日常可以按下面的顺序操作:
- 正常结束当前任务和后台子代理,退出使用同一 Magic Context 数据库的会话。
- 在 PowerShell 中定向更新扩展。
- 用官方
doctor检查安装、配置和依赖状态,阅读输出后再决定是否需要处理问题。- 回到项目目录重新启动 Pi,用
/ctx-status查看本次会话状态,再按下一节同步 Historian 模型。第 2、3 步的命令是:```
pi update npm:@cortexkit/pi-magic-context
npx @cortexkit/magic-context@latest doctor --harness pi
``注意两个包名不同:@cortexkit/magic-context是提供setup、doctor的统一 CLI,@cortexkit/pi-magic-context才是 Pi 加载的扩展。npx ...@latest doctor` 使用新版诊断 CLI,不等于把 Pi 插件也更新了。doctor也不完全是只读命令,可能迁移旧配置位置,所以先备份。日常更新不需要顺手加--force或--clear。Magic Context 默认把数据放在
~/.local/share/cortexkit/magic-context/。如果设置了MAGIC_CONTEXT_STORAGE_DIR等路径覆盖,就备份实际使用的目录。同一份数据库可能被 Pi、OpenCode 或 OMP 共用,混合版本进程可能阻止迁移,因此跨版本更新后建议完整退出重启。多供应商切换:子代理继承,Historian 同步
我经常会在不同供应商(中转)之间切换。同一个模型名在不同供应商下是不同的
provider/model,主会话切换以后,后台组件如果仍写死A/...,就不会自动跟着走。Pi
0.84.3增加了/thinking选择器。通过/model和/thinking做的临时选择保持在当前会话,按Ctrl+S才保存为启动默认。模型跟随要以当前父会话的选择为准,就不能只盯着settings.json中的默认值。于是乎为了解决上述问题,现在我的工作流里存在两种情况:一种是类似 pi-subagents 原生支持继承父会话模型直接改成继承父会话模型;一种是类似 Magic Context 的 Historian 需要读取独立配置,需要自己编写本地扩展同步。
Plan 角色已经改成继承。 三个专用角色仍保存在
~/.pi/agent/agents/,共同使用model: inherit:角色 |
当前模型设置 |
思考等级 |
工具 |plan-scout|inherit|
low |read, grep, find, ls|plan-researcher|inherit|
medium |read, grep, find, ls|plan-reviewer|inherit|
medium |read, grep, find, ls|inherit选择的是启动子代理时父会话正在使用的供应商和模型。角色的 low/medium 思考分工继续保留,plan-researcher的timeoutMs: 900000、空extensions和inheritSkills: false也没有放开。常规角色也需要去掉固定供应商,应删除
subagents.defaultModel的固定值,把各角色的model改为inherit,并删除旧的固定fallbackModels,否则失败回退时仍可能回到原供应商。下面是补齐跟随行为的配置示例:普通角色跟随父会话的模型配置```
{
"subagents": {
"agentOverrides": {
"delegate": { "model": "inherit", "thinking": "low" },
"scout": { "model": "inherit", "thinking": "low" },
"context-builder": { "model": "inherit", "thinking": "low" },
"researcher": { "model": "inherit", "thinking": "low" },
"planner": { "model": "inherit", "thinking": "medium" },
"worker": { "model": "inherit", "thinking": "medium" },
"reviewer": { "model": "inherit", "thinking": "medium" },
"oracle": { "model": "inherit", "thinking": "medium" }
}
}
}
``这段只覆盖模型和思考字段,前面配置好的tools、inheritProjectContext` 等字段保留。单次子代理调用若显式传入模型,仍会覆盖继承设置;已经运行的子代理也不会因为父会话切模型而中途换模型。如果想只跟随供应商,但让各角色继续使用不同型号,当前插件还支持
subagents.agentOverridesByProvider,按父会话的供应商匹配角色配置。它和“所有角色直接 inherit”是两种选择。Historian 通过本地扩展同步。 它的配置在
~/.config/cortexkit/magic-context.jsonc,我的配置是:```
{
"historian": {
"pi": {
"model": "a/gpt-6-astra",
"thinking_level": "xhigh"
}
}
}
``这里需要填写 Pi 中已经配置且可用的provider/model。为避免每次切换都手动修改,我新增了~/.pi/agent/extensions/magic-context-model-sync/index.ts`:magic-context-model-sync/index.ts```
import { readFile, writeFile } from "node:fs/promises";
import { createRequire } from "node:module";
import { homedir } from "node:os";
import { join } from "node:path";
import { getAgentDir, type ExtensionAPI, type ExtensionContext } from "@earendil-works/pi-coding-agent";type Model = { provider: string; id: string };
type MagicContextConfig = {
historian?: {
pi?: {
model?: unknown;
thinking_level?: unknown;
fallback_models?: unknown;
[key: string]: unknown;
};
[key: string]: unknown;
};
[key: string]: unknown;
};const configPath = join(
process.env.XDG_CONFIG_HOME ?? join(homedir(), ".config"),
"cortexkit",
"magic-context.jsonc",
);
const requireFromAgentPackages = createRequire(join(getAgentDir(), "npm", "package.json"));
const { parse, stringify } = requireFromAgentPackages("comment-json") as {
parse: <T>(source: string) => T;
stringify: (value: unknown, replacer: null, space: number) => string;
};function modelKey(model: Model): string {
return${model.provider}/${model.id};
}async function syncHistorianModel(model: Model, thinkingLevel: string | undefined): Promise<boolean> {
const source = await readFile(configPath, "utf8");
const config = parse<MagicContextConfig>(source);
const historian = config.historian ?? (config.historian = {});
const pi = historian.pi ?? (historian.pi = {});
const nextModel = modelKey(model);
const changed = pi.model !== nextModel
|| pi.thinking_level !== thinkingLevel
|| "fallback_models" in pi;if (!changed) return false;
pi.model = nextModel;
if (thinkingLevel) pi.thinking_level = thinkingLevel;
else delete pi.thinking_level;
delete pi.fallback_models;
await writeFile(configPath,${stringify(config, null, 2)}\n, "utf8");
return true;
}export default function magicContextModelSync(pi: ExtensionAPI) {
pi.on("model_select", async (event, ctx) => {
try {
if (await syncHistorianModel(event.model, ctx.thinkingLevel)) {
ctx.ui.notify(
Magic Context Historian 已同步至 ${modelKey(event.model)};执行 /sync-magic-model 可立即重载。,
"info",
);
}
} catch (error) {
ctx.ui.notify(
无法同步 Magic Context Historian:${error instanceof Error ? error.message : String(error)},
"warning",
);
}
});pi.registerCommand("sync-magic-model", {
description: "Sync Magic Context Historian with the current Pi model and reload",
handler: async (_args, ctx: ExtensionContext) => {
if (!ctx.model) {
ctx.ui.notify("当前没有已选模型,未同步 Magic Context Historian。", "warning");
return;
}
try {
await syncHistorianModel(ctx.model, ctx.thinkingLevel);
await ctx.reload();
} catch (error) {
ctx.ui.notify(
无法同步 Magic Context Historian:${error instanceof Error ? error.message : String(error)},
"error",
);
}
},
});
}
``- 收到model_select时,把完整的供应商、模型 ID 和当时的思考等级写入historian.pi`。- 删除旧的
fallback_models,避免后台继续沿用另一套固定供应商。- 提供
/sync-magic-model,手动同步当前选择并 reload。日常操作就是先在 Pi 里选好供应商、模型和思考等级,再执行
/sync-magic-model。只切模型会自动写文件,不会自动 reload;只调思考等级时也用这条命令同步。这个扩展只同步 Historian,不会重写
settings.json.subagents,所以普通角色的继承配置仍要单独完成。它写的是全局文件,多开会话时后一次写入会影响后续读取这份配置的会话;项目若另有 Magic Context 模型覆盖,也要避免把它固定在旧供应商上。MCP 减少无必要的提前启动
我用的 MCP 如下:
服务 |
当前生命周期 |
工具暴露方式 |context-mode |
eager |
direct |sequential-thinking |
eager |
direct |mcp-server-time |
eager |
direct |shrimp-task-manager |
eager |
direct |context7-1 |
lazy |
只直接暴露resolve-library-id、query-docs|mcp-deepwiki |
lazy |
direct |playwright |
lazy |
通过 adapter 代理调用 |chrome-devtools-mcp |
lazy |
通过 adapter 代理调用 |相较第三版,Context7 和 DeepWiki 从 eager 改成 lazy,避免每次启动就连接暂时不用的文档服务。全局
directTools为 false,再按服务覆盖。lazy表示按需连接,directTools决定工具如何暴露给模型。Context7 当前配置片段```
{
"protocolVersion": "auto",
"lifecycle": "lazy",
"directTools": [
"resolve-library-id",
"query-docs"
]
}
```界面、汉化和桌面通知Pi 本体这一个月增加了几项日常操作:
版本 |
与日常使用有关的更新 |0.84.2|
全屏对话全文搜索;单独点击展开思考块和工具结果 |0.84.3|
调整 Windows/WSL 的部分默认快捷键 |0.84.4|
新增fullscreenCopyOnSelect,可关闭拖选后自动复制;关闭后Ctrl+X优先复制选区 |0.85.0|
上翻后可点击 Jump to latest message 回到最新消息;优化长对话搜索的缓存、索引和高亮处理 |我的
tuiMode: fullscreen、自动滚动条和 Markdown 配置继续保留,没有显式关闭fullscreenCopyOnSelect。快捷键继续以自己的
keybindings.json为准。我的文件保留第三版的编辑器移动和换行绑定,另外显式设置了:```
{
"tui.altScreen.searchPrevious": "shift+enter"
}
```汉化从 pi-di18n 换成 rpiv-i18n。第三版为了避免内置工具重复注册,把
read/edit/write/bash留给 pi-di18n,tool-display 只接管搜索工具。现在因为 pi-di18n 作者维护不及时,我已经放弃了汉化,移除pi-di18n。rpiv-i18n 提供
/languages,统一切换接入其 SDK 的扩展界面语言;它不会把整个 Pi、所有内置工具或发给模型的提示词都翻译成中文。我现在的语言设置是:```
{
"locale": "zh"
}
``文件在~/.config/rpiv-i18n/locale.json`。这样能保留问答、Todo 等已接入扩展的中文界面,同时不再依赖 pi-di18n 覆盖内置工具显示。显示层的其他分工继续沿用:
- Pi 负责全屏布局、滚动、搜索和内置显示。
-
pi-zentui负责编辑器、用户消息和 Starship Footer;当前图标模式是ascii,主题为codex-graphite。-
pi-tool-display仍只启用grep/find/ls的内置工具覆盖,read/bash/edit/write保持 false。-
pi-markdown-preview保留独立预览能力。补齐桌面通知能力
顺便我还新增了插件
@pi-unipi/notify补齐桌面通知能力。长任务结束、模型需要我回答问题,或者权限插件正在等确认时,我希望在切到其他窗口后仍能收到提醒。它支持原生桌面、Gotify、Telegram 和 ntfy。我现在只开启原生桌面通知,另外三个渠道关闭,通知的模型摘要
recap也关闭。当前通知配置摘录```
{
"native": {
"enabled": true,
"suppressWhenFocused": true
},
"events": {
"agent_end": {
"enabled": true,
"platforms": []
},
"agent_settled": {
"enabled": true,
"platforms": []
},
"ask_user_prompt": {
"enabled": true,
"platforms": []
},
"permission_request": {
"enabled": true,
"platforms": []
}
},
"recap": {
"enabled": false
}
}
``配置位置是~/.unipi/config/notify/config.json,可以通过/unipi:notify-settings调整。suppressWhenFocused用来抑制 Pi 窗口处于焦点时的原生通知,空platforms` 则使用已启用的渠道。插件已经接入
rpiv-ask-user-question的提问事件和权限插件的确认事件。agent_end表示一次 agent run 结束,agent_settled才表示重试、压缩和排队续跑结束后的稳定状态。我当前两项都开着,不能把每条结束通知都理解成整项任务已经完成。其他工作流、MCP 错误等事件开关也已开启,但跨插件事件需要对应发送方配合。
当前插件版本一览
当前插件版本一览
包 |
已安装版本 |pi-mcp-adapter|2.32.1|pi-until-done|0.3.1|@narumitw/pi-plan-mode|0.56.0|@juicesharp/rpiv-advisor|2.9.0|pi-simplify|0.2.3|pi-markdown-preview|0.16.0|@juicesharp/rpiv-ask-user-question|2.9.0|@juicesharp/rpiv-i18n|2.9.0|pi-rewind|0.5.0|@gotgenes/pi-permission-system|31.1.1|pi-wtf|0.2.4|@ff-labs/pi-fff|0.10.6|pi-web-access|0.28.0|@juicesharp/rpiv-todo|2.9.0|pi-zentui|0.22.3|pi-subagents|0.65.1|pi-tool-display|0.5.0|@narumitw/pi-lsp|0.49.6|@cortexkit/pi-magic-context|0.41.3|@pi-unipi/notify|2.16.0|AGENTS.md 更新
我的最新 AGENTS.md
AGENTS.md.txt (17.1 KB)

主要差异是适配 pi 支持原生 PowerShell 那在提示词里的约束可以删去一些(但是必要的还是要保留),然后就是改善说废话,还有试图解决静态检查时候召唤子agent无限循环检查和非得给你写测试脚本的毛病,把功能改动约束在主流程里面解决,要求所有功能改动必须在检查前完成,检查只检查代码格式问题,配合 LSP 可以解决。
主楼 - 一摩尔氚2026-09-056098
- 15713790552026-09-0545737
佬,关注啦,很有用的教程
- 土豆哪里去挖2026-09-0535893
这个教程真不错^-^下次我照着给我的pi试一下这一套
- Aprils1482026-09-0531951
感謝分享,最近用pi覺得真心不錯