这两天写 DeepSeek Harness 插件时,我发现DSH 给了开发者极大的扩展权限。过去给 Codex 一类通用 Agent 安装 Skill,主要是在既有宿主里增加操作方法。DeepSeek Harness 把宿主本身也变成了扩展面。

扩展方式改变的东西
Skill教模型怎样完成一类任务
Tool / MCP让模型接触哪些外部系统
Harness Plugin扩展应用的运行方式与呈现

同一个运行时可以被组合成编程台、数据库分析台、投研终端、保险工作台或设计画布。插件把二次开发推进到界面和业务流程,是否成为产品仍取决于数据、权限、验证与运维。

安装 Node.js 后,可以启动本地 Web UI:

npx @deepseek-ai/dsh web

浏览器打开 http://127.0.0.1:3080,在 Settings → Models 中配置模型,在 Choose workspace 中选择工作目录,随后就能把任务交给它。界面看起来和其他编程 Agent 没有太大差别。

另一条命令会直接打印它的装配结果:

npx @deepseek-ai/dsh --profile web --dump-config

它打印的不是一份普通应用配置,而是一棵插件树。模型适配器、系统提示词、工具注册表、会话日志、审批、沙箱、上下文压缩、子 Agent,连默认的 Agent Loop 都只是树上的插件。DeepSeek Harness 没有把这些能力硬编码进同一个 Agent Loop;Cordis 的上下文与加载器承担最小装配内核。

AI 工作台维护的不只是一段 Agent Loop

最小的 Agent Loop 并不复杂:模型读取消息,决定是否调用工具,把工具结果放回上下文,再请求模型。几十行代码就能写出来。

但是会话需要恢复,流式输出需要重放,工具要审批,命令要进入沙箱,模型上下文会溢出,用户会在执行中追加指令,子 Agent 还要继承一部分能力、隔离另一部分能力。此时系统维护的已经不是一段循环,而是一次任务的完整生命周期。

层次负责的事情
模型层模型路由、流式响应、重试、上下文窗口
执行层Turn、Step、工具调度、取消、继续
能力层文件系统、终端、搜索、MCP、子 Agent
控制层审批、权限、沙箱、预算、超时、策略
状态层会话日志、持久化、重放、分叉、压缩
产品层Web UI、命令行、SDK、遥测、配置

相比层出不穷的 Agent 框架,不变的 Agent Protocol 是什么 讨论的是外部世界如何通过 Thread / Run / Step / Event / Artifact / Checkpoint 理解一次任务。Harness 位于协议之后,负责真的把模型、工具、状态和权限装配起来。

从 Profile 到 Agent Scope

DeepSeek Harness 启动的不是一个固定应用,而是一个 Profile。web 与 headless 都是预置 Profile:前者加上浏览器应用,后者执行一次任务、打印结果后退出。

Profile 由多层 Bundle 和补丁叠加而成。dsh-base 先挂载模型、工具、持久化、策略、凭据和遥测;上层 Bundle 再加入 Web UI 或一次性运行器。用户可以在 Profile、Harness Home 或本次启动的 --patch 中替换配置行。

flowchart TB
    command["dsh --profile web"] --> bundles["有序 Bundle 层<br/>dsh-base → dsh-web-app"]
    bundles --> profile["Profile cordis.patch.yml"]
    profile --> home["Home cordis.patch.yml"]
    home --> overlay["本次 --patch overlay"]
    overlay --> loader["Cordis Loader<br/>协调挂载、卸载与配置变更"]

    loader --> root["Root Context"]

    subgraph host["Host 级 Service"]
        sessions["ctx.sessions<br/>SessionEvent 日志"]
        tools["ctx.tools<br/>工具注册与执行管线"]
        prompt["ctx.systemPrompt<br/>Prompt 与工具 Schema"]
        llm["ctx.llm<br/>模型适配器"]
        agents["ctx.agents / ctx.agentLoop"]
        policy["Sandbox / Approval / Telemetry"]
    end

    root --> sessions
    root --> tools
    root --> prompt
    root --> llm
    root --> agents
    root --> policy

    root --> scopeA["Agent Scope A"]
    root --> scopeB["Agent Scope B"]
    scopeA --> presetA["本会话的工具、模型、策略与子 Agent"]
    scopeB --> presetB["另一组隔离后的能力"]

