两种智能体框架,两种工程哲学

Pi与DeepSeek Harness:两种控制复杂度、保留工程判断并构建智能体原生软件的不同哲学。

过去两年,关于编码智能体的讨论大多围绕模型展开。

哪个模型在编程基准测试中得分更高?哪个推理能力更强?谁的上下文窗口更长,工具调用更可靠?

但这些系统用得越多,我越觉得模型只讲了一半的故事。

真正决定智能体如何行动的,是包裹在模型外面的框架。

DeepSeek在DeepSeek Harness页面上对此有一句很好的概括:

模型是Agent的灵魂。

Harness 给予 Agent 理解环境、使用工具,并在真实场景中持续工作的能力。

DeepSeek Harness(简称DSH)也把自己的架构原则说得非常明确:

一切皆插件。

最近我花了不少时间使用Pi,因此DSH的发布恰好提供了一个很有意思的比较对象。

两者都是开源的智能体框架,也都非常重视可扩展性。

但当你不再只看README,而是深入代码库、提交历史、AGENTS.md和skills之后,会发现它们代表着两种颇为不同的工程哲学。

我个人更偏爱Pi的极简路线。不过,DSH里也有一些很有意思的设计,是我非常想借鉴的。


Pi:把复杂度挡在门外

Pi的创造者Mario Zechner将它称为一个坚持己见且极简的编码智能体

从概念上看,它的核心只有很少几项基本能力:读取文件、写入或编辑文件,以及执行shell命令。更多能力可以通过扩展、skills、prompt模板和软件包逐层加入。

Pi对贡献的态度相当保守:如果一项功能不是非进核心不可,它多半就应该成为扩展。

我喜欢这种态度,因为软件中最危险的复杂度,很少来自一眼就能看出的糟糕代码。

它往往来自那些被逐个加入的合理功能。每一项新增都有充分的理由,但最终,整个系统会复杂到没有任何人能在脑中完整理解它。

Pi用一种更传统的方式处理这个问题:

如果一种复杂度本来可以避免,就不要把它揽到自己身上再想办法管理。

这也正是Pi的可扩展性有趣的地方。

可扩展并不等于功能繁多。

一个系统完全可以提供强大的扩展点,同时对默认纳入的功能保持极度克制。


DSH:给复杂度以结构

DSH走的是另一条路。

它并不极力削减能力,而是把“能力”本身变成一种一等架构单元。

模型、工具、skills、会话、存储、智能体循环,甚至部分UI,都可以通过它的插件架构进行组合。

打开packages/目录,这种哲学便一目了然。

DSH的软件包层级,展示了不同软件包分组、职责和发布要求

文件系统访问、shell、LSP、skills、网页交互、上下文压缩等能力,都有各自独立的软件包。

走到这一步,它看起来已经不太像一个编码智能体,而更像一个智能体运行平台。

有意思的是,DSH并非不理解极简主义。它提供了一个minimal模式,工具数量要少得多。

但二者之间有一个微妙的差别:

Pi把极简主义当作架构的起点。

DSH则把极简主义当作这套架构能够生成的一种配置。


谁能管住复杂度?

观察Pi和DSH的代码库时,我最关心的问题是:它们各自如何防止复杂度失控?

Pi的答案主要是结构上的克制。它的贡献规则一再要求缩小系统的表面积,减少维护者必须装在脑中的概念。

其中有一条我尤其喜欢,其核心意思是:你必须理解自己的代码。使用AI写代码并不是问题;真正重要的是,提交改动的人能否解释代码做了什么,以及它会如何与系统的其他部分相互作用。在AI时代,真正有用的问题是:你理解自己正在添加的东西吗?

DSH采用的则是一种更制度化的方法。它依赖明确的架构规则、服务边界、严格类型、覆盖率门槛、文档要求、变更范围分析,以及代码库级别的skills。

新行为应当通过预先定义好的扩展点进入系统,就连对智能体循环的一项改动,也必须履行相应的架构义务。Pi试图减少需要治理的事物;DSH则假设有些复杂度无法避免,于是把它们转化为明确且可验证的契约。

