☰
DeepSeek Harness 到底是什么?从 Agent 到 Harness 的架构演进
2026/10/24 2:18:10 网站建设 项目流程

DeepSeek Harness 源码与架构解析(一)

从一个最简单的 Agent 出发,逐步理解 Agent、Runtime、Harness、Cordis,以及 DeepSeek Harness 的插件化与微内核架构。

DeepSeek Harness系列共16篇,每一篇对应顺序如下:

01|从一个简单的 Agent 开始

假设我们希望让大模型完成一个任务:

“读取项目中的 README.md,分析项目的技术架构,并给出总结。”

我们会怎么设计呢?

对于一个简单的 Agent,最直观的执行过程可能是:

用户输入任务 ↓ 调用 LLM ↓ LLM 判断需要读取文件 ↓ 提出 Tool Call read("README.md") ↓ 程序执行 read 工具 ↓ 将文件内容返回给 LLM ↓ LLM 根据文件内容生成总结 ↓ 返回用户

看起来并不复杂。

但这里有一个值得思考的问题:

当大模型输出Tool Call: read("README.md")时,文件就已经被读取了吗?

答案是:没有。

大模型可以根据任务和工具定义,决定提出一个工具调用请求,但它并不会仅凭输出这条请求就自动访问本地文件。

真正读取文件的,是模型之外的程序。

因此,一个最简单的 Agent 执行过程,其实已经涉及三个不同角色:

角色职责
LLM根据上下文进行推理,提出行动或生成回答
Tool提供具体的外部操作能力
执行程序接收模型的工具请求,执行工具,并将结果返回模型

这意味着:

LLM 负责提出需要采取的行动,外部执行程序负责真正完成行动。

而模型拿到执行结果之后,才能继续进行下一轮推理。

这便形成了 Agent 中非常典型的执行循环:

Reason → Act → Observe → Reason

也就是我们常说的 ReAct 思想。

但新的问题又出现了。

模型提出了一个 Tool Call,外部程序究竟如何知道应该执行哪个工具?


02|工具调用背后,究竟发生了什么?

继续刚才的例子。

假设模型输出:

{ "name": "read", "arguments": { "path": "README.md" } }

我们需要思考几个问题。

系统怎么知道存在read这个工具?

模型又是怎么知道它可以使用read的?

当模型提出调用后,程序怎样找到对应的实现?

如果参数错误,或者用户没有访问权限,又该怎么办?

为了回答这些问题,我们先梳理工具从被提供到最终执行的完整过程。

一个工具需要经历哪些过程?

开发者提供工具实现 ↓ 系统注册工具 ↓ 将允许使用的工具说明提供给 LLM ↓ LLM 根据任务提出 Tool Call ↓ 程序查找目标工具 ↓ 检查参数与执行权限 ↓ 调用对应工具实现 ↓ 处理执行结果 ↓ 将结果反馈给 LLM

实际上,这个过程已经包含一套相对完整的工具管理机制。

在 DeepSeek Harness 中,可以将几个关键概念对应起来。

概念作用
Tool Registry保存已经注册的工具定义,支持查找
Tool Schema向模型描述工具名称、功能及参数格式
Tool Executor具体执行工具的函数或逻辑
Tool Runtime管理工具注册、执行策略、调用和结果处理的整体机制

这里要特别注意:

Tool Schema 并不负责执行工具。

例如,模型通过 Tool Schema 知道有一个read工具,以及调用这个工具应该提供哪些参数。

但真正执行读取操作的,是工具对应的执行函数。

在当前 DSH 中,工具定义由Tool Registry管理。

注册工具时可以使用:

