(三)88K Stars的Agent框架长什么样?DeepSeek Harness架构全解析

项目地址:https://github.com/deepseek-ai/deepseek-harness
⭐ 88,000+ Stars | MIT License | 语言:TypeScript


开篇:一个"没有核心"的Agent框架

当大多数AI框架还在争论"该用LangChain还是LlamaIndex"时,DeepSeek扔出了一个重磅炸弹——Harness

这个斩获88K Stars的开源项目,用一句"Everything is a Plugin"彻底颠覆了传统Agent框架的设计哲学。没有特权核心、没有硬编码逻辑,甚至连模型适配器、工具注册表、会话管理这些"基础设施",统统都是可插拔的插件。

今天,我们就来拆解这个"叛逆"框架的完整架构。


一、整体架构:三层金字塔

Harness的架构可以用一个三层金字塔来概括:

        ┌─────────────────┐
        │   Application   │  ← 你的Agent应用
        │   (Web/CLI/API) │
        └────────┬────────┘
                 │
        ┌────────▼────────┐
        │     Cordis      │  ← 可逆编程运行时
        │   (插件系统)     │
        └────────┬────────┘
                 │
        ┌────────▼────────┐
        │   Capability    │  ← 能力边界层
        │     Seams       │
        └─────────────────┘

1.1 最底层:Capability Seams(能力边界)

这是Harness最精妙的设计。Seam原意是"接缝",在Harness中代表着能力的边界和交换点。

传统框架中,如果你想把"本地执行Bash"换成"云端E2B沙箱执行",可能需要改几十处代码。但在Harness中,只需要换一个FS Provider——因为文件系统、Shell执行、工具调用这些能力,都被抽象成了Seam。