我依然更倾向Pi的直觉,因为每一道护栏本身也会增加一层复杂度。即便如此,DSH显然在认真探索如何让大规模智能体工程变得可管理,我也很想看看这条路线会如何发展。


Git比README更诚实

两者的差异在这里变得尤其明显。架构文档告诉你一个项目想成为什么,提交历史往往更能说明它实际上如何运转。

写这篇文章时,Pi有5,683次提交,DSH则有12,293次,是前者的两倍还多。单看总数并不能说明质量,但这些历史呈现出的形态很有意思。

Pi近期主分支的历史很容易浏览,每次提交的意图通常都很集中:

Pi的GitHub提交历史,展示了近期范围明确的提交

大多数记录都能立刻回答一个简单的问题:这里改了什么?整段历史读起来像一连串工程决策,而不是开发过程的逐字记录。

DSH的历史则不太一样。合并提交、分支同步、CI修复和发布工作都更加显眼:

DSH的GitHub提交历史,展示了合并、发布、文档和CI提交

乍看之下,这会让它的主分支显得比Pi凌乱。但分支图表明,问题并不只是提交习惯不够整洁。DSH真正的组织单元不是单次提交,而是PR图。

Pi的分支图有一条清晰的主线。短期功能分支容纳少量彼此相关的提交,随后合并回主线:

Pi的Git分支图,展示了一条清晰的主线和若干短期功能分支

DSH的分支图则是一张密集得多的网络:大量智能体分支和worktree分支并行推进,并频繁从master同步合并:

DSH的Git分支图,展示了大量并行的智能体分支与worktree分支

这不只是视觉上的差异。Pi的历史强调一系列清晰可读、已经完成的工程决策;DSH的分支图还记录了让多条智能体工作流保持同步所需的协调过程。

这种密度,部分源于DSH对堆叠式PR的明确使用。假设有这样一条依赖链:

A ← B ← C

如果评审发现B里有问题,正确做法是在问题最初出现的位置修复,再把修正沿着堆栈向上传递,而不是直接在C上打个补丁就继续前进。

DSH围绕堆叠式PR评审、变基、受保护的历史重写和同步后的验证,设计了专门的工作流。

它解决的是一个非常“智能体原生”的问题:当许多智能体并行工作时,如何保留彼此独立的推理边界?

传统开发通常是:

开发者 → 分支 → PR

而DSH正越来越像:

任务 → 智能体/worktree → PR层 → 堆栈 → 评审 → 合并

到这一步,Git就不再只是版本控制工具,而成了智能体框架的一部分。


结果与工程记忆

这也引出了另一个很有启发的对比。Pi的哲学接近这样一种观念:Git可以保存历史,而当前状态应当保持简单。过去的推理不必永远留在活跃的代码库中;每一个抽象、每一条注释、每一种机制,都要不断证明自己仍有存在的价值。这种态度与Pi的极简主义非常契合。

DSH则从另一个问题出发:如果越来越多的代码由智能体编写,那么支撑这些代码的工程判断应该保存在什么地方?

它给出的一个答案是:skills。

例如,它的pre-push工作流不会简单要求智能体把所有可能的测试都跑一遍。

它会要求智能体先判断变更范围,再收集一组最小但充分的证据,为这次变更建立足够的信心。完整的平台级覆盖仍然可以交给CI负责。

此外还有一项专门用于简化代码的skill,负责寻找已经废弃、重复、臆想出来、过度构建,或没有必要手写实现的代码。

这是我最喜欢的一项,因为它恰好呼应了我在审查智能体生成的代码时,一遍又一遍做的事情。

同样的哲学也体现在文档中。代码库提供了相应指引,用来去除推理过程的逐字记录、重复解释和历史遗留痕迹,同时保留真正承担结构作用的内容。

这改变了我对skills的理解。过去,我主要把skill看成一种教智能体“再多做一件事”的方法;但DSH展示了另一种更广阔的用途:把资深工程师的判断编码为可执行的组织记忆。

