1. 项目全景概览
1.1 一句话解释
DeepSeek Harness 是一个“一切皆插件”的 AI Agent 运行平台,它把模型调用、工具执行、会话记录、Agent 主循环、权限和 UI 都组织成可替换、可热更新的 Cordis 插件。
依据:
- 根
README.md:It uses an architecture where everything is a plugin。 docs/architecture.md:Every part of the product is a plugin, including the model adapter, the tool registry, the session log, and the agent loop itself。
1.2 它解决什么问题
传统上,要做“能调用工具的大模型 Agent”,开发者通常会手写一个循环:
读用户输入 -> 拼 Prompt -> 调模型 -> 看模型是否要求调用工具 -> 执行工具 -> 把结果塞回上下文 -> 再调模型如果只有一两个工具,这种方式可行。但能力多了以后,问题会迅速出现:
- 工具、模型、文件系统、子进程、权限、持久化、UI 都耦合在同一个循环里。
- 每增加一种能力,都要改主循环或复制分支。
- 无法只替换模型厂商、沙箱或文件系统,而不影响其他能力。
- 流式输出、取消、断线重连、会话恢复、回放和审计没有统一的真相来源。
- 前后端和自动化协议各自实现一套,容易类型漂移。
DeepSeek Harness 用四个核心设计回应这些问题:
- Cordis 插件化上下文:能力作为服务注册到
ctx,依赖关系通过inject声明,注册都是可撤销 effect。 - capability seam 三件套:
Service Definition/Service Provider/Consumer把“接口、实现、调用方”分离。 - event-sourced Session log:只追加的
SessionEvent是唯一真相,模型上下文从日志派生。 - profile + bundle + patch:同一个内核通过配置层组合成
web、headless、ACP 等不同运行形态。
1.3 没有它时,开发者通常怎样解决
常见做法是使用某个模型的 SDK 自己写 Agent loop:
- 用
fetch或 OpenAI 兼容 SDK 调模型。 - 用
JSON.parse判断工具调用。 - 用一个大的
switch或工具注册表执行工具。 - 用内存数组保存消息。
- 需要恢复时自己设计 JSON 文件或数据库。
- 需要 Web UI 时再写一套 REST/WebSocket 协议。
这种方案在 demo 中很快,但缺少统一的事件系统、可撤销注册、热更新、会话恢复、工具策略和跨进程类型安全。
1.4 目标用户
- 想构建或扩展 AI Agent 产品的工程师。
- 想给 Agent 增加自定义工具、模型适配器、权限策略或 UI 的插件作者。
- 想理解“Agent Harness 应该有哪些组成”的架构学习者。
1.5 典型使用场景
- 通过
dsh --profile web启动一个本地 Web 编码 Agent。 - 通过
dsh --profile headless "task"跑一次性任务。 - 通过 ACP 自动化服务器把 Agent 暴露给外部自动化客户端。
- 在自己的
cordis.yml中组合工具、模型、沙箱和 UI 插件,形成定制 Agent。 - 增加
dsh-tool-*插件,让模型读写文件、执行命令、搜索网络、启动子 Agent。
1.6 核心价值
- 可替换性:换模型、换沙箱、换持久化后端、换 Agent 驱动器,不改主循环。
- 可回放性:模型可见内容都能从 Session log 重建。
- 可组合性:同一个内核通过 profile 组合成多种产品形态。
- 可观测与可测试:关键路径有 typed events、invariant、unit/snapshot/e2e 测试。
- 前端同样插件化:浏览器端也运行一棵 Cordis 插件树,UI 通过 slot 动态组合。
1.7 它不适合解决什么
- 它当前是 developer preview,兼容性明确不稳定,不适合当作稳定生产底座直接锁定。
- 它不是某个具体 Agent 产品的即开即用替代品,理解成本比简单 SDK 调用高。
- 它不负责训练、模型推理服务、向量数据库或复杂的多人权限体系。
- 如果你只需要一个一次性脚本调用模型,它带来的框架成本可能过高。
1.8 与主要同类方案的差异
基于当前仓库文档可以确认其定位是“插件化 Agent Harness”,而不是单纯的 SDK:
- 相对于直接使用模型 SDK:Harness 提供了 loop、工具管线、会话日志、持久化、UI 和协议边界。
- 相对于普通后端 MVC 服务:Harness 以 typed events 和插件 effect 作为主要扩展方式,而不是在 Controller/Service 里加分支。
- 相对于前端微服务/微前端:它用同一套 Cordis 插件模型同时组织 Host 和 Browser 两棵树。
对于其他具体产品的功能对比,本教程不凭印象罗列差异;如果后续需要,应查阅对应官方文档、仓库和发布说明。
1.9 成熟度与边界
仓库和文档明确声明 developer preview,会出现破坏性变更;SESSION_FORMAT_VERSION 当前为 0,不承诺兼容,见 packages/core/session/src/types.ts:34-56。核心 API 包标为 product,部分包如 E2B 标为 POC,见 packages/README.md。
1.10 30 秒解释版本
DeepSeek Harness 是一个用 Cordis 写的 Agent 运行框架。模型、工具、会话日志和 Agent 循环都是插件,插件通过 ctx 注册服务、监听 typed events,并且注册都可以撤销。Agent 每次请求的上下文都从只追加的 Session log 推导出来,因此可以回放、恢复、分叉和持久化。
1.11 5 分钟解释版本
运行一个 dsh,实际上是在加载一棵由 bundle patch 和 cordis.patch.yml 组成的插件树。基础 bundle 装上模型适配器、工具、会话、沙箱、权限和遥测;web 或 headless bundle 再补上不同表层。
当用户提交一条消息:
- 消息进入
Agent的 inbox。 ReactLoopAgent打开一个turn。preStep()认领消息,组装 system prompt 和 tool schema。step()从Session.deriveMessages()得到模型历史。LlmRuntime按 provider/model 找到 adapter,流式返回 chunk。- 如果模型要求工具,
ToolRuntime经过 pre/guard/around/post/result 管线执行。 - 所有模型可见内容都作为
SessionEvent写回日志,下一轮再从中推导。
想扩展系统,通常不修改 loop,而是在 ctx.tools、ctx.llm、ctx.systemPrompt、ctx.agents 或 typed events 上注册插件。