Seam的三角色模型

  • Service Definition:能力接口定义(如interface IFileSystem
  • Provider:能力实现者(如LocalFSProviderE2BProvider
  • Consumer:能力使用者(如BashToolFileEditor
// 换个Provider,整个Agent的"工作环境"就变了
ctx.provide('fs', new E2BFileSystem())  // 云端执行
ctx.provide('fs', new LocalFileSystem()) // 本地执行

1.2 中间层:Cordis运行时

Cordis是Harness的心脏,一个专为可逆编程设计的运行时。

什么是可逆编程?想象一下:

  • 传统插件系统:加载容易,卸载难(内存泄漏、状态污染)
  • Cordis插件:加载和卸载完全对称,就像搭积木一样,想拆就拆

Cordis的核心是EffectScope——每个插件都在自己的作用域内运行,作用域可以:

  • fork:创建子作用域
  • ensure:确保资源存在
  • reset:重置状态
  • dispose:完全清理
// 插件的生命周期完全可控
const scope = ctx.scope.fork()
await scope.plugin(MyPlugin)
await scope.reset()  // 干净重置
await scope.dispose() // 彻底销毁

1.3 最上层:Application

Harness提供三种开箱即用的应用形态:

形态 命令 适用场景
Web UI npx @deepseek-ai/dsh web 可视化交互、演示
Headless npx @deepseek-ai/dsh headless 服务器部署、API服务
CLI npx @deepseek-ai/dsh 命令行操作、脚本化

二、一切皆插件:没有特权核心

Harness最 radical 的设计是:框架本身没有特权核心

让我们看看传统Agent框架 vs Harness的区别:

组件 传统框架 Harness
模型适配器 硬编码在核心 llm 插件
工具注册表 全局单例 tools 插件
会话管理 核心服务 sessions 插件
Agent Loop 内置主循环 agent-loop 插件
系统提示词 写死在代码 system-prompt 插件

这意味着什么?你可以完全替换框架的任何部分,而不会破坏其他功能。

2.1 插件的Ctx键

Harness使用**上下文(Context)**作为插件间通信的唯一方式:

// 核心插件提供的ctx键
ctx.sessions      // 会话管理(core/session)
ctx.systemPrompt  // 系统提示词(core/system-prompt)
ctx.tools         // 工具注册表(core/tools)
ctx.agents        // Agent实例管理(core/agent)
ctx.agentLoop     // Agent主循环(core/agent-loop)
ctx.llm           // 模型适配层(llm/llm)

每个插件通过provide注册自己的服务,通过inject消费其他服务。


三、事件驱动:Agent Loop的瀑布流

Harness的Agent不是"轮询-响应"模式,而是纯事件驱动

一个完整的对话周期(Turn)会产生这样的事件流:

turn/start
  ↓
agent/pre-step      ← waterfall(需调用next())
  ↓
step/start
  ↓
agent/request       ← waterfall
  ↓
llm/stream          ← waterfall
  ↓
assistant/chunk     ← 流式输出片段
  ↓
assistant/message   ← 完整消息
  ↓
tool/call           ← 工具调用(可能有多个)
  ↓
tools/pre-execute   ← waterfall
  ↓
tools/execute
  ↓
tools/post-execute
  ↓
step/end
  ↓
turn/end

3.1 四种事件分发模式

Cordis支持四种事件分发方式:

模式 特点 适用场景
emit 广播,不关心返回值 日志、通知
parallel 并行执行所有监听者 独立副作用
serial 串行执行 有序处理
bail 返回第一个非空值 策略选择
waterfall 可拦截、可修改 中间件、预处理

waterfall事件是Harness的精髓——它允许插件在事件传播过程中"插手",比如:

  • agent/pre-step中修改输入
  • llm/stream中拦截并修改模型输出
  • tools/pre-execute中添加权限检查

四、配置系统:Profile + Bundle + Patch

Harness的配置系统同样体现了"分层叠加"的思想:

4.1 三层配置模型

Base Bundle (dsh-base)
    ↓
Profile Config (cordis.patch.yml)
    ↓
Home Config (~/.config/dsh/)
    ↓
CLI Patch (--patch)
  • Bundle:代码分发单元,包含一组插件和默认配置
  • Profile:预定义的配置组合(如dsh-web-appdsh-headless
  • Patch:无侵入式的配置覆盖

4.2 常用Profile

Profile 用途 包含的核心包
dsh-base 基础功能 core/, llm/, tools/*
dsh-web-app Web界面 + web-ui, react组件
dsh-headless 无头服务 + api-server

4.3 调试配置

# 查看实际生效的完整配置
npx @deepseek-ai/dsh web --dump-config

这个命令会输出所有合并后的配置,是排查问题的利器。


五、60+包的组织结构

Harness的代码库采用monorepo管理,packages目录下包含60多个包:

packages/
├── core/                    # 核心插件
│   ├── agent/              # Agent实例管理
│   ├── agent-loop/         # Agent主循环
│   ├── session/            # 会话管理
│   ├── system-prompt/      # 系统提示词
│   └── tools/              # 工具注册表
├── llm/                     # 模型适配层
│   ├── llm/                # 抽象接口
│   ├── anthropic/          # Claude适配器
│   ├── openai/             # GPT适配器
│   ├── deepseek/           # DeepSeek适配器
│   └── ...
├── tools/                   # 内置工具
│   ├── bash/               # Bash执行
│   ├── file/               # 文件编辑
│   ├── git/                # Git操作
│   └── ...
├── capabilities/            # 能力边界实现
│   ├── fs/                 # 文件系统
│   ├── shell/              # Shell执行
│   └── telemetry/          # 遥测
└── apps/                    # 应用层
    ├── web-ui/             # Web界面
    ├── cli/                # 命令行
    └── api-server/         # API服务

六、为什么Harness值得关注?

6.1 对比传统框架

特性 LangChain AutoGPT Harness
架构 链式调用 自主循环 插件化+事件驱动
可扩展性 中等 极高
可逆性 原生支持
能力边界 硬编码 硬编码 Seam抽象
部署形态 应用 Web/Headless/CLI

6.2 适用场景

  • 快速原型:用Web UI验证Agent想法
  • 生产部署:Headless模式提供API服务
  • 深度定制:替换任意组件,打造专属Agent
  • 研究实验:利用可逆性测试不同策略

七、快速上手

# 1. 安装
npm install -g @deepseek-ai/dsh

# 2. 启动Web界面
npx @deepseek-ai/dsh web
# 访问 http://127.0.0.1:3080

# 3. 配置模型(config.toml)
[llm]
provider = "deepseek"
api_key = "your-api-key"

# 4. 开始对话

结语:插件化是Agent框架的终极形态吗?

Harness用88K Stars证明了一件事:当一切皆插件,创新就没有边界

传统框架的"核心团队决定一切"模式,在Harness中变成了"社区共同定义框架"。每个人都可以:

  • 写一个新插件,扩展Harness的能力
  • 替换现有插件,实现自己的逻辑
  • 组合不同插件,创造全新的Agent形态

这不是一个框架,而是一个Agent操作系统


下一篇预告

(四)比LangChain更优雅?DeepSeek Harness的插件化Agent设计

我们将深入对比Harness与LangChain的架构差异,看看"无核心"设计到底强在哪里。


本文是「DeepSeek Harness源码分析」系列第3篇,系列共100篇,涵盖架构、源码、实战全流程。

Logo

欢迎加入DeepSeek 技术社区。在这里,你可以找到志同道合的朋友,共同探索AI技术的奥秘。

更多推荐