智能体框架背后的框架

DeepSeek Harness代码库里还藏着另一套框架:一个帮助智能体追踪上下文、决策、失败,以及来之不易的工程经验的文档系统。

作为知识架构的文档系统,展示了代码库级指令、文档类型、软件包契约、决策记录、技能、自动生成的参考文档、网站呈现,以及成对维护的双语文档

在我撰写《两种智能体框架,两种工程哲学》时,大部分注意力都放在了Pi与DeepSeek Harness(简称DSH)最明显的区别上。但在DSH代码库里摸爬久了些之后,我发现了一个比框架本身更有意思的东西:围绕它建立起来的文档系统。用“文档”来称呼DeepSeek构建的这套东西,甚至都小觑了这套系统。

是什么吸引了我

真正吸引我开始深入研究DSH的,不是某份架构文档,也不是某个格外巧妙的抽象,而是它的Git历史。提交图复杂得近乎荒诞:几十条并行线、反复出现的同步合并、多股工作流同时向前推进。它不像一个传统代码库的历史,更像一张协调众多智能体并发工作的系统地图。

DeepSeek Harness的提交图,展示了由并行分支、工作树和同步合并交织而成的密集网络

然后我打开了GitHub的提交活动页面,那个规模着实惊人。看看这张图:一周3,646次提交!一个代码库如何在如此高速的开发节奏下,依然不丢失对自身架构和设计思路的理解?而这一切发生在一个只有二十多位贡献者的项目里。

GitHub上的DeepSeek Harness年度提交统计,其中一周的提交峰值达到3,646次

这个问题让我越过代码,走进了这个代码库的文档系统。探索得越深,那张密集的Git历史图就越显得合理:要让这种惊人的并行开发规模得以持续,同时仍然便于理解,DSH依靠的并不只是传统的软件工程技巧。别忘了,这是一群追逐星辰大海的人。

不只是文档

大多数代码库都有文档,因为软件需要解释。通常会有一份README,或许还有架构文档、一些API参考资料和几篇指南。项目不断成长,文档也随之增加,而且往往长得参差不齐:一些页面逐渐过时,一些重复着代码里已有的内容,重要的设计决策则消失在过去的拉取请求中。

DSH采用了不同的处理方式:让每一种被记录下来的知识各司其职。架构文档解释核心模块如何组合,子系统文档描述具体概念与契约,软件包README让信息紧贴代码,操作指南带人完成反复出现的工程任务,而自动生成的目录则直接从源代码中提取信息。代码库里还有两种不太常见的内容——智能体笔记(Agent Notes)和事后复盘。因此,它给人的感觉不只是一个文档完善的项目,更像是一套围绕代码库建立起来的外部记忆系统。

AGENTS.md:控制平面

先从AGENTS.md说起。这些文件并不是通常意义上的文档,而是给代码库内的编码智能体看的指令。根目录文件规定了整个代码库都要遵循的架构规则、开发命令、测试要求、文档规范、软件包约定,以及智能体应该或不应该修改什么。代码库里的不同部分还可以添加各自更具体的指令。

从概念上看,它大致是这样的:

                       AGENTS.md

                     代码库级规则

             ┌─────────────┼─────────────┐
             │             │             │
             ▼             ▼             ▼
       packages/       docs/         notes/
       AGENTS.md       AGENTS.md     AGENTS.md

重要的是DeepSeek刻意避免了什么:子目录里的AGENTS.md不应该复制父级文件,只需添加自己所在区域特有的规则。这听起来是件小事,却反映了一个贯穿整个代码库的理念:每一类知识都应该只有一个归宿。

对智能体来说,这会形成层层展开的上下文。它先获得全局规则,进入代码库更深处时,再获得更局部的规则。所有内容不必统统塞进一个庞大的系统提示词,代码库本身也成为提示词的一部分。

架构文档解释关系

传统的架构文档依然存在,但DeepSeek主要交给它一项任务:解释系统如何组合在一起。它涵盖系统的组成方式、核心软件包、智能体循环、能力边界、生命周期以及其他系统级关系,却不会试图成为一部包罗万象的百科全书。

