技术随笔
最近在一个 QQ Bot 开发者群里,我们因为 DeepSeek Harness(简称 DSH)接入 QQ Bot 的事情聊了很久。

最开始的话题其实很普通:为什么 QQ Bot 最近不断接入 OpenClaw、Hermes、DSH 这类 Harness 项目?这究竟只是追赶 Agent 的热潮,还是它们之间真的存在某种技术上的关联?但聊到后面,我们发现真正值得讨论的已经不再是“QQ Bot 为什么要接 Harness”,而是另外一个更深层的问题:

为什么我们今天谈到 Personal Agent 时,总会下意识地认为,一个用户就应该对应一个 Harness,甚至对应一个独立的容器?

如果我们不再把 Harness 理解成“一个用户安装在自己电脑上的 Agent 程序”,而是把它重新理解成一种类似 Bot Framework 的基础设施,会发生什么?

我们最后得出的判断是:Personal Agent 的“一对一”是必要的,但这种一对一应该发生在 Agent Identity(身份层),而不一定发生在 Harness Runtime(运行时层),更不一定发生在永久的容器层。

换句话说,一套 Harness 完全可能承载海量彼此独立的 Personal Agent。而真正需要强隔离的,可能从来都不是 Harness 本身,而是某些具有副作用的执行环境。这可能是 Agent 从自托管工具走向真正平台化时,非常重要的一次架构解耦。

一、我们为什么天然认为 Agent 应该“一人一套”?

过去几年,很多 Personal Agent 产品给开发者建立了一套很自然的心智模型,即:一个用户,等于一个 Agent,等于一个 Harness,等于一个 Workspace,最终等于一个 Container 或 Runtime。

对于自托管场景,这种设计非常合理。用户在自己的机器或服务器上启动一个 Agent,它拥有自己的配置、模型 Key、文件目录、Shell、浏览器、长期记忆和各种凭证。从使用者角度看,这些东西本来就是一个整体。

于是久而久之,我们很容易把这种部署形态误认为 Agent 本身的架构定义,得出“Personal Agent 是一对一的,所以 Harness 也必须是一对一的”这样的结论。

但这里其实悄悄发生了一次概念绑定。Personal Agent 真正要求独占的到底是什么?是整个 Harness 进程?还是属于这个用户的身份、状态、记忆、权限和工作空间?这两个问题并不是一回事。

如果一个 Agent 的性格、记忆、凭证、策略、目标、工具权限和长期状态都属于唯一用户,那么即使底层有一万个 Agent 共用同一个 Harness Runtime,它仍然完全可以是一个 Personal Agent。就像一个 Web Server 可以同时服务几十万个账户,我们不会因此认为这些账户共享了同一个身份。

我们早就接受了 Web Runtime 不等于 User State。但是到了 Agent 时代,我们却暂时把 Harness Runtime、Agent 和 User 绑在了一起。这很可能只是 Agent 基础设施仍处在早期阶段留下的历史惯性。

二、Bot 开发者为什么很容易想到另外一种答案?

这也是今天这场讨论很有意思的地方。参与讨论的人长期从事 Bot 和 Bot Framework 开发,因此面对“一套 Harness 能不能服务很多用户”这个问题时,第一反应和典型的 Personal Agent 开发者可能并不一样。

因为对于 Bot Framework 来说,一个 Runtime 服务海量用户才是最正常的事情。一个机器人程序可能同时存在于几万个群里,每个群里又有成百上千个用户。但是我们从来不会为群 A、群 B、群 C 或用户 A、用户 B、用户 C 分别启动六套独立的框架进程。

框架通常只存在一份,真正发生变化的是 Context(上下文)。一个事件进入框架以后,框架首先确定:这是谁发送的?来自哪里?属于哪个群?拥有什么权限?应该读取哪份状态?哪些插件在当前上下文中有效?确认完毕后,才开始执行具体业务。

