← 全部极客知识库

主流 Agent 入门教程 / DeepSeek Harness

10. 插件系统

原文备份 · 第 11 / 21 篇 · 查看极客时间原知识库 ↗

本篇目录 · 23 节

来源:DeepSeek Harness

本文属于《DeepSeek Harness 入门教程(实战版)》· 第三部分 · 模型、预设与插件

第 10 章 插件系统:配置、启停与验证

上一章做出的“日报审阅”预设,本质上是一套插件组合。这一章把视角再往下移一层:看懂插件分别运行在哪里,学会区分配置、清单和管理入口,并亲手完成一次可回退的插件启停实验。

本章仍使用 daily-report 工作区,但不修改项目文件。你将完成两个真实任务:

  1. 配置网页搜索,用官方资料核对 Node.js 的 fetch 能力;
  2. 启用预装但默认关闭的“时间上下文”插件,验证它确实进入模型上下文,再将其关闭。

10.1 “一切皆插件”不是说所有东西都是工具

DeepSeek Harness 的 Cordis 内核主要负责加载、卸载和连接插件。模型、文件系统、Shell、网页访问、Agent 循环、会话存储、权限策略和界面,都可以由插件提供。产品页把这套设计概括为“一切皆插件”。

插件不一定直接给模型增加一个按钮或工具。更准确的理解是,一个能力常被拆成三种角色:

角色 负责什么 网页访问中的例子
Service Definition 定义统一接口和数据约定 ctx.web 规定搜索与抓取怎样被调用
Service Provider 提供某种具体实现 DeepSeek 搜索、公共 HTTP 抓取
Consumer 把能力交给使用者 web_search、web_fetch 工具

模型调用 web_search 时,并不是直接绑定某一家搜索服务。Consumer 通过统一的 Web 服务找到当前 Provider。以后替换搜索 Provider,模型看到的工具接口仍可以保持稳定。Web 子系统官方说明

这也解释了一个常见现象:插件列表里能看到很多包,但会话里没有同样数量的工具。有些插件提供底层服务,有些维护状态,有些只渲染界面,只有一部分会注册模型可调用的工具。

10.2 先分清三个插件入口

当前版本有三个名字相近、用途不同的页面。

“设置 → 插件 → 插件配置”

这里编辑当前 Profile 中开放给用户调整的 Host 插件参数。表单先保存草稿,点击“保存”后才写入;“恢复默认”也只是先清除草稿中的用户覆盖,仍要保存才生效。

当前官方界面会按实际组装和平台显示卡片。核心卡片包括终端、Agent 循环和网页搜索;v0.1.7-rc.2 的完整组合还可能出现子智能体模型选择。某张卡片没有出现,不代表整个插件损坏,可能只是对应设置命名空间没有在当前 Profile 中启用。

“设置 → 插件 → 插件列表”

这是只读清单。它能按 Agent 预设和全局作用域查看包名、条目 ID、启停状态、来源与加载错误,也能搜索,但不能在这里直接开关插件。插件清单官方说明

清单中的“已启用”只说明配置选择了它;真正能否提供能力,还要看运行状态和依赖是否正常。预设内的插件行也是只读的,要改变它们应编辑自定义预设,而不是在清单里寻找开关。

左侧边栏的“插件”管理页

这是安装、移除、启用或停用 Profile 插件的地方,不要和设置中的只读清单混淆。插件管理器可以操作全局插件条目和已安装 bundle;变更会影响使用同一 Profile 的任务。插件管理器官方说明

Desktop 和 CLI/Web 的 Profile 彼此独立:

  • Desktop 的“插件”页管理 Desktop 自己的 Profile,并使用应用内置的包管理运行时;
  • dsh plugin --profile web ... 管理 CLI 的 Web Profile,不能拿它修改 Desktop Profile;
  • 安装、启停和配置都应先确认自己正在操作哪个 Profile。

10.3 Host、Client、预设和 Profile

看插件卡片时,先判断它属于哪一层:

  • Host 插件运行在 Harness 进程里,可能访问文件、网络、凭证或注册工具;
  • Client 插件运行在界面侧,贡献设置卡片、面板或工具结果的可视化;
  • Agent 预设插件只在使用该预设的 Agent 作用域中组装;
  • Profile 插件属于整个运行实例,通常影响同一 Profile 下的多个任务。