Profile 解决“这次启动要装什么”,Scope 解决“这个 Agent 能看见什么”。同一个服务键可以在不同作用域中解析成不同实现。一个会话可以使用本地文件系统和 DeepSeek 模型,另一个会话可以使用远程沙箱和其他模型,而消费方仍然依赖相同的 ctx.fs 与 ctx.llm 契约。

Cordis 提供的不是普通依赖注入

把 ctx.llm 看成一个可替换接口,只解释了 Cordis 的一半。

普通依赖注入通常在应用启动时选择实现:

const llm: LLM = new DeepSeekLLM()

Cordis 关注的是运行中的依赖拓扑。插件通过 Service 发布能力,通过 inject 声明依赖。所需 Provider 出现后,Consumer 才能激活;依赖被撤回或换了身份,运行时重新协调相关组件。调用方依赖 ctx.<key>,不直接导入具体实现。

这个机制对应论文《A Programming Paradigm for Spatiotemporal Composability》中的空间可组合性。组件不再各自轮询依赖是否存在,依赖变化由统一上下文协调。

时间可组合性由可逆 Effect 支撑。插件注册一个工具、事件监听器或 Prompt Section 时,同时把清理动作交给运行时。插件卸载后,Cordis 按生命周期撤销这些注册,让受管上下文恢复到安装前的状态。

ctx.effect(() => {
  const resource = installSomething()
  return () => resource.dispose()
})

它比只约定 activate() / deactivate() 的生命周期更进一步:副作用登记、所有权和回收动作被绑定在同一处。

⚠️ “可逆”肯定有限制。已经发送的邮件、已经成交的订单、没有备份的文件删除,都不会因为插件卸载自动消失。Cordis 能回收的是进入其追踪范围、并且提供逆操作的 Effect。外部副作用仍需要幂等键、事务、补偿动作和人工审批。

Service、Event 与 Effect 各自做什么

DeepSeek Harness 没有让所有插件通过异步事件互相喊话。三个机制承担不同职责:

机制适合的事情例子
Service直接调用一项能力ctx.llm.stream()、ctx.tools.execute()
Event观察、改写或拦截生命周期节点请求路由、审批、工具前后处理
Effect记录安装产生的副作用及其回收动作注册工具、监听器、适配器

Agent Loop 的关键路径主要使用四种调度语义:

模式调度方式适用位置
emit同步通知,不等待返回的 Promise状态广播、观测
parallel并发执行,等待全部完成相互独立的异步观察者
serial按注册顺序等待,可提前给出结果终止检查、顺序决策
waterfall洋葱式调用,监听器通过 next() 委托下游请求改写、审批、策略、适配器

waterfall 让插件拥有明确的控制权。只想记录指标的监听器应调用 next();审批插件可以不调用 next(),直接拒绝操作;路由插件可以先改写请求,再等待下游结果。

异步插件没有打乱 Agent Loop。同一个 Agent 的控制流仍然按 Turn 和 Step 串行推进。会影响下一阶段的 waterfall 与 serial 会被 Driver 等待;纯观测的 emit 不允许承担关键业务决策。异步只是等待模型、网络、磁盘和工具时不阻塞线程,不等于所有插件同时修改状态。

Turn、Step 与 SessionEvent

Turn 从 turn/start 打开,到系统不再欠下一次请求时以 turn/end 关闭;它可以包含零个或多个 Step。每个 Step 对应一次模型请求,以及该响应触发的工具调用。

