☰
Harness Marketplace 剖析系列 - 之 DeepSeek Harness:Everything is a Plugin,重新理解 Agent Runtime 与 TaoToken 统
2026/10/3 6:37:36 网站建设 项目流程

1. 从 DeepSeek Harness 的插件化设计说起:Agent Runtime 为什么需要重新理解

DeepSeek Harness(简称 dsh)是 DeepSeek 官方开源的 Agent Harness,目前处于 Developer Preview 阶段,底层由 Cordis 驱动。它最核心的设计理念只有一句话:Everything is a Plugin。这句话听起来像口号,但落到架构上,它意味着 Model Adapter、Tool Registry、Session Log、Agent Loop 这些传统 Harness 里被视为“内核”的组件,全部都是 Plugin,都可以通过配置替换。

如果你之前用过 Claude Code 或 Codex,你脑子里可能已经有一套稳定的 Harness 认知模型:User Goal 进入 Harness,Harness 产生 Instruction,Instruction 驱动 Skill / Agent / Tool,再经过 Policy 和 Sandbox,最终执行。在这套模型里,通常存在一个相对稳定的 Harness Core,然后围绕 Core 挂载 Skill、Plugin、MCP、Hook、Custom Agent。扩展模型大致是 Core 先存在,Plugin 后加载。

DeepSeek Harness 走了一条明显不同的路线。官方架构文档明确把 Model Adapter、Tool Registry、Session Log、Agent Loop 都纳入 Plugin 体系,并说明运行中的 dsh 是启动阶段通过多层配置组合出来的一棵 Plugin Tree。也就是说,不是 Runtime 先存在再加载 Plugin,而是 Plugin 组合出 Runtime。这个区别看似微妙,但它直接决定了你如何理解 Agent Runtime 的构建方式、如何做能力替换、如何设计企业级 Agent 环境。

这篇文章面向的读者是:正在研究 Agent Harness 架构的工程师、需要为企业搭建可组合 Agent Runtime 的技术负责人、以及想理解 Cordis 和 Composable Runtime 设计思路的开发者。我会从静态目录结构入手,拆解 Plugin、Bundle、Profile 三层组合机制,给出可复制的 Runtime 配置片段和插件注册示例,最后通过 TaoToken 统一 Key/API 通道完成一次端到端调用验证。整个过程你可以跟着操作,不需要提前理解 Cordis 的全部细节。

2. TaoToken 前置准备:统一 Key 与 API 通道配置

在开始拆解 DeepSeek Harness 的 Runtime 配置之前,需要先解决一个实际问题:dsh 作为 Agent Harness,最终要调用 LLM。而 LLM 调用需要 API Key、Base URL 和 Model ID 三件套。如果你同时使用多个模型提供商,每个提供商一套 Key 和 Endpoint,配置会变得非常分散。TaoToken 在这里的角色是提供统一的 Key 和 API 通道,让你在 dsh 的 Model Adapter Plugin 里只需要配置一套凭据。

TaoToken 的 API 地址是 https://taotoken.net/api,官网是 https://taotoken.net/。你需要先在 TaoToken 控制台创建一个 API Key。创建完成后,你会得到一个以 sk- 开头的 Key。这个 Key 将用于 dsh 的 Model Adapter 配置。

在 dsh 的架构里,Model Adapter 本身就是一个 Plugin。官方 dsh-base Bundle 里包含了 Model Adapters 和 Default Model Selection。这意味着你不需要修改 dsh 的核心代码,只需要在 Profile 的 cordis.patch.yml 里覆盖或追加 Model Adapter 的配置即可。这正是 Everything is a Plugin 带来的实际好处:换模型提供商不需要动 Runtime 内核,只需要改一层 Patch。

具体来说,你需要在 dsh 的配置中设置三个值:Base URL 指向 https://taotoken.net/api,API Key 使用你在 TaoToken 控制台创建的 Key,Model ID 填写你要调用的模型标识。这三个值会通过 Model Adapter Plugin 注入到 ctx.llm 这个 Service 中,后续 Agent Loop 在 agent/request 阶段会通过 ctx.llm 发起请求。

如果你还没有 TaoToken 的 Key,可以先到控制台的 API Keys 页面创建一个。创建时建议给 Key 起一个可识别的名字,比如 dsh-dev,方便后续在多个 Harness 之间区分。Key 创建后只显示一次,记得保存到安全的地方。接下来我们会把这个 Key 写进 dsh 的配置片段里。

3. 可复制配置:dsh 的 Profile、Bundle 与 Model Adapter 设置

dsh 的 Runtime 组合由 Profile、Bundle 和 Patch 三层决定。Profile 是一个命名组合,记录要堆叠哪些 Bundles、安装哪些额外 Plugin、以及用户自己的 cordis.patch.yml。官方目前提供 web 和 headless 两个模板。Bundle 是一个 npm package,通过 package.json 中的 dsh.bundle 字段指向一个 cordis.patch.yml,成为 Profile 可以加载的一层 Patch。官方当前有三个关键 Bundle:base、web-app、headless。