一个完整功能可能同时包含 Host 和 Client 两半。例如 Host 提供定时任务能力,Client 再提供提醒列表;只启用其中一半,可能出现“工具存在但没有页面”或“页面存在但后端不可用”。

安装第三方 bundle 的风险也在这里:它不是浏览器里受限运行的一小段脚本,而可能把 Host 代码加载进 DSH 进程,在工作区沙箱之外运行。安装前至少检查来源、版本、源码、依赖、构建脚本和声明的插件行。随机找一个包练手,不值得承担这种风险。

本章只使用官方预装插件,不安装第三方代码。

10.4 终端配置:控制命令预算,不是打开“持久终端”

打开“设置 → 插件 → 插件配置”,展开“终端”。常见的两个字段是:

字段 作用 当前本地执行器的默认值
命令超时 一条前台命令的默认运行时限 120000 毫秒
单流输出上限 stdout、stderr 各自在内存保留的字节数 64000 字节

输出超过内存上限时,DSH 会保留尾部,并尽可能把完整输出转存到临时 spill 文件,同时在结果中给出路径;不是悄悄把超出部分吞掉。超时后的前台命令在具备后台任务运行时的组合中,还可能转成后台 job,而不是立即被杀死。POSIX 的 Bash 与 Windows 的 PowerShell 执行器使用相同的两项默认预算。本地 Bash 执行器说明、本地 PowerShell 执行器说明

这里的“终端”配置控制标准 Shell 执行器,不代表标准模式里存在一个跨调用保留 cd、变量和函数的持久终端。macOS/Linux 的标准 bash 与 Windows 的标准 pwsh 工具每次都启动新的 shell,应该通过工具的 workdir 指定目录。极简预设中的 persistent bash 是另一种工具,不要把两者混为一谈。

调整时遵循两个原则:

  • 测试和构建经常正常超过两分钟时,再有依据地提高超时;
  • 日志太大时,先让命令缩小输出范围,再考虑提高上限。

把超时改得极短,只会让正常命令频繁转入后台;把输出预算无限放大,也会增加内存和上下文压力。

10.5 Agent 循环:限制同一步的并行工具调用

“Agent 循环”卡片中的“并行工具调用数”对应 maxParallelToolCalls。官方默认值是 10,设为 1 时并行安全的工具也会串行执行。Agent 循环官方说明

它限制的是同一个步骤中同时在途的并行安全调用数,不是:

  • Agent 最多思考几轮;
  • 整个任务最多调用几次工具;
  • 可以同时创建几个任务;
  • 防止 Agent 循环失控的总预算。

独占工具调用仍会形成顺序屏障,多个可能互相覆盖的写操作也不该为了速度强行并发。

想观察这个参数,可以先把它改成 1 并保存,然后在标准模式的新任务中发送:

请只读并分别检查 PROJECT.md 和 sources.json,再汇总两者是否一致。必须实际读取两个文件,不要修改文件,也不要访问网络。

如果模型在同一步提出两个可并行读取,轨迹会显示它们按顺序执行。随后回到卡片点击“恢复默认”并保存,再新建任务重复一次;是否并行仍取决于模型是否在同一步发出独立调用,所以不要只凭耗时判断。独立验收是卡片不再显示“已覆盖”,并行数恢复到部署默认值。

10.6 网页搜索:配置的是另一条模型请求

“网页搜索”卡片配置 DeepSeek 搜索 Provider。它与当前聊天会话选择的模型不是同一条请求:搜索 Provider 会调用 DeepSeek 的 Anthropic 兼容 Messages 接口,让一个辅助模型执行原生 Web 搜索,再把结构化来源交回当前 Agent。

界面开放的高频字段通常包括:

字段 应该怎样理解
API Key 使用 DeepSeek 搜索所需凭证;密钥框为空表示不覆盖已保存凭证,不表示删除
接口地址 搜索专用基址,官方默认是 https://api.deepseek.com/anthropic/v1
单次请求最多搜索次数 服务端原生搜索工具最多使用几次,官方默认 5

不要把聊天模型的 Chat Completions 地址直接复制到这里。搜索地址与会话模型地址独立,适用的协议也不同。每次搜索会产生一次完整 Messages 模型轮次的延迟和 token 消耗,maxUses 只限制这一轮中服务端搜索工具的使用次数,不是免费额度。DeepSeek 搜索 Provider 官方说明