所以在 Bot 世界里,我们早就习惯了一件事情:Runtime 是共享的,但执行上下文不是共享的。甚至可以说,一套成熟 Bot Framework 的核心能力之一,本来就是在同一个运行时中,让海量彼此独立的上下文安全地共存。

今天再回头看 Agent Harness,一个非常自然的问题就出现了:为什么 Harness 不能也是这样?

三、DSH 真正有意思的地方,不只是“又一个 Agent”

这也是为什么这次 DSH 接入 QQ Bot,比单纯的“又适配了一个热门 Agent 项目”更值得讨论。

DSH 官方把自己描述为建立在 Cordis 之上的插件式 Harness。模型适配器、工具注册表、会话日志、Agent Loop 等核心能力本身都以插件形式挂载在共享的上下文中,而不是一个不可拆分的单体核心。

更关键的是,DSH 对 Cordis Context 与 Agent 或 Session Identity 做了明确区分。Cordis Context 负责服务、注册关系与生命周期,而 Agent 和 Session Identity 表示一次异步操作真正属于谁。官方的设计说明甚至专门讨论了为什么不能简单使用某个全局的“当前 Agent”,因为一个进程完全可能并发驱动多个 Agent。这其实已经非常接近 Bot Framework 开发者熟悉的思想了。

而腾讯的 dsh-qqbot 插件又进一步把这个关系表现得非常直接:数据流从 QQ 用户,到 QQ WebSocket,再到 dsh-im-qqbot 插件,随后进入 ctx.agents 和 dsh agent loop,最后调用 LLM。

在这里,QQ 并不是 Agent 本身,而是一种前端协议和事件来源。从这个角度看,DSH 和 QQ Bot 的结合其实并不突兀。它真正值得关注的不是能不能让 QQ 用户和大模型聊天,而是另外一种可能:如果 Agent 本身可以成为 Context,那么一个 Harness 是否也可以像 Bot Framework 一样,同时托管大量彼此独立的 Agent?

四、“一对多”会不会让 Personal Agent 退化成普通聊天应用?

讨论到这里,有人提出了一个非常关键的反对意见:Harness 一旦一对多,会不会最终退化成一个泛用的对话 App?

这是一个非常合理的担忧。如果所谓的一对多是指:一个 Harness、一个 Prompt、一个 Memory、一个 Tool Set,所有用户不断向里面发送请求。那么它当然已经不是什么 Personal Agent,而只是一个普通的聊天服务。

但这里真正应该区分的是:共享 Harness 和共享 Agent,不是同一件事情。

正确的多租户模型应该是,在一个共享的 Harness 之下,存在 Agent A、B、C,它们各自拥有独立的身份、记忆、策略、授权和目标。这里真正被共享的只是 Agent 的运行机制,而不是 Agent 自身。

因此,未来讨论 Agent 架构时,可以把过去那个简单的“一对一”拆成三个完全不同的层级:

第一层是 Harness。一个 Harness Runtime 可以同时管理大量 Agent,这是 1 对 N 的关系。

第二层是 Identity。对于 Personal Agent 来说,它仍然只属于一个主体。这个主体可以是一个人,也可以是一个企业、一个项目或一个组织。这是 1 对 1 的关系。

第三层是 Execution。Agent 根据任务需要创建零个、一个甚至多个隔离的执行环境。这是 1 对 N 的关系。

这样一拆,“一对多必然退化”的问题就不存在了。Personal Agent 的个人化属性,并不来源于它独占一个进程,而来源于它独占自己的身份与长期状态。

五、但 Coding Agent 为什么又经常真的需要“一对一”?

这个时候另一个问题就出现了。像 Trae SOLO 这样的 Coding Agent,为什么我们又明显感觉它需要自己的独立环境?

因为 Coding Agent 与普通对话 Agent 最大的区别之一,是它拥有一个强副作用对象:Workspace(工作空间)。Trae 对 SOLO 的公开描述就高度围绕项目代码、开发环境、浏览器预览和 Agent 执行能力展开。

