DeepSeek Harness 的 core 有几个子包:三份文档分别说 6、7、8

2026-08-16

翻一个陌生仓库的架构,最先想知道的往往是「主干那一坨代码里到底有几个模块」。DeepSeek Harness 里被 packages/core/README.md:1,5 自述为「产品 API 主干」的就是 packages/core,这个问题看起来五秒钟能回答,实际上取决于你翻开的是哪份文件:目录里数出来是 8 个,packages/core/README.md 的表格是 7 行,docs/subsystems/core.md 的第一句写的是「the six packages」。三个数都能在仓库里找到出处。

下面把三处的确切位置、各自列了哪些名字、差在哪一个包上摆出来。先声明口径:本文所有数字都来自 2026-08-16 我们对快照 47f9438(分支 master)的静态阅读与统计,我们没有安装、没有构建、也没有运行过这个仓库的任何一部分。该仓库根 package.json 版本是 0.1.0-rc.5README.md:9-11 自述处于开发者预览阶段并明写会出现破坏兼容性的变更,所以下面这些结构随时可能变。

先把「组目录」和「包」分开,否则数字没意义

packages/core 之前得先弄清楚它自己是什么。pnpm-workspace.yamlpackages: 列表里,这一条写的是 packages/*/*——两层 glob,不是 packages/*

这意味着 packages/ 下那 49 个目录都不是 npm 包,它们自己没有 package.json;真正的包在第二层。我们对快照逐个读了一遍:packages/*/* 共 219 个目录,219 个全部有 package.json,一个不缺。根 AGENTS.md:13 把这条规则写成一行:「packages/ @deepseek-ai/dsh-<pkg> workspaces at packages/<group>/<pkg>/」。

所以 packages/core 是一个组目录,它的「子包数」问的是第二层。我们数出来是 8 个:

agent  agent-default-model  agent-loop  agent-tool-presentation
scope  session  system-prompt  tools

顺带给一下该组的规模,方便你判断这是不是仓库的主干:packages/core 下有 109 个 .ts/.tsx 文件、40,745 行,其中路径含 /src/ 的是 13,462 行(统计递归排除 node_modules/dist/lib/.turbo)。packages/core/README.md:1,5 给它的一句话定位是「产品 API 主干:会话日志、system-prompt 装配、工具注册表、agent 词汇、部署默认模型选择、具体 loop」。

三处口径,逐个给位置

第一处:docs/subsystems/core.md:9,说 6 个。 首句原文是「A turn flows through the six packages in one loop」,紧接着 :11-19 的表格列了 6 行:session/system-prompt/tools/agent/agent-loop/scope/。这一节的小标题是「The spine, package by package」(docs/subsystems/core.md:7),它是围绕「一个 turn 怎么在这几个包之间走一圈」组织的。同一页 :21 补了一句:scope/ 是其中唯一的非 service 包,是个无依赖的库(createScope/scopeOf/scopeTarget),在模块图里的位置低于 session/system-prompt/,这样后两者可以消费它而不成环。

第二处:packages/core/README.md:7-15,7 行。 表头是 Package | Role | ctx key,列出的是 scope/session/system-prompt/tools/agent/agent-default-model/agent-loop/。比上一处多了 agent-default-model/

第三处:目录本身,8 个。packages/core/README.md 的表多出来的那一个是 agent-tool-presentation/

差异到这里就说完了,我不去推断哪一份「才是对的」、也不猜为什么三处不一样——按仓库红线,这类事只陈述「A 处写 X、B 处是 Y」,以实读的快照状态为准。

还有第四种「7」,但那个 7 不是这个 7

docs/architecture.md:39-51 也有一张叫「Core packages」的表,也是 7 行,很容易被当成第二处的另一份拷贝。但它的 7 行是:core/sessionctx.sessions)、core/system-promptctx.systemPrompt)、core/toolsctx.tools)、core/agentctx.agents)、core/agent-loopctx.agentLoop)、core/scope(library, no key),加上一个不属于 core 组的 llm/llmctx.llm

也就是说这张表里属于 packages/core 的仍然是 6 个,第 7 行来自 packages/llm 组。而且这张表的引导句自带限定词——docs/architecture.md:41 原文是「Here are some core packages that contribute to the Cordis tree.」,用的是 some,不是定指。三处的措辞粒度并不一样:一处写 some,一处是不加限定的包表,一处首句用了「the six packages」这种定指。

数「有几个」的时候,把「包属于哪个组目录」和「表里第几行」分清,比记住数字本身重要。

那个没进表的第八个包是什么

agent-tool-presentation/ 不是一个占位目录,它有自己的 package.json 与 README:packages/core/agent-tool-presentation/package.jsonname@deepseek-ai/dsh-agent-tool-presentationREADME.md:5 描述它是 agent preset 携带的一行,用来说明模型看到的是哪种工具形态——native / code / both

它也没有从仓库的机器视角里漏掉:docs/module-graph.md 首行注释写「Generated by scripts/gen-module-graph.ts — do not edit by hand.」,:6 说明边来自各包的 peerDependencies,我们把它 mermaid 里的 219 个节点名与 219 个真实包名(去掉 @deepseek-ai/dsh- 前缀)逐一比对,全部命中,不匹配数为 0——这个包在里面。