大型项目的架构文档常常什么都收:API、实现细节、过去的设计思路、临时解决方案等等,直到最后没人知道哪些部分还值得相信。DSH把这些其他类型的知识安置在别处。架构文档负责说明各部分之间的关系;它不需要告诉你每个部分的所有细节。

子系统文档解释概念

架构层之下还有一层更详细的子系统文档,分别介绍会话、持久化、权限以及其他内部概念。由此形成了一个很有用的分工:如果我想理解会话持久化如何融入智能体的完整生命周期,应该先读架构文档;如果我想知道会话投影究竟是什么,以及它具体如何工作,就应该去找子系统文档。

这种区别对编码智能体的重要性,可能比看上去更大。LLM搜索一个代码库时,需要的并不总是更多信息,而是与当前问题相匹配的那一类信息。DeepSeek似乎在设计文档时,也把这个搜索问题考虑了进去。

有些文档由代码生成

还有一类内容看似文档,工作方式却更像构建产物。DSH会根据实际定义这些内容的代码或模式,生成配置清单、工具清单、持久化参考资料和部分API文档。这改变了信息的来源:

代码 / 模式


  生成器


 参考文档

这些清单不需要由人手工保持同步;CI可以检查生成结果是否仍为最新。这解决了软件工程中一个由来已久的文档难题:把代码里的信息复制进Markdown,然后指望有人记得同时更新两边。DeepSeek的答案很简单:不要把同一条信息维护两遍;如果它可以从代码推导出来,就让代码生成它。

软件包README让知识贴近代码

软件包级README构成了另一层文档。它们涵盖直接使用某个软件包的人需要了解的配置、行为、扩展点、语义和限制。把这些信息放在代码附近很重要:智能体修改一个软件包时,不应该为了理解一份局部契约而读完整个框架的架构。代码库可以只给它一小片上下文:

package/
    src/
    tests/
    README.md

README成为源代码与高层架构之间的桥梁,用一种紧凑的方式为智能体提供恰好所需的上下文。

操作指南保存步骤

操作指南(cookbook)回答的是另一类问题:这件事具体该怎么做? 它们会解释如何添加工具、集成LLM适配器或引入另一个软件包。操作指南刻意采用逐步说明的形式,由此形成另一个清晰分工:操作指南解释怎么做,决策记录解释为什么。 这也把我们带到了代码库里最有意思的部分之一。

智能体笔记:代码库的长期记忆

对于较为复杂的改动,DSH要求创建一份智能体笔记(Agent Note)。它不应该成为冗长的实现说明;它的任务是保存那些会在拉取请求合并后消失的思考过程。

一份典型的笔记会记录:

  • 问题是什么
  • 做了什么决定
  • 考虑过哪些替代方案
  • 后果或取舍是什么

智能体笔记按照状态和类型组织。一项决策可能处于提议、已实施、已否决或已归档状态,内容可能涉及架构、功能、简化、测试、流程或缺陷修复。这让代码库记住了源代码通常无法回答的问题:为什么系统是现在这样,而不是采用某个看上去更简单的方案?

对于编码智能体,这个问题尤其重要。想象一下,一个智能体发现某个看起来很别扭的抽象,在不了解任何历史的情况下决定:我可以把它简化掉。 也许六个月前已经有三位工程师尝试过同样的做法,最后发现它会破坏一条重要的扩展边界。也许当前设计之所以显得笨拙,是因为它在防范一种仅从局部代码中很难察觉的故障。

代码不会自然地保留这段历史。拉取请求里可能会有,但噪音很多,也很难搜索。智能体笔记把这些推理变成一份持久记录,成为代码库的一种长期记忆。

事后复盘保存伤疤

事后复盘有另一项任务。智能体笔记说的是:我们因为Y选择了X;事后复盘说的则是:我们以为系统会像X那样运行,但事实并非如此。这里出了什么问题,我们的防护措施为什么没能发现它。 一个成熟的系统会携带两种共享记忆:决策与伤疤。 设计文档保存前者,后者则来自生产事故。

大多数代码库只会非正式地保留伤疤。有人还记得某次事故;代码里留着一项奇怪的校验;或者某条注释警告“不要删掉这个”。但到了最后,最初的上下文还是会消失。DSH有意用事后复盘保存这些背景,不仅记录哪里出了问题,也记录应当用什么护栏阻止同类问题再次发生。对人而言,这是共享记忆;对智能体而言,它更加实用——这是一份不该重新踩入的诱人陷阱清单。

