Skip to content

DeepSeek Harness 系列(一):从 Agent 工程化现状看核心设计

现在很多 Agent 项目看起来都很热闹:模型能调用工具,能读文件,能跑命令,能生成计划,也能接一个 Web UI。真正落到工程里,难点往往不在“能不能调一次模型”,而在这些能力能不能被组合、替换、审计、恢复,并且在出问题时有明确边界。

DeepSeek Harness 值得看的地方正在这里。它不是只提供一个聊天页面,也不是把一堆工具硬塞进固定循环里。按照当前公开源码快照中的 README 与架构文档,它处于开发者预览阶段,并明确提示未来可能有破坏性变更;这意味着它还不是一个可以无脑押注的稳定平台,但它展示了一套很值得学习的 Agent Harness 设计。

一句话说:DeepSeek Harness 把 Agent 产品拆成 Cordis 插件树。模型适配器、工具注册表、会话日志、Agent Loop、权限策略、Web 表层、headless runner,都不是特权内核的一部分,而是挂在同一个运行时上下文里的插件能力。

先区分三个概念

读 DeepSeek Harness 之前,最好先把三个词放稳。

概念在本文中的含义
DeepSeek 模型大语言模型提供方,负责生成文本、推理和工具调用意图。
DeepSeek Harness让 Agent 使用模型、工具、会话、权限、UI 和扩展插件的工程框架。
CordisDeepSeek Harness 底层使用的 TypeScript 插件运行时。

这三者的关系可以画成这样。

DeepSeek Harness 的名字容易让人误会,好像它只服务 DeepSeek 模型。源码里实际不是这样。dsh-llm 定义的是提供方无关的 LLM 运行时,适配器通过 ctx.llm.registerAdapter() 注册路由。DeepSeek 官方适配器只是其中一个实现;自定义 OpenAI 兼容端点、其他提供方目录、企业网关,都可以从同一个模型适配器边界接入。

它想解决的不是 Demo 问题

一个简单 Agent Demo 可以这样写:

text
用户输入 -> 拼提示词 -> 调模型 -> 执行工具 -> 把结果再发给模型

这条链路能跑,但它对真实工程太薄了。

真实工程会继续问这些问题:

  • 模型看到的上下文能不能从日志重建?
  • 工具执行前能不能走权限、审批、沙箱和审计?
  • Web UI 和自动化协议是不是复用同一套 Agent 状态?
  • 一个工具、模型适配器或策略插件能不能替换,而不是改循环?
  • 任务中断后,哪些结果已经发生,哪些只是模型意图?
  • 企业业务接入时,怎么避免 Agent 直接绕过业务边界?

DeepSeek Harness 的核心设计,就是把这些问题前置到架构里。

核心设计理念:运行时可组合

Harness 建在 Cordis 上。Cordis 的基本单位是插件,插件向共享 Context 贡献服务、监听事件、注册工具、安装副作用,并在卸载时清理这些副作用。

这个选择带来一个重要结果:Harness 的功能不是从一个巨大的主类里扩出来的,而是由插件组合出来的。

源码架构文档里给出的组合顺序是:先应用 profile 声明的 bundle,再应用 profile 自己的 cordis.patch.yml,然后是 home 级 patch,最后是 CLI --patch。patch 不是深度合并,而是按稳定 id 替换整条配置,或插入新配置项。

这套机制很克制。它要求扩展者明确地说:“我要替换哪一行配置,或者插入哪一个插件。” 代价是配置时需要重述完整字段;收益是最终运行树可以被 dsh --profile web --dump-config 打印出来,运行时真相不藏在隐式合并里。

一切皆插件,但不是一切都随便

“一切皆插件”听起来容易滑向松散。DeepSeek Harness 没有只靠插件自由发挥,它给关键能力设置了稳定的服务边界。

能力运行时服务解决的问题
会话日志ctx.sessions记录持久事实,派生模型历史,支持回放和 fork。
系统提示词ctx.systemPrompt组装提示词段、工具 schema 和上下文。
工具执行ctx.tools注册工具,执行权限、沙箱、结果处理和展示投影。
Agent 注册ctx.agents创建、恢复、驱动和管理活跃 Agent。
Agent 循环ctx.agentLoop实现默认“模型请求 + 工具执行 + 下一步”的循环。
模型调用ctx.llm注册模型适配器,统一流式输出协议。

这些服务边界让插件之间通过 ctx.<key> 协作,而不是互相导入实现类。比如一个权限插件不需要知道 Bash 工具、文件系统工具、MCP 工具各自怎么写,它只需要拦截 tools/pre-execute;一个 UI 插件不需要知道 Agent Loop 内部状态机,它监听 session/event 渲染即可。

