ARTICLE · 1003517
DeepSeek-Harness 源码解读(1)先导篇
💻 第 1 章 一个全插件化的 Cordis Agent Harness
阅读目标:先建立"这个仓库是什么、由哪几层构成、一次运行大概发生什么"的整体印象,再决定深入哪一章。
1.1 项目定位
DeepSeek Harness(仓库名 deepseek-harness,本书简称 dsh)是一个全插件化(all-plugin)的 Cordis Agent Harness。它把"LLM 智能体应用"分解成一组可以独立插拔、独立配置的能力,再通过 Cordis 插件框架把它们组装成可运行的应用:
模型适配层( ctx.llm:DeepSeek 等 provider 的流式对话能力);会话日志中枢( ctx.sessions:追加式SessionEvent日志,模型看到的一切都从日志派生);提示词系统( ctx.systemPrompt:分节装配 system prompt 与工具 schema);工具注册表与执行流水线( ctx.tools);- Agent 回合循环
( ctx.agentLoop与ctx.agents:把"模型请求 + 工具调用"编排成 step/turn 的驱动器); 以及围绕这些核心的庞大能力库:文件系统、Shell、LSP、代码执行沙箱、技能(skill)、子代理(subagent)、工作流(workflow)、会话持久化、审批交互、Web 客户端……
仓库对自己的定位有一句非常关键的话(docs/architecture.md):
There is no privileged core to patch: you extend dsh by mounting a plugin beside the others, and registrations are effects that unwind when their plugin unloads. (不存在需要打补丁的特权核心:扩展 dsh 的方式是把一个插件挂到其他插件旁边,而所有注册都是可逆的效果,插件卸载时自动回滚。)
这句话贯穿全书:模型适配器、工具注册表、会话日志、甚至 Agent 循环本身都是插件,因此每一层都可以从配置(cordis.yml)替换。第 2 章会展开这套"设计原理",第 3 章讲底座 Cordis,第 4 章解剖回合循环。
1.2 仓库地图
仓库顶层由四大部分组成(详见 AGENTS.md 的 Repository layout):
vendor/ | Vendored Cordis 源码vendor/cordis),外加 loader/include/group/hmr/schemastery/cosmokit 等卫星包;同步机制见 vendor/README.md,所有包重命名为 @deepseek-ai/* |
packages/ | @deepseek-ai/dsh-<pkg>,按功能分组:core/(产品脊柱)、llm/、fs/、shell/、subprocess/、lsp/、skill/、subagent/、workflow/、preset/、boot/、bundle/、session/、guard/、plan/、goal/、interaction/ 等三十余组 |
python/ | dsh CLI 架构) |
native/ | @deepseek-ai/node-addon-landlock-run |
docs/ | |
.agents/ | |
apps/website/、scripts/、snapshots/ |
在 packages/core/ 之下,agent、agent-loop、session、system-prompt、tools、scope、agent-default-model 各自是一个独立 npm 包——注意 dsh 的"一个包"粒度很小,一个服务(service)就是一个包,这本身就是"以服务为边界"设计的体现。
仓库采用 pnpm workspace(
pnpm-workspace.yaml),全部包为 ESM("type": "module")。构建产物与源码分层:tsc 产出lib/types,tsdown 打包运行时。详见docs/development.md。
1.3 一次运行的宏观切片
以"一键跑一个任务"的最简形态(headless profile)为例,一条命令:
DEEPSEEK_API_KEY=... pnpm dsh --profile headless "用 str_replace_editor 在 README 里加一行"到"模型真的开始干活"之间,发生了什么(细节分别见第 3、4、8 章):
- 启动(boot)
: dshCLI(packages/boot/cmdline)解析--profile headless,app-boot按 profile 找 bundle 列表、应用补丁层,最终把一份份cordis.yml配置行交给 Cordis loader 实例化成插件树; - 组合(composition)
: headlessprofile 以dsh-basebundle 为底层,base 挂载模型适配器、文件工具、会话持久化、沙箱与审批策略等;headless bundle 再加"一次性运行"的胶水; - 会话开始
:程序为这次任务建一个 Session,任务文本进入 Agent 的 inbox,唤醒驱动器; - 回合循环(agent loop)
:驱动器 claim 输入 → 打开 turn/start→ 组装提示词与工具 schema → 走agent/pre-step瀑布(允许策略插件改写或拒绝)→ 追加user/message→ 从会话日志派生模型历史 → 发一次 LLM 请求(assistant/chunk*逐块落日志)→ 提取工具调用 → 逐条走tool/call→ 工具执行流水线(权限、策略、超时)→tool/result落日志 → 若无后续则关回合(turn/end); - 结果
:回合收敛后,持久化会话日志,进程退出。
这条链路上每一步都有一个可观察的事件,这正是全书反复强调的"模型可见 ⟺ 已入日志"设计。工具调用产生文件修改后,产物通过 UI 交付层(deliverables)以"本轮改动了哪些文件"的形式回显给用户。
1.4 产品形态:同一内核、多个 profile
dsh 不是"一个可执行文件",而是"一个内核 + 若干命名的组合(profile)"。仓库自带模板 profile 有五个(packages/bundle/*):
web | ||
headless | ||
sdk | ||
sdk-minimal | ||
acp |
每个 profile 的 person 都以 "You are a coding agent powered by the {{model}} model." 开场——dsh 默认把自己塑造成编程智能体,第 7 章会专门讲这层"coding 能力"是怎么由文件编辑、Shell、LSP、代码执行、技能等组装起来的。
1.5 本书的阅读路线
第 1 章 导论(本章)第 2 章 整体设计原理 ← 先读,建立心智模型第 3 章 Cordis 插件运行时 ← 底座第 4 章 Agent Loop 回合引擎 ← 引擎第 5 章 会话日志 / 提示词 / 工具注册表 ← 产品脊柱第 6 章 Skill 技能系统第 7 章 Coding 编程能力组装第 8 章 组合与启动(profile/bundle/preset)第 9 章 能力接缝巡礼(llm/fs/shell/subagent/workflow/…)第 10 章 工程质量与演进附录 A 术语表 / 附录 B 参考索引想快速抓住系统本质:读第 2 章后直接跳到第 4 章,再回头补第 3 章即可。第 2 章是全书纲目,第 3、4 章是全书最硬的两章。
本章要点
dsh 是"全插件化"的 Cordis Agent Harness:无特权核心,一切皆可替换; 仓库 = vendored Cordis( vendor/)+ 按服务粒度拆分的 dsh 包(packages/)+ 文档/门禁体系(docs/、scripts/);一次运行 = boot 组装插件树 → session 记录一切 → agent loop 驱动 step/turn → 事件全部落日志; 同一内核以 web/headless/sdk/sdk-minimal/acp五种 profile 呈现,默认人设是 coding agent。