EDITOR’S SELECTION

深入 Harness:我误解 pi 的四个月

Nick Nisi 复盘自己为何错把 pi 当成更快的 Claude Code,以及可扩展的 Harness 如何让工具从外部脚本真正进入智能体会话。

原文:Inside the Harness: Four Months of Being Wrong About pi

作者:Nick Nisi

7 月 20 日,一位同事在我们的 #pi Slack 频道里问:

在我继续深入研究 pi 之前,谁能告诉我,为什么 @nicknisi 说他不再认为 pi 是个好主意?

Zack 已经开始基于 pi 做东西,刚好又听到我说它不值得投入。这个问题很合理,他想知道原因。

而我的全部回复只有一句:“不过我还是很爱 pi!:homer-disappear:”

我回避了这个问题。

两周后,我在十天里运行了 188 个 pi 会话,而 Claude Code 会话只有 17 个。Zack,下面才是我真正应该给你的答案。

我早已建好的那座城

我生活在终端里:tmux、Neovim、把 rg 的结果管道传给 fzf,还有一条被我调到除了自己谁也看不懂的状态栏。

到今年春天,我已经围绕 Claude Code 建起了一整座城市。case 通过流水线调度智能体,并用机械化方式强制执行约定。Fleet 监视我 tmux 服务器里的每一个智能体,把需要我介入的那些排在最前面。sessions 索引了我机器上每一段 Claude、Codex 和 pi 对话,让任何会话都能查询过去的任意会话。我的插件仓库存放 Skills,tmux 状态栏负责通知。

但这些东西没有一个运行在 Claude Code 内部。它们全部运行在 Claude Code 的旁边:存在于 bash、Bun 和 ~/.cache 下的文件里,再从 Harness 偶然暴露出来的缝隙伸进去。

真正打动我的说法

今年春天,我们 Slack 里有人开始把 pi 描述为“编程智能体里的 Neovim”,而 Claude Code 则像 VS Code。一个把你可能需要的一切都打包进去;另一个只交给你一个裸循环,然后退到一边。

如果你见过我的 dotfiles,就知道为什么这个说法会留在我脑子里。

又过了几周,我才真正试用它。3 月 18 日星期三下午 2:36,我还在 #pi 频道里开玩笑,说 pi 团队是不是也拥有 shittycodingagent.ai

下午 2:48,我第一次打开 pi,输入了 hello

下午 3:07,我问它“pi 能做什么?”,读完回答后试图用 :qa 退出。

到 3:20,我已经把 ~/.pi 软链接进自己的 dotfiles 仓库。3:27,我粘贴了 Claude Code 的状态栏脚本,问:“我们能为 pi 重做一个吗?”当天晚上,我就提交了一个 pi 状态栏扩展、一个 tmux 状态桥接、一个 Night Owl 主题和一组加载动画动词。

第二天,我问 pi 能不能编写自己的扩展。它写了一个。我把结果发到 Slack,只配了一个 🤯。

渐行渐远

下面是我按磁盘上的会话数量统计的 pi 月度使用情况:

月份 pi 会话 Claude Code 会话
3 月 111 ~1,200
4 月 17 ~590
5 月 29 ~535
6 月 2 ~400
7 月 0 ~710

dotfiles 里的 pi 提交也讲述着相同的故事:3 月 19 次,之后依次是 2、5、1、4 次。7 月的会话数是零。

pi 并不差。它非常好——更快、更安静、权限提示更少,模型切换也真的有效。#pi 里的每个人都一直这么说,他们是对的。

只是我建好的那座城没有跟着我迁移。Fleet 只知道怎样读取 Claude Code 的 Hooks;case 只知道怎样调度 Claude;我的 tmux 通知只会为 Claude 窗格亮起。在 pi 里度过的每一个小时,都意味着离开那套我已经打磨了几个月的工具。

dotfiles 里最能说明问题的一次提交来自 5 月 28 日:feat: cut tmux + Claude Code over to fleet。同一天,我发布了介绍 Fleet 的文章。那是这座城市的巅峰,也是 pi 在结构上变得不可能适合我的那个时刻。

所以当 Zack 来问时,我告诉他不值得。我没有撒谎,我描述的是一种真实成本。只是我把成本产生的原因判断错了。

我一直遗漏的东西

8 月 1 日星期六上午 10:08。我在 dotfiles 仓库里打开 pi,输入:

到目前为止,我一直把 pi 当成 Claude Code 来用。我知道自己可以再深入一些,让 pi 变得更好,但我不确定具体该怎么做。除了一个类似 Claude Code 的简单编程 Harness,它还有什么能力?

我已经把它当成一个更快的终端聊天窗口用了四个月,却始终没有问过它还能做什么。

