ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

DeepSeek Harness 上手:把 Agent 拆成插件来拼,TaoToken 统一 Key 接入实践

DeepSeek Harness 上手:把 Agent 拆成插件来拼,TaoToken 统一 Key 接入实践 1. 为什么要把 Agent 拆成插件来拼做 Agent 工程迟早会遇到一个绕不开的问题模型可以换工具可以加但 Agent 的“工作方式”通常改不了。你能选择它用哪个模型却不能完全决定它什么时候调用模型、如何调用工具、失败后怎么恢复以及什么时候判断任务完成。Cursor、Claude Code 这类产品用起来很顺手它们更像一个完整产品普通用户不需要关心底层细节但对想自己研究 Agent 架构、调整执行流程的工程师来说真正的核心逻辑仍然藏在产品内部。DeepSeek Harness简称 DSH选择了另一条路。它的核心主张是一切皆插件。模型、工具、Agent Loop、UI、存储、沙箱每一层都能拔下来换。这句话听起来像是“支持插件”但 DSH 想表达的其实更彻底不仅外围功能是插件连通常被当作核心的 Agent Loop也可以作为插件被替换。DSH 是一个 AI Agent 运行时不是聊天 AppMIT 开源当前是 v0.1 开发者预览本机包版本为 0.1.0-rc.6入口命令是dsh用dsh web启动浏览器 UI内核基于 Cordis 插件元框架。“支持插件”本身并不稀奇。Claude Code 支持 MCPVSCode 也支持插件它们都可以在原有系统上扩展功能。DSH 里的“皆”指的是另一件事它自己也是用插件拼出来的没有一个不能替换的特权核心。接入模型是插件执行命令是插件读写文件是插件网页界面是插件Agent 主循环也是插件。官方提供的插件和第三方开发者写的插件遵循的是同一套装配方式只是官方的那批插件会在默认配置中被加载。可以把它理解成两种设备Claude Code 更像一台装配好的 iPhone很好用但 CPU、系统和主要零件都不是用户可以随便替换的DSH 更像一台自己装的电脑模型、工具、存储、执行环境都有插槽想换哪一块就换哪一块。当然自己装机的代价是门槛更高你需要理解插件、依赖和配置而不是装好就直接用。这篇内容面向的是想用统一 Key/API 通道管理多模型调用的开发者。我会先讲清楚 DSH 的三个核心概念再给出插件目录结构、Agent Loop 配置片段最后把 endpoint 改到 TaoToken 做一次本地验证。如果你正在做多模型 Agent又不想每个 provider 都维护一套 Key 和计费这套思路可以直接搬。2. DSH 的三个核心概念seam、插件与 Agent Loop2.1 能力缝 seam接口和实现分开先分清接口和实现接口约定“我能提供什么能力”实现负责“我具体怎么完成这件事”。所谓 seam就是在这两者之间划出一条边界让调用方只依赖接口而不依赖某个具体实现。想想墙上的插座插座是接口发电厂是实现发电厂烧煤、烧核还是用风电充电器都不用改。DSH 把很多能力都做成了这种接口ctx.fs文件系统、ctx.shell命令执行、ctx.web联网访问、ctx.storage数据存储、ctx.jobs后台任务。比如 Agent Loop 只需要调用ctx.fs读取文件它不用知道文件最终是从本地磁盘读取还是从一个受限沙箱读取。要换执行环境时替换对应的实现插件即可上层代码不用跟着改。这就是接口和实现分离带来的直接好处调用方稳定底层实现可以替换。2.2 插件会自己报到的代码插件不是一种特殊的文件格式它更像是一种代码组织方式。普通模块通常是这样使用的调用方知道模块叫什么也知道什么时候调用它。插件的方向相反插件加载后会拿到框架提供的上下文然后主动向框架声明自己提供什么、依赖什么以及在什么生命周期阶段执行框架负责把它装配起来。业内把这种关系称为“好莱坞原则”Dont call us, well call you。一个插件至少需要说清楚三件事我是谁提供哪个服务、工具或模型、我需要什么依赖哪些已有服务、我什么时候运行挂在哪些生命周期或事件上。DSH 里可以把这些注册位置理解成几本花名册模型注册表、工具注册表、UI 注册表等。dsh-tool-bash会登记“我提供 bash 工具”dsh-llm-deepseek会登记“我提供 DeepSeek 模型连接”。Agent Loop 不需要把这些插件的名字写死它只需要读取当前已经注册的工具和模型。2.3 Agent Loop一台反复工作的发动机Agent Loop 就是驱动 Agent 持续工作的主循环。DSH 的dsh-agent-loop文档把它的核心概括得很简单call the model, run the tools, repeat。每次“模型决定下一步、调用工具、拿到结果”就是一次 step多个 step 组成一次 turn整段持续的对话属于一个 session。更有意思的是Loop 自己也不是一个不可触碰的核心。沙箱、权限、上下文压缩、失败重试、子代理等功能都可以通过其他插件接入。子代理、工作流、目标管理甚至也可以以工具的形式提供给模型。Loop 只负责把“模型 → 工具 → 结果 → 模型”这条链路继续跑下去其他能力从外面接进来。理解了这三个概念你就能明白为什么 DSH 值得单独拿出来讲它把 Agent 运行时应该如何拆分展示得比较清楚。模型会换工具会换执行环境也会换能够把这些变化隔离开本身就是一种长期有效的工程能力。而多模型调用恰恰是这种隔离最直接的收益点——下面我们就从统一 Key 接入开始。3. TaoToken 前置统一 Key 与插件目录结构3.1 为什么要在 DSH 里接 TaoTokenDSH 是 provider 中立的模型连接本身就是一个插件。这意味着你可以把dsh-llm-*这类 provider 插件指向任意兼容 OpenAI 协议的 endpoint。TaoToken 提供的就是这样一个统一入口一个 Base URL、一个 Key就能调用多个模型不用为每个 provider 单独维护 Key、额度和计费。对 DSH 这种“模型是插件”的架构来说这一点特别契合。你不需要为每个模型写一个 provider 插件只要让 provider 插件指向 TaoToken 的 endpoint模型 ID 在请求里切换即可。Agent Loop 读取的是“当前已注册的模型”至于这个模型背后是哪家Loop 不关心。TaoToken 官网是 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API 入口是 https://taotoken.net/api 。注意 API 地址不带 UTM 参数配置里填的就是这个。你需要先去控制台创建一个 API Key控制台地址是 https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentconsoleutm_campaignrewrite Key 管理页面在 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite 。接入文档在 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 。3.2 DSH 插件目录结构DSH 的插件树不是写死在一个入口文件里的而是通过 profile、bundle 和 patch 层逐步组合出来的。一个典型的插件目录结构大致是这样my-dsh-profile/ ├── package.json # 声明 dsh.bundle.patch 和 dsh.client.inject ├── cordis.patch.yml # profile 补丁声明加载哪些插件 ├── src/ │ ├── index.ts # 宿主端插件入口 │ └── client.ts # 浏览器端插件入口可选 └── plugins/ ├── dsh-llm-taotoken/ # 自定义 provider 插件 │ ├── package.json │ └── src/index.ts └── dsh-tool-bash/ # 工具插件 ├── package.json └── src/index.tsprofile 根配置本身可以是一个空列表插件树通过后续的 bundle 和 patch 层组合。第三方插件的package.json里通过dsh.bundle.patch声明自己的 profile 补丁通过dsh.client.inject声明浏览器端需要的依赖。宿主端代码直接使用 Cordis 的服务和上下文例如import { Service } from deepseek-ai/cordis ctx.inject([settings], (sctx) { // 使用框架注入的 settings 服务 })它不是在 DSH 的某个固定入口里被硬编码调用而是通过自己的声明进入 profile再由框架完成装配。这就是“第三方插件和官方插件使用同一个插槽”的具体证据。3.3 可复制的 provider 配置片段下面是把模型 endpoint 指向 TaoToken 的配置片段。先看cordis.patch.yml它声明加载哪些插件# cordis.patch.yml - insert: - dsh-llm-taotoken - dsh-tool-bash - dsh-agent-loop再看 provider 插件里的模型配置用 JSON 形式给出路径与 DSH 的 settings 服务一致{ llm: { providers: { taotoken: { baseURL: https://taotoken.net/api, apiKey: sk-你的TaoToken密钥, models: [ deepseek-chat, deepseek-reasoner ] } }, defaultProvider: taotoken, defaultModel: deepseek-chat } }如果你用的是 Codex 风格的auth.json三件套要写全Base URL、Key、Model ID。对应关系是 Base URL 填https://taotoken.net/apiKey 填你在控制台创建的密钥Model ID 填deepseek-chat或deepseek-reasoner。这三者缺一不可只填 Base URL 不填 Model ID 是最常见的错误。3.4 Agent Loop 配置片段Agent Loop 的配置决定了它怎么调模型、怎么跑工具、失败后怎么恢复。一个可用的配置片段如下{ agentLoop: { maxSteps: 20, maxTurns: 5, retry: { enabled: true, maxRetries: 3, backoffMs: 1000 }, contextCompression: { enabled: true, threshold: 0.8 }, tools: [ bash, fs, web ] } }maxSteps控制单次 turn 里最多跑多少步maxTurns控制整段 session 里最多几个 turn。retry是失败重试contextCompression是上下文压缩tools声明当前 Loop 能用哪些工具。这些能力本身也是插件Loop 只负责把链路跑下去。4. 验证请求一次本地成功调用配置写完之后必须做一次本地验证确认 endpoint 真的通了。最直接的方式是先用 curl 打一次 TaoToken 的接口确认 Key 和 Base URL 没问题curl https://taotoken.net/api/v1/chat/completions \ -H Content-Type: application/json \ -H Authorization: Bearer sk-你的TaoToken密钥 \ -d { model: deepseek-chat, messages: [ {role: user, content: 用一句话说明什么是 Agent Loop} ] }如果返回里能看到choices数组和message.content说明 Key 和 endpoint 都是通的。这一步能排除掉大部分配置问题因为如果 Key 错了会返回 401如果 Base URL 错了会返回 404 或连接失败。curl 通了之后再启动 DSH 本体dsh web启动后浏览器会打开 UI你会看到对话界面、文件树和变更面板。在对话里输入一个需要调用工具的任务比如“读取当前目录下的 package.json 并告诉我项目名”。观察 Loop 的行为它应该先调用fs工具读取文件拿到结果后再调模型生成回答。如果这一步能跑通说明 provider 插件、工具插件和 Agent Loop 三者已经正确装配。我实测下来最容易出问题的地方不是 Loop 本身而是 provider 插件的注册时机。如果dsh-llm-taotoken没有在cordis.patch.yml里正确声明Loop 启动时会找不到可用模型报错信息通常是“no model provider registered”。这时候回头检查 patch 文件确认插件名和目录名一致即可。验证成功后你可以在同一个 DSH 实例里切换模型只要改defaultModel就行。比如从deepseek-chat切到deepseek-reasonerLoop 不需要任何改动因为它只认“当前注册的模型”不认具体是哪家。这就是统一 Key 接入带来的直接好处模型切换的成本从“改代码”降到了“改一行配置”。如果你还想验证更多模型可以直接在模型对话页面里试https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_contentchatutm_campaignrewrite 。长期做编码和 Agent 任务的话Coding Plan 更划算https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite 。5. 本篇常见错排查401、local proxy failed、reading choices、OAuth配置和验证过程中有几类报错特别常见。下面按真实报错逐条对照给出排查方向。401 Unauthorized。这是最常见的一类几乎都是 Key 的问题。先确认apiKey字段填的是 TaoToken 控制台创建的密钥不是其他平台的 Key。再确认请求头里的Authorization格式是Bearer sk-xxx中间有一个空格。如果 curl 能通但 DSH 里报 401检查 provider 插件读取 Key 的路径是否正确有时候是 settings 服务没注入成功插件读到了空字符串。local proxy failed。这个报错通常出现在网络层说明请求根本没发出去。先确认 Base URL 填的是https://taotoken.net/api没有多余的空格或换行。再确认本机没有配置会拦截请求的环境变量比如HTTP_PROXY、HTTPS_PROXY。如果这些变量指向了一个不可用的地址请求会在本地就失败。清掉这些变量再试。reading choices 报错。这类报错说明请求发出去了也拿到了响应但响应结构不符合预期。常见原因是 Model ID 填错了比如填了一个 TaoToken 不支持的模型名返回体里没有choices字段。对照接入文档确认模型名deepseek-chat和deepseek-reasoner是确定可用的。另一个原因是 Base URL 少了/v1路径有些客户端会自动补有些不会建议直接用https://taotoken.net/api让客户端自己拼。OAuth 相关报错。如果你用的是 Claude Code 或 Codex 这类带 OAuth 流程的客户端报错可能出现在认证阶段。这类客户端通常有自己的登录态和 API Key 是两套机制。如果你要走 TaoToken 的 Key 通道需要在配置里显式指定 API Key 模式而不是 OAuth 模式。Claude Code 的接入方式可以参考文档https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 里面有 ClaudeCodeAnthropic 的配置说明。排查的时候有一个通用顺序先用 curl 确认 Key 和 endpoint再确认客户端配置最后看插件装配。大部分问题在前两步就能定位真正出在插件装配上的很少。如果 curl 通了、客户端配置也对但 DSH 里还是报错那就去看cordis.patch.yml里插件有没有正确加载以及 provider 插件的注册时机是不是在 Loop 启动之前。6. 把统一 Key 接进你的 Agent 工作流走到这里你已经有了一个可以跑的 DSH 实例模型 endpoint 指向 TaoTokenAgent Loop 正常装配工具插件按需加载。接下来可以做的事情有几件。第一件是把模型切换做成配置项。既然 provider 是插件、模型是注册表里的条目你完全可以在 profile 里准备多套模型配置按任务类型切换。比如日常对话用deepseek-chat复杂推理用deepseek-reasoner切换只改defaultModel一行。第二件是把工具插件按需组合。DSH 的工具也是插件bash、fs、web都是独立注册的。你可以根据任务场景决定加载哪些工具比如做代码任务时加载bash和fs做资料收集时加载web。Loop 读取的是当前注册的工具列表不需要改 Loop 本身。第三件是把这套配置迁移到其他客户端。TaoToken 的 Base URL 和 Key 是通用的你在 DSH 里验证通过的配置同样可以用在 Claude Code、Codex、Cline 等客户端里。区别只是配置文件的位置和字段名Base URL、Key、Model ID 这三件套是不变的。如果你打算长期跑编码和 Agent 任务建议直接上 Coding Plan额度更划算https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite 。需要管理多个 Key 或者查看用量去控制台https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentconsoleutm_campaignrewrite 。Key 的创建和轮换在 API Keys 页面https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite 。最后说一个我踩过的坑DSH 还是 v0.1 开发者预览插件生态还在早期第三方插件的质量和兼容性参差不齐。装插件之前先看它的package.json里dsh.bundle.patch指向哪个文件确认它声明的是 profile 补丁而不是硬编码入口。这一点决定了它能不能和官方插件用同一套装配方式。如果它绕过了 patch 机制直接改入口那它就不是真正的 DSH 插件升级时大概率会出问题。模型会换工具会换执行环境也会换。把这些变化隔离开让上层只依赖接口是这套架构最值得带走的东西。统一 Key 接入只是第一步真正的价值在于你可以在不改 Agent 逻辑的前提下把底层换掉。
返回列表