1. 从“能用”到“好用”:Pi 1.0 到底改了什么
先说结论,这次升级最值得关注的就两个点:原生 MCP 支持和 Pi Durable 持久化执行。我是在开发版里泡了一周之后,再切回正式版对比用的,体验差距非常明显。在终端里跑编程代理的人应该都有一个同感:之前用 Pi,能干的事不少,但每次对话一断、任务一长,或者要接入外部工具的时候,就总有一种“使不上劲”的感觉。1.0 版本把这两个短板一次性补上了。
但我想先替大家问一句:原生 MCP 是什么?Pi Durable 又是什么?如果你不关心协议细节,只想知道“这次升级跟我有什么关系”,那我用一句话概括:MCP 让 Pi 能直接调用你电脑上、服务器里、云平台上的各种工具和数据源,而不是靠开发者提前写死的插件;Durable 则让 Pi 能在断线、重启、网络抖动后继续之前没干完的活,任务做到一半不会白费。就这两件事,足以让终端编程代理从“能陪你聊代码”进化成“能替你办成事”。
这一版的意义不在于功能数量的堆叠,而在于工作方式的转变。以前我在终端里用 Pi,基本是“问答式”:我描述需求,它生成代码,我再复制到项目里跑。现在不一样了,Pi 可以直接操作我的 Git 仓库、调用测试框架、读取线上日志,甚至把耗时几十分钟的批量重构任务挂在后台,我关掉终端去忙别的,回来之后它能告诉我进展到哪一步。这种体验,用过就回不去。
2. 原生 MCP 接入:配置方式与为什么不走兼容层
2.1 配置文件里的一小段 JSON,背后是协议级的变化
MCP 的全称是 Model Context Protocol,说白了就是给 AI 代理和外部工具之间定的一套“统一插口协议”。Pi 1.0 之前也支持接工具,但走的是自家闭源格式,你要用工具,得等 Pi 官方适配,或者自己写插件。现在原生 MCP,等于直接把插口标准开放给整个生态,凡是支持 MCP 的工具,理论上都能直接接进来。
我实际配置的第一个 MCP 服务是一个团队内部日志查询服务,配置过程比我想象中简单。在 Pi 的配置文件里加一段:
{ "mcpServers": { "log-service": { "type": "remote", "url": "https://mcp.example.internal/log-service", "tokenEnvVar": "LOG_SERVICE_TOKEN" }, "local-db": { "type": "stdio", "command": "node", "args": ["/path/to/mcp-local-db/index.js"], "env": { "DB_PATH": "/workspace/data" } } } }里面有两类比较典型:remote走网络协议连远程服务;stdio则在本地拉起一个子进程,用标准输入输出通信。配完之后,在 Pi 里输入/mcp list,能看到两个服务都连上了。整个流程比从前要顺滑太多,因为 Pi 不用再花额外时间做协议转换,请求直接从代理层透传到目标工具。
2.2 如果只改配置不改权限模型,一定会踩坑
只接好管道不设权限,等于把家门钥匙挂门口。我第一天把 Pi 接入团队的日志服务之后,顺手对它说“把最近三天的 error 日志按模块分组统计一下”,结果 Pi 不只统计了,还自作主张查了生产环境某个表的计数。这不怪 Pi,是我没在 MCP 配置里声明哪些操作允许、哪些操作需要人工确认。
Pi 1.0 的权限控制是分级的。对每个 MCP 工具,你可以选allow、ask、deny三种策略。ask模式会在 Pi 准备调用某个工具时弹一次确认,确认信息里会写明工具名、参数和预计影响范围。我建议把写操作、删除操作、生产环境相关的工具统一设为ask,读操作可以allow。别嫌每次确认麻烦,等你在线上环境误触发过一次批量修改,就会明白这十秒钟的确认有多值。
另外要注意,MCP token 的存储位置尽量别写在配置文件明文里。用环境变量引用的方式,就是上面 JSON 里tokenEnvVar字段存在的意义。它会把 token 从 Shell 的环境变量里读取,而不是把密钥暴露在明文配置文件里。这点虽然看起来微不足道,但对团队协作来说,能避免不少密钥泄露事故。
2.3 MCP 工具调用的实际体验差异
接入 MCP 之后,Pi 的思考链路会发生一个明显变化:它会先判断“这个任务需不需要外部工具”,再决定要不要调用,而不是像以前那样先猜一个答案再问你。举个例子,我问“当前分支比 main 领先多少个提交,并且有哪些文件被改过”,它不再凭印象估算,而是直接调 Git MCP 工具去查,然后给出精确数据。
体验上的差距主要在两点。一是信息新鲜度,接上日志、数据库、监控系统的 MCP 之后,Pi 的回答永远基于实时数据;二是操作闭环,它完成的不只是“写一段代码”,而是“改完代码、跑完测试、给你把结果发到终端”。这种感觉很像你旁边坐了一位能直接上手敲键盘的同事,而不是一个只能给建议的顾问。
3. Pi Durable 持久化执行:会话恢复、任务续跑与底层实现逻辑
3.1 Durable 到底持久化了什么
Pi Durable 是个很容易被误解的功能。它不是简单的聊天记录保存,而是把“代理的执行状态”完完整整地持久化下来。所谓执行状态,包括当前任务的执行计划、已经完成的步骤、各步骤的输出结果、正在等待的外部调用、上下文窗口中的关键决策记录,以及任务之间的依赖关系。也就是说,当一次任务被打断,恢复之后 Pi 知道“我之前做到哪一步了、为什么要做这一步、下一步原本打算做什么”。
从用户视角看,最直观的变化就是:你可以放心地在任务执行到一半时关掉终端。以前我跑一个多文件的批量重构,最怕的就是笔记本合盖、断网、或者终端意外退出,一切都要从头再来。现在直接在 Pi 里启动一个 Durable 任务,它会生成一个任务 ID,像这样:
pi task start "重构 auth 模块,并把所有 API 返回统一格式" --durable # 输出: task_9f2c81b4 started (durable mode)然后你可以随时用pi task resume task_9f2c81b4把它捞回来。即使 Pi 进程本身退出了,重启之后也能接上。
3.2 断线重连的恢复链路
恢复链路的处理很有意思,它不只是简单“把对话记录倒回去”,而是基于执行图做状态重建。所谓执行图,就是任务被拆解后形成的步骤节点和依赖关系。某个节点如果已经执行完成,它的输出会被缓存;如果执行到一半依赖外部 MCP 工具调用,那它会根据这次调用的结果快照恢复上下文;如果还没执行,就继续往下走。
比如我让 Pi 用一个脚本处理一千个数据文件,处理到第 316 个文件时网络断了。如果我开了 Durable,恢复之后它会直接从第 317 个开始,而不是重新跑全量。这里的关键就在于它对“已完成节点”的判断。实测下来,恢复后任务能精确跳转到断点附近,即使中途有几次 MCP 调用结果发生变化,它也能感知到并做出重新计算。
这不是魔法,本质上是把执行计划做成可序列化的数据,再配合日志存储和状态检查点。但从使用者角度看,它把终端编程代理从“会话工具”变成了“任务系统”。这是质的区别。
3.3 任务编排中的 Durable 应用
除了断点续跑,Durable 在任务编排上的价值更值得琢磨。Pi 1.0 允许你把一个大任务拆成多个子任务,每个子任务都可以单独设置为 Durable,而且可以定义依赖顺序。这非常接近一个轻量级的工作流引擎。
我尝试过的一个典型场景是这样的:每天早晨让 Pi 自动拉取最新代码、跑测试、汇总失败用例、给出第一轮修复建议。如果测试失败,它进入修复模式,修复后重新跑一次相关用例;如果修复不了,就把失败信息整理成报告推送给我。整个流水线由四个 Durable 子任务串联。中途任何一个环节失败,比如测试服务超时了,Pi 会记录失败状态,等下一次重试时只重跑失败的那个环节。
更重要的是,Pi 会为每个子任务保留执行痕迹。当出现问题时,我可以直接问它“第二个子任务失败时,执行到哪个测试用例了”,它能给出具体答案,而不是含糊地说“测试没通过”。这种可追溯性,对排查代理自身的问题也有帮助——本质上你要 debug 的不仅是你自己的代码,还有代理的执行逻辑。
4. 升级迁移实测:旧配置兼容性与最容易爆雷的地方
4.1 升级前备份与迁移路径
从 0.9.x 升级到 1.0,官方说“无缝兼容”,但我建议别信“无缝”这种词。老老实实先备份。备份内容主要是三块:Pi 的全局配置目录、项目级配置文件、以及已有的任务状态数据。在 macOS 和 Linux 上,配置通常在~/.pi/目录下;Windows 则在%USERPROFILE%\.pi\。
备份命令很简单,直接拷贝目录就行:
cp -r ~/.pi ~/.pi.bak升级完成后,先跑一次pi doctor检查环境,它会列出当前版本、配置加载情况、MCP 服务连接状态。我第一次升级时,发现问题出在一个旧的插件配置上:0.9.x 时代我为内部代码搜索工具配的插件,在 1.0 里被标记为 deprecated,但它还能加载,只是每次调用会打印一条警告,并且部分能力被限制。你如果也遇到类似情况,建议尽早把旧插件迁移到 MCP 方式,别拖着。
4.2 兼容性问题和补救方案
最容易爆雷的是以下几类:
第一类是自定义 prompt 模板中的变量名变化。旧版本里我用过{workspace}这个变量,1.0 改成了{workspacePath},导致我写的一段自动生成提交信息的规则失效。这类问题通常不会有报错,只会表现为“脚本行为不符合预期”,排查起来比较费劲。
第二类是旧插件和 MCP 服务的功能重叠。如果你以前同时开着旧版代码搜索插件,又新配置了同样的 MCP 服务,Pi 可能会把同类工具合并展示,但也可能出现“两个工具互相覆盖”的情况。我的建议是功能重复的旧插件直接禁用,不要两个都开。
第三类是权限配置变化。1.0 对文件读写权限做了更严格的默认限制。以前 Pi 可以直接写/tmp目录下任意文件,现在需要显式授权。如果你原先跑得好好的自动化流程,升级后突然说“没有权限”,去权限列表里把对应目录加回来就行。
如果你在升级后发现某个项目没法正常工作,还有个排查技巧:在项目根目录跑pi doctor --project,它会输出项目级别的配置文件解析结果,帮你定位是全局配置覆盖了项目配置,还是项目配置里的某个字段格式不对。这个命令在 0.9 里没有,算是 1.0 新增的“体检工具”。
5. 把 MCP 和 Durable 组合起来跑通一个真实任务
5.1 任务设计:批量处理 + 断点续跑
光看不练不行,我拿一个真实任务组合跑了一遍。这个任务的背景是:我需要把某仓库里所有 Python 文件的 import 语句规范化,按标准库、第三方库、本地模块三组排序,同时把重复的 import 合并掉。这个任务有一定重复性、操作量不小,又正好能用上“批量替换 + 安全检查”的场景。
老办法是写个脚本一把梭,但脚本处理边界情况容易翻车。用 Pi 的做法是:让它先分析所有文件,挑出需要修改的,再逐个改,最后统一跑一遍语法检查和测试。我把它定义成一个 Durable 任务,全程记录执行状态。
启动之前,我先通过 MCP 接入了一个代码静态分析服务。这个服务能对 Python 代码做 AST 结构分析,判断修改前后是否有语法差异。这样 Pi 每改一个文件,就可以调用这个工具做一次校验,而不是等全部改完才发现某个文件格式错了。
5.2 用 Pi 完成一次跨工具调用
任务启动后,我观察到的执行流程大致是这样的:Pi 先调用了 Git MCP 工具,列出当前分支上所有修改过的 Python 文件清单;然后对清单里的文件逐个读取内容,在上下文里规划出每个文件的 import 排序方案;接着按方案修改,每改完一个,调用静态分析服务校验语法;最后,全部文件改完后,Pi 自动跑了pytest里的相关用例,并汇总结果。
整个流程中 Pi 一共调用了三类外部工具,全部走 MCP。这期间我把终端关掉了大概二十分钟,回来之后执行pi task resume打开任务会话,它把已经完成的 43 个文件和剩余 7 个文件的处理情况直接列了出来。注意,这里不是简单说“任务还在进行”,而是给出了有结构的信息:哪些文件已经通过语法检查、哪些文件等待修改、哪些文件报告了潜在冲突。这种透明度是以前版本完全不具备的。
5.3 几个实际运行数字
这次任务总共涉及 50 个 Python 文件。全部处理完,耗时约 37 分钟。其中 Pi 主动调用 MCP 工具的次数是 113 次,包括 Git 操作、文件读取、静态分析校验和测试执行。整个过程中,有 3 个文件在修改后静态分析服务报了“潜在名称冲突”的警告,Pi 没有硬改,而是转成了两条人工确认请求。这里我要给一个好评:它没有为了追求“全自动完成”而强行忽略风险。
如果不用 Pi,我用脚本处理这批任务,估计也就 10 分钟左右能跑完初版,但后续检查冲突、修异常、跑测试的循环,可能还要再花两个小时。Pi 的方式是慢一点,但出错概率明显低很多。核心原因就是每一步都留痕、每一步都能回溯、每一步都能断点续跑。
6. 性能、安全与使用边界
6.1 权限模型和安全底座
MCP 和 Durable 都涉及执行外部操作,所以安全是绕不开的话题。Pi 1.0 的安全模型可以拆成三层看。
第一层是命令执行权限。Pi 执行的每条 Shell 命令都会先经过规则引擎,匹配你配置的 allow/ask/deny 列表。默认未匹配的情况下是 ask,也就是会弹确认。第二层是文件系统权限,细化到读、写、执行三种操作,可以按路径前缀配置。第三层是 MCP 工具权限,即上面提到的工具级策略。三层叠加,形成一个还算严密的访问控制矩阵。
有个细节值得点赞:当 Pi 准备执行一条被规则引擎判定为“高风险”的命令时,它不会简单拒绝,而是会把命令改写为一个更保守的版本,然后提示你确认。比如它想对整个仓库执行git clean,如果规则不允许,它会改为列出将被清理的文件清单,让你先过目。这种“建议替代方案”的思路,比生硬拦截体验好很多。
6.2 会话存储与隐私
Durable 模式要求 Pi 把任务状态写入本地存储。默认存储在~/.pi/tasks/下,每个任务一个子目录,里面包含执行日志、状态快照、上下文摘要。这个目录的权限位默认是 700,也就是只有当前用户能读写。如果你在多用户机器上使用,一定要确认这个权限没有被改过。
我建议定期清理不再需要的任务记录。特别是涉及生产环境操作、数据库查询的任务,任务日志里可能包含敏感信息。Pi 提供了自动清理策略,可以在配置里设置任务数据的保留天数。比如设成 7 天,过期任务就会被归档压缩。清理前它会给出可恢复的归档文件,等确认无需要时再物理删除。这个机制对于日常工作流来说,够用了。
6.3 什么时候别用 Durable
Durable 很强,但别以为所有任务都该开。我在使用中总结出几个不适合用 Durable 的场景,供你参考。
第一是超短任务。比如“帮我把这个函数加上注释”这类一两分钟就能完成的,没必要挂 Durable,纯属浪费存储空间。
第二是强交互任务。如果你需要 Pi 在每个步骤之间频繁征求你的决策意见,而且决策依赖最新的外部反馈,那么断点续跑的意义并不大。因为恢复后你还是要重新提供判断依据。
第三是涉及“一次性环境”的任务。比如某容器里临时跑一段脚本,容器销毁后任务状态就算存下来,也无法在干净环境里继续。Durable 适用范围更偏向持续存在的、可重复触发的执行环境。
这里还想多说一句关于成本的问题。Pi 1.0 的 Durable 模式下,每次恢复任务都会消耗一定的 token 来重建上下文。如果你的任务断点特别多,恢复十几次,光重建上下文的开销就非常可观。建议任务设计时合并连续步骤,减少不必要的断点,既省钱也省时间。
7. 我的最终结论与使用建议
折腾了两周,我觉得 Pi 1.0 最大的价值不在单个功能,而在于把两个原本独立的能力焊在了一起。原生 MCP 解决的是“手能伸多远”,Durable 解决的是“活儿能不能干完”。合在一起,终端编程代理才真正具备了常驻后台、跨工具协作、断点续跑的完整闭环。
如果你也想上手,我的建议是从场景倒推需求。不要为了用 MCP 而接一堆服务,先想清楚你日常最耗时、最容易中断的长任务是什么,然后只接对应必要的 MCP 工具。我目前工作中收益最大的三类接入是:代码仓库操作、自动化测试执行、日志查询。这三类恰好在日常开发中出现频率最高、也最适合让代理直接动手。
最后分享一个小技巧:在 Durable 任务运行过程中,我习惯每隔一段时间问一句“当前进展如何”,这个动作看起来可有可无,但实际上它会倒逼 Pi 把执行状态整理成摘要,等于顺手给任务打了日志标记。将来如果要回溯整个任务,这些摘要就是最清晰的目录。你要是还没升级到 1.0,不用犹豫,备份好配置直接上。这一版值得。