如果上一章已经保存了官方 DeepSeek API Key,搜索 Provider 通常可以通过同一凭证引用解析它;没有凭证时,web_search 会以 WEB_PROVIDER_CREDENTIAL_MISSING 失败。不要把 Key 写进对话或项目文件。

为了完成一次小而明确的搜索,保持官方接口地址不变,把“单次请求最多搜索次数”暂时设为 3,点击“保存”。保存后卡片应显示该字段已被用户覆盖。

回到 daily-report 工作区,新建一个标准模式、Read Only 权限的任务,发送:

请只使用 Node.js 官方来源核对两件事:
1. 当前受支持的 Node.js 版本中,全局 fetch 是否可直接使用;
2. fetch 返回 404 或 500 时是否会自动抛出异常。

给出来源链接,并说明这些结论会怎样影响“零依赖日报助手”的第一版实现。暂时不要修改项目文件。

一个合格结果应满足:

  • 执行轨迹里出现 web_search,必要时还有 web_fetch;
  • 来源域名来自 nodejs.org,而不是博客或搜索摘要;
  • 能区分网络失败与 HTTP 4xx/5xx:后者需要代码检查 response.ok 或状态码;
  • 没有因为“零依赖”而建议安装第三方 HTTP 库;
  • 工作区代码差异为空。

独立验收时,不要只看 Agent 的总结。展开搜索工具卡片,确认真实来源 URL;再打开其中一条 Node.js 官方链接,核对页面标题和正文是否支持结论。搜索 Provider 的回答文本本身不会被当作可信答案,DSH 只保留结构化搜索结果中的 URL、标题、日期和引用片段。

实验完成后回到网页搜索卡片,点击“恢复默认”并保存,让 maxUses 回到部署值。API Key 不需要重新粘贴。

10.7 用“时间上下文”走一遍插件生命周期

现在操作一个预装但默认关闭的插件。@deepseek-ai/dsh-time-context 会在符合条件的步骤前,向会话追加一条带来源的时间读数,包含当前时间、浏览器时区和经过时长。它不是一个模型工具,而是上下文插件。

第一步:在只读清单中找到它

打开“设置 → 插件 → 插件列表”,搜索 time-context。在 v0.1.7-rc.2 的 Web/Desktop 默认组合中,它应该存在但处于停用状态。

展开卡片,记录三个事实:

  • 完整包名是 @deepseek-ai/dsh-time-context;
  • 条目 ID 是 time-context;
  • 当前状态是已停用,而不是未安装或加载失败。

第二步:在管理页启用

离开设置,打开左侧边栏的“插件”管理页,搜索同一个包名或条目 ID,选择启用。

启用 Profile 插件是持久配置变更。如果出现确认或审批,确认目标是内置的 time-context 条目,而不是陌生包。启用成功后:

  • 若页面提示已应用,可以直接继续;
  • 若提示需要重启,先结束正在运行的任务,再重启当前 Desktop 或 Web Profile;
  • 回到只读插件列表重新打开页面,确认状态已变为启用且没有加载错误。

第三步:用新任务验证真实效果

在 daily-report 工作区新建标准模式、Read Only 任务,发送:

请告诉我当前时间、你采用的时区,以及你从哪里得到这些信息。不要运行 Shell,不要访问网络,也不要修改文件。

模型回答的时间可能有格式差异,真正的验收点在轨迹或会话上下文:应该出现来源标记为 plugin: time-context 的注入内容,其中包含带数字偏移和 IANA 时区的时间戳,以及浏览器时区策略。只看回答“现在几点”不足以证明插件生效,因为模型可能根据其他上下文猜测。

时间上下文官方说明指出,这类读数会进入持久会话历史;它帮助模型解释没有写明时区的自然语言时间,但不会替其他工具偷偷填写时区参数。

第四步:停用并验证回退

回到左侧“插件”管理页停用 time-context,按界面提示完成应用或重启。然后再创建一个新任务,发送相同问题。

这一次轨迹中不应再出现新的 plugin: time-context 注入。旧任务里已经持久化的读数不会被删除,所以一定要用新任务验证停用结果。

至此你完成了一个完整闭环:

发现 → 查看作用域与状态 → 启用 → 确认加载 → 真实任务验证
     → 停用 → 新任务验证回退

10.8 预装列表里哪些插件值得认识

不必逐个背包名,但下面几类会在后续课程反复出现:

插件家族 它给 Agent 带来什么 后续怎么用
文件、搜索与 Shell 读取、修改、检索文件并运行命令 下一章开始实现日报助手
Skill 可发现、按需加载的任务指导与脚本 后面制作一份真实项目 Skill
Plan、Todo、Goal 计划、待办和跨轮持续目标 长任务章节实际使用
Subagent / Workflow 委派或编排边界明确的子任务 多智能体章节实际使用
Sandbox 与审批 约束文件和命令操作,决定何时询问用户 每次写入和外部操作都依赖它
Session 与 Trajectory 持久记录模型、工具、上下文和子智能体事件 用于验收、恢复和排错

Skill、MCP 和 Agent 预设虽然都能扩展 Agent,但不是同一个概念:

  • 插件提供或组合运行时能力;
  • Skill教 Agent 如何完成一类任务,实际动作仍依赖已有工具;
  • MCP把外部工具或资源服务器接进来,DSH 通过 MCP Client 插件桥接;
  • Agent 预设选择一组插件和提示词,作为新任务的工作环境。

后续章节会分别做真实 Skill、MCP 和多智能体案例。本章只建立边界,避免把所有扩展都叫成“装插件”。

10.9 安装、停用和移除不是一回事

以后安装第三方插件时,按下面的生命周期处理:

  1. 检查:确认来源、版本、许可证、源码、依赖、构建脚本和兼容版本;
  2. 安装:把 bundle 及依赖写入当前 Profile;
  3. 启用:把 bundle 或插件行选入组合;
  4. 应用:通过热重载生效,或按提示重启 Profile;
  5. 验证:用真实任务和插件清单确认能力,而不是只看“安装成功”;
  6. 停用:保留依赖和配置,只停止组合;
  7. 移除:卸载依赖并从 bundle 列表中删除。

遇到加载错误时,先停用有问题的第三方 bundle。官方 Desktop 即使在 Host 无法正常启动时,也提供“禁用第三方插件并重启”的恢复路径。不要一出问题就删除整个 $DSH_HOME,那会把会话、凭证和其他 Profile 数据一起卷入。

还有一条简单的选择原则:**没有这个插件,任务是否仍能可靠完成?**如果答案是能,就先不装。每个工具都会增加模型要理解的 schema,每个 Host 插件都会扩大运行面,每个状态系统也会增加排错成本。

10.10 常见问题

配置改了,却看不到变化

先确认点击了“保存”,而不是只收起卡片。再检查字段是否显示“已覆盖”。如果表单提示 revision 已变化,重新打开卡片读取最新值后再修改,避免覆盖其他页面刚提交的配置。

插件列表显示已启用,但功能不可用

展开卡片看运行状态与错误。已启用表示配置选择了它,不等于依赖已经解析、Host 和 Client 两半都已加载。需要重启时按提示重启当前 Profile,不要只刷新浏览器页面。

找得到插件,却没有开关

你可能在“设置 → 插件 → 插件列表”。该页面有意只读;全局 Profile 插件应去左侧“插件”管理页操作,Agent 预设中的插件则要通过自定义预设调整。

网页搜索提示缺少凭证

回“设置 → 插件 → 插件配置 → 网页搜索”确认凭证状态,并核对当前搜索端点。搜索凭证和聊天模型路由是两层配置;聊天正常不等于搜索一定可用。

Desktop 中运行 dsh plugin --profile web 后没有变化

你修改的是 CLI 的 Web Profile,不是 Desktop Profile。Desktop 插件应在应用内“插件”页管理,两者的可执行包、锁文件、启用状态和 node_modules 不共享。

10.11 本章验收

进入下一章前,请确认:

  • 能解释 Service Definition、Provider 和 Consumer 的关系;
  • 能区分插件配置、只读插件列表和左侧插件管理页;
  • 知道 Host、Client、Agent 预设与 Profile 插件的作用域差异;
  • 理解终端超时、输出上限和 Agent 循环并行数分别控制什么;
  • 已用官方 Node.js 来源完成一次真实网页搜索,并确认工作区零改动;
  • 已启用、验证、停用并再次验证 time-context;
  • 能区分插件、Skill、MCP 和 Agent 预设;
  • 知道停用与移除的区别,以及第三方 Host 插件的风险边界。

插件层已经讲清楚了。下一章开始正式改造日报助手:让 Agent 先读需求、制定最小实现方案,再写出第一版程序和测试。


← 上一章:Agent 预设:标准、PTC、极简与创造 | 回目录 | 下一章:案例二:从需求到可运行的第一版 →