启动时的层叠顺序是:Empty Entry List → Profile 中声明的 Bundles → Profile cordis.patch.yml → Home cordis.patch.yml → --patch CLI Overlay。最终得到的 Effective Plugin Tree 是所有这些层叠加的结果。你可以用 dsh --profile web --dump-config 查看当前环境真正会启动的组合树。

下面是一个可复制的 cordis.patch.yml 片段,用于配置 Model Adapter 指向 TaoToken 的统一通道。这个文件可以放在你的 Harness Home 目录下,也可以作为 Profile 的 patch 层:

# cordis.patch.yml # 配置 Model Adapter Plugin 使用 TaoToken 统一 API 通道 plugins: '@deepseek-ai/dsh-llm-openai': baseURL: 'https://taotoken.net/api' apiKey: '${TAOTOKEN_API_KEY}' defaultModel: 'deepseek-chat' models: - id: 'deepseek-chat' name: 'DeepSeek Chat' contextWindow: 65536 - id: 'deepseek-reasoner' name: 'DeepSeek Reasoner' contextWindow: 65536

这里有几个关键点。第一,baseURL 指向 https://taotoken.net/api,这是 TaoToken 的 API 入口。第二,apiKey 使用环境变量 ${TAOTOKEN_API_KEY},避免把 Key 硬编码在配置文件里。你需要在启动 dsh 之前设置这个环境变量:

export TAOTOKEN_API_KEY="sk-your-tao-token-key"

第三,defaultModel 设置为 deepseek-chat,这是 dsh 默认使用的模型。如果你需要更强的推理能力,可以切换为 deepseek-reasoner。Model Adapter Plugin 会把这两个模型注册到 ctx.llm 这个 Service 中,Agent Loop 在 agent/request 阶段会根据当前配置选择合适的模型。

如果你使用 headless Profile,配置结构类似,但 Bundle Stack 不同。headless Profile 大致是 dsh-base + dsh-headless + user patch。你可以在 headless 的 cordis.patch.yml 里做同样的 Model Adapter 覆盖。区别在于 headless 没有 Web Host 层,适合一次性任务运行。

另外,如果你需要同时配置多个 Model Adapter,可以在 plugins 下追加多个条目。Cordis 的 Context 会管理这些 Service 的注册和发现。当多个 Plugin 提供同一个 Service 时,后加载的会覆盖先加载的,这就是 Patch 层叠机制的作用。

4. 插件注册示例与端到端调用验证

理解了配置之后,我们来看一个实际的插件注册示例。dsh 的 Plugin 通过 Cordis Context 提供 Service、监听 Event、创建 Effect。下面是一个简化的 Plugin 注册示例,展示如何向 Runtime 注册一个自定义 Tool:

// my-tool-plugin.ts import { Context, Plugin } from '@cordisjs/core'; export const name = 'my-tool-plugin'; export const inject = ['tools']; export function apply(ctx: Context) { // 向 ctx.tools 注册一个自定义 Tool ctx.tools.register({ name: 'echo', description: 'Echo back the input text', parameters: { type: 'object', properties: { text: { type: 'string', description: 'Text to echo' } }, required: ['text'] }, async execute(args: { text: string }) { return { content: `Echo: ${args.text}` }; } }); // 监听 tool/call 事件,在 Tool 执行前介入 ctx.on('tools/pre-execute', async (event) => { console.log(`[my-tool-plugin] Tool called: ${event.toolName}`); }); }

这个 Plugin 做了两件事:第一,通过 ctx.tools.register 向 Tool Registry 注册了一个名为 echo 的 Tool;第二,通过 ctx.on 监听了 tools/pre-execute 事件,在 Tool 执行前打印日志。这就是 Cordis 的 Service + Event 机制:Plugin 不需要修改 Agent Loop 的核心代码,只需要向共享 Context 注册能力或监听事件。

注册完成后,你需要把这个 Plugin 加入 Profile 的配置中。可以在 cordis.patch.yml 里追加:

plugins: './my-tool-plugin.ts': enabled: true

现在来做端到端调用验证。启动 dsh web:

npx @deepseek-ai/dsh web

默认监听 http://127.0.0.1:3080。打开浏览器访问这个地址,你会看到 dsh 的 Web UI。在对话框里输入一段话,比如“请用 echo 工具回显 hello”,然后发送。Agent Loop 会经历以下链路:turn/start → claim input → assemble prompt + tools → agent/pre-step → step/start → derive model history → agent/request → llm/stream → assistant/message → tool/call → tools/pre-execute → tools/execute → tools/post-execute → tool/result → step/end → turn/end。

如果一切正常,你会看到模型返回了 echo 工具的执行结果。同时,终端里会打印出 [my-tool-plugin] Tool called: echo 这行日志,说明你的 Plugin 成功介入了 Runtime。整个过程中,LLM 请求是通过 TaoToken 的 https://taotoken.net/api 通道发出的,Model Adapter Plugin 从环境变量读取了 API Key,ctx.llm 在 agent/request 阶段完成了模型调用。

