(二)DeepSeek又开源了!Harness:一个让AI Agent像搭积木一样组装的框架
📖 系列导航:《(一)DeepSeek Harness炸场:88K星的开源Agent框架,把「一切皆插件」玩到了极致》→ 本文 → 敬请期待(三)
零、前情提要
上篇我们从宏观视角鸟瞰了 DeepSeek Harness 的全貌——一个由 Cordis 运行时驱动、主张"一切皆插件"的 Agent 框架。本篇我们深入它的运行机制:如何启动、如何组合、如何扩展,以及它与传统框架的本质区别在哪里。
一、门槛低到离谱:一条命令跑起来
Harness 最大的诚意,体现在上手成本上。
零安装体验(推荐):
npx @deepseek-ai/dsh web
一条命令,无需 clone 仓库,无需装 pnpm,npx 自动下载最新包,执行完毕浏览器打开 http://127.0.0.1:3080,Web UI 直接可用。任何有 Node.js 环境的机器,3 秒内就能见到正在跑 Agent 的界面。
从源码跑(开发者模式):
git clone https://github.com/deepseek-ai/deepseek-harness.git
cd deepseek-harness
pnpm install
pnpm run build
pnpm dsh web
整个仓库 monorepo 结构,55+ 个 npm 包,所有源码 TypeScript,工具链标准化(Vitest 测试 + Dsddown 构建 + pnpm workspaces)。
二、一切皆插件:Cordis 运行时的魔力
这是 Harness 与市面上绝大多数 Agent 框架最根本的区别。
传统框架:核心是固定的,你想扩展就得改核心代码,或者用"钩子"在核心外层包一层,核心与扩展之间泾渭分明。
Harness 的思路:没有核心。
所有功能——模型适配器、工具注册、会话日志、Agent 循环本身——全部是插件。它们向一个共享的 Cordis Context(ctx)注册服务、发布类型化事件、贡献可逆副作用(Effects)。当你卸载一个插件时,它注册的所有东西连带副作用一起"撤销",不留痕迹。
┌─────────────────────────────────────────────────────┐
│ Cordis Context (ctx) │
│ ctx.llm · ctx.tools · ctx.sessions · ctx.fs ... │
└─────────────────────────────────────────────────────┘
↑ ↑ ↑ ↑
ModelAdapter ToolRegistry SessionLog FileSystem
(llm 包) (core/tools) (session) (fs 包)
↑ ↑ ↑ ↑
┌──────────────────────────────────────────┐
│ 每一个都是插件,Mount/Unmount 完全可逆 │
└──────────────────────────────────────────┘
这带来了一个优雅的能力:配置即扩展。
你不需要 Fork 仓库,不需要写插件代码,只需要写一个 YAML Patch 文件,就可以替换掉框架中的任何一个服务。换一个模型提供商、换一个文件系统后端、换一个沙箱策略——全在配置层完成,代码零改动。
三、Profile + Bundle + Patch:三层组合的艺术
3.1 Bundle(包):代码分发的最小单元
Bundle 是 Cordis 配置行(Config Rows)和它们所挂载代码的发行格式。每个 Bundle 在自己的 package.json 中声明:
{
"name": "@deepseek-ai/dsh-bundle-base",
"dsh": {
"bundle": "cordis.patch.yml"
}
}
Bundle 封装了一个完整的功能集,并保证其中的任何配置行都能被上层的 Patch 覆盖——这叫"可补丁化"(patchable)。
3.2 Profile(配置集):Bundle 的叠加顺序
Profile 是命名化的 Bundle 组合,存于 Harness Home 目录。它不仅列出要叠加的 Bundle 顺序,还管理外链插件(out-of-tree plugins)和用户的个人 Patch:
{
"name": "web",
"extends": "base",
"bundles": [
"dsh-base",
"dsh-web-app"
]
}
框架默认提供两个 Profile:
| Profile | 包含内容 | 使用场景 |
|---|---|---|
web | Base + Web App(浏览器 UI) | 日常对话、GUI 操作 |
headless | Base + 无服务器单次运行 | 脚本化、CI/CD、无人值守 |
3.3 Patch(补丁):最终生效的覆盖层
Patch 是真正在运行时生效的配置覆盖文件。它按 ID 定位到某一行 Config Row,然后整体替换:
# cordis.patch.yml
- id: llm/provider
replace:
provider: openai
model: gpt-4o
3.4 叠加顺序:Layers Stack
实际运行时,配置按以下顺序叠加,后一层覆盖前一层:
[空配置]
↓ Bundle 1
↓ Bundle 2
↓ Profile 内 cordis.patch.yml
↓ Home 级 cordis.patch.yml
↓ --patch 命令行覆盖
= 最终生效配置
这个顺序是 Harness 设计中最精妙的地方:越底层越稳定,越上层越灵活。dsh-base 里的内容是默认配置,你的个人 Patch 永远在最上面,可以任意改写。
查看当前机器实际启动时的完整配置树:
dsh --profile web --dump-config
打印出来的每一行都可以被你自己的 Patch 替换。这是 Harness 给开发者的"X光透视"工具。
四、核心包一览:55个包在做什么
Harness 的 monorepo 包含 55+ 个 npm 包。按职责分类:
模型层
| 包 | 职责 |
|---|---|
packages/llm | LLM 适配层(ctx.llm),统一消息格式 + 流式处理 |
packages/llm/llm | 核心接口 + adapter seam(可插拔模型) |
packages/api | DeepSeek 官方 API adapter |
packages/context | 上下文管理、deriveMessages() |
Agent 核心
| 包 | 职责 |
|---|---|
packages/core/agent | Agent 接口 + 内存注册表 |
packages/core/agent-loop | 默认驱动实现,turn/step 循环 |
packages/core/session | SessionEvent 日志(ctx.sessions) |
packages/core/scope | 每个 Agent 的作用域隔离原语 |
packages/core/system-prompt | Prompt 片段 + 工具 Schema 拼装 |
工具系统
| 包 | 职责 |
|---|---|
packages/guard | 工具执行前的守卫(安全审查) |
packages/sandbox | 沙箱隔离后端 |
packages/shell | 本地 shell 后端 |
packages/subprocess | 子进程执行模型 |
packages/terminal | PTY 终端管理 |
packages/lsp | LSP(Language Server Protocol)支持 |
文件与存储
| 包 | 职责 |
|---|---|
packages/fs | 文件系统能力边界(seam) |
packages/storage | 持久化存储抽象 |
packages/spill | 大型附件溢出处理 |
扩展生态
| 包 | 职责 |
|---|---|
packages/mcp | MCP(Model Context Protocol)协议支持 |
packages/skill | Skill 定义与加载 |
packages/workflow | 工作流引擎 |
packages/e2b | E2B 远程沙箱集成 |
packages/web | Web UI(浏览器应用) |
配套工具
| 包 | 职责 |
|---|---|
packages/boot | 应用启动链路(app-boot) |
packages/sdk | 对外 SDK |
packages/preset | Agent 预设组合 |
packages/credentials | 凭证管理 |
packages/settings | 用户设置 |
packages/session-query | Session 查询语言 |
五、两种运行模式:web vs headless
这是 Harness 另一个贴心的设计——同一个内核,两套前端。
Web 模式(dsh web / npx @deepseek-ai/dsh web)
- 启动本地 HTTP 服务器(默认
3080端口) - 打开浏览器是完整的 Chat UI
- 支持多会话、实时流式输出、文件上传
- 适合日常使用和开发调试
Headless 模式(dsh run <prompt>)
- 零服务器,执行完单条 prompt 即退出
- 适合嵌入脚本、CI/CD 流水线
- 所有输出到 stdout/stderr
# 安装后直接跑
npx @deepseek-ai/dsh run "用 Bash 统计当前目录文件数量"
两套模式的底层代码完全复用,差异只在 Profile 加载的 Bundle 不同:web 多加载了 dsh-web-app。
六、开发者视角:扩展的七种姿势
架构文档里有一张扩展点总表,覆盖了所有开发场景:
| 开发目标 | 机制 |
|---|---|
| 加一个新模型提供商 | 在 ctx.llm 注册 adapter |
| 加一个工具 | 在 ctx.tools 注册,Schema 自动进入 Prompt |
| 换一套文件系统 | 注册 ctx.fs Provider |
| 加 shell 执行能力 | 注册 ctx.shell 后端 |
| 加沙箱隔离 | 使用 ctx.sandbox 后端 |
| 拦截请求/工具/对话 | 监听 agent/* 或 tools/* 事件 |
| 注入上下文给模型 | 调用 agent.inject() |
每一种扩展都有配套的 Cookbook 文档,分步骤讲解如何操作。文档体系在 docs/cookbook/ 下:
adding-a-package.md— 如何新增一个包adding-a-tool.md— 如何注册一个新工具adding-an-llm-adapter.md— 如何对接新模型adding-a-conversation-node.md— 如何添加自定义对话节点
七、与 LangChain 的核心差异
| 维度 | LangChain | DeepSeek Harness |
|---|---|---|
| 扩展方式 | Chain / Agent 组合 | 插件 + Patch |
| 核心是否可替换 | 核心固定,扩展在外层 | 无特权核心,配置即扩展 |
| 模型切换 | 需要改代码或用 LangChain LM | 写一行 YAML 替换 ctx.llm provider |
| 副作用管理 | 手动清理 | Cordis Effects 自动可逆 |
| 运行模式 | 单一 | web / headless 双模式 |
| 配置调试 | 黑箱 | dsh --dump-config 全透明 |
| 沙箱隔离 | 第三方集成 | 内置 sandbox 包,支持本地/远程切换 |
LangChain 的思路是"一切皆 Chain",组合自由度靠拼装;Harness 的思路是"一切皆插件",组合自由度靠叠加顺序和 Patch。这两种哲学各有适用场景,但如果你追求最小改动、最快迭代,Harness 的配置驱动扩展会更舒服。
八、社区与生态
- GitHub Discussions:反馈 + Bug 报告
- Discord:活跃的开发者社区(DeepSeek Harness Discord)
- Topic 标签:给自己的插件打
dsh-plugin标签即可被索引 - 微信公众号:DeepSeek Harness 团队公众号(扫码入群)
- 企微群:扫码填问卷,自动邀请入群
目前框架处于 Developer Preview 阶段,迭代快,API 可能有破坏性变更。MIT 许可证,商业可用。
九、总结
DeepSeek Harness 带来了一套全新的 Agent 框架思路:
- Cordis 运行时作为无特权核心,所有功能都是可卸载的插件
- Profile + Bundle + Patch 三层组合,让你用 YAML 就能换掉任何功能
dsh --dump-config让配置完全透明,调试不靠猜- npx 一条命令跑起来,门槛低到尘埃里
- web / headless 双模式,日常开发和生产脚本无缝切换
下一期我们将深入 Cordis 运行时的核心机制——可逆效应(Reversible Effects) 如何让插件真正做到"插上去能用、拔下来无痕"。敬请期待。
下一篇预告:(三)Cordis运行时解密:DeepSeek Harness的可逆编程心脏——Effects如何让插件热拔插成为可能
DeepSeek又开源了!Harness:一个让AI Agent像搭积木一样组装的框架&spm=1001.2101.3001.5002&articleId=163832603&d=1&t=3&u=3b3933d6acab447b88f02fd660ce8b21)
230

被折叠的 条评论
为什么被折叠?