Agent 的运行事实来自事件日志

Harness 最重要的工程纪律之一是:模型可见的内容必须能从会话日志重建。

这不是一句漂亮话。源码中的 dsh-sessionSession 定义为仅追加事件日志,模型历史由 deriveMessages() 从日志的 surface 投影派生。用户消息、助手消息、工具结果会进入模型历史;助手 token 分片、轮次边界、用量和审计事件留在日志里,用于回放、UI、遥测和恢复。

这个设计的价值很实际:当 Agent 出错、重试、被取消、被 fork、被 Web UI 回放时,系统不需要猜模型之前到底看过什么。只要日志是权威的,模型历史、页面展示和审计线索都可以从同一份事实投影出来。

工具是能力,不是任意函数

很多 Agent 框架把工具理解成“给模型一个函数列表”。Harness 的工具模型更接近一条受管执行流水线。

这条流水线把几个责任拆开:

  • 工具定义负责参数 schema、规范 JSON 输出、模型可见渲染和 UI 展示投影。
  • 策略插件负责允许、拒绝、审批、超时、重试、指标和结果改写。
  • Agent Loop 负责按模型顺序记录结果,并决定是否进入下一步。
  • Session 负责把最终模型可见结果变成持久事实。

这意味着企业接入业务能力时,不应该把“查数据库、补偿任务、发通知”写成模型能随意拼 SQL 的大口子。更合理的方式是写成受约束的工具:参数明确、输出结构化、写操作走审批、结果可审计。

Web 与 Headless 是同一棵树的不同表层

DeepSeek Harness 同时提供 webheadless profile。两者不是两套独立产品,而是在 dsh-base 之上叠不同 bundle。

这个分层很关键。基础能力不被 Web UI 绑死,Web 只是一个表层;Headless 也不需要复制一套工具、模型和会话逻辑。以后如果要接企业内部协议、自动化平台或自己的控制台,正确方向是做新的表层插件,而不是 fork 掉 Agent Loop。

它的能力边界

按源码文档,DeepSeek Harness 当前已经把很多 Agent 工程能力放进了可组合边界里:

能力架构位置
多模型提供方ctx.llm 适配器注册与模型目录。
工具调用ctx.tools.register() 与统一执行流水线。
Code Mode工具通过生成 SDK 暴露给 run_code,中间值不进入对话。
权限与审批tools/pre-execute、守卫、approval 服务和沙箱。
会话持久化监听 session/event,在 session/flush 做持久屏障。
Web UI监听会话事件流渲染,通过 Agent API 发送输入。
subagent通过 ctx.subagents provider 与工具暴露委派能力。
定时任务插件注册调度工具,定时触发时 followup()inject()
插件热重载Cordis effect 和 Loader/HMR 共同支撑重载与清理。

这些能力有一个共同点:它们都尽量挂在事件和服务边界上,而不是侵入默认循环。默认循环只做它必须做的事:领取输入、组装请求、调用模型、执行工具、记录事件、判断是否继续。

需要冷静看的部分

当前版本仍处在开发者预览阶段,博客里不应该把它写成成熟平台。几个风险需要提前看见:

  • API、配置和事件词汇可能变化。
  • patch 替换整条配置,覆盖时要重述需要保留的字段。
  • 插件系统要求作者遵守 effect、inject、schema、输出值等纪律;绕过纪律会破坏可组合性。
  • 企业业务接入时,权限、审计、数据脱敏和幂等仍要由业务插件设计,Harness 不会替你自动理解业务风险。
  • Headless、Web、SDK、业务协议都应复用同一套会话和工具边界;复制逻辑很容易制造事实漂移。

所以我更愿意把 DeepSeek Harness 看成一个值得学习和试点的 Agent 工程框架,而不是一个马上替换所有内部平台的答案。

小结

DeepSeek Harness 的吸引力不在“它又做了一个 Agent UI”,而在它把 Agent 工程化问题拆成了可组合的运行时能力:模型适配、工具执行、会话日志、权限策略、UI 表层、业务扩展,都能在 Cordis 插件树里找到自己的位置。

如果你只想跑一个 Demo,它可能显得重。但如果你关心 Agent 如何进入真实工程:如何审计、如何扩展、如何恢复、如何接业务、如何不把模型权限放飞,那么它的设计就很值得往下读。

下一篇会进入核心架构:Profile/Bundle 怎么组装,Agent 轮次怎么跑,工具流水线和会话日志为什么是整个系统的骨架。

继续阅读:DeepSeek Harness 系列(二):核心架构与运行时骨架