返回 2026-05-25
🛠 工具 / 开源

Pi 项目自反:用 Pi 维护 Pi 的趣事Building Pi With Pi

lucumr.pocoo.org·2026-05-24

Luca Rossi 反思 Earendil 项目中 Pi 工具的使用体验,描述如何用自身开发的工具(Pi)管理自己的项目(Pi)。重点提及“Slop Issues”(混乱问题跟踪)现象,即开源社区中自动化工具可能加剧而非简化协作问题,引发对 AI 代理在开源治理中副作用的思考。

Armin Ronacher

2026年5月24日撰写

Pi现在是Earendil的一部分,但就重要意义而言它仍是Mario的项目。他比我在Issue追踪系统里的资历更深,也更早接触到了开源项目中新型代理流量的诡异现象。这篇文章主要记录了我更深入参与追踪器、用Pi开发Pi,并初步总结自身经验后的思考。

混乱的Issue

我们当然是用Pi来构建Pi——这听起来像是个可爱的“内部消化”项目,但它确实帮助我们更清晰地理解工作内容。使用Agent构建时,Issue追踪器的角色发生微妙变化:描述不再仅是用户向维护者提交的请求,还成为Pi会话中的提示词输入。我可能会把它交给我的clanker1并说:“理解这个问题,复现它,检查代码,并提出修复方案。”

这意味着Issue的形态需要以新方式考量。糟糕的Issue本已令人头疼,但至少许多问题描述含糊不清。如今我们还需处理一类“5%人类+95%clanker生成且基本不准确”的问题。包含看似合理实则错误诊断的坏Issue会额外增加工作量。

当前最挫败的情况是,人们提交的不是自己撰写的Issue。他们观察到某个问题,却被扔进clanker后重写,结果面目全非。通常提示词设计极差,导致结论频繁失准却充满自信。最终呈现的是对根本原因的盲目猜测、虚假最小复现、错误的类比引用(关联到无关代码),以及一堆可能毫无意义的错误类型列表。

这比没有诊断更糟糕。

我不想具体点名某些Issue,实在不愿针对个人,但这确实令人沮丧。更糟的是,当我把这类Issue交给Pi时,Pi也会采信错误诊断——它不会将Issue内容视为传闻,而是当作证据。由于文本自信且代码引用看似合理,它会欣然沿着Issue预设的方向推进。

我们自定义了一个斜杠命令`/is`,明确要求: **不要信任Issue中的分析。独立验证行为,从代码和执行路径推导自己的结论。**