当 Agent 可以修改文件、启动进程、执行 Shell、读取环境变量、运行测试、安装依赖、访问 Git 凭证时,这个工作空间本身当然必须拥有明确的安全边界。我们不可能让一万个陌生用户共同使用同一个工作目录、进程命名空间或环境变量。

所以“一对一隔离”仍然必要。但这里需要再次问一句:究竟是谁和谁一对一?

Workspace 需要与安全主体隔离,并不意味着整个 Harness 也必须永久属于这个用户。这是两个完全不同的边界。

六、真正应该拆开的,是控制平面与执行平面

这可能是整场讨论最后最重要的一个结论。

未来规模化 Agent Platform 更合理的架构,很可能不是用户、Harness、Container 之间相互绑定的一一对应。

更合理的架构应该是:一个共享的 Harness 作为 Agent 控制平面,管理各自拥有独立记忆、授权和策略的多个 Agent 逻辑实体。控制平面下方连接任务调度器。对于安全的远程工具调用,直接通过 API 处理;而对于危险的执行任务,则调度到沙盒或虚拟机中执行,任务完成后自动回收资源。

Harness 负责的是控制平面:涵盖 Agent 身份、会话、记忆、目标、提示词、模型、工具注册、授权、调度与长期状态。

真正容易产生安全副作用的部分进入执行平面:涵盖文件系统、Shell、进程、浏览器自动化、代码库构建以及未知代码执行。

实际上,DSH 自己的近期架构设计也已经出现了类似的分离。Host 侧持有 Cordis、Agent Loop、状态管理和 LLM 调用逻辑,而远端执行环境可以负责可变文件系统、终端命令行等执行资源。这意味着一个非常重要的变化:容器不再是 Agent 的生命周期单位,而成为 Execution(执行阶段)的生命周期单位。

七、从“一个 Agent 一个容器”到“一个任务一个 Sandbox”

这会直接改变 Personal Agent 的成本模型。

过去我们可能认为,用户创建了一个 Personal Agent,所以我要为它长期保留一个容器。但绝大多数 Agent 请求其实根本不需要本地计算环境,例如查询天气、读取日历、搜索资料、总结聊天、调用企业 API 或生成文本。这些工作完全可以通过远程 API 完成。只有当 Agent 真正需要执行 Bash、写入文件系统、自动化浏览器或构建代码时,才需要创建强隔离的执行环境。

于是,“每个 Agent 一个容器”的模式,可以逐渐变成“每个危险任务一个沙盒”,甚至对于安全任务实现“零沙盒”。

Google 在 Gemini Spark 上公开的设计提供了一个非常有意思的现实例子。Spark 被定义为持续存在的 Personal AI Agent,会长期理解用户上下文并代替用户完成工作。但是 Google 并没有因此要求一个 Personal Agent 永久绑定一台虚拟机,而是让每个需要执行的任务进入新的、严格隔离的临时虚拟机。

这说明,持续存在的 Agent 和持续存在的 Runtime,本来就不是一回事。Agent 可以长期存在,记忆、身份和目标都可以长期存在,但执行它某一次任务的虚拟机,只需要存在几分钟。任务结束后虚拟机销毁,下一次任务到来再创建新的环境。

从架构上看,这已经非常接近“持久化逻辑 Agent + 临时化物理执行”的模式。这比一人一台永远运行的 Agent 容器,更接近真正能够规模化的平台形态。

八、Bot Framework 曾经解决过一次类似的问题

这也是为什么我认为 Bot 开发者看 Harness 会有一个特殊的视角。

早期 Bot 同样很容易写成简单的线性流程:收到消息、判断指令、执行代码、返回结果。后来随着群、用户、权限、插件、跨平台事件越来越复杂,Bot Framework 才逐渐开始解决另外一些问题:上下文怎么传播?插件怎样隔离?谁拥有某个服务?不同群的配置怎样共存?插件卸载以后,注册的副作用如何一起消失?

