DeepSeek Harness:好的框架,坏的产品
About
DeepSeek Harness 发布后,我先翻了仓库里的 BENCHMARK.md。
文件只有三行:标题、安装 Python SDK 的方法,以及一句提醒,跑 benchmark 时要使用不同的 workspace 和 session ID。没有结果,没有 baseline,也没有测试环境。
再看另一边。当前快照里有 219 个 workspace package,base composition 有 78 个配置 row,web patch 又加了 51 个,standard agent preset 写了 251 行。底层 Cordis 还有一篇 88 页的论文,讨论 effect、coeffect、fiber、依赖拓扑、恢复定理和“时空可组合性”。模型、工具、session、sandbox、permission、persistence、UI,统统做成插件。官方的概括是:Everything is a plugin。
一边是 88 页的架构理论,一边是三行、没有结果的 benchmark。这个反差基本就是我对 DeepSeek Harness 的第一印象。
我说它“技术自 High”,骂的是优先级错位。Cordis 有技术含量,很多设计也有明确来路。可这套系统花了巨大力气解释自己为什么优雅,还没认真回答用户为什么需要为这份优雅买单。
Cordis 到底在解决什么
先把 Cordis 讲明白,否则批评很容易滑成“复杂就是烂”。
可以把它想成一座不能停业的商场。里面的店随时可能开张、撤走,也可能更换供电、支付和会员系统。开店时,店主要挂招牌、接电、注册收银台、订阅广播。撤店时,如果只把店主和货架搬走,之前接上的线路仍然留着。系统跑久了,就会到处都是失效路由、幽灵监听器和没人清理的定时器。
Cordis 要求组件在产生一个 effect 时,同时登记对应的 inverse。翻成普通话,就是做一件事时,顺手把“以后怎么撤销它”写清楚。组件卸载后,运行时按照相反顺序执行这些撤销操作。
coeffect 处理的是依赖。组件先声明自己需要哪些外部能力。比如一家店只有在供电和支付服务都可用时才营业;其中一项消失,它就暂停;新的 provider 接管后,它再恢复。论文里的“时间可组合性”主要讨论生命周期和撤销,“空间可组合性”处理依赖关系变化后的重组。
这些问题很实在。长期运行的插件宿主里,卸载通常比加载更麻烦。很多系统最后只能靠重启清场。Cordis 把清理、依赖切换和热替换收进一套协议,这部分我认。
Harness 的 append-only session log 也做得不错。system prompt、用户消息、reasoning、tool call、tool result、context injection,只要模型看得到,就必须先进入事件流。也就是“进模型脑子的东西先记账”。resume、fork、trajectory、telemetry 和 UI 都从这份账本派生。调试时不用再猜某段上下文从哪冒出来,恢复和审计也有同一个数据源。
读完这些,我对 Cordis 的评价比刚打开仓库时高。它认真处理了生命周期追踪、依赖切换和热替换,并没有停在给依赖注入换名词。作为复杂插件宿主的运行时,它有研究价值,也解决了真实工程问题。
麻烦从下一步开始。DeepSeek 把这套运行时放到了 coding agent 的正中央,却没有证明 coding agent 最急迫的矛盾是插件无法热卸载。
架构开始替产品做决定
coding agent 今天怎么失败,大家已经很熟了。它会丢上下文、选错工具、越过权限边界,在长任务里兜圈,或者把前面改对的代码重新改坏。用户要看结果也很直接:任务有没有完成,花了多少 token,等了多久,diff 好不好审,挂掉以后能不能接着跑。
DeepSeek Harness 投入大量设计精力处理的是插件如何不停机替换,provider 变化时 fiber 怎么迁移,一个 capability 应该放在 host plane、agent plane 还是 browser plane,service 要不要进入 isolate realm,上层 patch 应该插入 row 还是覆盖整份 config。
这些问题都有道理。但技术问题有道理,只能证明它值得研究,不能自动获得产品最高优先级。
在 Harness 里,增加一个普通能力,往往要先把它翻译成 Cordis 的语言:定义 service,实现 provider,再交给 consumer;启动配置经过 profile、bundle、home patch 和命令行 overlay 多层合成;每项能力还要决定自己住在哪个 plane、哪个 realm、哪棵插件树里。
传统代码里的复杂度并没有消失。它搬到了配置层、service graph、生成目录和生命周期协议里。这个交换如果能换来更低故障率、更快的恢复或者更好的任务表现,当然值得。现在的问题是,DeepSeek 把付款方式展示得很完整,货还没摆出来。
仓库里 minimal preset 恰好可以拿来对照。它主要只有 persistent bash 和 str_replace_editor 两个工具,系统提示词只有一句,也没有 standard 模式那套庞大的组合。整个文件 62 行,其中不少还是注释。
同一个模型跑同一批任务,需要测出 standard 相比 minimal 的实际提升,同时统计失败、重试、启动时间、内存、tool schema 和调试成本。这些本该是发布时最先出现的数字,目前一个都没有。
社区早期反馈也很直白。大家集中要 CLI、TUI、VS Code、SSH、diff 展示和 token 统计。这些东西没有 fiber migration 那么漂亮,但它们决定了用户每天怎么用。用户还在找门把手,项目已经开始研究整栋楼如何在营业时更换承重结构。
DeepSeek 做复杂系统的能力没什么可怀疑的。麻烦在于,团队太容易被自己最擅长的问题吸走。它擅长构造完整抽象,于是需求也开始迁就抽象,架构逐渐替产品划定什么问题值得解决。
架构本身就是价值排序。代码会记录团队优先预防哪些失败,把哪些成本留给插件作者,又允许哪些用户摩擦以后再处理。
DeepSeek Harness 对内部秩序非常敏感,对用户眼前的摩擦却没那么着急。这比 package 数量更能说明它为什么显得过度设计。
论文里的保证,没有宣传听起来那么大
Cordis Paper 试图证明组件可以恢复、继续运行,并在依赖变化后收敛。这项工作很严肃,论文自己对边界也写得清楚。传播时,那些边界经常被省略,最后听起来像“系统可以安全地持续改写自身”。
论文第 56 页明确说,运行时不会检查 inverse 是否真的恢复了 effect。插件作者提交撤销操作,Cordis 负责保存、排序和调用。撤销逻辑有没有写对,还是作者负责。
还是前面的商场。Cordis 能保证撤店流程会执行,先后顺序也不会乱;但店主交上来的清单有没有漏掉墙里的电线,它不知道。它管理清理流程,不验证清理结果。
第 68 页又区分了 acquisition 和 emission。打开文件拿到 descriptor、启动进程拿到 handle,这些资源可以关闭或回收。已经写入磁盘的字节、发出网络请求、提交给外部系统的结果,则离开了 Cordis 能撤销的范围。之后只能靠删除文件、退款或者补偿事务处理。
Context 里的状态能回滚,现实世界没有统一的撤销键。agent 发了邮件、删了云端数据、提交了错误交易,运行时再优雅地卸载插件也没用。
论文里的全局 recovery、progress 和 confluence 还依赖一组前提:effect 彼此独立,依赖关系无环,fiber 数量有限,迭代过程有界,运行期间没有额外失败,组件完整提供了声明过的 service。循环依赖可以拆出 integration component,但一般情况下,这类连接组件可能增长到 O(n²)。系统主要按 key 连接接口,也不能只凭名字保证两边对接口的理解完全一致。
这些前提是形式化证明的正常组成。Cordis Paper 对范围写得相当坦率。宣传把范围抹掉以后,“在这些假设下可以恢复”很容易变成“系统天然安全,可以任意演化”。
真实插件已经撞上边界了。外部插件可以在类型层声明新的 session event,也可以把它写进日志;但标准 persistence 不认识仓库以外的事件类型,公开接口又不能把普通事件标记成可忽略。代码编译通过,session 重启后却可能读不回来。类型系统把门打开了,持久化协议没有把路接完。
“没有 privileged core”也需要打个问号。把核心拆成插件,核心不会消失。真正需要信任的部分分散到了 loader、Context proxy、事件协议、配置生成器和多个 provider。系统仍然有中心,只是这个中心不再集中,出了问题更难追。
形式化方法可以回答“接受这些前提以后,会发生什么”。它不负责决定哪些问题最值得解决。数学可以先定义一个世界再做证明,产品不能把用户碰到的麻烦定义到世界外面。
会改自己,离 RSI 还很远
DeepSeek Harness 最容易引发想象的,是单独提供的 cordis agent preset。模型可以检查当前插件树,定义新的 host 或 browser 代码,直接挂到正在运行的系统上,再停止或删除。社区很快把它和 RSI,也就是 Recursive Self-Improvement,递归自我改进,联系起来。
这个联想有一部分是合理的。系统要改进自己,至少得先能观察和修改自己。Cordis 允许 agent 在不重启宿主的情况下挂载新工具、提示词或监听器,再随时撤掉。做自修改实验会方便很多。
但“改过”离“改好”还差一个完整闭环。新旧版本要在同样的任务上运行,由独立信号评价,候选之间要比较,胜出的版本要稳定保留下来。要称为 recursive,还得证明改进后的系统更擅长完成下一轮改进,排除某次碰巧多拿几分的情况。
现在这套工具的核心动词是 inspect、define、run、stop 和 undefine。没有 evaluate、compare 和 select。系统也没有内置 task suite、A/B 对照、独立 evaluator、回归检测、版本晋升和多轮提升曲线。
动态 package 只存在于共享进程的内存里,重启后就消失,也不会自动晋升成持久插件。它还可能影响同一进程里其他 session。官方要求按 bash access 的风险等级看待 VM sandbox,异步 host body 也不完全受执行超时约束。
cordis preset 是 opt-in 的,高权限风险不能算到默认模式头上。准确一点说,DeepSeek 做出了一个很灵活的 live prototyping 工具,模型可以临时改造运行时。这个工具适合研究,也可能成为 RSI 实验的一块积木。称它为经过验证的 RSI 系统,目前还缺证据。
Paper 自己很克制。结论只把 self-evolving agent harnesses 写成“未来值得验证的方向”。到了二手传播里,关系慢慢倒过来了:原本是以后可以用 agent 系统验证 Cordis,最后讲成了 Cordis 正在开启 RSI。
这类叙事有个讨巧之处。自动重试可以叫 self-refinement,生成工具可以叫 capability growth,改 prompt 可以叫 self-evolution,再加上热加载插件,似乎马上就要 recursive self-improvement。概念抬得越高,今天的产品越不需要接受今天的比较。它不用先证明自己比现有 coding agent 更稳,只要让人相信它正在修未来智能的地基。
可任何拿到 bash 和仓库权限的 coding agent,都能修改代码、运行测试然后重启。难点一直是判断“什么叫改对了”。这需要交代评价标准由谁定义,系统是否会迎合 evaluator,局部 benchmark 上升有没有伤害其他任务,以及一次成功能否跨版本保留。
RSI 里的 improvement 必须由某种外部尺度来确认。系统可以独自发生变化,不能独自宣布进步。缺少 evaluator 时,自修改越方便,越可能只是在更高效地制造变化。这套判断也应该反过来用在 DeepSeek Harness 自己身上。
先交结果,再谈未来
DeepSeek Harness 现在需要一组普通得不能再普通的对照实验。
固定同一个 DeepSeek 模型和 reasoning 配置,准备一批公开、可复现的长短任务,分别运行 minimal 和 standard。记录成功率、重试次数、输入输出 token、缓存命中、首 token 延迟、总耗时、峰值内存和人工接管次数,再加入一个成熟系统作为 baseline。
standard 如果稳定赢,插件体系的复杂度就换来了任务质量。如果它只在某类长任务上赢,也能看出适用边界。如果差异不明显,团队就该重新判断哪些能力应该留在默认配置。动态替换若能降低故障恢复成本,也可以直接测恢复时间和失败率。
RSI 的验证同样具体:候选修改隔离运行,评价信号独立,新旧版本公平比较,优胜版本能够持久化,连续多轮出现可复现的提升,而且系统确实提高了下一轮改进的效率。在这些证据出现前,runtime self-modification 或 live prototyping 都更准确。
我愿意把 Cordis 叫作一套有原创性、有理论支撑的动态插件框架。DeepSeek 也确实用它搭出了一个规模可观的 coding agent。我的不满集中在团队至今没有证明,这份复杂首先属于用户的问题。
工程师有时会被一套过于完整的理论困住。系统内部越自洽,外部反证越容易被解释成“产品还没补完”;抽象越漂亮,用户的不适越容易被归因于“还没理解设计”。
这就是 DeepSeek Harness 目前给我的感觉。
所以我仍然会把它称为一场精致的技术自 High。精致,是因为技术真做到了这个份上。自 High,是因为项目目前拿出的证据,主要证明了 Cordis 可以完整地解释 Cordis。
先把 minimal、standard 和一个外部 baseline 放到同一张表里,交代任务、成功率、成本和失败模式。这张表应该比下一篇架构论文更早出现。