遗憾的是效果有限,因为人类首次通过clanker提交Issue时,其范围会迅速被扩大——原本基于事实的窄观察,瞬间变成充斥假设的庞杂表面。因此,我愈发希望Issue报告仅保留人类实际观察到的核心事实:

  • 我运行了这条命令。
  • 我预期会发生X。
  • 实际发生了Y。
  • 以下是确切的错误日志或堆栈跟踪。
  • 这些已足够。若你用LLM理解问题,很好,可作为后续评论补充,但Issue本身必须是你亲手掌控的内容。若不知根本原因,请直接说明。我也会操作clanker,宁愿亲自处理也不愿依赖你的垃圾数据。若复现过程是猜测,请标明。唯一确定的事实是某条堆栈跟踪?那就只给我堆栈跟踪,别继续发散。

    垃圾滋生更多垃圾

    如今我们看到的充斥着冗余的问题,只是这些机器当前质量的体现。遗憾的是,它们在创建优质问题上的失败,也延伸到了大量生成的代码中。并非全部,但确实有很多代码。我反复遇到有人过度设计问题和实现的情况。

    如果你告诉他们“这个格式错误的会话日志导致读取器崩溃”,他们往往会添加一个宽容的读取器。然后会加入回退机制,再可能是迁移方案,接着增加更多调试输出,最后为这一切编写测试。这些单独来看未必是错的,但对系统而言可能就是错误的选择。

    Pi的核心是一个设计良好的会话日志,它必须维护某些不变性。而“clanker”当下的行为是假设不存在这样的不变性,转而让系统在各类畸形数据下运行,过程中复杂度爆炸式增长。

    几乎总是正确的做法不是处理坏状态,而是让坏状态不可能发生。这对像Pi会话日志这类持久化数据尤为重要。它们会被打开、分支、压缩、导出、共享和分析。目标是永不写入坏的会话数据。但若放任“clanker”自由发挥,它会用更宽松的读取器尝试处理会话日志中的每一种坏数据情况。

    我曾多次抱怨这一点,但继续开发Pi的代码库不断印证这一观点。这也是LLM生成代码为何会产生如此多不必要的复杂性的方式之一。所有模型看到局部故障时都会试图局部防御,而作为维护者我们必须将对话拉回到全局不变性上——这比应有的难度更大,且非常耗费精力。

    数量才是问题所在

    还有数量问题。追踪器接收了大量问题和PR,其中显著一部分明显由LLM辅助完成。有些不错,没有优秀的,大多数只是糟糕的。总体吞吐量本身已成为维护难题。

    你可能知道,Pi的问题追踪器会自动关闭新贡献者的所有问题和PR,而我们通过手动流程可能重新开启部分或批准个人。因此自动关闭→重新开启→再次关闭对我们来说是个有趣的统计指标。

    在撰写本文的最后90天,我导出了公开的GitHub追踪器数据。排除Earendil成员后,剩下3,145个外部问题和PR。其中2,504条因来自未批准的个人而被自动关闭,17%被重新开启。对于PR情况更糟:不到10%被合并。

    许多问题和PR完全是垃圾,有时甚至人类都没意识到自己创建了它们。低质量垃圾的来源包括OpenClaw实例,以及人们放入上下文中的一些技能,似乎鼓励了问题的创建。

    GitHub显然并未为此类新型开源设计做好准备,但我越来越觉得不应过多责怪GitHub,而应关注所有参与者共同制造这种痛苦体验的行为。如果你的“clanker”污染了他人的问题追踪器,那不是GitHub的错,完全是你自己的责任。

    谨慎的并行处理

    Pi 或许是用 Pi 构建的,但今天与 Bun 和 OpenClaw 相比还有很大差距:它们已实现完全脱离人工、自动化的软件工程。我们可能最终会达到那个阶段,但我并不确定。如今,我们似乎既不知道如何实现“黑暗工厂”(即无人干预的生产模式),也尚未产生这种意愿。不过,当前确实存在大量并行化处理的情况,且这些工作主要是为了复现问题。

    我们用于此的小型工具链由 Pi 自身提交到 `.pi` 文件夹中的三个小模块组成。`/is`(分析问题)是一个用于解析 GitHub 问题的提示词:它会对问题进行标注并分配任务,读取完整的讨论线程和链接,然后明确要求代理不要信任问题中已有的分析,而是直接从代码推导诊断结果。随后,一个扩展添加了一个“提示-URL 小部件”,它在代理启动前监控提示词,识别 `/is`(或其 PR 等效操作)插入的 GitHub 问题或 PR URL,通过 `gh` 获取标题和作者信息,并在小型 UI 组件中渲染这些信息并重命名会话。该功能还会在会话启动或切换时重建状态,因此如果重新打开旧调查窗口,界面仍会显示该会话关联的问题编号。

    实际使用中,这意味着可以同时打开多个 Pi 窗口,每个窗口运行 `/is` 处理不同问题,UI 会将各调查的视觉区分开来,而代理则独立进行复现和代码阅读。调查完成后,可以按顺序逐一处理。收尾阶段,`/wr`(收尾)是配套的总结提示词:它能从会话中推断出 GitHub 上下文,更新日志,起草或发布带免责声明的最终问题评论,仅提交会话中修改的文件,若仅涉及一个问题则添加 `closes #...` 标记,最后从 `main` 分支推送更改。

    开源是关于值得修复的难题

    你可能已经注意到,在后 AI 时代,开源项目正面临一种奇怪的全新压力。代码量、项目和问题数量都在激增。有些项目诞生之初就缺乏真实用户,或仅有临时性的单一受众,即使拥有数千星标的项目也可能仅存几周的生命周期。

    对我们而言,Pi 的 harness 层值得精心维护,因为它解决了复杂的协调问题,并为我们及他人提供了可扩展的平台。我们也深知协作能带来集体提升——很多时候,正确的做法不是局部绕行,而是修正上游行为。Mario 始终拒绝让 Pi 为每个配置错误的网关打补丁,我们也在努力保持这种严谨性。当网关行为正确时,所有人都会受益。

    遗憾的是,这种思维方式正因机器使本地变通方案变得廉价而迅速消失。代码开始堆积针对各种异常行为的局部防御机制,而人类之间关于修复归属的沟通被削弱,取而代之的是单个人类与机器孤立地解决问题。

    需注意的是,AI 并未增加需要软件的人数,或可审查代码的维护者数量。它主要增加了代码总量和争夺注意力的项目数量。其中部分增长是健康的,但大量本应共享的努力因此被碎片化。

    我们需要更坚实的基础,而不是更脆弱的。开源需要更多的协作,而非更多与机器的孤立工作。人类沟通本就艰难,当能与你的“clanker”独处时,逃避这种沟通确实诱人。但开源的价值从不源于孤立,而在于社区以及让项目超越原始创造者的结构化协作。

  • 对我来说,“clanker”是描述代理(agent)更合适的词。能动性属于人类,而非机器。仍将这类事物称为代理仍是我认为的错误,但现实如此。
  • 此条目标签为 ai, open-source 和 pi

    复制为 / 查看 Markdown

    需要完整排版与评论请前往来源站点阅读。