DeepSeek Harness 的内核,是 Koishi 那个 Cordis
DeepSeek Harness 发布时,我并没有觉得它有什么特别。编程助手已经很多,“一切皆插件”也不是新概念。真正让我重新审视它的,是内核 Cordis。
Cordis 最初服务于 Koishi,一个 QQ 聊天机器人框架。它经过四年演进,被 DeepSeek 搬进 Harness,并与一篇关于“时空可组合性”的论文同时发布。
我认为,这件事的意义不在于 DeepSeek 又做了一个编程工具,而在于它试图回答一个更底层的问题:一个长期运行的程序,能不能在不停机的情况下安全地重组自己?
把副作用变成可撤销的操作
传统插件系统最大的隐患,不是插件装不上,而是卸不干净。
一个插件可能注册事件监听、启动定时器、修改全局对象、打开文件监听。开发者通常需要手写清理逻辑。只要漏掉一项,程序当时未必报错,却可能在几小时甚至更久以后出现异常。
这类问题的根源,是系统把清理责任交给了人的记忆和自觉。
Cordis 的做法不同。每次修改上下文时,操作都要携带对应的逆操作,由运行时统一记录。卸载组件时,运行时按照记录反向撤销,而不是寄希望于开发者写对一个完整的 cleanup 函数。
清理因此不再是一条开发规范,而成为运行时机制。
时间可逆,空间响应
Cordis 把组件组合拆成两个维度。
时间维度是副作用可逆。组件被加载、卸载或替换,运行时负责追踪状态变化,并将其恢复。
空间维度是依赖响应。组件只声明自己依赖哪些能力。当能力出现、消失或被替换时,只有真正受影响的部分重新计算和启动,其余部分继续运行。
这两个维度都被放进上下文系统中。论文还提出了一个可机械判断的独立性条件:如果两个副作用都通过依赖声明访问共享键,而且这些共享操作可以交换,那么两个组件就不会相互干扰。
过去需要靠经验和代码审查判断的插件冲突,开始有机会变成运行时能够检查的问题。
像 Nix,但管理的是活状态
我很自然地想到 Nix。
Nix 能够原子回滚,是因为构建产物已经按内容组织好,切换版本只需要改变指向。但它管理的是构建后的文件树,无法处理进程运行以后不断变化的内存状态。
Cordis 想做的是活状态的可逆管理:用上下文树隔离资源,用逆操作撤销变化。
其中最重要的性质是合流性。一个系统无论经历多少次加载、卸载和替换,最终状态都应该等价于按照最终配置从零启动。
换句话说,一个运行三个月、热更新过很多次的系统,理论上可以与刚刚冷启动的系统保持等价。中间走过什么路径,不应留下无法解释的脏状态。
对于长期运行的 Agent,这不是理论洁癖。它直接决定我们能不能回答:这个 Agent 现在到底处于什么状态?
可逆性真正难在边界
理论很漂亮,工程实现却远没有那么轻松。
Harness 没有直接把 Cordis 当作 npm 依赖,而是把框架源码搬进自己的仓库,锁定在 4.0.0-rc.7,并记录了 18 项本地修改。这样做是为了能够审计、修补和锁定版本,也说明上游接口还没有稳定。
其中一些修改专门处理重入卸载:组件初始化时触发卸载怎么办,初始化失败后如何回滚,组件正在卸载时又产生新的副作用怎么办。
另一些修改处理并发应用和回滚相互交错造成的卡死与死锁。
这恰恰揭示了可逆性的真实难度。给每个操作配一个逆操作并不困难,困难的是卸载本身也可能产生副作用,异步清理可能尚未结束,并发操作还可能修改同一批状态。
我反而因为这些修改记录更信任这个项目。论文描述理想状态,修改日志暴露实现代价。一个团队愿意公开偏离上游的原因和测试覆盖,至少说明他们知道自己面对的不是普通插件框架。
仓库中还有四百多条中英双语架构笔记,区分“已实现”和“提议中”。这种白盒不仅面向产品运行,也面向产品自身的开发过程。
Harness 更像运行时底座
我判断 Harness 的价值,不应主要用短时编程任务的完成率衡量。
它更值得关注的方向,是成为一个长期运行、能够不停机修改能力构成的 Agent 运行时。
在这个运行时里,插件就是被管理的资源。增加一个工具,能力立即出现;某个组件出问题,可以单独卸载;模型适配器、工具注册表、会话日志乃至主循环,都可以成为插件。
上下文树则提供了能力继承和隔离的结构。父节点的能力可以被子节点继承,也可以在某一层切断;共享记忆服务可以挂在共同上层,敏感工具则可以只对特定分支开放。
多 Agent 系统最难处理的问题之一,就是哪些能力应该共享,哪些状态必须隔离。树状上下文把它转化成了资源在什么位置可见的问题。
Agent 不再是底座
今天多数 Agent 框架都把 Agent 当作主体,再为它配置工具、记忆和权限。Agent 是底座,能力是附件。
如果 Harness 把所有能力都插件化,关系就可能倒过来。
Agent 不再是固定主体,而是运行时在某个时刻形成的一组配置。需要编程助手,就组合出编程能力;需要运维助手,就换成告警、诊断和处置插件;长期记忆、日程管理和资料整理,也可以在同一棵上下文树中按需共享或隔离。
这样看,Cordis 支撑的甚至不只是一种 Agent。它更像一个能够安全动态重组自身的通用程序框架,只是 Agent 恰好最需要这种能力。
现在还不能把它当标准答案
Harness 目前仍是开发者预览版,存在破坏兼容性的可能;Cordis 还是 rc 版本,接口没有稳定。现在就把它设为团队标准,风险很高。
它的文档也没有把核心概念讲清楚。不了解 Koishi 和 Cordis 的人,很容易把相关介绍看成抽象词汇的堆叠。
更现实的问题是安全。安装插件意味着让外部代码进入运行时,而当前没有签名机制和权限清单。插件生态越快扩张,这个缺口越危险。动态组合能力越强,权限边界就越不能依赖开发者自觉。
项目目前也不接受外部 PR,只允许讨论或自行编写插件。对于希望参与底层建设的人,这是一道明确的墙。
Pi 和 Harness 解决的不是同一件事
不能因为 Harness 的方向更底层,就否定 Pi 的工程价值。
Pi 用极少的核心原语完成编程任务。原文提到,Databricks 在数百万行代码库上的内部评测中,Pi 的通过率最高,成本也更低,因为每轮发送的上下文大约少三倍。
Pi 解决的是怎样把编程助手做得更锋利,今天就能产生回报。Harness 想解决的是运行时本身应该如何组织,赌的是更长的未来。
二者并不在同一条赛道上。
四年持续做一件底层小事
Cordis 建于 2022 年,最初只是一个聊天机器人项目下面的插件系统。四年以后,它进入 DeepSeek 的新产品,并获得了一套形式化理论解释。
这件事给我的触动,不只是一个开源项目被大公司采用。
真正稀缺的是,有人在一个当时看起来并不重要的地方,连续几年打磨同一个底层问题。技术突破未必总从宏大的目标开始,很多时候,它来自对一个小问题长期而准确的坚持。