主流 Agent 入门教程 / DeepSeek Harness
10. 插件系统
原文备份 · 第 11 / 21 篇 · 查看极客时间原知识库 ↗
本篇目录 · 23 节
本文属于《DeepSeek Harness 入门教程(实战版)》· 第三部分 · 模型、预设与插件
第 10 章 插件系统:配置、启停与验证
上一章做出的“日报审阅”预设,本质上是一套插件组合。这一章把视角再往下移一层:看懂插件分别运行在哪里,学会区分配置、清单和管理入口,并亲手完成一次可回退的插件启停实验。
本章仍使用 daily-report 工作区,但不修改项目文件。你将完成两个真实任务:
- 配置网页搜索,用官方资料核对 Node.js 的
fetch能力; - 启用预装但默认关闭的“时间上下文”插件,验证它确实进入模型上下文,再将其关闭。
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 安装、停用和移除不是一回事
以后安装第三方插件时,按下面的生命周期处理:
- 检查:确认来源、版本、许可证、源码、依赖、构建脚本和兼容版本;
- 安装:把 bundle 及依赖写入当前 Profile;
- 启用:把 bundle 或插件行选入组合;
- 应用:通过热重载生效,或按提示重启 Profile;
- 验证:用真实任务和插件清单确认能力,而不是只看“安装成功”;
- 停用:保留依赖和配置,只停止组合;
- 移除:卸载依赖并从 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、极简与创造 | 回目录 | 下一章:案例二:从需求到可运行的第一版 →