也就是说,Bot Framework 最终解决的已经不只是“怎么执行一个指令”,而是“如何让大量彼此独立的状态和能力,在同一个运行时中安全而有序地共存”。

现在 Agent Harness 似乎正在重新经历一次非常类似的演化。第一阶段关注怎么让 LLM 调工具;第二阶段关注怎么循环执行任务;然后是怎么拥有记忆、工作空间和长期目标。再往后,当真正开始考虑数十万甚至数百万用户时,下一个问题一定会变成:这些 Agent 为什么必须每一个都拥有一整套独立 Runtime?

这时候,过去十几年 Bot Framework、Web 框架、数据库和云计算已经反复解决过的多租户问题,会重新进入 Agent 世界。

九、DSH 的潜力,不是“不需要容器”,而是有机会把 Harness 和容器解绑

因此,如果让我重新描述今天讨论中对 DSH 最有价值的判断,我不会说它的优势是“不用容器”。这显然是不准确的,对于执行不可信代码的场景,沙盒与微型虚拟机的安全边界依然不可缺少。

我真正关注的是:DSH 这种面向框架的 Harness,有可能让 Harness 不再和某个具体容器绑定。

这一点的意义远远大于“少启动几个 Docker”。因为一旦 Harness、Agent 身份与执行环境被真正拆开,Agent 平台的基本单位就发生了变化。过去是“用户-Agent-Harness-容器”的单线程绑定,未来可能变成一个共享 Harness 承载多个逻辑 Agent 和独立身份,并按需调度执行环境。于是成本控制、插件管理、模型路由和资源复用都会拥有完全不同的可能性。

十、Agent 的“一对一”,应该停留在身份层

回到最开始的问题:Personal Agent 到底需不需要一对一?

我认为答案依然是:需要。但是我们应该非常准确地说清楚,它需要的是“一个 Agent 对应一个身份”,而不是对应一个 Harness 进程,更不是对应一个永久的容器。

一个真正属于我的 Agent,应该拥有我的长期记忆、我的授权、我的偏好、我的工具、我的目标以及只有我能够访问的状态。这才构成真正的个人化。至于它背后的 Agent Loop 究竟运行在哪一个进程里,我其实并不应该关心。就像今天没有人会因为自己的银行账户与另外一百万人共享同一套服务端程序,就认为这个账户不再属于自己。

当 Harness 真正成为 Framework

今天很多 Agent Harness 仍然带有非常明显的个人软件形态:下载、安装、配置密钥、启动运行时,然后拥有一个专属 Agent。这是 Personal Agent 非常自然的第一阶段。

但如果 Agent 最终真的像我们想象的那样,进入每个人的聊天软件、工作平台和企业系统,那么它迟早会面对 Bot Framework 曾经面对过的问题:一个系统究竟应该怎样同时承载海量彼此独立的主体?

到那个时候,Harness 可能就不再是一款“安装以后替我干活的软件”,它会越来越像真正意义上的基础设施。聊天软件只是传输管道,大模型是能力提供方,记忆与凭证属于 Agent 身份,而容器和沙盒只是需要发生副作用时临时申请的执行资源。Harness 本身则变成了承载和调度这些 Agent 的运行时框架。

最终,我们或许会重新定义所谓 Personal Agent:它的“一对一”,从来不应该由一台机器、一个进程或者一个容器来证明。真正应该一对一的,是身份、记忆、权限与意志。Harness 可以是一对多的,Agent 仍然可以永远只属于一个人。

如果这个边界能够真正被建立起来,那么从自托管 Agent 到平台托管 Agent 的跨越,可能就不再只是一次部署方式的变化,它会是 Agent 基础设施的一次真正成熟。

Logo

欢迎加入DeepSeek 技术社区。在这里,你可以找到志同道合的朋友,共同探索AI技术的奥秘。

更多推荐