Skip to main content

DeepSeek Harness 深度解析:从一切皆插件到用基座构建自己的 Agent 应用

Rainy
雨落无声,代码成诗 —— 致力于技术与艺术的极致平衡
Rainy
15 MIN READ... VIEWS

DeepSeek Harness:Cordis 内核、能力插件与追加式会话日志

2026 年 8 月,DeepSeek 开放了 DeepSeek Harness 的开发者预览与源代码。它不是“又一个 DeepSeek 模型”,也不是只把聊天框套在模型 API 外面;它是一套让模型能够读取环境、调用工具、维持会话、接受审批并持续完成任务的 Agent 运行时

官方给出的公式很直接:

Agent = Model + Harness

模型负责推理与决策,Harness 负责把推理接到真实世界:上下文从哪里来、工具如何注册、命令在哪里执行、状态怎样恢复、危险动作由谁批准、失败以后能否重放。本文会从“能跑起来”一直讲到“如何基于它开发自己的应用”。

开发者预览意味着什么

DeepSeek Harness 当前仍处于 Developer Preview,官方明确提示核心插件与 API 会快速演进并可能产生不兼容变更。本文基于 2026-08-24 的官方文档与主分支;生产项目应固定版本、保留迁移测试,不要直接追随 master


一、它解决的不是“模型不聪明”,而是“模型无法可靠工作”

单次模型调用通常只有三样东西:输入消息、模型参数、输出文本。一个可用 Agent 至少还需要:

能力单次模型调用DeepSeek Harness
上下文调用者临时拼接系统提示、历史与注入信息统一装配
工具手写函数调用循环工具注册表、Schema、执行管线与权限钩子
状态由应用自行保存追加式 Session Event Log
执行应用直接运行命令文件系统、Shell、沙箱等可替换后端
生命周期请求成功或失败Turn、Step、取消、恢复、分叉与重放
可观测性日志靠自己补模型可见事实与工具轨迹天然可追踪
扩展方式修改主循环挂载插件、监听事件、替换能力提供者

这也是 Harness 最重要的价值:把模型能力变成一个有边界、有状态、有反馈的执行系统。

如果只是做 FAQ 聊天,直接调用 API 更简单;如果任务要跨多轮读取代码、修改文件、运行测试、等待工具结果并接受人工审批,Harness 才开始体现价值。


二、“一切皆插件”到底是什么意思?

DeepSeek Harness 建立在 Cordis 之上。Cordis 内核本身只负责三类事情:

  1. 装载和卸载插件;
  2. 解析插件之间的依赖;
  3. 跟踪副作用,使插件卸载时能够撤销注册和监听。

模型适配器、工具、Session、Agent Loop、存储、沙箱、UI 都不是不可替换的“内核特权代码”,而是挂载在同一个 Context 上的插件。这与常见的“核心框架 + 少量扩展点”不同:DeepSeek Harness 试图让核心执行链本身也可组合。

1. Service:插件向系统提供什么

一个插件可以提供服务,例如:

  • ctx.llm:模型请求与流式输出的统一接缝;
  • ctx.sessions:会话创建、加载、分叉与事件日志;
  • ctx.tools:模型可见工具的注册与受控执行;
  • ctx.agents:Agent 创建、恢复和运行时句柄;
  • ctx.agentLoop:默认的 Turn/Step 驱动器。

消费者依赖的是接口而不是具体实现。因此,本地文件系统可以换成远程工作区,默认模型适配器可以换成兼容端点,Agent Loop 也可以被另一种调度策略替代。

2. Event:插件怎样介入正在发生的事

官方架构把事件分为三层:

事件域用途是否持久化
Session Event用户消息、模型输出、工具调用与结果等事实
Agent Event请求改写、Step 状态、取消、继续等运行中控制通常否
Capability Event文件、工具、遥测等能力的策略与适配视实现而定

例如,企业想在执行工具前检查权限,无须复制 Agent Loop,只要在 tools/pre-execute 处挂一个策略插件;想给模型添加仓库规则,可以注册系统提示片段或向 Agent 注入上下文。

3. Reversible Effects:为什么“卸载插件”很重要

传统插件注册完事件监听、定时器或服务后,很容易留下悬挂状态。Cordis 要求副作用归属当前插件的生命周期:插件卸载时,相关服务、监听器与注册项一起撤销。

这使“运行时换能力”从一句口号变成架构约束,也为 Creator Mode 的动态试验提供了基础。


三、一次任务如何流过 Turn、Step 与 Session Log

DeepSeek Harness 的 Turn、Step、工具循环与 Session Events

官方将一次用户任务称为 Turn,一次模型请求及其工具调用称为 Step。一个 Turn 可以包含多个 Step:

Turn 开始
├─ Step 1:拼装上下文 → 请求模型 → 模型调用工具
├─ Step 2:带上工具结果 → 再请求模型 → 继续调用工具
└─ Step 3:模型确认目标完成 → 输出最终回答
Turn 结束

更精确的执行链是:

读取 Inbox
→ 拼装 System Prompt、历史与 Tool Schema
→ agent/pre-step(允许插件改写或拒绝)
→ 将输入写入 Session Log
→ 从日志派生模型历史
→ llm/stream
→ 写入 assistant/chunk 与 assistant/message
→ tools/pre-execute
→ tools/execute
→ tools/post-execute
→ 写入 tool/result
→ 判断继续下一 Step,或结束 Turn

这里有一个非常关键的设计原则:

凡是模型看见过的事实,都必须能从 Session Log 重建。

因此,会话恢复、轨迹回放、分叉、搜索、遥测不是额外挂在旁边的功能,而是同一条事件流的不同投影。相比只保存最终聊天文本,这种事件溯源方式可以回答更细的问题:模型为何调用这个工具、当时看到了什么结果、审批发生在第几步、恢复以后上下文是否一致。


四、四种模式不是四套产品,而是四种插件组合

模式适合场景主要特点
Standard日常编码与通用 Agent文件、Shell、搜索、Skills、计划、目标、子 Agent 等完整能力
Code多工具编排在 Standard 基础上,将工具暴露给 Code Mode SDK,由模型生成 TypeScript 组合多步操作
Minimal模型评测、最小实验只保留持久 Bash 与 str_replace_editor,减少 Harness 变量
Creator开发新 Harness 组合运行时检查、内存插件试验、Preset 构建指导

理解这张表的正确方式不是“选择哪个 UI”,而是理解 Profile = 一棵有顺序的插件树webheadless Profile 都从基础 Bundle 开始,再叠加各自的 UI 或一次性运行能力,最后应用用户自己的 cordis.patch.yml

可以查看机器实际启动的组合:

dsh --profile web --dump-config

这条命令很适合学习源码:先看到真实运行树,再沿着每个配置行找到对应插件,比从 packages/ 根目录盲读更有效。


五、第一条使用路径:先用 Web UI 建立正确心智模型

1. 启动

安装 Node.js 后运行:

npx @deepseek-ai/dsh web

默认会启动本地 Web UI。进入 Settings → Models,配置 DeepSeek API Key;也可以按官方模型配置指南接入兼容端点。然后选择一个允许 Agent 操作的工作区。

2. 不要一开始就给真实主仓库最高权限

第一次建议使用临时仓库或 disposable checkout,并从类似任务开始:

只读分析这个仓库:列出主要包、入口文件、构建命令和潜在风险。
不要修改文件,不要安装依赖。

观察 Trajectory 时重点看四件事:

  1. 系统提示由哪些来源拼装;
  2. 模型拿到了哪些工具 Schema;
  3. 每个工具结果如何进入下一 Step;
  4. 审批策略在哪些操作上触发。

确认边界以后,再允许它在隔离分支上修改和测试。

3. 从源码运行

要研究或贡献 Harness 本身,可以使用官方仓库流程:

git clone https://github.com/deepseek-ai/deepseek-harness.git
cd deepseek-harness
pnpm install
pnpm run build
pnpm dsh web

开发者预览期最好记录当前 commit,并在升级前对自己的插件、Preset 与 Session 兼容性做回归测试。


六、第二条使用路径:用 Python SDK 把 Harness 作为应用基座

如果 UI 只是你产品的一部分,或者任务来自 API、队列、CI,而不是聊天页面,应使用 SDK 驱动 Harness。

1. 安装

官方 SDK 当前要求 Python 3.10+:

python -m venv .venv
. .venv/bin/activate
python -m pip install deepseek-harness-sdk

发布包包含固定版本的 Harness 运行时,应用侧不需要另装系统 Node.js。准备好凭证:

export DEEPSEEK_API_KEY=sk-your-key-here
# 使用兼容代理时再设置:
# export DEEPSEEK_BASE_URL=http://127.0.0.1:8000/v1

2. 最小可运行应用

以下代码直接采用官方 SDK 的核心调用方式:

from pathlib import Path

from deepseek_harness import DeepSeekHarness

config = Path("./minimal.cordis.yml").resolve()
workspace = Path("./workspace").resolve()
sessions = Path("./sessions").resolve()

with DeepSeekHarness(
provider="deepseek-official",
model="deepseek-v4-flash",
max_tokens=49_152,
cwd=str(workspace),
session_root=str(sessions),
cordis=str(config),
) as harness:
result = harness.run(
"检查仓库中的失败测试,解释原因并给出最小修复。",
session_id="repo-doctor-001",
)

print(result.final_response)

这里真正构成“应用基座”的不是 run() 这一行,而是四个你必须主动设计的边界:

  • cordis:应用究竟装载哪些能力;
  • cwd:Agent 的工作区在哪里;
  • session_root:轨迹与状态怎样持久化;
  • session_id:何时延续上下文,何时创建独立任务。

复用同一个 Harness 实例与 Session ID,会继续原会话及其持久 Shell 状态;新任务应使用新 ID,避免历史和环境变量串入。

官方最小示例的权限边界

官方 jsonrpc-agent 最小组合使用 danger-full-access,文件编辑器可访问运行时进程能看到的路径。它适合 disposable checkout 或容器,不应原样放入处理真实用户输入的服务。


七、实战:把它做成“仓库诊断服务”

假设我们要构建一个内部应用:用户选择仓库与 CI 失败记录,Agent 分析原因,生成修复建议;只有用户批准后才允许修改文件。

1. 应用与 Harness 的责任划分

产品层
├─ 身份、仓库选择、任务队列、审批 UI
├─ 将 CI 日志和业务规则整理成上下文
└─ 展示 Session Events 与最终结果

Harness 层
├─ Agent Loop、上下文拼装、工具调用
├─ Session 持久化、恢复、分叉
└─ 沙箱、工具策略、模型适配器

基础设施层
├─ 临时工作区 / 容器
├─ Git、测试命令、制品缓存
└─ 凭证代理与遥测系统

2. 最小能力集

不要把 Standard 模式所有工具直接暴露给业务任务。第一版只需要:

  • 只读文件搜索;
  • 受限 Bash:只允许测试、类型检查与 Git diff;
  • 精确文件编辑;
  • 一个 request_approval 或等价审批接缝;
  • Session JSONL 存储与任务级日志。

“工具越多越智能”通常是错的。工具越多,Schema 占用越大,错误选择面和安全面也越大。

3. 两阶段运行

建议把任务拆成:

阶段 A:read-only diagnosis
→ 输出根因、证据、拟修改文件、验证命令

人工审批

阶段 B:workspace-write remediation
→ 应用补丁、运行验证、返回 diff 与测试结果

即使模型可以一次完成,也不要省略边界。Harness 的目标不是最大化自治,而是让自治发生在可解释、可撤销的范围内。

4. 状态模型

业务数据库至少保存:

type AgentTask = {
taskId: string;
sessionId: string;
repositoryRevision: string;
workspaceLeaseId: string;
phase: "diagnose" | "waiting_approval" | "apply" | "done" | "failed";
requestedBy: string;
createdAt: string;
};

不要只存 sessionId。如果仓库 revision、工作区租约或权限主体改变,恢复旧 Session 可能让模型基于过期世界继续执行。


八、第三条开发路径:插件、Preset 与 SDK 应该怎样选

目标最合适的扩展层
从后端启动、继续一个 Agent 任务Python SDK
替换模型、文件系统、Shell 或存储实现Service Provider 插件
给模型新增一个业务动作Tool 插件
在工具前做权限、审计、限流Capability Event / Hook 插件
给某类任务固定一组能力和提示Agent Preset / Profile Patch
给 Web UI 增加业务节点或视图Client/UI 插件
改变 Turn/Step 的根本语义最后才考虑替换 Agent Loop

最常见的错误是直接修改 packages/core/agent-loop。官方架构已经提供工具、事件、服务接缝时,修改主循环会放大升级成本,也更难验证状态与重放不变量。

一个业务工具插件在概念上只做三件事:

export const plugin = {
inject: ["tools"],
apply(ctx) {
const dispose = ctx.tools.register({
name: "query_incident",
description: "Read one incident by id",
inputSchema: {
type: "object",
properties: { id: { type: "string" } },
required: ["id"],
},
async execute({ id }) {
return await loadIncident(id);
},
});

return dispose;
},
};

上面是帮助理解边界的简化伪代码,不应当作当前预览 API 的可复制模板。真正开发时必须以仓库内对应包的类型、官方 Extension Cookbook 与当前版本示例为准。


九、如何高效读懂 DeepSeek Harness 源码

这个仓库包很多,按目录从 A 读到 Z 会很快迷失。建议使用下面的顺序:

第 1 天:先跑 Minimal Mode

只观察 Bash、编辑器、模型与 Session Log。目标是回答:“一次工具调用怎样进入下一次模型请求?”

第 2 天:读六个 Spine 包

按调用顺序阅读:

scope
→ session
→ system-prompt
→ tools
→ agent
→ agent-loop

重点不是记住类型名,而是画出每个包“提供什么服务、发出什么事件、依赖谁”。

第 3 天:追一条真实 Turn

agent-loop 的输入领取开始,跟踪到:

agent/pre-step
→ session append
→ deriveMessages
→ llm/stream
→ tool pipeline
→ step/end

用 Session JSONL 对照源码,比只看静态代码更容易理解。

第 4 天:研究一种 Capability Seam

选择文件系统、Shell、LLM 或 Subagent 中的一种,分别找出:

  1. Service Definition;
  2. Service Provider;
  3. Model-facing Consumer。

理解这三个角色,就理解了“一切皆插件”如何落地。

第 5 天:写最小外部插件

先注册只读工具或遥测监听,不要一开始改 UI、持久化和 Agent Loop。验证插件卸载以后,所有注册是否消失。


十、生产化清单

安全

  • 工作区使用容器、临时 VM 或明确的 writable roots;
  • Shell 命令按语义和参数审批,不只按命令名前缀;
  • API Key 不进入 Prompt、Session Event 或工具输出;
  • 来自网页、Issue、日志的文本全部视为不可信输入;
  • 写文件、发请求、提交代码等高影响动作设置显式审批。

可靠性

  • 固定 Harness、SDK、插件与 Cordis 版本;
  • 每个 Turn 配置最大 Step、时间、Token 与工具调用预算;
  • 工具返回结构化错误,让模型区分可重试、权限拒绝和永久失败;
  • 恢复 Session 前验证仓库 revision 与工作区租约;
  • 对取消、超时、进程退出和部分工具成功设计补偿路径。

可观测性与评估

  • 以 Task、Turn、Step、Tool Call 四级关联日志;
  • 保存模型、配置、Prompt 版本与插件组合摘要;
  • 指标至少包含成功率、人工接管率、平均 Step、工具失败率、Token 与耗时;
  • 使用真实但脱敏的任务集做回归,不只评最终文本,还评副作用是否正确。

十一、什么时候不该用 DeepSeek Harness

以下场景直接使用模型 API 往往更合适:

  • 一问一答、摘要、分类等无工具任务;
  • 延迟要求极低且只需要一次推理;
  • 团队暂时无法维护沙箱、审批与轨迹存储;
  • 产品流程完全确定,用普通工作流引擎即可精确表达;
  • 不能接受开发者预览期的 API 变化。

Harness 是运行复杂 Agent 的基础设施,不是所有 LLM 功能的默认起点。


十二、总结:真正值得学习的是“可替换的控制面”

DeepSeek Harness 最值得研究的地方并不是工具数量,而是四个架构判断:

  1. 能力插件化:模型、工具、会话、沙箱乃至循环都从内核解耦;
  2. 事件即扩展点:观察、策略与拦截不必侵入主循环;
  3. 日志即事实源:模型可见内容可以恢复、重放和审计;
  4. 组合优于分支:面向不同产品,用 Profile、Bundle、Preset 和 Patch 组装,而不是长期维护 Fork。

如果要以它为基座构建自己的应用,最稳妥的路线是:

Web UI 跑通并观察轨迹
→ Minimal Mode 理解 Turn/Step
→ Python SDK 嵌入业务流程
→ 以最小工具集建立安全边界
→ 用插件与 Preset 扩展
→ 最后才考虑替换核心 Loop

这样做,你构建的就不只是“能调用 DeepSeek 的聊天应用”,而是一套能在真实环境中工作、被人类控制、也能持续演进的 Agent 系统。


参考资料

Logo
RainLib

Exploring the frontiers of technology, design, and distributed systems. Building tools for the future developers.

Suggestions & Feedback

© 2026 RainLib. Built for the Future.
All rights reserved.
System Normal