模型没有要求工具时,当前 Turn 可以结束。模型返回工具调用时,Harness 执行工具、记录结果,再进入下一个 Step。用户在执行中追加的信息会进入统一 Inbox,根据 followup、steer 或 inject 的语义,在下一 Turn 或下一 Step 被领取。

flowchart TD
    input["用户输入进入 Inbox"] --> turnStart["记录 turn/start"]
    turnStart --> claim["领取 next-turn / next-step 消息"]
    claim --> pre["agent/pre-step waterfall<br/>注入、压缩、拒绝或改写"]
    pre -->|reject| turnEnd["记录 turn/end"]
    pre -->|enter messages| stepStart["记录 step/start 与 user/message"]
    stepStart --> assemble["组装 Prompt Section 与工具 Schema"]
    assemble --> request["agent/request → llm/stream"]
    request --> chunks["记录 assistant/chunk 与 assistant/message"]
    chunks --> hasTool{"模型是否调用工具"}
    hasTool -->|否| stopping["agent/turn-stopping"]
    hasTool -->|是| toolPipe["pre-execute → execute → post-execute"]
    toolPipe --> result["按模型调用顺序记录 tool/result"]
    result --> next{"工具或 Inbox 是否要求继续"}
    next -->|是| claim
    next -->|否| stopping
    stopping --> turnEnd

