Files
research-blog/content/posts/deepseek-harness-architecture-evaluation.md
2026-08-14 18:43:07 +08:00

440 lines
30 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
{
"title": "DeepSeek Harness 插件化架构与工程评估",
"summary": "说明 Cordis 如何装配插件,插件如何通信,服务提供方如何选择,以及插件开发、测试和发布如何进行。",
"date": "2026-08-14",
"updated": "2026-08-14",
"topic": "agent-systems",
"tags": ["deepseek", "agent-harness", "architecture", "evaluation", "cordis"],
"kind": "article",
"status": "published",
"visibility": "public",
"canonicalUrl": "https://blog.k1412.top/articles/deepseek-harness-architecture-evaluation/",
"sourceRepo": "https://git.k1412.top/wuyang/research-blog"
}
---
> DeepSeek Harness 把模型、工具、会话和执行循环都做成可组合插件。它的架构值得研究,但公开证据目前只支持受限试点,不支持组织级默认采用。
调研冻结在 2026 年 8 月 14 日。目标代码为提交 [`47f943859bef60e4160492346772ded9b24f765a`](https://github.com/deepseek-ai/deepseek-harness/tree/47f943859bef60e4160492346772ded9b24f765a),该提交与调研日的远端 `HEAD` 一致。本文只评价 Harness 架构、工程流程和公开评测,不评价 DeepSeek 模型能力。
## 一、DeepSeek Harness 的插件化架构
### 1.1 Cordis 插件运行时
DeepSeek Harness 的命令名是 `dsh`。它是一套 Agent 运行外壳:接收请求,调用模型,执行工具,保存会话,并向 Web、ACP 和 SDK 暴露入口。
dsh 主要使用 TypeScript 编写,运行在 Node.js ESM 环境。TypeScript 让插件作者共享类型,但运行时真正加载的是 JavaScript 模块。插件通常导出 `apply(ctx, config)`,或导出一个 `Service` 子类。[根 package.json](https://github.com/deepseek-ai/deepseek-harness/blob/47f943859bef60e4160492346772ded9b24f765a/package.json) [Cordis 插件教程](https://github.com/deepseek-ai/deepseek-harness/blob/47f943859bef60e4160492346772ded9b24f765a/docs/cordis-tutorial/01-first-plugin.zh.md)
| 概念 | 作用 |
|---|---|
| Profile | 选择一种产品形态,例如 Web 或 headless |
| Bundle | 提供一组可复用的默认插件 |
| patch | 增加、替换、禁用或删除配置行 |
| Context | 插件访问 Service、Event 和子插件的入口 |
| Loader | 按有效配置加载插件模块 |
| Fiber | 一次插件挂载的运行实例 |
| Service | 插件向其他插件提供的具名能力 |
| effect | 与 Fiber 同生共死的注册、监听器或资源 |
| Agent loop | 在模型、工具和最终回答之间推进一次任务 |
| SessionEvent | 记录用户消息、模型消息和工具结果等事实 |
Cordis 负责前八项。它把配置变成一组可管理的插件实例,检查服务依赖,并在配置或依赖变化时卸载、重建相关实例。Agent loop 负责每次请求的执行。两者不在同一层。
### 1.2 插件运行时的启动流程
![配置先生成插件运行时](/articles/deepseek-harness-architecture-evaluation/dsh-startup-assembly.png)
启动时,dsh 按顺序合并 Bundle、Profile patch、Harness home patch 和命令行 `--patch`。最终配置由带稳定 `id` 的配置行组成。后层命中同一 `id` 时,会替换该行的完整 `config`,不会做字段级深合并。[CLI 组合参考](https://github.com/deepseek-ai/deepseek-harness/blob/47f943859bef60e4160492346772ded9b24f765a/apps/cli/reference/README.md)
Loader 为每一行创建 Fiber。Fiber 指一次插件挂载的运行实例,与线程和用户请求无关。它保存配置、父 Context、依赖、状态、effect 和清理逻辑。
Fiber 常见状态为 `PENDING → LOADING → ACTIVE → UNLOADING`。插件声明 `inject = ['tools', 'shell']` 后,缺少任一 Service 都会停在 `PENDING`。服务出现后才执行 `apply`;服务被替换或消失时,Cordis 会卸载依赖它的 Fiber,再按新依赖重建。YAML 中的先后顺序不决定启动顺序,Service 是否可用才决定。[Cordis 服务教程](https://github.com/deepseek-ai/deepseek-harness/blob/47f943859bef60e4160492346772ded9b24f765a/docs/cordis-tutorial/03-services.zh.md)
`inject` 只声明硬依赖。插件在某项能力缺失时仍可工作,就不应把它放进 `inject`,而应在使用处调用 `ctx.get('serviceName')`。未挂载 provider 时它返回 `undefined`,Fiber 仍可保持 `ACTIVE`。硬依赖的 provider 被替换时,消费方会重载;可选依赖是否响应变化,则由插件自己的监听和调用方式决定。
插件通过 `ctx.on()` 注册监听器、通过 `ctx.tools.register()` 注册工具,或通过 `ctx.effect()` 管理连接和定时器。这些操作都会返回或绑定清理逻辑。Fiber 卸载时,Cordis 自动撤销它们。插件树表达的正是这种所有权和生命周期关系。
### 1.3 Agent 请求的执行流程
![请求在模型和工具之间循环](/articles/deepseek-harness-architecture-evaluation/dsh-request-flow.png)
一次请求发生在插件全部就绪之后:
1. Web、ACP 或 SDK 把输入交给 Agent inbox。
2. Agent loop 读取会话历史、系统提示和可用工具。
3. 模型直接回答,或发出结构化工具调用。
4. Tools Runtime 校验参数、执行策略和工具。
5. 工具结果回到 Agent loop,模型继续生成。
6. Agent loop 提交最终消息。
`SessionEvent` 在这条链路旁边记录事实。它保存用户消息、step、模型消息、工具调用、工具结果和最终回答,用于历史、恢复、fork 和 UI 投影;工具结果仍由 Agent loop 送回模型。[会话持久化](https://github.com/deepseek-ai/deepseek-harness/blob/47f943859bef60e4160492346772ded9b24f765a/packages/session/session-persistence/README.md)
### 1.4 插件树、依赖图与调用链
插件树、依赖图和调用链分别描述不同关系:
| 关系 | 回答的问题 | 示例 |
|---|---|---|
| 插件树 | 谁挂载谁,谁随谁卸载 | Loader 挂载 `tool-bash` Fiber |
| 依赖图 | 谁必须等待哪项能力 | `tool-bash` 等待 `tools` 和 `shell` |
| 调用链 | 一次请求经过哪些活跃组件 | Agent loop → LLM → Tools Runtime → shell → LLM |
### 1.5 插件规模与关系
在当前提交中,仓库包含 219 个 DSH package,其中 170 个可以由 `cordis.yml` 直接加载。其余 15 个是不能单独挂载的抽象 Service 定义包,34 个是供其他包导入的普通库包。因此,219 是仓库包数量,170 是可加载插件数量。
| 口径 | 数量 | 含义 |
|---|---:|---|
| DSH package | 219 | 排除 7 个测试 fixture 后的仓库包 |
| 可加载 Cordis 插件 | 170 | 105 个有配置,65 个无配置 |
| Web 根配置行 | 129 | Base Bundle 78 行,加上 Web Bundle 新增的 51 行 |
| ACTIVE Fiber | 动态值 | 由操作系统、`disabled`、Profile、patch、Agent Preset 和运行时挂载共同决定 |
129 不是 Web Profile 启动后的 ACTIVE Fiber 数量。它只是用户 patch 生效前的根配置行数;条件分支、禁用项、Realm 和运行时动态挂载都会继续改变实际插件树。
插件关系需要按四种口径分别观察:
| 关系 | 当前规模 | 回答的问题 |
|---|---:|---|
| Package 依赖 | 1,089 条边 | 哪个 package 在代码层依赖哪个 package |
| Service 协作 | 56 项 Service、213 条角色关系 | 谁定义、谁提供、谁使用一项能力 |
| 运行时硬依赖 | 101 个插件、198 条 `inject` 关系 | 哪项 Service 缺失会让插件无法激活 |
| Event 协作 | 56 个事件名 | 谁发布事件、谁监听,以及使用哪种分发语义 |
正文以 Service 关系作为主图,因为它最能回答“插件怎样接入已有能力”。箭头含义固定为:Definition 声明接口,Provider 注册实现,Consumer 依赖并调用 Service。
![三条 Service 能力边界展示定义、提供与使用关系](/articles/deepseek-harness-architecture-evaluation/dsh-service-seams.svg)
这张图只呈现三条代表性的 Service 能力边界;移动端可横向滑动查看。
完整关系可以继续查阅仓库自动生成的 [Plugin Catalog](https://github.com/deepseek-ai/deepseek-harness/blob/47f943859bef60e4160492346772ded9b24f765a/docs/config-catalog.md)、[Module Graph](https://github.com/deepseek-ai/deepseek-harness/blob/47f943859bef60e4160492346772ded9b24f765a/docs/module-graph.md)、[Capability Seams](https://github.com/deepseek-ai/deepseek-harness/blob/47f943859bef60e4160492346772ded9b24f765a/docs/capability-seams.md)和 [Event Producer/Consumer](https://github.com/deepseek-ai/deepseek-harness/blob/47f943859bef60e4160492346772ded9b24f765a/docs/event-producer-consumer.md)。这些清单来自代码扫描,比手工维护一张总图更适合作为完整索引。
## 二、插件协作的三类接口
![插件通过三类接口协作](/articles/deepseek-harness-architecture-evaluation/dsh-interaction-contracts.png)
Cordis 提供 Service 和 Event。dsh 在此基础上增加 Tool。三类接口解决的问题不同。
| 接口 | 调用者 | 接收者 | 适合的关系 |
|---|---|---|---|
| Service | 另一个插件 | 唯一服务提供方 | 需要返回值的直接调用 |
| Event | 发布事件的插件 | 零到多个监听器 | 通知、策略和中间件 |
| Tool | 模型 | Tools Runtime 和工具插件 | 模型发起的结构化动作 |
### 2.1 Service 接口
定义包声明服务名和方法,provider 实现它,consumer 通过 `ctx.<name>` 调用。consumer 依赖服务名,不依赖具体 provider 包。一个 Context 内重复注册同名 Service 会直接报错,避免两个实现静默争用。
### 2.2 Event 接口
发布者只知道事件名、参数和分发语义,不知道谁在监听。监听器通过 `ctx.on()` 注册;它属于 effect,插件卸载时自动注销。
| 模式 | 执行方式 | 适用场景 |
|---|---|---|
| `emit` | 同步通知所有监听器 | 无返回值广播 |
| `parallel` | 并发执行并等待全部结果 | 相互独立的异步任务 |
| `serial` | 依次执行,首个有效结果结束 | 异步查询或策略裁决 |
| `bail` | `serial` 的同步形式 | 同步查询或短路 |
| `waterfall` | 监听器包装、修改或短路下一层 | 请求改写、guard 和中间件 |
`waterfall` 的关键是 `next()`。监听器调用 `next()` 才会继续后续链路;不调用就会短路。选择错误的模式会改变执行顺序和失败语义,所以 Event 契约不只有参数类型,还必须说明分发模式。
### 2.3 Tool 接口
插件用 `defineTool` 注册名称、描述、输入 Schema、输出 Schema 和 handler。模型只看到公开 Schema。调用进入 Tools Runtime 后,依次经过 `tools/pre-execute`、审批与 guard、`tools/execute`、handler、`tools/post-execute` 和结果固化。[Tools Runtime](https://github.com/deepseek-ai/deepseek-harness/blob/47f943859bef60e4160492346772ded9b24f765a/packages/core/tools/README.md)
### 2.4 接口契约的保障机制
TypeScript 接口只提供编译期检查,运行时会被擦除。交互由四层共同保障:
1. Definition package 固定名称、方法和类型。
2. Cordis 检查 Service 唯一性、`inject` 依赖和生命周期。
3. Tools Runtime 用 Schema 校验模型输入和输出。
4. 文档、组合测试和 snapshot 检查类型无法表达的行为语义。
代码里的 `interface` 也不一定都是“给其他插件的 API”。判断方式如下:
| 定义位置 | 主要对象 | 含义 |
|---|---|---|
| `declare module ... interface Context` | Service consumer | `ctx` 上存在什么服务 |
| `declare module ... interface Events` | 事件发布者和监听器 | 事件名、参数和返回值 |
| 插件导出的 `Config` | Profile 和部署者 | 这个插件接受什么配置 |
| `defineTool` 的 Schema | 模型和 Tools Runtime | 模型可以传什么、得到什么 |
| 普通内部 `interface` | 当前包实现 | 可能只是内部数据结构 |
只有前四类可能构成跨插件或外部契约。是否公开还要看它是否从 Definition package 导出,并在 subsystem 文档中出现。
## 三、Service 的实现与选择
Provider 不是一种独立的 dsh 组件类型,而是插件相对于某项 Service 承担的角色。一个插件可以为一项 Service 提供实现,同时使用另一项 Service。例如,`@deepseek-ai/dsh-bash-local` 是 `shell` 的 Provider,也是 `subprocess` 的 Consumer。
### 3.1 Service 的定义方、提供方与使用方
官方 shell 链路包含三种角色:Definition(定义方)声明接口,Provider(提供方)实现接口,Consumer(使用方)调用接口。这些名称描述插件与 Service 的关系,不是三种固定的插件类型。
Definition 包 `@deepseek-ai/dsh-shell` 定义 `ctx.shell`:
```ts
declare module '@deepseek-ai/cordis' {
interface Context {
shell: ShellExecutor
}
}
export abstract class ShellExecutor extends Service {
constructor(ctx: Context) {
super(ctx, 'shell')
}
abstract resolve(request: ShellExecRequest): ShellExecSpec
abstract run(spec: ShellExecSpec): Promise<ShellRunResult>
}
```
Provider 实现这项服务。`@deepseek-ai/dsh-bash-sandbox` 和 `@deepseek-ai/dsh-bash-local` 都继承 `ShellExecutor`,最终都把自己注册为名为 `shell` 的 Service。
Consumer `@deepseek-ai/dsh-tool-bash` 不导入具体 provider。它只导入 Definition 包中的类型,并声明服务依赖:
```ts
export const inject = ['tools', 'shell', 'systemPrompt', 'shellEnv']
ctx.tools.register(defineTool({
name: 'bash',
execute: async (args) => {
const spec = ctx.shell.resolve(args)
return ctx.shell.run(spec)
},
}))
```
因此,`@deepseek-ai/dsh-tool-bash` 只知道 `ctx.shell` 的接口,不知道当前实现来自 `dsh-bash-local` 还是 `dsh-bash-sandbox`。
### 3.2 Profile 对 Service 实现的选择
Profile 不直接把 `shell` 绑定到某个类名,而是挂载一个会注册 `shell` 的 Provider 插件。默认基础 Bundle 在非 Windows 环境选择 `@deepseek-ai/dsh-bash-sandbox`。其关键配置是:
```yaml
- id: bash-sandbox
name: '@deepseek-ai/dsh-bash-sandbox'
- id: tool-bash
name: '@deepseek-ai/dsh-tool-bash'
```
这条链路可以读成:Profile 挂载 Provider → Provider 注册 `ctx.shell` → Cordis 激活依赖 `shell` 的 Consumer → Consumer 调用 `ctx.shell`。如果 Profile 改为挂载 `@deepseek-ai/dsh-bash-local`,Consumer 的代码不需要改变。
同一个 Context 只能注册一个同名 Service。若 Profile 在同一作用域同时挂载两个 `shell` Provider,Cordis 会因重复注册而报错,不会静默选择其中一个。
### 3.3 实际 Service 实现的确认
用户可以查看实际挂载结果,但目前没有一条命令直接输出完整的 `Service → Provider → 配置来源` 映射:
1. `dsh --profile web --dump-default-config` 查看 Profile 默认配置。
2. `dsh --profile web --patch ./extra.yml --dump-config` 查看叠加 patch 后的有效配置和来源注释。
3. 运行时 plugin inventory 查看模块名、启用状态和 Fiber phase。
4. 对照 Definition 或 subsystem 文档,确认该模块注册了哪项 Service。
`dump-config` 解决“配置选择了什么”,inventory 解决“当前启动了什么”。inventory 不保留完整配置来源,也不直接反推 Service provider。这是当前排障能力的明确缺口。[Plugin inventory](https://github.com/deepseek-ai/deepseek-harness/blob/47f943859bef60e4160492346772ded9b24f765a/packages/host/plugin-inventory/README.md)
## 四、自定义插件的接入流程
### 4.1 扩展类型与接入点
开发新插件应先确定自己使用哪类扩展接口,再查对应的 Definition 和生成文档,无需遍历所有实现包。
| 目标 | 首选接入点 |
|---|---|
| 替换一项核心能力 | 实现对应 Service Definition |
| 监听或改变现有流程 | 订阅 Event 或 waterfall |
| 增加模型可调用动作 | 注册 Tool |
| 组合已有能力 | 编写 Profile 或 patch |
| 接入外部工具服务器 | 使用 MCP client |
| 从外部控制 Agent | 使用 ACP 或 SDK |
仓库提供三类索引:`cordis-surface` 文档列出 Service;`event-producer-consumer` 列出事件、分发模式、发布者和监听器;`tool-catalog` 列出模型可见 Tool Schema。高级 Cordis 组合还提供 `cordis_inspect_list/query`,可从当前仓库和运行时服务存储中查询 Service、Event、Tool 和 Slot。它们比遍历每个插件 README 更适合作为入口,但仍需要阅读目标 Definition 的语义和测试。
### 4.2 自定义插件开发流程
一个正常的自定义插件流程是:
1. 选择扩展接口。
- 直接调用使用 Service。
- 广播或中间件使用 Event。
- 模型动作使用 Tool。
2. 导入 Definition 包,只依赖公开类型和服务名。
3. 声明运行约束。
- 硬依赖写入 `inject`。
- 插件配置定义运行时 Schema。
- 监听器、工具和资源注册为 effect。
4. 用 patch 挂载插件。
- 用 `--dump-config` 检查有效配置。
- 用 inventory 确认 Fiber 已进入 `ACTIVE`。
5. 补齐工程测试。
- 增加单元测试和一次真实组合测试。
- 影响模型或用户的行为增加 keyless snapshot。
6. 固定兼容提交,再发布插件包。
动态 `cordis_define/run` 适合在当前进程里试验,但定义只存在于内存。进程重启后会消失,也不会生成插件包、安装依赖或写入 Profile。正式接入仍要落到插件包、配置和测试。
### 4.3 外部协议与进程边界
外部边界与进程内插件也应分开理解:Cordis 是进程内组合机制;Web 使用 HTTP 与 WebSocket;ACP 使用基于 stdio 的 newline-delimited JSON-RPC;SDK 使用项目自己的 line JSON-RPC 2.0;MCP 把外部工具注册进 Tools Runtime。MCP 当前主要桥接 Tool,Cordis 插件仍由进程内模块接口管理。[ACP](https://github.com/deepseek-ai/deepseek-harness/blob/47f943859bef60e4160492346772ded9b24f765a/packages/acp/acp/README.md) [SDK 协议](https://github.com/deepseek-ai/deepseek-harness/blob/47f943859bef60e4160492346772ded9b24f765a/packages/sdk/protocol/README.md) [MCP client](https://github.com/deepseek-ai/deepseek-harness/blob/47f943859bef60e4160492346772ded9b24f765a/packages/mcp/mcp-client/README.md)
## 五、插件变更与重启机制
### 5.1 配置变更
Profile 和 Harness home 的 `cordis.patch.yml` 会被监听。有效配置变化会事务式重算,相关 Fiber 和 effect 随之卸载或重建,通常不需要重启整个 dsh 进程。
### 5.2 代码变更
代码变更只有在挂载 `@deepseek-ai/cordis-plugin-hmr` 并覆盖目标路径时才会热替换。Web 客户端插件还需要 `pnpm run dev:web` 重建前端 bundle。生产环境升级 npm 包时,不能假设 HMR 一定覆盖新文件;除非部署明确启用了完整 watcher 链,否则应重启进程。
HMR 的行为是卸载旧 Fiber、加载新模块,再重建依赖方。前端新模块加载失败时,Fiber 会进入 `FAILED`,不会自动回滚到旧代码。因此关键插件更新仍需保留固定版本、健康检查和回退方案。[组合与 HMR](https://github.com/deepseek-ai/deepseek-harness/blob/47f943859bef60e4160492346772ded9b24f765a/docs/cordis-tutorial/06-composition-and-hmr.zh.md)
## 六、仓库质量保障流程
![代码改动先经过仓库质量链](/articles/deepseek-harness-architecture-evaluation/dsh-contribution-flow.png)
仓库同时约束单包行为、真实组合、跨平台兼容和发布产物。
### 6.1 代码与文档的同步要求
代码按责任分区:`packages/*/*` 保存官方 Service、provider 和 consumer;`apps/*` 保存 CLI 与 Web 产品入口;`docs/` 和 `.agents/notes/` 保存公开契约与设计记录;`scripts/` 和 `.github/workflows/` 保存生成器、门禁和 CI。修改一项能力时,应从所属 package 开始,再同步它的 README、JSDoc、测试和必要的 Agent Note。[仓库布局](https://github.com/deepseek-ai/deepseek-harness/blob/47f943859bef60e4160492346772ded9b24f765a/AGENTS.md)
### 6.2 本地验证的三个层级
1. 验证单包行为。
- 运行 `pnpm run test`。
- 按改动运行 `typecheck`、`lint`、`doc-sync` 和 `build`。
2. 验证真实组合。
- 产品可见插件必须经过 Loader、应用或进程入口。
- 只手工构造 `ctx.plugin` 不能替代组合测试。
3. 验证模型和真实服务边界。
- 模型、协议或用户行为增加 `test:snapshot`。
- 真实 provider 才选择带密钥的 `test:e2e`。
### 6.3 Issue 与 PR 的关联规则
内部 PR 的关联采用“作者显式声明、程序自动校验”的方式。PR 作者或编码 Agent 必须在正文中写明关联关系,自动化不会根据代码内容寻找 Issue,也不会替作者创建 Issue。
1. 解决型关联。
- 写法:`Fixes #123`、`Closes #123`、`Resolves #123`。
- 含义:该 PR 用于解决 Issue,会进入解决型关联和状态同步。
2. 信息型关联。
- 写法:`Related to #123`、`#123`。
- 含义:只记录关联关系,不表示合并后关闭 Issue。
当非 Draft、非 Bot 的 PR 请求评审或收到 Review 后,`issue-policy.yml` 会从默认分支检出可信规则并执行 `node .github/issue-management/policy.mjs pr`。脚本解析同仓引用,排除指向其他 PR 的编号,再校验 Issue 关联、唯一的 `kind/*`、至少一个 `area/*` 和 Priority 一致性。[PR 模板](https://github.com/deepseek-ai/deepseek-harness/blob/47f943859bef60e4160492346772ded9b24f765a/.github/pull_request_template.md) [Issue policy](https://github.com/deepseek-ai/deepseek-harness/blob/47f943859bef60e4160492346772ded9b24f765a/.github/workflows/issue-policy.yml) [规则实现](https://github.com/deepseek-ai/deepseek-harness/blob/47f943859bef60e4160492346772ded9b24f765a/.github/issue-management/policy.mjs)
`issue-lifecycle.yml` 使用 `dsh-issue-management` GitHub App 同步解决型 Issue 的 Project 状态。PR 开始开发后可进入 `In progress`,请求评审后进入 `In review`,Review 要求修改时退回 `In progress`。这套组件执行固定 JavaScript 规则,不是负责理解需求和评审代码的 LLM Agent;语义评审、合并和发布授权仍属于维护者。[Issue lifecycle](https://github.com/deepseek-ai/deepseek-harness/blob/47f943859bef60e4160492346772ded9b24f765a/.github/workflows/issue-lifecycle.yml) [项目配置](https://github.com/deepseek-ai/deepseek-harness/blob/47f943859bef60e4160492346772ded9b24f765a/.github/issue-management/config.json)
项目配置指向 `deepseek-harness/deepseek-harness`,而公开仓库是 `deepseek-ai/deepseek-harness`。结合公开仓库当前不接受外部 PR,更合理的解释是这套 Issue/PR 流程主要服务内部仓库。该判断来自配置与公开政策的交叉推断,官方没有公开内部仓库的完整协作说明。
### 6.4 开发参与者的公开规模
截至 2026 年 8 月 14 日,GitHub Contributors API 返回约 30 个非 Bot 贡献记录。Contributor 记录可能包含匿名作者、同一人的多个提交身份或历史导入,因此不能直接当作员工人数。15 个记录的贡献数不少于 100;前 10 个记录约占全部贡献的 90%,前 5 个约占 73%。这支持“代码主要由约十几名高频贡献者完成”的判断,不支持“100 多人共同开发”的说法。[Contributors API](https://api.github.com/repos/deepseek-ai/deepseek-harness/contributors?per_page=100&anon=1)
1. 内测用户。
- 职责:使用产品并反馈问题。
- 规模:官方仓库与文档没有公布人数;百人级说法未获官方证据确认。
2. 开发贡献者。
- 职责:领取 Issue、修改代码、提交内部 PR。
- 规模:高频贡献者约为 10~15 个公开记录;包含零星贡献后约为 20~30 个记录。
3. 维护者。
- 职责:进行语义评审,决定合并和发布。
- 规模:GitHub Team、仓库权限和审批名单不公开,无法确认人数。
4. 自动化账号。
- 职责:校验元数据、同步状态、执行 CI。
- 边界:GitHub Actions 和 GitHub App 不等同于开发者或 LLM Agent。
内测规模、代码贡献规模和维护权限规模属于三个不同口径。即使存在百人级内测,测试者也不必拥有仓库写权限;从反馈到内部 Issue 的转化入口没有出现在公开代码中。公开证据只能说明:反馈面可能较宽,持续代码生产集中在十几名贡献者,最终写入和发布权限进一步收窄。
### 6.5 合并与发布的权限边界
1. Git hooks 先检查翻译、lint、空白、生成文件和 typecheck。
2. 开发者或编码 Agent 在 PR 正文中显式关联 Issue,并填写变更、验证和标签。
3. GitHub Actions 自动校验 Issue 关联、元数据以及 static、逐文件 100% coverage、snapshot、Node 兼容、Python、Wine 和 Windows 等检查。
4. `all checks passed` 聚合通过后,改动才具备进入 master 的技术条件。
5. 维护者完成语义评审并决定是否合并;自动检查通过不能代替这项判断。
6. 发布先构建和打包全部 DSH 成员,再验证安装产物;tag 和受保护 environment 由有权限的维护者触发。
逐文件 100% coverage 只是一项仓库门槛。行为质量还依赖真实组合测试和 keyless snapshot。真实 API e2e 使用密钥,只在可信事件运行;fork 和 Dependabot 会跳过,避免泄露 secret。[开发指南](https://github.com/deepseek-ai/deepseek-harness/blob/47f943859bef60e4160492346772ded9b24f765a/docs/development.md)
公开工作流只能证明 CI 已配置。required checks 是否已在 Branch Protection 或 Ruleset 中设为强制、reviewer 数量、merge method 和发布 environment 审批名单均无法从公开仓库文件确认。
本轮按要求没有重新运行 Harness 本地测试。以上内容描述冻结仓库定义的开发流程,不代表本轮测试已经通过。
## 七、外部插件的发布方式
当前 [`CONTRIBUTING.md`](https://github.com/deepseek-ai/deepseek-harness/blob/47f943859bef60e4160492346772ded9b24f765a/CONTRIBUTING.md) 明确说明项目仍处早期,暂不接受外部 Pull Request。官方建议外部开发者创建独立插件仓库,并使用 GitHub topic `dsh-plugin` 供用户发现。
现在可以让 Codex 在 fork 或独立仓库中完成插件、测试、文档和补丁,也可以准备一份可供维护者参考的变更记录。创建本地分支和提交需要用户明确授权;推送 fork 或创建 PR 还需要已登录的 GitHub 身份、目标仓库权限和外部写入授权。官方仓库当前不接受外部 PR,具备工具权限也不能绕过这项政策。
如果目标是扩展 dsh,当前可执行路径是:基于公开 Definition 开发独立插件,锁定兼容提交,完成组合测试,发布自己的包和 `dsh-plugin` 仓库。只有官方重新开放外部 PR 后,主仓贡献链才成立。
## 八、公开评测与证据边界
### 8.1 公开 Agent 任务评测
本文把“公开 Agent 评测”限定为同时给出任务或数据集、指标与分母、已测量结果。在冻结范围内,没有发现 SWE-bench、Terminal-Bench、AgentBench 或 GAIA 等 Agent 任务的公开成绩。
[`BENCHMARK.md`](https://github.com/deepseek-ai/deepseek-harness/blob/47f943859bef60e4160492346772ded9b24f765a/BENCHMARK.md) 只说明怎样用 Python SDK 启动 minimal agent,并为独立任务设置 workspace 和 session ID。它提供评测接入口,没有给出评测结果。
### 8.2 工程评测资产
仓库包含工程评测资产:
| 资产 | 指标 | 当前证据 |
|---|---|---|
| Web 长历史 runner | 侧边栏、长对话、轨迹和 soak 的 wall time、p95 等 | 有脚本,未发现正式结果 |
| reasoning chunk 压力 | 10 万 chunk;主线程和交互延迟门槛 250 ms | 有断言,未发现官方汇总 |
| CI runner benchmark | 不同平台和 core 数下的检查耗时 | 用于 CI 容量,与 Agent 能力评测无关 |
| 单元、snapshot、e2e | 类型、行为、组合和真实 API 链路 | 证明工程链路,不证明任务成功率 |
### 8.3 评测缺口
缺失的评测至少包括:
- 固定模型和预算下的任务成功率。
- 工具调用正确率。
- 权限拒绝与恢复率。
- 断点恢复正确率。
- 长会话质量。
- 插件组合兼容性。
- 相同任务上的对照 Harness。
没有这些结果,就不能从高覆盖率推导出 Agent 效果。
## 九、采用建议
### 9.1 当前采用判断
| 阶段 | 当前判断 | 条件 |
|---|---|---|
| 架构观察 | 通过 | 源码和文档足以解释主要机制 |
| 受限试点 | 有条件通过 | 固定提交、隔离 workspace、低风险任务、明确权限和回退 |
| 组织级采用 | 不通过 | 缺少稳定发布、迁移承诺、安全审查和目标任务评测 |
DeepSeek Harness 当前标注 Developer Preview,会主动发生兼容性变化;会话格式仍为 v0;调研日未见正式 GitHub Release。这些事实不否定架构价值,但会放大插件兼容、会话迁移和运维成本。
### 9.2 受限试点要求
合理的下一步是选择一个低风险任务做隔离试点:
1. 固定版本。
2. 保留 `workspace-write + ask`。
3. 逐项确认 shell、文件、Web 和外部服务是否进入审批策略。
4. 保存有效配置和 plugin inventory。
5. 把升级、会话导出和插件回退都当作可能失败的步骤。
只有在固定任务集上取得可复现结果,并补齐安全、发布和迁移责任后,才应重新讨论默认采用。
## 十、调研范围与证据
- 目标仓库:[deepseek-ai/deepseek-harness](https://github.com/deepseek-ai/deepseek-harness)
- 冻结提交:[`47f943859bef60e4160492346772ded9b24f765a`](https://github.com/deepseek-ai/deepseek-harness/tree/47f943859bef60e4160492346772ded9b24f765a)
- 主要资料:[README](https://github.com/deepseek-ai/deepseek-harness/blob/47f943859bef60e4160492346772ded9b24f765a/README.md)、[Architecture](https://github.com/deepseek-ai/deepseek-harness/blob/47f943859bef60e4160492346772ded9b24f765a/docs/architecture.md)、[Tools](https://github.com/deepseek-ai/deepseek-harness/blob/47f943859bef60e4160492346772ded9b24f765a/packages/core/tools/README.md)、[Persistence](https://github.com/deepseek-ai/deepseek-harness/blob/47f943859bef60e4160492346772ded9b24f765a/packages/session/session-persistence/README.md)、[Development](https://github.com/deepseek-ai/deepseek-harness/blob/47f943859bef60e4160492346772ded9b24f765a/docs/development.md)、[Contributing](https://github.com/deepseek-ai/deepseek-harness/blob/47f943859bef60e4160492346772ded9b24f765a/CONTRIBUTING.md)
- 已核验:冻结源码、官方文档、仓库测试与 CI 配置、调研日远端 `HEAD`
- 未核验:真实模型端到端效果、生产负载、在线保护设置、跨版本迁移和第三方插件质量