我们正在做Agent管理平台,在搞Agent Runtime。
正好DeepSeek发布了自家的开源Agent Harness——DeepSeek Harness(下面简称DSH)。
DeepSeek出品,必出精品。就去翻翻DSH的架构文档和源码,看看DeepSeek团队对Agent Runtime的理解跟我们有什么不同,哪些设计值得偷师。
翻完官方GitHub的architecture.md和整个packages目录结构后,说实话,有几个设计确实让我眼前一亮。
这篇文章不是评测,不聊DSH好不好用。我只关心一个问题:
作为一个Agent Runtime的设计参考,DSH给出了哪些值得借鉴的架构决策?
先搞清楚DSH在做什么定位
从GitHub官方README:
DeepSeek Harness (dsh) is an open-source agent harness developed by DeepSeek AI. It uses an architecture where everything is a plugin, and is powered by Cordis.
关键词三个:
open-source(MIT协议)、
everything is a plugin(一切皆插件)、
Cordis(底层框架)。
它不是"DeepSeek版的Codex"。
Codex是一个产品,DSH是一个Agent运行时——你拿它来组装自己的Agent,而不是直接用。
一句话总结定位:DSH交付的是零件和图纸,不是成品。
对我们做Agent管理平台的启发是:
Runtime层应该是"可组装"的,而不是"可配置"的。
可配置意味着在既定框架内调参数,可组装意味着连框架本身都能替换。
架构核心:没有特权核心
DSH架构文档里最狠的一句话:
There is no privileged core to patch: you extend dsh by mounting a plugin beside the others.
没有特权核心。
模型适配器是插件,工具注册表是插件,会话日志是插件,连Agent Loop本身都是插件。你要改任何一部分,不需要fork核心代码,只需要挂一个新插件上去。
这跟大部分Agent框架的设计完全不同。LangChain的核心链路是写死在代码里的,你最多用Callback来"旁路"监听,改不了主干逻辑。OpenClaw的核心循环(heartbeat → memory → tools → reply)也是固定的骨架。
DSH的选择是把骨架也变成插件。代价是复杂度上去了——理解Cordis的事件系统需要学习成本。收益是灵活性极高——同一个进程里可以跑完全不同架构的Agent。
对我们的参考价值:我们的Agent Runtime在设计时,也要想清楚哪些是"骨架"(不可替换),哪些是"血肉"(可替换)。DSH给出的极端答案是——全是血肉。你不需要走到这个极端,但这个方向值得认真考虑。
Session Log:append-only事件流
DSH对会话数据的处理方式,是我在其他Agent框架里没见过的。
The session log is the source of the context the model sees. Model-visible means logged.
模型能看到的一切,都必须能从日志重建。
Session Log是append-only的事件流。每一条事件(turn/start、step/start、user/message、assistant/chunk、tool/call、tool/result、turn/end)都不可修改地追加到日志里。
上下文压缩不会删除原始数据——它只是插入一个replacement事件,改变模型此后的"视图"。原始历史永远在。
这意味着什么?
你可以完整回放Agent的每一步决策。Debug时可以精确定位到"第3轮第2步,模型收到的prompt是什么,调了什么工具,返回了什么"。这在生产环境里价值巨大——出了问题不需要靠日志推断,直接重放。
还有一层好处:fork和resume变得自然。因为日志是append-only的,fork一个会话就是"从某个事件点开始复制",resume就是"从某个事件点继续追加"。
对我们的参考价值:我们的Agent Runtime目前用的是消息列表+快照来管理状态。DSH的Event Sourcing模式更优雅,尤其对于多Agent协作场景——每个Agent的决策链路都是可审计的。
Seam机制:能力可替换的三角色设计
DSH用"Seam"(接缝)来定义可替换的能力。
一个Seam有三个角色:
Service Definition:声明接口(比如"文件系统读取")
Service Provider:实现接口(比如"本地文件系统"或"远程沙箱文件系统")
Consumer:使用接口(通常是模型可调用的工具)
文档里举了个例子:文件系统和子进程共享同一个执行环境,所以把它们的Provider指向远程沙箱,Bash、PTY、LSP工具就会自动跟着走,不需要为每个工具单独适配。
这就是"换一个Provider,整个产品的行为变了"的效果。
对我们的参考价值:我们的Agent管理平台也在做"能力抽象",但抽象粒度偏粗——基本是"工具"级别。DSH的Seam设计提醒我们:能力、实现、消费者三者分离,才能做到真正的运行时可替换。
插件即配置:Profile + Bundle + Patch
DSH的组合体系是三层:
Profile:一个命名的组合方案,存在Harness的home目录下。指定加载哪些Bundle,以及用户自己的cordis.patch.yml。web和headless是两个自带的Profile模板。
Bundle:Cordis配置行和对应代码的分发格式。每个Bundle在自己的package.json里声明dsh.bundle指向自己的patch文件。
Patch:最细粒度的覆盖层。可以替换某个plugin row的整行配置,也可以插入新行。
加载顺序:Profile指定的Bundle(按顺序)→ Profile的cordis.patch.yml → Home级别的patch → 命令行--patch参数。
这是一个有序分层、逐层覆盖的配置系统。底层Bundle提供默认行为,上层Patch可以精准替换任何一个具体的plugin row。
看实际配置:
dsh --profile web --dump-config
这行命令可以打印出当前机器实际启动时的完整插件树。任何一行都可以被你自己的Patch覆盖。
对我们的参考价值:我们的Agent配置目前是"一套参数一套配置",缺乏分层组合能力。如果要做多租户、多场景的Agent管理,DSH的Profile→Bundle→Patch三层组合模型非常值得参考。
Agent Loop:turn和step两级生命周期
DSH的Agent Loop设计:
一个turn包含零或多个step
一个step是"一次模型请求 + 模型调用的工具执行"
事件流:
turn/start
→ step/start
→ 模型请求 → 工具调用
→ step/end
→ [下一个step]
→ turn/end
每个关键环节都有对应的扩展事件(agent/pre-step、agent/request、llm/stream、tools/pre-execute等),插件可以拦截和修改。
特别值得注意的是agent/pre-step事件——它在模型请求前触发,监听器可以重写模型即将看到的消息,甚至直接拒绝这一步。
这意味着什么?你可以在"模型即将看到上下文"之前插入一个审查层——比如过滤敏感信息、注入额外指令、甚至基于某些条件完全跳过这一步。
对我们的参考价值:我们的平台正在做"Agent执行前的安全审查",DSH的pre-step钩子设计提供了一个干净的实现路径——不需要侵入Agent Loop主流程,挂在事件上就行。
DSH的边界和风险
不是所有设计都值得照搬。几个需要注意的点:
Cordis框架的学习曲线。DSH的底层是Cordis,一个"时空可组合的编程范式"。这不是主流技术栈,社区资源有限。选择它意味着跟DeepSeek的技术路线绑定。如果Cordis本身不火,DSH的生态会受限。
开发者预览阶段。官方README明确写了"CURRENTLY IN DEVELOPER PREVIEW"和"THERE WILL BE COMPATIBILITY-BREAKING CHANGES"。API不稳定,生产使用有风险。
复杂度的代价。"一切皆插件"听起来美好,但对普通用户来说上手门槛高。大多数人需要的可能只是"开箱即用的Agent",而不是"自己组装Agent的工具箱"。
文档还在早期。架构文档写得不错,但cookbook和tutorial还不完整。上手需要读源码。
我们可以怎么用DSH来验证自己的设计
作为一个Agent管理平台的开发者,我建议几个具体的实验方向:
实验一:跑通极简Profile。
npx @deepseek-ai/dsh web
先跑默认web profile,用--dump-config打印插件树,理解它的启动流程和插件加载顺序。
实验二:写一个最小的自定义插件。
不需要复杂功能——写一个在system prompt里注入一句自定义指令的插件。验证"插件能改变Agent行为"这个核心承诺是否成立。
实验三:对比Session Log格式。
跑一个简单的多轮对话,然后去看Session Log的原始事件流。跟我们自己的日志格式对比,评估Event Sourcing模式的优劣。
实验四:测试Seam的运行时替换。
写两个不同的文件系统Provider(一个真实文件系统、一个内存mock),在运行时切换,验证工具是否真的能跟着走。
实验五:跑headless模式做CI集成。
DSH支持headless模式(无UI,一次性执行)。用它跑一个自动化任务,评估它作为CI/CD pipeline中Agent执行引擎的可行性。
一句话总结
DSH给Agent Runtime的设计者上了一课:
不是"给Agent加插件",而是"Agent本身就是插件组合的产物"。
从模型适配器到工具注册表到Agent Loop到前端UI,全是可替换的插件。没有特权核心,只有有序的组合。
这个方向对不对,现在还没有定论。但至少DeepSeek给出了一个完整的、开源的、可运行的参考实现。对于正在做Agent Runtime的团队来说,这份架构文档值得逐页精读。
https://github.com/deepseek-ai/deepseek-harness
💡 一句话带走:
DSH最值得偷的设计不是插件本身,而是"Agent Loop也是插件"这个架构决策——它把Runtime从"框架"变成了"组装台"。
你们团队在做Agent相关的平台吗?Agent Runtime的设计上遇到过什么架构难题?评论区聊聊,说不定我们踩过同一个坑。