技能把知识变成行为

接下来是技能(skills)。它们不只解释某件事,还会把反复出现的工程任务变成智能体可以遵循的工作流。翻译维护可以成为一项技能,文档规范、决策记录归档或专门的维护任务也可以。到了这里,文档与执行之间的界线开始变得模糊。传统代码库里可能会有:

docs/how-to-review-x.md

DSH则可以直接给智能体一套完成这项任务的可复用工作流。它们之间的关系大致是:

文档          → 告诉智能体需要知道什么
AGENTS.md     → 告诉智能体需要遵守什么规则
技能          → 告诉智能体如何完成反复出现的工作

至此,文档已经不再只是支持这个框架,它正在成为框架的一部分。

为什么所有东西都会出现三次

浏览代码库时,我还发现了另一种让文档数量看起来更加庞大的模式。许多文件会成组出现,例如:

architecture.md
architecture.zh.md
architecture.i18n.yaml

乍看之下,这似乎是同一份文档的三个版本,实际上却是两份文档加一份同步记录。architecture.md是英文版,architecture.zh.md是简体中文版,而*.i18n.yaml*文件记录了两份文件上次被确认内容一致时的确切版本。与其说它是另一个译本,不如说它是一份锁文件。

假设两份文档已经同步:

英文 v1  ←→  中文 v1

之后有人修改了英文版:

英文 v2  ←→  中文 v1

此时,记录中的Git哈希值不再匹配,CI便能发现一件代码审查者经常漏掉的事:译文可能已经过时。接下来必须更新中文版——或者至少对照这次改动检查一遍——然后刷新同步记录。.i18n.yaml不是文档内容,而是让文档保持同步的机制。

不让文档沦为文字垃圾

这里显然存在一种危险:如果每项重要改动都需要书面背景,每个软件包都有文档,每份重要文档都有两种语言,而且智能体几乎可以零成本生成文字,这个代码库难道不会淹没在Markdown里吗?DeepSeek显然非常清楚这一点。它的规则会阻止重复的指令、流水账式的实现历史、手工复制的清单、过时的状态更新以及重复的API清单。有些长期维护的文档甚至还有篇幅限制。

这个细节吸引了我,因为它背后的理念并不只是写更多文档,而更接近于:用更少的重复文字,保留更多知识。 这件事要难得多。LLM让添加一页、一段或一份解释变得极其廉价;真正困难的是判断什么应该存在、它应该放在哪里,以及哪些内容可以删除,因为同一条信息已经有了更合适的归宿。DSH用约束代码的那套纪律来约束自己的文档。

下面这张图展示了所有这些部分如何组合在一起。

作为知识架构的文档系统,展示了代码库级指令、文档类型、软件包契约、决策记录、技能、自动生成的参考文档、网站呈现,以及成对维护的双语文档

Pi与DSH的差别比看上去更深

这让我再次想到Pi身上仍令我欣赏的一点:它的克制。Pi提出了一个很有力量的问题:一个智能模型究竟只需要多少基础设施? 它用一个小巧的循环、一组可靠的基础能力、清晰的代码,以及对不必要抽象的强烈抵制给出了答案。

DSH问的是另一个问题:当系统不断变大,我们如何避免智能体迷失其中? 它给出的答案不只是增加架构层次,更是在模型之外建立记忆。代码保存实现,架构文档保存关系,子系统文档保存概念,自动生成的参考资料保存事实,智能体笔记保存推理,事后复盘保存伤疤,技能保存操作流程,而AGENTS.md保存规则。单看任何一部分都谈不上惊人;真正有意思的是DeepSeek如何谨慎地划分它们的职责。

Pi试图让系统保持足够小,让阅读代码本身依然足以理解一切。DSH似乎认为,规模超过某个临界点后,光读代码就不够了。它不要求智能体每次都从源代码重新建立对系统的理解,而是在代码周围构建了一套结构化记忆。这或许就是DSH代码库里隐藏的宝藏:所谓框架,并不只有智能体循环、插件或工具。代码库本身也是框架的一部分。