DeepSeek Harness 开发者预览版:一切皆插件
DeepSeek Harness(dsh)是 DeepSeek AI 推出的智能体框架,采用「一切皆插件」架构,由 Cordis 驱动。模型、工具、技能、会话、沙箱、存储、循环、调度、UI 等 Agent 所有能力均由插件组合而成,可以自由替换和灵活重组。
目前处于开发者预览阶段,同步开放源代码,MIT 协议。GitHub 已获 41.1K Star,3.2K Fork。
一切皆插件,运行有迹可循
传统框架的核心是固定的,你需要按照它的设计来扩展。DeepSeek Harness 反过来:没有特权核心,所有能力都是插件,包括模型适配器、工具注册表、会话日志、Agent 循环本身。每个部分都可以从配置中替换。
这个设计由 Cordis 框架驱动。Cordis 的设计参见论文《A Programming Paradigm for Spatiotemporal Composability》,核心理念是:插件向共享上下文贡献服务、类型事件和可逆效果。注册是效果,插件卸载时自动撤销。
快速开始
通过 npm 运行
安装 Node.js,一行命令启动 Web UI:
npx @deepseek-ai/dsh web
默认访问地址 http://127.0.0.1:3080。不需要克隆仓库、不需要构建,下载即用。
从源码运行
git clone https://github.com/deepseek-ai/deepseek-harness.git
cd deepseek-harness
pnpm install
pnpm run build
pnpm dsh web
配置模型
打开设置 → 模型,输入 DeepSeek API 密钥并保存。模型路由立即可用,不需要重启服务器。也支持其他 OpenAI 兼容端点。
选择工作区
点击「选择工作区」,添加启动 dsh 时所在的项目目录,然后选中它。选中工作区前,会话输入框不可用。
运行任务
启动一个会话并发送:
Summarize this repository and identify its main packages.
Agent 可以读取和编辑工作区文件、运行命令、委派工作并维护计划。当操作在当前权限策略下需要审批时,Web UI 会先询问你。
架构核心概念
Profile 和 Bundle
一个运行中的 dsh 是从有序层组合而成的插件树。
Profile:存储在 Harness home 中的命名组合,列出它堆叠的 bundle,保存任何非树内插件,并保留用户的
cordis.patch.yml。web和headless作为模板随产品发布。Bundle:Cordis 配置行和它们挂载的代码的分发格式,所以它插入的任何内容都可以被上面的层打补丁。
每个都在自己的 package.json 的 dsh 字段下声明:dsh.profile 列出 profile 的 bundle,dsh.bundle 指向 bundle 的补丁文件。
dsh-base:每个 profile 的第一层,包含模型适配器、工具、持久化、沙箱和审批策略、设置、凭证、遥测。dsh-web-app:添加浏览器应用程序。dsh-headless:添加没有服务器的一次性运行器。
查看你的机器实际启动的配置树:
dsh --profile web --dump-config
任何打印的行都可以被你自己的补丁替换。
核心包
| 包 | 职责 | ctx key |
|---|---|---|
core/session | 只追加的 SessionEvent 日志和内存存储 | ctx.sessions |
core/system-prompt | Prompt 片段和工具 schema 组装 | ctx.systemPrompt |
core/tools | 作用域工具注册表和守卫执行管道 | ctx.tools |
core/agent | Agent 接口、实时注册表和 agent/* 事件 | ctx.agents |
core/agent-loop | 实现该接口的默认驱动 | ctx.agentLoop |
core/scope | 每个 agent 的作用域注册原语 | 库,无 key |
llm/llm | 消息和流词汇表加适配器接缝 | ctx.llm |
事件系统
事件是扩展点。大多数更改的第一个决策是选择正确的域。
- Session 事件:追加到日志并通过
session/event广播的持久事实。当事实必须在重载后存活时使用。 - Agent 事件(
agent/*):携带实时Agent:inbox、step、status、request、validation、continuation。用于观察或拦截飞行中的工作。 - Capability 事件:将策略和适配器附加到接缝(
fs/*、tools/*、telemetry/*),无需导入循环。
Turn Flow
一个 step 是一次模型请求加上它调用的工具。一个 turn 是零个或多个 step:它在第一个输入被认领之前打开,一旦不欠任何东西就关闭。
turn/start
claim next-step input plus one queued message
assemble prompt sections + tool schemas
-> agent/pre-step reject | enter(messages)
reject, or a first enter rewritten empty -> close the turn with no step
step/start
append entered messages as user/message
derive model history from the log
agent/request -> llm/stream -> assistant/chunk* -> assistant/message
tool/call* -> tools/pre-execute -> tools/execute -> tools/post-execute -> tool/result*
step/end
tools owe another request, or next-step input arrived -> claim -> next step
-> agent/turn-stopping
turn/end
turn/*、step/*、user/message、assistant/* 和 tool/* 是持久会话事件;其余是跨三个域的实时扩展点。
Session Log
会话日志是模型看到的上下文的来源。deriveMessages() 从中投影模型历史,原始 assistant/chunk 事件保留重放和 UI 保真度。Fork、resume、transcript、遥测和持久化都从这个流派生。
模型可见意味着已记录。 任何到达模型请求的内容都必须可以从日志重建,运行时不变量断言它。这就是为什么新的模型可见输入需要新的会话事件:扩展 SessionEventMap 并从日志渲染。
Capability Seams
一个 seam 是具有三个角色的可交换能力:声明接口的 Service Definition、实现它的 Service Provider、使用它的 Consumer(通常是面向模型的工具)。一个包可以组合角色,但一个角色本身不是 seam;添加能力意味着设计所有三个。
Seams 是为什么一个 provider 交换会改变整个产品。文件系统和子进程 provider 共享一个执行世界,所以将它们指向远程沙箱会将 Bash、PTY 和 LSP 随之移动,没有 provider 分支。Subagent provider 在一个接口后面变化同样广泛,从新的子 agent 到另一个产品中的委托 turn。
扩展能力:新行为放在哪里
新行为附加到文档化的扩展点。
| 目标 | 机制 |
|---|---|
| 添加模型 provider | 在 ctx.llm 上注册其适配器 |
| 添加面向模型的能力 | 在 ctx.tools 上注册;其 schema 加入 prompt 组装 |
| 给一个会话不同的能力集 | 组合 agent preset;那里的服务行需要一个 isolate realm |
| 添加 shell 执行 | 注册 ctx.shell 后端;本地一个通过 ctx.subprocess 生成 |
| 添加持久终端执行 | 注册 ctx.terminals 后端加上 dsh-tool-terminal |
| 添加人工命令 | 在 ctx.commands 上注册;它无需模型 turn 就分发 |
| 添加后台工作 | 在 ctx.jobs 上注册;job_* 工具收集或停止它 |
| 添加文件系统访问或策略 | 注册 ctx.fs provider 或监听 fs/* 事件 |
| 限制生成的进程 | 使用 ctx.sandbox 后端;消费者在生成前包装 argv |
| 拦截请求、工具或 turn | 使用其 agent/* 或 tools/* 事件;agent/turn-stopping 停止 turn |
| 添加面向模型的上下文 | 调用 agent.inject();它落在下一个准入的请求中 |
| 添加 UI 或编辑器集成 | 驱动 ctx.agents 并从 session/event 渲染 |
| 添加 Web Client Chat 节点 | 注册 ConversationNodeDefinition + keyed renderer |
| 添加持久会话状态 | 扩展 SessionEventMap;从日志渲染和重放 |
| 生成会话标题 | 注册唯一的 ctx.sessionTitle provider |
| 管理同会话目标 | 使用 ctx.goals;通过 agent/* 继续 |
| Fork 实时会话 | ctx.sessions.fork(source, boundary?, childSessionId?) |
| 将注册限制到一个 agent | 使用该 agent 的 agent.ctx |
社区与支持
- GitHub Discussions:提交反馈或 bug 报告
- dsh-plugin 话题:为你的插件仓库添加此话题,便于被发现
- Discord 社区:discord.gg/Ycq5dCaS4
- 企微群:扫码添加企微小助手并填写入群问卷
开发资源
- 开发指南:
docs/development.md - 架构文档:
docs/architecture.md - Agent 指南:
AGENTS.md - 贡献指南:
CONTRIBUTING.md
许可证
MIT License,第三方依赖及其许可证见 THIRD_PARTY_NOTICES.md。
相关链接
DeepSeek Harness 用「一切皆插件」重写了 Agent 框架的设计思路:没有特权核心,所有能力可替换。Cordis 驱动的插件系统让扩展变得干净——注册是效果,卸载自动撤销。一行命令启动 Web UI,配置 API 密钥即可开始。目前处于开发者预览阶段,迭代快速,适合想要深度定制 Agent 能力的开发者尝鲜。