pi 刻意选择了不自带子智能体、计划模式、权限弹窗、待办事项、后台 bash 和 MCP。因为每一项本来就是有意留下的扩展点。扩展是一个 TypeScript 模块:它可以注册工具,替换内置的 read / edit / bash 工具,挂接每一个生命周期事件,拦截或改写工具调用,还可以接管编辑器、页脚、页头和浮层。这个模块接口就是产品本身。如果一个功能不是扩展,pi 就不会自带它。

状态栏给出的证明

这个对比的两边都是我亲手做的,所以它才如此击中我。

为了判断一个 Claude Code 智能体是在工作、等待还是已经完成,Fleet 必须融合三种信号,而其中任何一种都不能单独信任。Bash Hooks 会写入状态文件——很快、有结构,但到达顺序可能错乱。每个窗格一份 JSONL 事件日志——知道意图,却有延迟。还有 tmux capture-pane——它是事实来源,但一次要花约 50ms,而且 Claude 的加载图标会,所以只匹配固定字符会漏掉一半帧。整个项目最终教会我的就是:每一层只对自己真正值得信任的那部分信息具有权威性。因为整套技术栈里,没有任何东西可以直接问智能体“你现在在做什么”。

pi 的状态栏扩展只有 519 行 TypeScript。它订阅 tool_execution_startagent_end,调用 ctx.getContextUsage(),把一个渲染函数交给 ui.setFooter(),再从 footerData 中读取分支。没有抓取,没有信号融合,也没有新鲜度规则。我旧 Fleet 技术栈里的每一个 Bash Hook 和 capture-pane 抓取,都被这一个订阅替代了。

十天

仅 8 月 3 日一天:58 个会话。

我在 #pi 里发了一句:“有人把自己的 pi 配置开源了吗?我很想把它们都翻一遍!”然后我把能找到的每一份都读了:oh-my-pi、pikit、LazyPi,还有一个陌生人的 my-pi-setup。就像凌晨一点翻看别人的 dotfiles 一样。

我移植了自己真正想念的便利功能:动态工作流、/goal/loop/btw、会话自动命名、AskUserQuestion、草稿暂存、回顾卡片。我替换了那个已经抱怨了几个星期的网页搜索工具。我还做了 /mg——一个《人生切割术》风格的“100% 文件完成”动画,由像素化的 CEO 主演,还带音效——因为我能做,而且没人能阻止我。两小时后,我把它发到了 X,配上了它唯一值得拥有的文字:WorkOS 的开发者与智能体体验工程师所做的工作,神秘且重要。

我还认真地问 pi:是否应该把这一切打包成一个发行版给别人使用。它启动了一个由 18 个智能体组成的研究工作流,回来后告诉我:不要。这个生态里的“发行版位置”同时处于被占据和空缺的状态,而能力包的价值大约是精选配置的 400 倍。随后它还继续指出了两件我根本没问的事:每一个会话都在加载约 2,600 行失效代码;我的 trust.json 还被提交进一个公开仓库,其中包含我的绝对路径。

这才是有用的部分。它不同意我的判断,用数字支撑了反对意见,然后主动寻找还有哪些地方出了问题。

8 月 6 日上午 10:36,我把所有内容从 dotfiles 移进一个独立的 monorepo。一次提交:修改 53 个文件,新增 25 行,删除 25,635 行

回到家

如今,pi-extensions 包含 26 个包、32,847 行 TypeScript。状态栏、输入区、页头、加载动画、回合计时器、置顶提示词;子智能体调度、工作流、代码模式、LLM 评审团;用于会话间通信的 relay;在 read 结果进入模型前擦除秘密信息的 cloak;让 Claude Code 插件继续工作的 claude-compat。其中大多数现在都已经发布到 npm。

还有 bosun:一个会变成联络官的 pi 会话,统筹一支无界面的 pi 船员队伍——生成任务、转发进度、批准交付。有一天晚上,我让它同时管理七个智能体,然后去睡觉了。

这又是 Fleet。同一个问题,同一种形状。区别在于,Fleet 是一个位于 Harness 外部、眯着眼读取终端输出的编译后二进制文件;而 bosun 是会话内部的一个包。

这个故事还有一个工作版本,等允许公开时我会好好讲。简短版本是:就在我拆解 dotfiles 的同一周,我们开始在 WorkOS 基于 pi 构建东西。因为 pi 的整个表面都是扩展,从“我们自己的 Harness 到底应该长什么样”到“给,安装它”的距离,最终只需要用天来衡量。

让我切换的并不是速度、成本或模型选择。这些都很重要,但四个月里没有一个真正推动我改变。真正让我改变的是,我终于注意到自己的技术栈中有多少东西——case、Fleet、抓取脚本、~/.cache 下的文件——只因为我无法进入 Harness 内部才存在。

pi 让你走进去。

Zack,抱歉当时回避了你的问题——这才是我应该说的话。

COMMUNITY NOTES · 讨论

讨论与补充

评论将在接近此处时加载。

    本文目录