如果你想验证模型切换,可以把 cordis.patch.yml 里的 defaultModel 改为 deepseek-reasoner,重启 dsh,再次发送请求。你会看到 Agent Loop 使用了不同的模型,但整个 Runtime 结构没有变化。这就是 Composable Runtime 的实际效果:换模型不需要改 Runtime,只需要改一层 Patch。

5. 常见报错排查:401、local proxy failed、reading choices、OAuth

在配置 dsh 和 TaoToken 的过程中,你可能会遇到几类典型报错。下面逐一排查。

第一类:401 Unauthorized。这通常意味着 API Key 没有正确传入。检查步骤:确认环境变量 TAOTOKEN_API_KEY 已经设置,可以用 echo $TAOTOKEN_API_KEY 查看;确认 cordis.patch.yml 里的 apiKey 字段引用了正确的环境变量名;确认 Key 没有过期或被撤销。如果使用 dsh --dump-config 查看配置,检查 Model Adapter 的 apiKey 字段是否被正确解析。注意不要在配置文件里直接写 Key 明文,也不要把 Key 提交到 Git 仓库。

第二类:local proxy failed。这个报错通常出现在网络请求层。dsh 的 Model Adapter 会向 baseURL 发起 HTTPS 请求。如果 baseURL 配置错误,比如漏了 https:// 或者写成了 http://,就会导致连接失败。确认 baseURL 是 https://taotoken.net/api,不要添加多余的路径后缀。另外检查本地网络环境是否能正常访问该地址。如果你在企业内网,可能需要确认出口策略。

第三类:reading choices 相关报错。这个报错通常意味着 API 返回的响应结构不符合预期。可能的原因包括:Model ID 填写错误,导致服务端返回了错误格式的响应;或者请求参数不完整。检查 cordis.patch.yml 里的 defaultModel 是否与 TaoToken 支持的模型标识一致。你可以先通过模型对话页面单独验证模型是否可用,确认 Key 和 Model ID 正确后,再回到 dsh 配置。

第四类:OAuth 相关报错。dsh 的某些 Plugin 可能涉及 OAuth 流程,比如 GitHub 集成或第三方服务授权。如果你在配置过程中看到 OAuth 报错,检查对应的 Plugin 配置是否完整。对于 Model Adapter 来说,通常不需要 OAuth,只需要 API Key。如果你使用了需要 OAuth 的 Plugin,确认回调地址和 Client ID 配置正确。

排查时的一个实用技巧是:先用最小配置启动 dsh,只保留 dsh-base 和 Model Adapter,确认 LLM 调用通路正常后,再逐步追加其他 Plugin。这样可以快速定位是哪个 Plugin 或哪层配置引入了问题。另外,dsh --dump-config 输出的 Effective Plugin Tree 是排查配置层叠问题的关键工具,建议在每次修改配置后都运行一次,确认最终生效的 Plugin 列表和参数值。

6. 从 Plugin System 到 Composable Runtime:下一步怎么走

到这里,你已经完成了 DeepSeek Harness 的 Runtime 配置、Plugin 注册和端到端调用验证。回过头看,dsh 和传统 Harness 最大的区别在于:传统 Harness 问的是“Harness 有哪些 Extension Point”,而 dsh 进一步问“Harness 本身能不能就是一种 Composition”。Model Adapter、Tool Registry、Session Log、Agent Loop 都是 Plugin,都可以通过 Profile + Bundle + Patch 三层机制替换和组合。

这种设计带来的实际好处是:你可以为不同的 Agent 场景组合不同的 Runtime。比如 Developer Agent 可以组合 Filesystem Write、Shell、LSP、Git、Skill、Subagent;Reviewer Agent 可以组合 Filesystem Read、Search、LSP,但不给 Shell Write 和 Network;Production Agent 可以使用 Remote Sandbox、Strict Permission、Audited Tool Gateway。这已经不是简单的 Tool Permission 问题,而是 Runtime Composition 问题。

如果你要继续深入,下一步可以研究 Cordis 的 Context、Service、Effect、Event、Inject、Isolate 和 Plugin Lifecycle 机制,理解一个 Plugin 是如何进入 Cordis 的、Service 是如何注册和发现的、Plugin 为什么能够卸载、Event 为什么能够改写 Runtime。这些问题的答案,才是 Everything is a Plugin 真正被拆开的地方。

在实际操作层面,建议你先把 TaoToken 的 Key 配置好,确保 Model Adapter 通路稳定。然后尝试写一个最简单的自定义 Plugin,注册一个 Tool 或监听一个 Event,观察它如何介入 Agent Loop。最后,尝试用不同的 Profile 组合不同的 Bundle,感受 Runtime Composition 的实际效果。如果你需要长期运行编码 Agent 或构建复杂的 Agent 工作流,可以考虑使用 Coding Plan 来获得更稳定的调用额度。验证模型可用性可以直接在模型对话页面操作,接入文档里有完整的 Base URL、Key 和 Model ID 配置说明。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询