这些判断包括:如何进行代码评审,某项改动适合哪些测试,什么时候应该删除一个抽象,以及怎样修复一组堆叠式PR。它还包括判断哪些架构选择必须清晰可见,以及一项决定做出后,哪些推理过程可以安心丢弃。

这些通常都是隐性知识,只存在于资深工程师的脑中。DSH开始把这类知识放进代码库,让智能体能够稳定地访问并应用它们。这或许是整个项目中最值得我借鉴的部分。


DSH也在借力Pi

如果只看架构,我们很容易把Pi和DSH描述成两个竞争项目。但它们之间的真实关系要有趣得多。DSH包含一个名为_@deepseek-ai/dsh-llm-pi-ai_的软件包,它使用Pi的_pi-ai_抽象,将DSH连接到DeepSeek以外的模型。

这件事远不只是借用一个模型选择界面。Pi的多供应商LLM适配器和模型目录,已经解决了每个智能体框架最终都会遇到的一类棘手问题:不同供应商的API和模型元数据各不相同,推理与流式传输能力存在差异,各种兼容性细节也会随着时间不断累积。DSH没有为了“完全自主”而重造这一层,而是复用了一个已经运作良好的抽象。

DSH团队的Tianyi Cui后来进一步明确了这种关系:

Tianyi Cui在X上解释DeepSeek研究人员如何使用Pi,以及DSH如何复用Pi的LLM适配器

好的工程并不意味着什么都要自己写,而是要知道哪些抽象重要到必须亲自掌控,哪些问题已经被别人解决得足够好,可以直接复用。


对手,还是同行?

开源项目经常被套进一种可预测的竞争叙事:谁会取代谁,谁又会胜过谁。但Pi和DSH之间的互动更有意思。Armin Ronacher曾公开表示,DSH是这个领域很久以来第一个真正启发他重新审视Pi自身设计选择的项目,同时他也明确指出,DSH并不完美。

Tianyi的回应解释了这种影响早已是双向的:DeepSeek的研究人员和开发者每天都在使用Pi,而Pi的LLM适配器也已经成为DSH的一部分。Mario Zechner则用一个简单的握手表情回应了这段交流:

Mario Zechner用握手表情回应Tianyi Cui关于DeepSeek使用Pi的帖子

我喜欢这个小细节,因为它把故事从“Pi对阵DSH”,变成了两种不同工程传统之间的彼此观察和相互学习。Pi证明了,只要抽象足够干净,一个小型框架也能成为其他系统的基础设施;DSH则展示了,当智能体开发走向更大规模后,插件架构、结构化工程记忆,以及智能体原生的Git工作流究竟可以走多远。

健康的开源生态就应该是这样:不是所有项目都收敛到同一种架构,而是每个项目都从其他项目中借鉴最好的想法。


我心中的智能体框架

如果让我打造一套自己的智能体框架,我会以奥卡姆剃刀为锚点,遵循更接近Pi的哲学。我会从一个很小的核心开始,拒绝那些尚未证明自己有存在必要的抽象,并尽可能把可选能力留在默认系统之外。目标不是为了极简而极简,而是让这套代码在不断演化的过程中,始终保持在我可以理解其行为的范围内。

与此同时,我也很想融入DSH的部分智能体原生方法。把代码评审惯例、测试选择和简化原则编码为skills,可以保留有价值的工程判断;结构化记忆和理解Git的工作流,则可以帮助多个智能体共同工作,又不丢失改动背后的推理。

真正的挑战,是在加入这些能力的同时,不破坏核心的简洁。每一种协调智能体的机制都会带来自己的复杂装置,因此这场实验需要不断判断:哪些部分真的改善了系统,哪些只不过让它变得更加繁复。这种张力会让工作变得困难,却也正是它值得尝试的原因。

两个项目带给我的启示很简单:让代码像Pi一样简洁,让工程记忆像DSH一样完整。用奥卡姆剃刀决定什么值得进入系统,再用DSH的结构化实践保存那些留下来的事物背后的工程判断。