ByteNoteByteNote
拆解 DeepSeek Harness 的模块依赖图
字

字节笔记本

2026年10月6日 · 约 5 分钟读完

拆解 DeepSeek Harness 的模块依赖图

API中转
¥120

DeepSeek 在 GitHub 上开源的 agent 框架 deepseek-harness,把一个能干活的编码助手拆成了 219 个 npm 包。仓库的 docs 里躺着一张脚本生成的模块依赖图:49 个分组、219 个节点、1089 条依赖边,整个工程的骨架一图打尽。这张图本身就是一份难得的架构教材,本文按底座、核心、能力、出口四层把它拆开看。

DeepSeek Harness 模块依赖图的四层结构

图是怎么来的

这张图不是手画的。脚本读取每个包的 package.json,以 peerDependencies 作为运行时依赖的规范信号,自动汇总成图,再按 packages/分组/包 的目录层级摆放节点。边 a 指向 b 就表示包 a 依赖包 b,节点名统一省略 @deepseek-ai/dsh- 前缀。依赖结构跟着代码走,图由脚本重新生成,不存在文档过时的问题。这个做法本身就值得借鉴:与其在文档里手绘架构图,不如让构建过程自己长出一张不会说谎的图。

底座:218 个包脚下垫着同一个包

全图 219 个包里,invariants 是唯一不依赖任何其他包的节点;反过来,其余 218 个包每一个都有边指向它,其中 31 个包的依赖清单里干脆只有它一个。它属于 runtime-diagnostics 组,是一个可配置的运行期不变量检查注册表:根插件把它挂到上下文里,各包把自己的检查项注册进来,它自身不含任何业务检查。把出错要早发现做成全局底座,而不是散落各处的零散判断,是这张图给出的第一条工程约定。

核心环:八个包管住一轮对话

core 组只有八个包,却站在全图重心。llm 沉在最下面;session、system-prompt、scope 居中;agent 依赖 llm、session、system-prompt、scope 和类型协议 typert-protocol,一共六条边。真正的主循环是 agent-loop,它一口气依赖九个包:agent、llm、scope、session、session-persistence、settings、system-prompt、tools,外加底座 invariants。读提示词、调模型、执行工具、把结果写回会话,这一圈全由它串起来。tools 依赖八个包,把 code-runtime 和 user-approval 也接进主干,工具执行与人工审批从这里汇入核心。

能力组:围绕核心铺开的手脚

核心之外,一个能力自成一组:fs 管文件读写,shell 管命令执行,web 管搜索与抓取,lsp 管语言服务,skill 管技能加载,goal 管多轮目标,compaction 管上下文压缩,workflow 管后台流程。几个数字能看出体感。subagent 组共 11 个包,除本体与工具消费端外,备了 acp、claude-code、codex、dsh-sdk 四种外部驱动,还有三种进程内驱动;沙箱分三层,sandbox、sandbox-local、sandbox-policy 各司其职,bash 与 pwsh 都有本地版和沙箱版;e2b 组给云沙箱留了接口。扇出最多的是几个总装位:示例工程 agent-spine-demo 依赖 22 个包,界面会话包 client-ui-conversation 依赖 19 个,subagent 与 api-remotes 各 15 个。

依赖个数最多的包排名

出口:219 个包只露三张脸

最外层是出口。bundle 组的 base、headless、web-app 是三种安装形态;api 组的 api-remotes 汇集 15 个依赖,充当远程调用的总装层;sdk 组拆成 protocol、client、jsonrpc-server 三块,供外部程序嵌入;界面则整个压在 client 组,39 个包里 32 个以 client-ui 开头,把会话、设置、技能、子代理切成独立小块。使用者最终碰到的入口只有三类:装 bundle、连 api、嵌 sdk。

这张图值得学的三件事

第一,依赖图脚本化。219 个包的关系靠手维护必死,从 peerDependencies 生成,图和代码永远一致。第二,底座先行。全项目先立一个零依赖的不变量检查包再往上盖楼,异常暴露得早,修起来便宜。第三,核心小、能力多、出口窄。核心环只有八个包,能力按组平行扩展,对外的门面收敛到三类。想读这个仓库源码的人,按这四层往下翻,比按目录顺序翻快得多。

相关文章

分享: