从一个问题开始
你用 Python 写了一个 Agent,接了几个工具,在本地跑得不错。然后你想把它上线------
- 对话历史怎么存?进程重启后怎么恢复?
- 用户 A 的 Agent 不能用用户 B 的工具,怎么隔离?
- Agent 要执行 shell 命令,怎么防止它删掉不该删的文件?
- 哪个工具被调了几次,每次花了多少 token,怎么统计?
- 想换一个模型提供商,需要改多少地方?
如果你在用 LangChain、LangGraph、AutoGen,你会发现这些问题要么没有官方答案,要么需要自己拼很多东西。
**DeepSeek Harness(dsh)**就是为了解决这些问题而生的。它不是一个"帮你调 LLM 的库",而是一个生产级的 Agent 运行时------把 Agent 跑起来需要的那些基础设施,它全部内置了。
dsh 是什么
官方的一句话定义:
DeepSeek Harness (
dsh) is an open-source agent harness developed by DeepSeek AI, built on an everything-is-a-plugin architecture.
拆开来看:
Agent Harness:harness 这个词来自工程领域,意思是"线束/安全带"------把各种松散的部件约束在一起,让它们安全、有序地协同工作。Agent Harness 就是让 Agent 的各个部件(模型调用、工具执行、记忆管理、权限控制......)有序运转的运行时框架。
Everything-is-a-plugin:这是 dsh 的核心设计哲学。模型适配器是插件,工具注册是插件,Agent 循环本身也是插件,甚至日志记录和权限控制也是插件。没有不可替换的"核心"------你可以换掉任何一个部分,系统照常运行。
Open-source:MIT 许可证,代码在 GitHub 上完全公开。
它能做什么
功能一览
| 功能 | 说明 |
|---|---|
| 工具调用 | 注册工具、schema 自动生成、权限审批、执行沙箱 |
| 多 Agent 协作 | Subagent 调用、Agent Teams(实验性) |
| Session 持久化 | 对话历史 append-only 存储,进程重启后可完整恢复 |
| 沙箱隔离 | 文件写入、shell 执行都可以限制在安全边界内 |
| 可观测性 | Token 计量、Session 遥测、OTel 集成 |
| 动态 Prompt | 各插件注册自己的 prompt 片段,统一组装 |
| 热重载 | 修改插件配置,不重启进程即可生效 |
| 多种运行模式 | Web UI、headless(命令行)、SDK、ACP 服务 |
一键启动
sh
# 不需要 clone 代码,直接运行
npx @deepseek-ai/dsh web
这一行命令会启动一个完整的 Agent 服务,带 Web UI,默认地址 http://127.0.0.1:3080。背后已经内置了:模型连接、完整工具集(文件操作、shell 命令、网络搜索)、Session 持久化、权限策略。
整体架构
dsh 的架构可以从三个层次来理解:
vbnet
┌────────────────────────────────────────────────────────┐
│ 应用层 │
│ Web UI │ headless │ SDK │ ACP API │
├────────────────────────────────────────────────────────┤
│ 核心子系统层 │
│ Agent Loop │ Tools │ Session │ System Prompt │
│ LLM Adapter │ Sandbox │ Subagent │ Observability │
├────────────────────────────────────────────────────────┤
│ Cordis 插件框架 │
│ Plugin │ Context │ Service │ Event │ Effect │
└────────────────────────────────────────────────────────┘
底层:Cordis 插件框架
这是整个 dsh 的地基。所有上层功能都是以 Cordis 插件的形式挂载的。Cordis 提供:插件的注册/注销、服务的依赖注入、类型化事件系统、可逆的注册效果。
如果你理解了 Cordis,你就理解了 dsh 的一切。这也是系列第二篇要重点讲的内容。
中层:核心子系统
这些是 dsh 真正做事情的地方:
- Agent Loop (
ctx.agentLoop):Agent 的主循环,负责接收用户输入、调度工具调用、管理对话流程 - Tools (
ctx.tools):工具注册表,管理工具的注册、schema 生成、执行 pipeline - Session (
ctx.sessions):对话持久化,append-only 日志存储 - System Prompt (
ctx.systemPrompt):动态 prompt 组装,各插件贡献自己的片段 - LLM (
ctx.llm):模型适配器注册表,支持多种模型提供商 - Sandbox (
ctx.sandbox):沙箱隔离,保护宿主系统安全
上层:应用
同一套核心,可以组合成不同的运行形态:
dsh web:带 Web UI 的交互式 Agentdsh --profile headless:命令行一次性任务dsh --profile sdk:SDK 模式,供其他程序调用dsh --profile acp:自动化控制协议服务
Profile 和 Bundle:配置即产品
dsh 的运行形态不是通过代码切换的,而是通过配置组合决定的。
Bundle :一组插件配置,描述"要挂载哪些插件"。比如 dsh-base 这个 bundle 包含了模型适配器、工具集、持久化、沙箱等基础插件。
Profile :按顺序叠加的 bundle 列表,加上用户自己的覆盖配置。web profile 在 dsh-base 上叠加了 Web UI 相关的插件;headless profile 叠加的是命令行运行器。
yaml
# 这是一个最小化的自定义 profile
{
"name": "my-profile",
"dsh": {
"profile": {
"bundles": ["@deepseek-ai/dsh-base"]
}
}
}
想看当前 profile 包含了哪些插件?
sh
dsh --profile web --dump-config
这会把完整的插件树打印出来------每一行都是一个可以被你的配置覆盖的插件。
和其他框架的本质区别
市面上的 Agent 框架很多,dsh 的定位是什么?下面是一个直接的对比:
dsh vs LangGraph
| LangGraph | DeepSeek Harness | |
|---|---|---|
| 核心抽象 | 有状态图(State Graph) | 插件树(Plugin Tree) |
| 执行控制 | 图节点 + 条件边 | Agent Loop 事件 |
| 扩展方式 | 自定义节点、Runnable | 注册插件到 ctx |
| 持久化 | 需要自己接 Checkpointer | 内置 Session append-only 日志 |
| 生产就绪 | 需要大量自定义工作 | 开箱即带沙箱/权限/遥测 |
| 适合场景 | 复杂工作流编排,需要精确控制图结构 | 生产级 Agent 直接部署 |
LangGraph 是"先设计图,再跑";dsh 是"直接跑,需要什么挂什么插件"。
dsh vs AutoGen
| AutoGen | DeepSeek Harness | |
|---|---|---|
| 核心抽象 | 对话式 Agent | 插件化 Agent 运行时 |
| 多 Agent | 多 Agent 对话是核心 | Subagent 作为扩展能力 |
| 工具支持 | 有,但需要较多配置 | 内置完整工具集 + 执行沙箱 |
| 持久化 | 基本没有 | 内置 Session 日志 |
| 适合场景 | 多 Agent 协作研究 | 工程化单 Agent/多 Agent 部署 |
dsh vs Dify / n8n
| Dify/n8n | DeepSeek Harness | |
|---|---|---|
| 类型 | 流程驱动 Agent(低代码) | AI Native Agent(代码驱动) |
| 使用方式 | 可视化拖拽 | 写代码/配置文件 |
| 灵活性 | 流程预设,动态性有限 | 完全可编程 |
| 适合人群 | 非开发者、快速原型 | 工程师、需要精确控制 |
一句话总结
- LangGraph:我要精确控制 Agent 的执行流程,用图来描述
- AutoGen:我要让多个 Agent 相互对话协作
- Dify/n8n:我不想写代码,拖拽搭建工作流
- dsh:我要把一个 Agent 部署到生产环境,需要持久化、沙箱、权限、监控这些全套基础设施
什么时候用 dsh
适合 dsh 的场景:
- 需要把 Agent 真正部署到生产环境(不是 demo)
- Agent 需要执行真实的 shell 命令、文件操作,需要沙箱保护
- 需要 Session 持久化(用户离开后可以继续上次对话)
- 需要细粒度的权限控制(哪些工具需要用户确认)
- 需要接入监控系统,统计 token 消耗、延迟、错误率
- 想要一个可以按需扩展的插件架构,而不是 fork 框架代码
不适合 dsh 的场景:
- 你只是想快速实验一个 Agent 想法(LangGraph + LangChain 更轻)
- 你需要复杂的图状工作流(LangGraph 更擅长)
- 你的团队没有 TypeScript 经验(dsh 主体是 TypeScript)
- 你需要一个国内有完整商业支持的方案(dsh 还在快速迭代中)
五分钟跑起来第一个 Agent
需要先装好 Node.js(18+)。
sh
# 启动 Web UI 版本
npx @deepseek-ai/dsh web
浏览器会打开 http://127.0.0.1:3080,在设置里填入你的 API Key(支持 DeepSeek、OpenAI 等),就能和 Agent 对话了。
Agent 默认具备:
- 文件读写(限制在当前工作目录)
- Shell 命令执行(有沙箱保护)
- 网络搜索和 HTTP 请求
- 任务追踪
想用命令行模式?
sh
# 一次性任务,不启动 Web UI
npx @deepseek-ai/dsh --profile headless "帮我列出当前目录下所有的 Python 文件"
系列规划
这是系列的第一篇,后续每篇会深入一个模块:
| 篇 | 主题 | 你会学到 |
|---|---|---|
| 01(本篇) | dsh 是什么 | 全局认知,定位,和其他框架的区别 |
| 02 | Cordis 插件系统 | 理解 dsh 一切的基础 |
| 03 | 工具系统 | 怎么给 Agent 加工具,怎么控制权限 |
| 04 | Agent Loop | 一次对话是怎么跑起来的 |
| 05 | Session 与记忆 | 对话历史怎么存、怎么跨会话恢复 |
| 06 | System Prompt 组装 | 动态 prompt 的工程实现 |
| 07 | 能力 Seam | 一行配置换掉整个执行环境 |
| 08 | 多 Agent 协作 | Subagent 和 Agent Teams |
| 09 | 可观测性 | 怎么知道 Agent 在干什么 |
| 10 | 写一个完整插件 | 从需求到上线的完整流程 |
如果你已经对插件系统有些了解,可以直接跳到感兴趣的模块。如果你是第一次接触 dsh,建议先读第二篇 Cordis 入门------它是读懂后续所有内容的钥匙。
在 PrimeSkills 可以找到已在真实企业场景验证过的 AI Agent 技能和工作流,不是演示级的,是用在实际项目里的。
更多内容见我的个人主页