软件世界里有一种很古老的妥协。
我们喜欢说系统是“模块化”的。数据库可以换,模型可以换,搜索引擎可以换,工具可以换,甚至用户界面也可以彻底重写。但沿着架构图不断向中心走,总会抵达某个地方——那里通常有一小块代码不能碰。
它可能叫 Kernel,也可能叫 Runtime、Scheduler、Orchestrator,或者 Agent Loop。
名字并不重要。
重要的是,我们默认那里必须有一个不可替换的中心。
2026 年,DeepSeek Harness 做了一件颇有挑衅意味的事情:
它问,为什么?
模型越来越聪明,真正麻烦的却变成了模型之外的世界
早期的大语言模型应用非常简单。
输入一段文字,调用一次 API,得到另一段文字。
那时候,软件工程师面对的问题主要是 Prompt 怎么写、Temperature 设多少、上下文窗口够不够长。
Agent 改变了这一切。
一个真正工作的 Agent,需要读取文件、修改代码、调用 Shell、访问网络、维护会话、恢复中断的任务、管理权限、启动子智能体,甚至连续运行几十分钟乃至几个小时。
模型只是其中的一部分。
围绕模型开始出现越来越庞大的基础设施:
Tools、Memory、Session、Sandbox、Permission、Agent Loop、Subagents、Event Bus、Observability……
如果把大模型看作一个人的大脑,那么这些东西更接近他的身体、感官、记忆和行动系统。
问题也随之发生了变化。
过去我们问:
哪个模型更聪明?
现在越来越重要的问题变成:
怎样给这个模型造一副足够好的身体?
这副身体不仅要能够行动,还必须能够被拆开、替换、修复和重新组合。
传统 Agent 框架当然也允许扩展。你可以增加 Tool,可以注册 Hook,也可以接入不同的模型。
但扩展通常存在一个边界。
工具可以替换。
模型可以替换。
Memory 可以替换。
可是控制 Agent 如何思考、何时调用工具、怎样把结果重新交给模型的那段核心循环,往往仍然隐藏在框架深处。
于是,当开发者真正想改变 Agent 的工作方式时,事情很快会变得不那么优雅。
Fork。
修改源码。
维护自己的分支。
然后等待上游更新。
再开始漫长的 Merge。
这就是软件世界里一种并不陌生的税:
Fork Tax——分叉税。
DeepSeek Harness 想从架构上消灭它。
它提出了一句近乎宣言式的话:
Everything is a Plugin.
万物皆插件。
不是“大部分东西”。
而是——所有东西。
如果万物皆插件,那么谁是核心?
第一次看到 DeepSeek Harness 的架构时,真正值得注意的并不是它拥有多少工具,也不是它支持多少模型。
而是一个奇怪的缺席:
它几乎没有传统意义上的“特权核心”。
模型适配器是插件。
工具系统是插件。
Session 是插件。
Sandbox 是插件。
Permission 是插件。
Web UI 是插件。
甚至连负责驱动智能体不断执行“思考—行动—观察—再思考”的 Agent Loop,也只是一个插件。
这件事比听起来更加激进。
在许多 Agent Framework 中,工具是“家具”,模型是“住客”,而 Agent Loop 是房屋本身。
家具可以换,住客可以换。
但没人会在居住过程中把承重墙拆下来。
DeepSeek Harness 的想法更接近另一种建筑:
连承重结构都是可替换的。
于是一个很有意思的问题出现了:
如果所有组件都可以替换,那么究竟是什么维持着整个系统?
答案藏在 DeepSeek Harness 最不显眼、却可能也是最重要的部分:
Cordis。
Cordis:让软件学会“忘记”
插件架构并不是新鲜事。
浏览器有插件。
VS Code 有插件。
WordPress 有插件。
操作系统甚至可以动态加载内核模块。
真正困难的从来不是“加载”。
而是:
怎样安全地卸载?
想象一个插件进入系统以后注册了三个事件监听器,修改了两个状态,启动了一个后台任务,又向某个服务注册表加入了一项能力。
几分钟以后,你决定把它换掉。
问题来了。
谁负责把这些东西全部清理干净?
少清理一个监听器,就可能出现幽灵回调。
忘记关闭一个后台任务,就可能发生资源泄漏。
留下一个旧引用,新旧组件便可能同时操作同一份状态。
动态系统最危险的地方,往往不是新组件没有启动。
而是:
旧组件没有真正死去。
Cordis 给出的答案叫:
Revertible Effects——可逆副作用。
它要求插件对环境做出的每一个改变,都必须附带一个相反方向的动作。
注册事件监听器,就必须知道怎样注销。
创建资源,就必须知道怎样释放。
修改状态,就必须知道怎样撤销。
这些清理操作被记录下来。
插件退出时,它们按照与创建时相反的顺序执行。
像搭积木。
最后放上去的一块,最先拿下来。
这其实是一种非常简单,却又非常深刻的纪律:
任何进入系统的东西,都必须知道自己怎样离开。
于是插件不再只是“可加载”。
它开始真正变得:
可撤销。
这构成了 Cordis 所谓“时间可组合性”的基础。
另一半问题:如果依赖突然消失怎么办?
时间解决了卸载的问题。
但大型 Agent 系统还有另一个麻烦。
依赖关系。
假设一个插件需要两个能力:
tools
llm
传统软件通常要求工程师决定启动顺序。
先初始化模型。
再初始化工具。
然后启动 Agent。
如果顺序错了,系统就报错。
Cordis 做了一件更接近现代分布式系统的事情。
插件可以直接声明:
我需要 tools 和 llm。
如果这些能力还不存在,它不会崩溃。
它只是进入:
PENDING。
等待。
某个时刻,一个 LLM Provider 被加载,ctx.llm 出现了。
Cordis 发现依赖已经满足。
插件自动启动。
但更有意思的是反方向。
如果运行途中 LLM Provider 被卸载了呢?
依赖它的组件也会停止工作,撤销自己的副作用,重新回到等待状态。
直到新的 Provider 出现。
整个系统因此不再像传统程序那样拥有一个固定的启动顺序。
它更像一座城市。
电力恢复,依赖电力的设施逐渐苏醒。
某项基础服务消失,相关区域自动关闭。
新的服务重新出现,系统再次恢复运行。
DeepSeek Harness 把这种能力称为:
Reactive Coeffects——响应式共效应。
如果 Revertible Effects 解决的是:
一个组件怎样干净地离开?
那么 Reactive Coeffects 解决的就是:
一个组件怎样知道什么时候应该存在?
两者结合,才形成所谓:
Spatiotemporal Composability——时空可组合性。
这听起来很学术。
但翻译成工程语言其实很简单:
组件可以随时出现,也可以随时消失,而系统仍然保持完整。
Agent 不再是一台机器,而是一片不断变化的拓扑
这种思想带来了一个很有意思的结果。
DeepSeek Harness 不再像传统程序那样,由一组固定模块构成。
它更接近一棵运行时不断变化的插件树。
每一个插件实例都有自己的生命周期句柄:
Fiber。
一个 Fiber 可能处于:
PENDING → LOADING → ACTIVE → UNLOADING → DISPOSED。
如果加载失败,则进入 FAILED。
这套状态机真正重要的地方并不是这些名字。
而是它让系统第一次可以非常明确地回答:
此刻,这个组件究竟处于什么状态?
它正在等待依赖?
正在初始化?
已经工作?
还是正在退出?
对于一个几十个乃至上百个插件组成的 Agent Runtime,这种确定性极其重要。
因为未来的 Agent 系统越来越不像传统应用。
它们更像一个动态生态系统。
模型可能改变。
工具可能改变。
权限可能改变。
子 Agent 可能出现又消失。
运行策略也可能在任务执行过程中发生变化。
DeepSeek Harness 试图让这种变化成为系统的正常状态,而不是异常状态。
真正大胆的地方:把 Agent Loop 从王座上赶下来
这也许是整个 DeepSeek Harness 最值得关注的设计。
几乎所有 Agent 都有某种循环。
简化以后,大致如此:
读取上下文
↓
调用 LLM
↓
模型决定调用工具
↓
执行工具
↓
把结果加入上下文
↓
再次调用 LLM
这个循环就是 Agent Loop。
在很多框架里,你可以修改循环周围的东西。
但循环本身往往属于框架。
DeepSeek Harness 做了一个非常不同的决定:
Agent Loop 也只是 Cordis 插件。
它提供一个服务:
ctx.agentLoop
仅此而已。
于是理论上,你完全可以把默认 Agent Loop 拔掉。
换成一个自己的版本。
例如,一个传统同步循环可以被替换成:
并行 Actor 模型;
多智能体协作网络;
Plan-and-Execute;
Tree Search;
异步事件驱动 Agent;
甚至未来某种今天还没有名字的推理架构。
而 Session、Tools、Sandbox、LLM Provider 和 UI 都不需要因此重新开发。
这是一种非常重要的架构倒置。
传统 Agent Framework 的潜台词是:
这是我的 Agent,你可以扩展它。
DeepSeek Harness 更像是在说:
这里有一组能力。至于什么叫 Agent,由你决定。
区别非常大。
这也悄悄打开了一扇危险而迷人的门:Agent 修改自己
一旦 Agent Loop 本身可以替换,事情就开始变得有些科幻。
因为一个 Agent 理论上可以:
检查当前运行时;
发现自己的调度方式不适合当前任务;
生成一个新的 Agent Loop;
安装它;
卸载旧 Loop;
然后继续执行任务。
也就是说:
程序修改的对象,开始包含程序自己。
DeepSeek Harness 提供的 Creator Mode,正是在试探这个方向。
我们过去习惯把 AI 写代码理解为:
AI 修改另一个程序。
但这里出现了另一种可能:
AI 修改承载自己的程序。
两者之间隔着一道非常重要的边界。
前者是 Coding Agent。
后者已经开始触碰:
Self-Modifying Agent。
甚至是更遥远的:
Recursive Self-Improvement。
当然,能够修改自己的运行时,并不意味着系统已经拥有真正意义上的递归自我改进。
“可以改变自己”和“能够持续把自己变得更聪明”,是两件完全不同的事情。
但基础设施已经开始为后者留下接口。
这才是 DeepSeek Harness 最值得注意的地方。
如果一切都可以变化,什么东西不能变化?
一个无限可修改的系统会立刻遇到另一个问题:
怎样知道自己没有坏掉?
DeepSeek Harness 的答案有些反直觉。
它一方面允许大量组件被替换,另一方面又对系统状态保持近乎偏执的纪律。
其中最重要的一条原则是:
Model-visible means logged.
模型看到的东西,就必须被记录。
DeepSeek Harness 的 Session 并不是普通聊天记录。
它更接近一个:
Append-Only Event Log。
系统不反复修改“当前状态”。
它不断记录:
发生了什么。
工具调用。
工具结果。
上下文注入。
Agent 状态变化。
模型交互。
然后通过这些事件重新推导当前状态。
这与金融账本有某种相似之处。
银行不会只保存:
余额:10,532 元。
它更愿意保存:
收入 5000。
支出 120。
转账 800。
退款 50。
……
最后:
余额只是历史事件的投影。
DeepSeek Harness 对 Agent 状态采取了类似的哲学。
于是,Agent 第一次拥有了可以真正重放的“过去”
这带来一个非常现实的工程收益:
Replay。
传统 Agent 出问题时,工程师经常面对一种令人沮丧的场景。
日志看起来没问题。
Prompt 看起来没问题。
工具也工作正常。
可是模型为什么在第 37 步突然做了那个决定?
没人知道。
因为日志只是“尽量记录”。
它并不一定等于模型当时真正看到的世界。
DeepSeek Harness 强制要求:
模型看到的上下文必须与事件日志能够重建出的上下文一致。
这意味着某个 Agent 在凌晨三点失败以后,第二天工程师可以重新构造:
失败前一秒,模型眼中的整个世界。
甚至可以不调用真正的模型。
历史运行轨迹可以成为 Fixture。
Mock Model 根据历史记录返回确定性结果。
Agent 重新执行。
然后:
Diff。
旧轨迹。
新轨迹。
哪里不同,一目了然。
对于传统软件开发,这很普通。
对于概率性的 LLM Agent,却是一件意义很大的事情。
Agent 工程开始拥有类似普通软件的:
Regression Testing。
PTC:为什么 Agent 不应该把整个世界塞进 Prompt
Agent 时代还有一个越来越昂贵的问题:
Token。
传统 Function Calling 的工作方式通常是:
模型输出工具调用;
工具返回结果;
结果被转成文本;
文本塞回上下文;
模型继续阅读。
如果工具返回 50 KB JSON,也许还可以忍受。
如果返回 50 MB 呢?
模型真正需要的可能只是:
符合条件的记录有 17 条。
但为了得到这个数字,我们让模型阅读了一整座仓库。
DeepSeek Harness 的 PTC——Programmatic Tool Calling——试图改变这个过程。
它的思路是:
不要让模型不断调用工具。
让模型:
写程序。
例如模型不再依次执行:
fetch()
fetch()
filter()
sort()
aggregate()
而是直接生成一段 TypeScript。
程序在 Sandbox 中运行。
几十 MB 的 JSON 留在沙盒内存。
过滤、排序、聚合也在那里完成。
最后只把真正需要的结果:
submit(result)
交回模型。
这背后其实是一种很重要的 Agent 设计哲学:
让计算发生在计算应该发生的地方,而不是把所有数据都变成语言。
LLM 很擅长语言。
但数据库擅长过滤。
代码擅长循环。
CPU 擅长计算。
搜索引擎擅长检索。
未来真正成熟的 Agent,不应该试图让 LLM 做所有事情。
它应该知道:
什么时候不需要思考。
能力越大,围墙就必须越厚
问题也随之而来。
如果模型能够生成代码,并且代码真的可以运行,那么一句:
rm -rf /
就不再只是文本。
它可能成为行动。
于是 Sandbox 不再是 Agent Framework 的附加功能。
它开始成为:
基础设施边界。
DeepSeek Harness 把权限拆成两个维度。
一个决定:
你实际上能做什么。
另一个决定:
做之前是否需要人类批准。
例如文件系统可以处于:
read-only;
workspace-write;
或者 danger-full-access。
操作策略则可以要求:
ask;
或者 never。
更重要的是,它遵循:
Fail Closed。
如果权限系统坏了怎么办?
传统软件有时会选择:
“先继续运行。”
DeepSeek Harness 的答案相反:
拒绝。
安全机制无法确认,就不执行。
这是一条看似保守,却可能决定 Agent 能否真正进入企业生产环境的原则。
因为未来最大的 Agent 安全事故,很可能并不是模型“说错了什么”。
而是:
模型真的做了什么。
一个 Agent 已经不够了
当任务越来越复杂,单一 Agent 也开始显得笨重。
一个 Agent 同时阅读几百个文件、分析架构、修改代码、运行测试、检查安全问题,会产生越来越长的上下文。
于是任务开始自然分裂。
一个 Agent 分析数据库。
一个检查前端。
一个研究测试。
一个负责架构。
另一个负责最终整合。
DeepSeek Harness 把 Subagent 同样抽象成服务:
ctx.subagents
于是子智能体究竟运行在哪里,也变成可以替换的实现。
它可以与主 Agent 处于同一进程。
可以继承主 Agent 的部分上下文。
可以启动独立 DSH 进程。
甚至可以通过协议调用其他 Agent Runtime。
这意味着未来的 Agent 系统可能不再是一棵简单的调用树。
而是一张:
动态计算网络。
Agent 出现。
执行任务。
交换结果。
然后消失。
真正稳定存在的,也许只有:
事件。
接口。
权限。
以及协议。
真正有意思的并不是 DeepSeek,而是 Harness
过去两年,AI 行业的大部分注意力都集中在模型。
GPT。
Claude。
Gemini。
DeepSeek。
参数规模。
Benchmark。
Context Window。
推理能力。
但随着模型能力逐渐接近一个新的平台期,竞争正在向模型之外移动。
一个越来越重要的词开始出现:
Harness。
它很难准确翻译。
“框架”太轻。
“运行时”又太窄。
“智能体基础设施”可能更接近它真正的含义。
Harness 决定:
模型能看见什么;
能够调用什么;
怎样保存记忆;
怎样恢复任务;
怎样使用计算资源;
怎样受到权限约束;
怎样与其他 Agent 合作;
以及——
怎样改变自己的行为。
从这个角度看,未来 AI 系统真正的差异,也许不会只来自模型。
同一个模型,被装进不同 Harness,可能表现得像完全不同的智能体。
就像同样的大脑,如果拥有不同的身体、记忆、工具和社会环境,最终会成为完全不同的人。
DeepSeek Harness 真正激进的地方,是它拒绝相信“核心”
计算机科学长期存在一种近乎本能的架构习惯:
总要有一个中心。
操作系统有 Kernel。
数据库有 Engine。
Web Framework 有 Runtime。
Agent Framework 有 Agent Loop。
DeepSeek Harness 提出了另一种可能。
真正稳定的东西也许不应该是一段不可替换的代码。
真正稳定的应该是:
接口、契约、事件和不变量。
实现可以变化。
模型可以变化。
工具可以变化。
调度方式可以变化。
甚至“Agent 是什么”本身也可以变化。
只要契约仍然成立。
这让 DeepSeek Harness 看起来不像一个普通的软件框架。
它更像是一种关于未来软件的实验。
机器开始拥有一副可以重新设计的身体
1965 年,I. J. Good 描述“智能爆炸”时,想象的是一台足够聪明的机器开始设计比自己更聪明的机器。
六十多年以后,我们距离那个场景究竟还有多远,没人知道。
但真正的递归自我改进不会只发生在模型权重里。
一个智能系统如果想真正改进自己,它必须能够观察自己的行为,理解自己的失败,修改自己的工具,改变自己的调度方式,验证修改后的结果,并在失败时安全地回滚。
换句话说,它不仅需要一个聪明的大脑。
还需要一副:
可以被自己重新设计的身体。
DeepSeek Harness 最值得关注的地方,也许就在这里。
今天,它仍然只是一个年轻的 Agent Runtime。
它的 API 仍然可能变化。
它的插件生态还远未成熟。
它也没有证明 Agent 可以因此实现真正意义上的递归自我改进。
但它已经把一个过去被认为理所当然的问题重新摆到了桌面上:
为什么 Agent 的运行时必须是固定的?
如果模型能够写代码。
如果工具可以动态安装。
如果组件可以安全卸载。
如果 Agent Loop 本身可以被替换。
如果系统能够记录自己的历史。
如果它能够重放失败、验证修改,然后重新启动……
那么某一天,我们也许会发现:
真正重要的那一步,并不是机器第一次写出了更好的代码。
而是机器第一次意识到——
那段需要被改写的代码,就是它自己。