这条流程中,turn/*、step/*、user/message、assistant/*、tool/* 是写入 SessionEvent 日志的持久事实;agent/* 与 tools/* 多数是运行中的控制点。

两类事件不能混用。界面如果需要断线重放聊天内容,应消费 session/event;插件如果要在本次请求发出前修改模型参数,应监听 agent/request。前者回答“发生过什么”,后者回答“现在是否允许继续以及怎样继续”。

模型可见的信息必须已经进入日志。下一次请求不是从若干插件的临时内存拼凑历史,而是通过 deriveMessages() 从 SessionEvent 投影出来。恢复、分叉、转录和 UI 重放因此共享同一份事实源。

一次请求的时序

sequenceDiagram
    autonumber
    participant U as User
    participant UI as UI / SDK
    participant A as Agent Inbox
    participant D as Agent Loop Driver
    participant H as Cordis Hooks
    participant S as Session Log
    participant P as System Prompt
    participant L as LLM Service
    participant T as Tool Service

    U->>UI: submit(message)
    UI->>A: followup(message)
    A->>D: 唤醒当前 Agent
    D->>S: append turn/start
    D->>A: claim messages
    D->>H: await agent/pre-step waterfall

    alt 插件拒绝本次 Step
        H-->>D: reject
        D->>S: append turn/end(blocked, 0 Step)
    else 进入 Step
        H-->>D: enter(messages)
        D->>S: append step/start + user/message
        D->>P: assemble sections + tool schemas
        P-->>D: prompt assembly
        D->>H: await agent/request waterfall
        H-->>D: model route + request config
        D->>L: stream(request)
        loop 每个 StreamChunk
            L-->>D: assistant chunk
            D->>S: append assistant/chunk
            S-->>UI: session/event
        end
        D->>S: append assistant/message

        opt 模型返回 Tool Calls
            D->>T: classify barriers + rolling pool
            D->>S: 按模型顺序 append tool/call
            D->>T: ordered pre-execute / approval / guards
            par 有界并发执行
                T->>T: execute tool A
            and
                T->>T: execute tool B
            end
            T->>T: ordered post-execute / normalize
            T-->>D: authoritative results
            D->>S: 按模型顺序 append tool/result
        end

        D->>S: append step/end
        alt 工具或 Inbox 要求下一次请求
            D->>A: claim next-step messages
            D->>D: 回到下一个 Step 边界
        else 自然停止且 next-step Inbox 为空
            D->>H: await agent/turn-stopping
            D->>S: append turn/end
        end
    end

工具调度把执行顺序与提交顺序拆开。多个标记为 parallel 的工具可以进入有界并发池,真正的工具体允许重叠执行;执行前策略保持顺序,执行后结果仍按模型给出的调用顺序提交。遇到 exclusive 工具就形成屏障。

这让系统同时保留吞吐量和确定性。天气查询与数据库读取可以并发,后一个工具即使先返回,也不会抢先改变模型看到的结果次序。策略插件在前一个结果落盘后改变注册表时,尚未启动的工具还会重新分类。

工具管线为什么做得这么长

工具执行不是 tool(args) 一次函数调用。DeepSeek Harness 把它拆成:

tool/call 写日志
  → tools/pre-execute
  → approval
  → monotonic guards
  → tools/execute
  → tool body
  → tools/post-execute
  → result normalization
  → tools/result
  → tool/result 写日志

审批、沙箱、文件写入保护、超时、重试、指标和结果改写都能接入同一条管线,而工具本身不需要导入某个具体策略服务。

这套设计的优势

能力替换发生在 Runtime 内部

换一个 LLM Provider、文件系统、沙箱或子 Agent Provider,消费方不需要跟着分叉。文件系统与子进程 Provider 共享同一个执行世界;将这组实现协调替换为远程沙箱后,文件工具、终端与语言服务才能一起迁移。

普通接口也能替换实现,但 Cordis 还知道依赖何时满足、插件作用于哪个 Scope、安装时产生了哪些 Effect。这才构成运行时热插拔。

控制面不用侵入 Agent Loop

审批、压缩、请求路由、工具策略和遥测都挂在稳定事件边界。默认 Driver 仍然保持一条容易审计的主线,不必为每项横切能力增加条件分支。

状态事实与实时控制分开

SessionEvent 保存可回放事实,agent/* 保存活跃对象上的控制动作。断线重连不会要求复活旧的监听器,插件也不必把临时决策伪装成历史事实。

产品形态只是不同 Profile

Web UI、一次性 headless 运行器和未来其他入口可以复用同一个能力图。差异被表达成 Bundle 与补丁层,而不是复制一套应用再慢慢漂移。

给实验和演化留下可回收边界

Agent-Native 中的 Production Plane 希望 Agent 能观察、诊断、修改并验证产品能力。Cordis 为这件事提供了比“改完代码重启整个进程”更细的实验单元:挂载组件、限定 Scope、观察结果、卸载并回收受管副作用。

它提供的是可审计的变更容器,不是自修改正确性的证明。模型生成的插件仍然要经过测试、权限检查、资源预算和发布策略。

代价也写在架构里

调用链变得间接

看到 ctx.tools.execute() 并不能立刻知道最后由谁处理。Profile、Bundle、Scope、Service Provider 和 waterfall 都可能影响结果。排障必须先打印真实装配树,再沿事件生产者、消费者和作用域追踪。

插件顺序成为公共语义

两个都能改写请求的 waterfall 插件,顺序不同就可能产生不同结果。监听器忘记调用 next() 会意外截断下游;把关键逻辑放进 emit,主流程又不会等待它完成。类型系统只能检查事件签名,不能证明插件组合的业务语义正确。

可逆 Effect 有明确边界

进程内注册容易回收,远程系统的不可逆动作很难。数据库迁移、外部消息、支付、云资源创建仍然需要传统事务和补偿机制。Cordis 不能替代部署系统,也不能替代分布式工作流引擎。

热插拔必须尊重执行边界

已经开始的模型流或工具调用不能随意换掉半边实现。合理的切换点通常是下一次请求、下一个 Step 或新会话。进行中的调用要持有稳定的 Provider 引用,并通过 AbortSignal、超时与清理协议结束。

生态和稳定性尚未成熟

“一切皆插件”只有在插件契约、诊断工具、版本策略和第三方生态成熟后才会产生复利。当前版本仍快速变化,配置和扩展点的学习成本不应低估。

适合与不适合的场景

适合

  • 同一产品要支持多种模型、工具、沙箱、存储和权限组合;
  • 桌面或本地 Agent Host 要按工作区、用户或会话隔离能力;
  • 团队准备建设第三方插件生态,希望能力可以独立安装与卸载;
  • 安全策略、审批、遥测和上下文压缩需要跨越大量工具统一生效;
  • 正在研究 Agent 自修改,但希望每次实验都有作用域和回收边界。

不适合

  • 只有一个模型和几个固定工具的聊天应用;
  • 控制流长期稳定、分支明确,状态图比运行时插件树更容易审计;
  • 组织没有插件版本治理,却准备让大量第三方代码进入主进程;
  • 需求首先是跨机器的持久队列、租约、灾难恢复与 exactly-once 语义;
  • 强监管系统要求每次能力变化都绑定不可变制品、审批单和完整验证记录。

最后两类场景不是绝对不能使用 DeepSeek Harness,而是 Cordis 只解决进程内组合。外部仍要部署、数据库、队列、审计和供应链安全承接。

插件生态正在把 Harness 变成工作台

官方已经把通用底座拆成几十组插件包。模型、文件系统、终端、沙箱、Skill、压缩、子 Agent、会话、凭据、存储、计划、工作流和 Web UI 都有独立的能力接缝。社区可以复用既有日志和循环,在公开的 Service、Event 与界面扩展点上增加实现,再用 Bundle 组合成可安装的 Profile。官方 Packages 清单 展示了这条 API 脊柱。

生态先争夺界面和工具

截至 2026 年 8 月 22 日,独立社区目录 DSH Directory 页面列出 651 条通过静态 Bundle 合约识别的插件记录。它的分类快照很偏科:

主要分类数量占比社区正在补什么
Tools26240.2%浏览器、视觉、外部 API、数据库、通知和编辑器能力
User Interface24137.0%侧边栏、TUI、主题、可视化、成本面板和插件市场
Sessions446.8%回退、分支、导入、分享和跨实例协作
Scheduling375.7%多 Agent、工作流、任务板、定时与后台执行
Storage264.0%长期记忆、知识库、检索和上下文观测
Skills223.4%可复用的知识和方法包
Models & Providers192.9%模型接入、路由、订阅复用和降级
Sandboxes / Agent Loops00%尚未形成可见的第三方供给

Tools 与 User Interface 合计约占 77%。目录中没有条目落入 Sandboxes / Agent Loops 主分类;当前可见供给首先集中在用户能看见的入口和 Agent 能接触的对象。

基础通用插件先把宿主做完整

现有项目主要补齐任何领域都会使用的工作台能力:

横向能力代表方向对工作台的改变
操作界面dsh-better-sidebar、dsh-tui、dsh-at-file文件、终端、Git、子 Agent 和上下文选择进入同一屏幕
多模态与检索ModLens、dsh-vision-router、modsearch给纯文本模型补充视觉、OCR、定位、搜索和引用
模型接入Codex、ChatGPT OAuth、Claude CLI、NewAPI Provider模型成为同一工作台中的可替换资源
Session 与恢复Turn Rewind、Chat Import、Message Edit对话可以回退、分支、迁移和继续执行
Memory 与 Contextdsh-context、dsh-memento、dsh-mnemon查看上下文组成,跨会话保存经过约束的长期记忆
协作与治理Agent Teams、Taskboard、Auto Review、Plannotator长任务可以分工、排队、复核和接受结构化反馈
分发与运维插件市场、插件管理器、成本面板、通知器用户不用手改 cordis.patch.yml,开发者开始经营组合与升级

模型接入插件增长得很快,但它们很难成为长期壁垒。

垂直插件已经露出产品轮廓

少数项目已经越过“增加一个工具”,开始同时定义领域对象、专属界面、工作流和校验规则。

领域已出现的项目已经进入的产品层
数据分析dsh-data-agent专用 Preset、数据库连接界面、SQL 工具、只读保护与分析流程
Exceldsh-excel-chat单元格、公式、样式、表格和图表操作,编辑后自动检查公式健康度
金融与会计dsh-finance日记账、对账、报表、差异分析、月结、SOX 测试与人工审批边界
股票与量化dsh-us-stocks、dsh-quant行情、财务数据、因子、回测、风险和图表渲染
设计Superdesign、OpenPencil、GenUI读取设计系统、生成分支方案、画布预览和交互式产物
HarmonyOS 开发Harmony NEXT离线 API 库、DevEco / HDC、模拟器自动化、Trace 审计和测试工程

dsh-data-agent 很接近一款真正的垂直工作台。它不把全部编程工具塞给模型,而是用专用 Preset 保留文件工具和 sqlcmd,再把数据库连接、只读策略和结果呈现放进会话界面。

金融插件也暴露了垂直产品与通用工具的差别。计算收益率只是函数;生成日记账、核对借贷平衡、准备审计底稿,并把“生成建议”与“正式过账和签字”隔开,才是会计工作流。领域中的名词、审批权和失败代价都进入了插件设计。

单个股票行情插件还不是投研产品。把实时数据、组合记忆、研究流程、风险计算、图表、引用和人工复核装进同一个 Profile,打开页面时直接看到自选股、研究任务和证据,才开始接近一款投研产品。

从插件到产品还有几层

我把当前生态粗略分成五级:

阶段交付物用户买到什么
L0主题、皮肤、状态标签更顺眼或更有趣的宿主
L1单一工具、API、模型 Provider一项新增能力
L2Skill + Tool + Prompt一组领域方法和动作
L3领域 UI、数据对象、工作流、校验可以完成具体工作的业务台
L4身份、权限、审计、部署、计费、组织协作可以采购和运营的软件产品

从目录的主要分类和公开说明看,可见供给仍集中在 L0 到 L2。Data Agent、Excel 和 Finance 已经碰到 L3;能带着版本承诺、数据治理和组织权限进入生产环境的 L4 产品仍然稀少。

开发者真正要交付的,也不会是一条安装命令:

垂直 AI 工作台
  = 通用 Harness
  + 领域数据连接器
  + 领域工具与知识
  + 业务状态机
  + 专属交互界面
  + 审批、校验与审计
  + 可安装、可升级的 Profile / Bundle

插件只是模块边界,Profile 才接近产品边界。用户不会自己研究二十个包的加载顺序;开发者需要替他选好组合、固定版本、配置默认策略,并为失败和升级负责。

普通用户不需要写插件。开发者负责把一组能力做成可安装的 Bundle 和开箱即用的 Profile;保险顾问、会计、研究员或独立创作者打开应用时,看到的已经是自己的业务对象和工作方式。对开发者来说,下一步是把这组能力封装成用户可以直接打开的应用。

把 Web UI 封装成独立桌面应用

如果第一版只需要自有品牌、固定 Profile 和免环境配置的体验,不准备重做业务界面,可以先在官方 Web UI 外增加一个 Tauri 或 Electron 桌面壳。应用启动时拉起固定版本的 dsh web 子进程,等待本地服务就绪,再让 WebView 打开回环地址;退出时由桌面壳关闭整棵进程树。

flowchart LR
    user["用户启动独立桌面应用"] --> shell["自有品牌的 Tauri / Electron Shell"]
    shell --> supervisor["进程监管<br/>启动、健康检查、退出与崩溃恢复"]
    supervisor --> runtime["随包分发的 Node.js<br/>固定版本 dsh web"]
    shell --> webview["WebView<br/>加载 127.0.0.1 随机端口"]
    webview <--> runtime
    runtime --> profile["产品 Profile / Bundle<br/>模型、插件、主题与默认策略"]
    runtime --> data["应用专属数据目录<br/>会话、配置与工作区"]
    shell --> keychain["系统 Keychain<br/>模型凭据"]
    keychain --> bridge["宿主凭据桥<br/>不经过 WebView"]
    bridge --> runtime

这条路线复用了官方 Web UI、会话协议和插件兼容面。开发者交付的是自己的应用名、图标、安装包、默认 Profile、插件白名单和升级策略。用户双击一个应用,不需要先安装 Node.js、执行 npx,也不必理解 cordis.patch.yml。社区的 deepseek-harness-desktop 已经提供了这条路线的 Tauri 原型;官方的 GUI 分层说明 则把 dsh web 描述为 Host + Web Server + Web Frontend 的组合,并给出了桌面壳通过 IPC 复用客户端层的方向。

独立打包不等于复制仓库后换一个图标。第一个可交付版本至少要处理这些边界:

边界桌面产品需要补上的工作
运行时把 Node.js 与 DeepSeek Harness 固定到经过验证的版本,不依赖用户机器上的全局环境
本地服务只监听 127.0.0.1,使用系统分配的空闲端口,并用一次性访问令牌、严格的 Origin 校验或等价宿主认证限制调用方
进程生命周期启动后等待健康检查;窗口退出、应用升级或异常崩溃时清理全部子进程
数据使用应用自己的数据目录,不直接占用用户已有的 ~/.dsh;升级前迁移并保留回滚路径
凭据模型密钥进入系统 Keychain,由宿主凭据桥交给 Runtime,不写进安装包、Profile,也不返回前端页面
插件供应链默认只加载产品审核过并固定提交版本的插件,不让生产用户随意安装未经检查的 GitHub 源码包
分发完成 macOS 签名与公证、Windows 代码签名,并提供自动更新、第三方许可证清单与崩溃诊断

MIT License 允许修改、再分发和商业销售,但安装包必须保留版权与许可声明。代码许可也不会自动授予 DeepSeek 的商标和图标使用权。二次产品应使用自己的名称与视觉标识,并说明它基于 DeepSeek Harness 构建,避免让用户误以为是官方发行版。

桌面壳方案仍受官方 Web UI 与现有扩展点约束,版本升级还要持续验证壳、前端资源、插件和配置是否兼容。等领域产品真的需要保单工作区、审计底稿或多窗格设计画布,再把前端替换为自有界面,通过 Host API、SDK 或 JSON-RPC 接入同一个 Runtime。当前项目仍处于 developer preview,这些接口还不能被当作长期稳定的桌面嵌入协议。第一版先把安装、启动、升级和退出做稳,比过早维护一个完整 Fork 更划算。

插件生态下一步缺的是可信组合

插件市场已经不止一个,社区还在制作插件搜索器、管理面板、桌面启动器和按角色整理的插件包。生态开始从“谁写了更多插件”转向“谁能给出可信组合”。接下来首先缺的是兼容矩阵、签名、权限清单、静态扫描和托管运行。

在保险、会计和投研产品中,界面不会再按聊天记录组织。页面围绕保单、账套、标的、审批结论和任务进度展开,聊天框只是一种输入方式。

官方的插件发布文档已经暴露了供应链成本。从 GitHub 安装源码插件时,pnpm 的 prepare 可能在 Agent 沙箱之外执行;用户必须显式允许构建,官方建议只信任经过检查的来源,并把依赖固定到具体提交。Package and install a plugin 定义了分发格式,却没有替生态完成信任判断。

从当前生态回看 Agent Harness 的沿革

图中的实线表示问题范围扩展,虚线把项目放到它主要回答的架构问题旁边,不表示代码依赖或直接继承。

flowchart TB
    p1["问题 1:怎样让模型持续行动"]
    p2["问题 2:怎样编排协作与持久状态"]
    p3["问题 3:怎样交付可用的长任务 Harness"]
    p4["问题 4:怎样动态重组 Harness 自身"]
    p1 --> p2 --> p3 --> p4

    react["ReAct / 手写循环<br/>Reason → Action → Observation"] -.-> p1
    chat["AutoGen AgentChat<br/>Participant / Message / Team"] -.-> p2
    langgraph["LangGraph<br/>State / Node / Edge / Checkpoint"] -.-> p2
    sdk["OpenAI Agents SDK<br/>Agent / Tool / Handoff / Guardrail"] -.-> p3
    claude["Claude Agent SDK / Managed Agents<br/>Workspace / Sandbox / Permission / Session"] -.-> p3
    deep["Deep Agents<br/>Plan / Filesystem / Subagent / Memory"] -.-> p3
    dsh["DeepSeek Harness<br/>Profile / Service / Event / Effect / Scope"] -.-> p4

早期 ReAct 把 Reasoning → Action → Observation 固定成最小循环。框架首先解决的是“怎样让模型重复调用工具”。

AutoGen AgentChat 把协作单位变成参与者、消息和团队,多 Agent 对话成为编排方式。它的底层 autogen-core 进一步提供事件驱动模型,但产品抽象仍然围绕谁和谁对话。

LangGraph 把共享 State、Node、Edge 和 Checkpoint 放进图运行时,长任务的分支、循环、持久化、暂停和恢复更容易表达。它是一套低层编排 Runtime,并不替开发者决定完整的 Harness 应该带哪些工具与上下文策略。

OpenAI Agents SDK 选择更轻的代码优先路线。SDK 接管循环,提供工具、Handoff、Guardrail、状态和观测;应用仍拥有服务部署、工具实现、存储和审批决策。它适合希望保留普通代码结构、不想先建图的团队。

Claude Agent SDK 把成熟的编程 Agent Loop 暴露给应用,文件、命令、MCP、权限、Hook 和子 Agent 都围绕工作空间运行。后续的 Claude Managed Agents 又把 Agent、Environment、Session 和 Event 变成托管资源,进一步接管沙箱与长任务基础设施。

Deep Agents 则明确把自己称为构建在 LangGraph 之上的 Agent Harness。它把计划、文件系统、上下文压缩、记忆、权限和子 Agent 组合成有主见的默认体验。

DeepSeek Harness 再向下走了一层。它没有发明另一种推理循环,而是追问:当模型、工具、循环、会话、权限和界面都需要被替换时,运行时怎样保持可组合?它给出的答案是把 Harness 自身也变成 Cordis 组件图。

横向看它们的架构重心

项目主要控制容器一等对象主要解决的问题扩展的主要粒度
AutoGen AgentChat多 Agent 消息与团队Agent、Message、Team对话式协作与角色分工Agent 与消息处理器
LangGraph状态图运行时State、Node、Edge、Checkpoint可恢复的复杂控制流节点、边、子图
OpenAI Agents SDK代码优先的 RunnerAgent、Tool、Handoff、Guardrail轻量地接管循环和多 Agent 路由Agent、工具、生命周期回调
Claude Agent SDK / Managed Agents编程 Agent Loop 或托管 SessionWorkspace、Tool、Permission、Session、Event带沙箱的长任务与编程执行工具、Hook、子 Agent、环境
Deep AgentsLangGraph 上的预制 HarnessPlan、Filesystem、Subagent、Memory长任务的上下文管理与委派Middleware、Backend、Skill
DeepSeek HarnessCordis 插件树中的默认 DriverProfile、Service、Event、Effect、Scope、SessionEvent运行时能力的细粒度替换与组合几乎所有 Harness 组件

这些选择没有统一终点。业务流程清晰时,图比插件树容易推理;只想快速接管循环时,代码优先的 SDK 更轻;要交付一个可配置的本地 Agent Host,DeepSeek Harness 的装配方式更有吸引力。

会调用工具的 Agent 已不稀缺。DeepSeek Harness 把二次开发边界从模型和 Prompt 推到了界面、业务对象、权限与工作流。

相关内容