顺带一个数包时容易翻车的点:packages/core 这一组里包名尾段与目录名是对得上的(例如上面那个 agent-tool-presentation),但这条规则不是全仓通用packages/host/*packages/client/* 两组的包名必须带组前缀而目录名不带:host/apiproxy 的包名是 @deepseek-ai/dsh-host-apiproxyclient/runtime@deepseek-ai/dsh-client-runtime。这条写在 .agents/notes/implemented/architecture/2026-07-19-gui-layering-and-rpc-protocol.md:74,原文明写「The package-name tail therefore ≠ the directory name」。所以拿包名反推目录、或拿目录名去 pnpm add,在那两组会直接扑空。

同一类差异,在上一层也有

把视线从 packages/core 里退到 packages/ 这一层,会看到同一种「表的行数与目录数不等」的情况。

packages/README.md:11-59 的「Group | Role | Release expectation」表共 47 行数据行,而真实组目录是 49 个:表里 47 个组名全部对应真实目录、没有多余项,不在表里的是 mcp/runtime-diagnostics/ 两组。同一文件 :61 写着「New packages join existing groups; new groups update their README and this table.」

另外,根 AGENTS.md:11-55 那段 text 围栏的 Repository layout 里,缩进两格的组名有 34 个。逐个与真实目录比对::35self-modification/:46support/packages/ 下都找不到同名目录(承担相近描述的真实目录分别是 packages/extensions/packages/test-support/),同时这段清单没有列出 17 个真实存在的组目录。该段末尾 AGENTS.md:57 写「Package groups: packages/README.md.」,即把完整分组指给了另一份文件。

同样只陈述差异:位置在这里,数字是这些,以实读的目录为准。

你自己怎么核这一处

给读者一条能落地的路径,三步:

  1. 数目录packages/core 下的子目录就是子包,逐个看有没有 package.json。组目录这一层的整体计数我们用的是这段 Python(在仓库根跑,输出 49 / 219 / 219):
python -c "
import os,glob
pkgs=[p for p in sorted(os.listdir('packages')) if os.path.isdir(os.path.join('packages',p))]
print('dir count:',len(pkgs))                      # → 49
subs=[s for s in sorted(glob.glob('packages/*/*')) if os.path.isdir(s)]
print('packages/*/* dir count:',len(subs))         # → 219
withpj=[s for s in subs if os.path.exists(os.path.join(s,'package.json'))]
print('with package.json:',len(withpj))            # → 219,missing: []
"
  1. 对生成物docs/module-graph.md 自述由脚本生成,节点即包;docs/graph-atlas.md 是文档图索引,标出了哪几张是 generated、哪几张是 hybrid generated、哪几张是 curated
  2. 再读三份说明文字docs/architecture.mdpackages/core/README.mddocs/subsystems/core.md,注意各自的限定词和表头。

需要说清楚的是:仓库里带着一批 verify-* 形态的校验命令(如 pnpm run verify-doc-graphspnpm run verify-config-catalog,后者按 docs/config-catalog.md:9 的说法归在 doc-sync 下),我们一条都没执行,所以本文不能说任何「校验通过 / 校验失败」的话——上面全部是文本比对的结果。

这件事对读者的实际影响

一是别把任何一张表当成包的全集packages/README.md:9 写着「Groups hold packages/<group>/<pkg>/; names stay @deepseek-ai/dsh-<pkg>. Group READMEs own package/ctx-key maps.」——组 README 承载的是包与 ctx key 的映射,而按 ctx key 组织的表本身就会漏掉没有 ctx key 的成员:scope/docs/architecture.md:50 那行的 ctx key 列写的就是 library, no key。「按 ctx key 找服务」和「列出组里所有包」是两件事。

二是知道每层文档各管什么docs/AGENTS.md 是这个仓库的文档标准,它的「tier taxonomy」表定义了 12 个层,并对每层写明不该放什么,例如 architecture.md 那行明确写不放类型定义(去 subsystems)、不放每包细节(去包 README)、不放决策理由(去 Agent Notes)。所以要按包对号入座,起点应该是组 README 与目录本身,而不是架构页。

三是什么时候这条差异跟你无关。如果你只是想理解一个 turn 怎么在主干里流一圈,docs/subsystems/core.md 那 6 个包的叙述是自洽的,多出来的两个包不影响你读那条链路;只有当你要做「按包遍历」的事——写脚本扫依赖、给每个包挂检查、统计覆盖面——三处的行数差才会变成实际问题,那时候以目录为准。

最后重复一次时间限定:以上全部对应 2026-08-16 的快照 47f9438,这个仓库建立于 2026-08-13,README 自述开发者预览并明写会有破坏性变更,包的增删随时可能发生,请以仓库当前内容为准。

延伸阅读


本文依据 DeepSeek Harness 官方仓库(github.com/deepseek-ai/deepseek-harness)的 README、docs/ 下的 架构与子系统文档、以及 packages/ 下的源码整理,核对日 2026-08-16,对应仓库快照 47f9438(版本 0.1.0-rc.5)。 本文内容为仓库源码与文档口径,我们没有安装、也没有运行过这个项目, 因此不涉及界面外观、操作手感与运行速度的任何描述。 该仓库建立于 2026-08-13,README 自述处于开发者预览阶段并明确说明未来会有破坏兼容性的变更, 文中出现的命令、配置与默认值随时可能变动,请以仓库最新内容为准。

想系统学会用 AI?报名体系课或加入会员,照着学、照着用。