ctx.tools.register(defineTool({ // 工具名称 // 工具说明 // 参数定义 // 输出约定 // execute 函数 }))

这段代码只是展示关键结构,并非完整可运行示例。

defineTool可以帮助开发者定义输入与输出约定,并进行相应的校验。

而 Tool Runtime 可以通过ctx.tools.execute()调度已接受的工具调用,再经过工具策略、执行、结果处理等流程。

因此,模型不需要知道工具内部怎样实现。

它只需要知道:

有什么工具可以使用、工具负责什么、调用时需要哪些参数。

至于工具怎样被检查和执行,则由外部程序负责。

但是,当项目规模逐渐增大时,这种简单的工具调用机制很快就会遇到更多工程问题。


03|为什么有了 LLM 和 Tool Calling 还不够?

假设我们不再只需要一个read工具。

而是希望开发一套真正可以长期运行的 Agent 系统。

系统可能需要读取文件、执行命令、访问数据库、调用外部 API,甚至协调其他 Agent。

这时,问题就不再只是“怎样调用一个工具”了。

1. 工具管理问题

如果系统有几十个甚至上百个工具,我们需要考虑:

怎样统一注册和发现工具?

怎样给不同 Agent 提供不同的工具权限?

怎样检查工具参数?

怎样管理并发、超时和工具执行失败?

又怎样避免未授权操作?

2. 状态管理问题

假设一个 Agent 已经执行了三个工具。

接下来模型如何知道之前发生了什么?

如果用户继续提问,系统怎样保留必要的历史?

如果程序突然退出,哪些执行记录还能恢复?

3. 执行控制问题

假设模型第一次读取文件失败。

系统应该立刻结束任务,还是将错误返回模型,让它决定下一步?

如果模型反复调用同一个工具,怎样限制无效循环?

如果某次模型请求超时,又应该怎样处理?

4. 系统扩展问题

假设我们现在使用 DeepSeek 模型。

未来想切换到其他模型,是否必须修改整个 Agent 系统?

如果我们想增加统一的日志、审计和性能统计功能,是否需要修改每个 Agent?

如果想引入新的工具或工作流,又该怎样扩展?

这些已经不只是语言模型的推理问题,而是完整的软件工程问题。

模型负责产生推理结果,但围绕模型的执行、状态、安全和扩展机制,需要由外部系统提供。

于是,我们就可以开始理解 Agent Harness。


04|什么是 Agent Harness?

在理解 Harness 之前,我们先区分五个经常被混用的概念。

Model:模型

Model 是负责推理与生成的模型。

它根据输入上下文,输出文本、工具调用请求等结果。

模型可以提出一个行动,但不一定具有直接执行该行动的能力。

Agent:智能体

Agent 是围绕某个目标开展行动的智能体。

它通常结合模型、上下文、工具和执行机制,根据任务进展持续作出决策。

因此,Agent 不等于一次 LLM API 调用。

一个 Agent 可能需要多次调用模型和工具,才能完成一个任务。

Agent Runtime:智能体运行时

Runtime 本身是一个通用概念。

在 Agent 系统中,Agent Runtime 通常指支持 Agent 在运行期间真正执行任务的机制。

例如:

模型请求、执行循环、工具调度、状态管理、取消与错误处理。

但 Runtime 并没有一个在所有框架中完全统一的范围。

Agent Loop 就是 Agent Runtime 中常见的核心执行机制之一。

Agent Harness:智能体执行基础设施

Harness 则站在更完整的系统层面。

它围绕模型与 Agent 提供执行控制、工具管理、状态管理、安全策略和扩展机制。

可以简单理解为:

Agent 负责完成任务,Harness 负责为 Agent 提供完成任务所需的运行与控制能力。

这里需要强调:

Harness 并不一定要管理多个 Agent。

即使只有一个 Agent,也可以拥有完整的 Harness。

DeepSeek Harness:Harness 的一个具体实现

DeepSeek Harness,简称 DSH,是 DeepSeek 开源的一套 Agent Harness。

它将 Agent 执行所需的多种能力组织成可扩展的系统。

其最鲜明的设计原则是:

Everything is a Plugin——一切皆插件。

这也是 DSH 与许多围绕固定核心功能进行开发的 Agent 应用,在架构设计上值得比较的地方。


05|DeepSeek Harness 为什么强调“一切皆插件”?

假设我们自己开发一个 Agent 系统。

一开始可能会把模型调用、工具执行、Session 管理和任务循环都写在一套固定的程序结构里。

Agent Application │ ├── Agent Loop ├── LLM Client ├── Tool Manager └── Session Manager

这种方式能够实现功能。

但是如果希望替换模型适配器、增加新的工具策略,或者改变 Agent 的执行控制机制,就需要考虑模块之间的耦合。

DSH 采用了另一种设计思路:

将 Agent 系统中的大量核心能力实现为插件,并通过配置进行组合。

根据 DSH 官方架构文档:

模型适配器、工具注册表、Session 日志,甚至 Agent Loop 本身,都属于可替换的插件能力。

这意味着 DSH 并不是简单地在一个固定 Agent 核心之外增加几个插件接口。

它进一步尝试让 Agent 的主要运行能力本身也成为可组合的模块。

例如:

DeepSeek Harness │ ├── Agent Loop Plugin │ ├── LLM Adapter Plugin │ ├── Tool Registry Plugin │ ├── Session Plugin │ ├── Permission Plugin │ └── Observability Plugin

注意:这是一张概念示意图,不是 DSH 实际的插件配置树。

这里自然会引出新的问题:

如果系统中的这些能力都是插件,那么谁负责加载插件、管理依赖、实现通信以及处理生命周期?

这就是 Cordis 出现的原因。


06|Cordis 与 DSH 的微内核设计

6.1 Cordis 到底是什么?

Cordis 是 DeepSeek Harness 底层使用的插件框架。

它本身不是专门负责 LLM 推理的 Agent 系统。

它负责解决的是一个更通用的软件架构问题:

当一个软件由大量可组合插件构成时,怎样管理这些插件之间的关系?

例如:

插件 A 提供工具服务。

插件 B 需要使用工具服务。

插件 C 希望在模型请求之前执行自己的逻辑。

插件 D 希望观察工具调用结果。

这些插件不应该要求核心程序知道每个插件的全部实现细节。

因此,Cordis 提供一套统一的插件组织机制。

6.2 什么是微内核架构?

微内核(Microkernel)在这里指一种软件架构设计思想,不是操作系统中的微内核实现。

其基本思路是:

保留相对精简、稳定的基础机制,将更多具体功能放在可扩展的模块中。

在传统的单体式设计中,很多功能可能直接写在核心执行逻辑内部。

而在微内核式设计中,核心更强调提供明确的扩展机制,让外围功能能够通过统一接口参与系统运行。

DSH 的设计就体现了这种思想。

官方早期设计记录明确强调:

扩展 Agent Loop 时,应尽量利用 Cordis 的事件体系,而不是不断往默认 Agent Loop 中增加新的专用执行逻辑。

甚至默认的 Agent Loop 本身也被实现为可替换插件。

所以,更准确的表达是:

DSH 借助 Cordis 的插件、服务和事件机制,实现微内核式的 Agent Harness 架构。

这里的“微内核”不是说 DSH 所有功能都很简单,而是强调核心机制与可扩展能力之间的关系。

6.3 Cordis 通过什么机制实现插件化?

Cordis 的核心机制可以概括为五个方面。

机制解决的问题
Plugin怎样组织可以独立挂载的功能
Context / Service插件怎样访问其他模块提供的能力
Dependency Injection插件怎样声明所需依赖,并在依赖就绪后激活
Event / Waterfall插件怎样监听或参与系统执行过程
Effect / Lifecycle插件卸载时怎样清理注册和资源

例如,工具插件可以把能力注册到ctx.tools。

Agent Loop 通过这个服务取得工具能力,而不是直接依赖某个具体工具插件的代码。

又例如,dsh-tool-turbo可以注册agent/request事件监听器,在模型请求配置处理阶段参与决策。

这就使插件能够扩展 Agent 行为,而不一定需要修改 Agent Loop 的实现。

当然,插件也只能在框架已经提供的接口和扩展点范围内工作,并不意味着任意内部逻辑都能够无条件被插件覆盖。


07|Cordis 和 Agent Loop 究竟有什么区别?

这里是理解 DSH 架构最重要的一步。

因为 Cordis 和 Agent Loop 都参与系统运行,但它们解决的是完全不同的问题。

我们从时间顺序来理解。

第一阶段:系统启动

启动 DSH ↓ 读取 Profile / Bundle / Patch ↓ Cordis 组织插件树 ↓ 根据依赖激活插件 ↓ 执行插件初始化逻辑 ↓ 注册 Service / Event / Tool ↓ 系统具备处理 Agent 任务的能力

在这个阶段,Cordis 负责组织和管理插件。

但是,插件加载完成,并不代表已经开始执行某个用户任务。

第二阶段:Agent 运行

用户输入 ↓ Agent Loop 开始执行 ↓ 组装上下文 ↓ 调用 LLM ↓ LLM 提出 Tool Call ↓ Tool Runtime 执行工具 ↓ Session 记录结果 ↓ Agent Loop 再次调用 LLM ↓ 返回最终结果

这一阶段,Agent Loop 负责驱动模型与工具之间的执行循环。

Cordis 仍然在提供服务访问、事件分发和插件生命周期支持,但它本身并不代替 Agent Loop 执行推理循环。

因此:

CordisAgent Loop
通用插件框架Agent 执行驱动器
组织插件与服务推动任务执行
管理依赖与生命周期管理 Turn / Step 执行过程
提供事件分发机制在执行过程中使用相关服务并触发扩展事件
不负责理解用户任务根据模型输出推进工具调用与后续请求

Cordis 解决“系统中的能力如何组合和协作”;Agent Loop 解决“Agent 的任务如何一步步执行”。


08|DeepSeek Harness 完整架构

前面我们分别理解了工具机制、Harness、插件化以及 Cordis。

现在将它们放进同一张架构图。

这里需要同时展示两条关系:

第一条:插件怎样组成 DSH。

第二条:用户任务怎样通过这些组件执行。

说明:这是根据 DSH 官方架构整理的逻辑关系图,而非逐函数调用图。权限控制实际作用于工具执行流水线中的多个环节;Agent Loop 的请求准备、Session 写入和工具结果提交也有更严格的时序。后续文章会分别通过源码展开。

这张图最重要的地方是:它将插件组装关系和Agent 执行关系放进了同一套架构。

Cordis 负责让组件和扩展点能够正常协作。

Agent Loop 则在这些组件已经具备相应能力后,真正驱动用户任务运行。


09|总结

从一个简单的文件读取任务出发,我们可以看到:

大模型能够提出工具调用,但工具需要外部程序执行。

当 Agent 从简单 Demo 发展成复杂系统后,就需要处理工具管理、状态记录、执行控制、权限和扩展问题。

Agent Harness 正是围绕这些需求构建的执行与控制基础设施。

DeepSeek Harness 则提供了一种具体实现,并将“一切皆插件”作为重要设计原则。

它利用 Cordis 组织插件、管理服务依赖与事件扩展,通过 Agent Loop 驱动模型和工具之间的执行循环,再结合 Tool Runtime、Session 和其他能力构建完整的 Agent 运行系统。

理解 DSH 的关键,不是记住它有多少插件,而是理解这些能力为什么需要被拆开、怎样重新组合,以及这种设计解决了什么工程问题。

下一篇我们将深入 Cordis,从插件之间如何通信与依赖开始,理解 Service、Context、Event、Waterfall 和 Effect 的实现原理。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询