← 极客知识库本地镜像
主流 Agent 入门教程 · Agent 工具 / 插件化 / 运行配置 / 实践方式

DeepSeek Harness

从运行与配置入手,认识插件化 Agent 的工作方式。

来源 time.geekbang.org/space/wiki/DSH_Tutorial 21 讲 主流 Agent 入门教程

01 学习交流群

知识库之外,我们还建了「主流 Agent 入门交流群」。

进群和大家一起交流主流 Agent 的使用方法、适用场景和入门实践,分享不同工具的上手经验、工作流与真实案例,也会同步专题最新更新和实战资料。

扫码加入,一起找到适合自己的 Agent,真正用起来。

【知识库】主流 Agent 入门交流群


02 DSH是什么

本文属于《DeepSeek Harness 入门教程(实战版)》· 第一部分 · 先认识这个产品

第 1 章 DeepSeek Harness 是什么

第一次打开 DeepSeek Harness,很容易把它理解成“又一个 AI 聊天窗口”:选择模型、输入需求,然后等它返回一段代码。

界面确实有点像聊天工具,但这只是表面。普通对话产品主要负责生成答案,Harness 的重点则是让模型进入一个可以使用工具、受到权限约束、能够持续执行任务的运行环境。

读完这一章,你不需要记住所有术语,只需要能分清模型、Agent、插件、Profile 和客户端分别负责什么。这个区别会直接影响后面配置产品的顺序。

一句话理解 DSH

DeepSeek Harness,简称 DSH,是 DeepSeek 开源的一套 Agent Harness:它把模型、工具、权限、工作方式和交互界面组合成一个可以真正执行任务的 Agent。

这里的 Harness 可以理解成“运行和约束 Agent 的整套装置”。模型负责判断下一步做什么;Harness 负责把文件、终端、网页、外部服务等能力提供给模型,同时记录过程并控制边界。

所以,DSH 不是一种新模型。你可以给它配置 DeepSeek 官方模型,也可以接入内置的第三方 Provider 或兼容 API。更换模型以后,工作区、插件和 Agent 的其他配置不必跟着全部重建。

从一句需求到真正完成,中间发生了什么

假设你对 DSH 说:

请给这个项目增加 --limit 参数,补上测试并确认原功能没有被破坏。

要完成这个任务,光生成一段代码还不够。Agent 通常需要:

  1. 查看项目里有哪些文件;
  2. 找到命令行参数的入口和现有测试;
  3. 制订或调整修改方案;
  4. 编辑代码和测试文件;
  5. 在终端运行测试;
  6. 根据报错继续修正;
  7. 把实际改动和验证结果交给你审查。

模型只负责其中的推理和选择。读取文件、执行命令、审批危险操作、保存会话、展示差异,都是 Harness 提供的能力。

这也是 Agent 和普通问答最实际的区别:它不只是告诉你“可以怎么做”,而是可以在授权范围内把事情做完。不过,最后仍要由你检查文件、测试和差异,不能只接受一句“已经完成”。

先建立五层心智模型

DSH 的名词不少,但初学时可以先把它看成五层。

第一层:模型与 Provider——谁来思考

模型负责理解任务、生成内容,并决定下一步调用什么工具。Provider 则负责把请求发送给对应的模型服务。

因此,“切换 DeepSeek 模型”和“接入一个自定义中转 API”属于模型与 Provider 层的问题。我们会在第8章专门处理。

第二层:Agent 预设——以什么方式工作

同一个模型可以用不同方式完成任务。例如,有的任务适合使用完整工具链,有的任务更适合让模型通过代码批量处理工具结果,还有的任务只需要很少的基础能力。

Agent 预设定义的不是一句角色提示词,而是一组工作方式、工具和插件组合。DSH 内置了标准、PTC、极简和创造等预设,也允许通过创造模式制作自己的预设。第9章会让同一个项目分别体验这些差异。

第三层:插件——能够做什么

文件读写、Shell、网页搜索、Skill、会话记录、计划、子智能体,甚至 Agent Loop 本身,都可以由插件提供。

这里的插件不是浏览器里的小扩展,而是 DSH 的基本组成方式。官方用“Everything is a Plugin”概括这套架构:模型适配器、工具注册表、会话日志和 Agent 循环都可以通过配置组合或替换。官方架构说明

插件越多不等于 Agent 越强。每多一个工具,模型都要理解它的用途,权限和故障面也会增加。正确做法是围绕任务安装和启用必要能力,而不是把所有插件一次性打开。

第四层:Profile——这次启动装载哪套系统

Profile 是一套可以启动的组合配置。它决定装载哪些 Bundle、插件和补丁,并保存属于这套运行环境的依赖与设置。

例如,Web、Headless、SDK 和 ACP 都有各自的运行组合。桌面端还拥有独立的 desktop Profile。它们可以复用 DSH 的共同能力,但启动入口和加载的组件并不完全相同。

对初学者来说,暂时不需要手写 Profile。先记住一点就够了:在桌面端安装或启用的插件,不应想当然地认为已经同步到 CLI 的 Web Profile,反过来也一样。

第五层:交互入口——你从哪里使用它

你可以通过不同入口使用同一套 Harness 能力:

  • 桌面端:适合直接打开应用、管理工作区和查看文件、计划与差异;
  • Web:由本机 dsh web 启动,在浏览器中使用完整界面;
  • Headless:不打开界面,执行一次任务后退出,适合脚本和自动化;
  • SDK / ACP:把 Harness 接入其他程序或 Agent 客户端,属于进阶开发场景。

桌面端并不是另起炉灶的一套产品。它携带匹配版本的 DSH 运行时,并在 Electron 外壳中运行完整的 Web 应用;差别主要在安装、生命周期、本地目录选择和系统集成。桌面端官方说明

把这五层放在一起,就是下面这条链:

桌面端 / Web / Headless / SDK
            ↓
          Profile
            ↓
    Agent 预设 + 插件组合
            ↓
      Provider 与模型
            ↓
      文件、命令和外部服务

这不是严格的内部调用图,但很适合用来判断“某个问题应该去哪里配置”。

后面会遇到的几个词

现在只需要认识,不必背定义。

概念 先这样理解 后续出现位置
Provider 模型服务的接入方式 第8章
Agent 预设 Agent 的工作方式与能力组合 第9章
Plugin 给 Harness 提供能力的模块 第10章
Skill 可被发现并按需加载的任务说明 第12章
MCP 连接外部工具与资源的标准协议 第12章
Subagent 把一项独立工作委派给另一个智能体 第13章实操
Workflow / Agent Team 多步骤编排,或让具名成员持续协作 第13、18章只讲选型边界
Goal 让 Agent 跨多个回合持续推进的目标 第14章

DSH 现在仍处于开发者预览阶段

这一点不能略过。官方明确说明 DeepSeek Harness 仍是 Developer Preview,后续可能出现不兼容变更。官方仓库说明

这意味着:

  • 教程中的按钮名称和配置位置以后可能变化;
  • 第三方插件可能暂时跟不上新版本;
  • 自定义 Profile、插件和旧配置在升级后更需要先检查兼容性;
  • 遇到差异时,应先确认自己的版本,再查对应版本的发布说明。

对入门学习没有必要因此停下来,但不要把候选版本当成接口永远不变的成熟平台。

动手前,先约定三条边界

Agent 能读取文件、执行命令和访问网络,所以它需要比普通聊天产品更明确的边界。

  1. 只开放练习目录。 不要把整个个人主目录、公司资料目录或包含无关凭证的仓库作为练习工作区。
  2. 密钥只放在凭证设置中。 不把 API Key 写进提示词、README、代码或截图。
  3. 审批前看清动作。 安装依赖、删除文件、访问工作区以外的路径和向外部服务写入数据,都要先确认必要性与目标范围。

如果项目使用 Git,在重要改动前保存一个干净基线。之后审查的重点不是“Agent 说了什么”,而是文件究竟变成了什么、测试是否真的通过。

这一章真正需要记住的内容

以后碰到设置问题,可以按下面的顺序判断:

先确认自己从哪个入口、哪个 Profile 运行,再选择 Agent 的工作方式和插件,最后确认由哪个 Provider 与模型执行。

下一章先不急着安装。我们会从实际任务出发,看看 DSH 能做哪些事情,以及哪些能力值得放进这套入门教程。


← 上一章:封面与导读 | 回目录 | 下一章:DeepSeek Harness 能做什么 →


03 DSH能做什么

本文属于《DeepSeek Harness 入门教程(实战版)》· 第一部分 · 先认识这个产品

第 2 章 DeepSeek Harness 能做什么

上一章把 DSH 拆成了模型、Agent 预设、插件、Profile 和使用入口。这一章换一个更实际的角度:哪些任务值得交给它,哪些能力会在后面的项目中真正用到。

DSH 的功能很多,尤其是插件不断增加以后,很容易列出一张很长的清单。但入门阶段没有必要把所有功能都试一遍。判断一项能力是否重要,可以看它是否进入了下面这条完整工作链:

理解任务 → 查看环境 → 制订方案 → 使用工具执行
→ 检查结果 → 根据反馈继续 → 把改动交给用户审查

这套教程围绕这条工作链选择内容。

1. 在真实项目里创建和修改文件

这是最容易看到价值的一类任务。

你可以让 DSH:

  • 从空目录创建一个小项目;
  • 阅读已有代码并解释结构;
  • 搜索某个参数、函数或配置出现在哪里;
  • 修改代码、测试和文档;
  • 打开生成的 Markdown、图片或其他支持预览的文件;
  • 汇总本轮实际改动。

区别不在于它能不能“写出一段代码”,而在于它可以围绕同一个工作区连续行动。模型先看到项目当前状态,插件再把文件读写能力提供给它,所有操作都受到工作区和审批策略约束。

第7章中,我们会让它从零创建「日报助手」。第11章再在已有代码上增加功能,体验“先读懂、再修改”的区别。

2. 执行命令,并根据结果继续处理

很多任务必须运行以后才能判断是否完成。例如:

  • 安装或检查项目依赖;
  • 运行测试、构建和格式检查;
  • 启动本地程序;
  • 查看 Git 状态和代码差异;
  • 运行一次数据处理脚本;
  • 观察长时间任务的实时输出。

DSH 可以让 Agent 调用 Shell 工具,也可以在 Web 或桌面端侧边栏中打开由你亲自操作的终端。这两者不要混淆:

  • Agent 调用的 Shell受当前工具、沙箱和审批策略控制;
  • 你打开的侧边栏终端以当前系统用户权限运行,不会因为 Agent 是只读模式就自动变成只读。

因此,侧边栏终端适合你手动复核命令,却不应拿来绕过 Agent 的安全限制。第7章和第11章会反复使用“Agent 执行一次、用户独立复核一次”的方式闭环验证。

3. 把执行过程变成可以审查的工作

一个 Agent 是否好用,不只看它最后给出的答案,还要看你能否确认中间发生了什么。

在当前 Web 和桌面端中,你可以查看工具调用、文件改动、代码差异、提交的计划以及子智能体会话。代码差异支持逐行或左右分栏审查;长命令和工作流也可以转入后台,在任务面板中继续显示输出。v0.1.7-rc.1 更新说明

这些界面能力解决的是三个不同问题:

你想确认什么 应该看哪里
Agent 调用了哪些工具 对话中的工作过程或工具卡片
哪些文件发生了变化 文件改动或代码差异面板
修改后是否真的可用 自己重新运行测试或打开产物

最后一项最重要。界面里的“任务完成”只是 Agent 的判断,测试结果和最终文件才是独立证据。

4. 更换模型,也更换 Agent 的工作方式

DSH 把“谁来思考”和“如何工作”分开了。

你可以配置 DeepSeek 官方模型、内置第三方 Provider,或者兼容 API;也可以在标准、PTC、极简、创造及自定义预设之间选择。于是同一个任务可以从两个方向调整:

  • 模型不合适:切换 Provider 或具体模型;
  • 工具使用方式不合适:切换 Agent 预设或调整插件组合。

这比简单地把所有问题归结为“模型不够聪明”更实用。第8章会配置三类 Provider,第9章则用同一个项目对比不同 Agent 预设,并创建一个自定义预设。

5. 用插件扩展和裁剪能力

插件既可以增加能力,也可以减少不必要的能力。

当前插件管理页支持安装、配置、启用、停用和运行时卸载插件;安装时还可以根据网络情况选择官方源、国内镜像或自定义源。v0.1.7-rc.1 更新说明

在实际使用中,一个完整的插件动作不是“点一下安装”,而是:

确认任务需要什么
→ 查看插件的来源、权限和兼容性
→ 安装并配置
→ 在新任务中验证能力是否出现
→ 不再需要时停用或卸载

第10章会完整走一遍这个闭环,还会配置终端、Agent Loop 和网页搜索等常用项目。这样学完后,你不只是理解“万物皆插件”,还会真正管理插件。

6. 用 Skill 固化做事方法,用 MCP 接入外部能力

Skill 和 MCP 经常一起出现,但解决的不是同一个问题。

  • Skill更像一份可以被 Agent 发现并按需加载的操作说明,适合沉淀项目规范、固定流程和工具使用方法;
  • MCP是一套连接外部工具与资源的协议,让 Agent 能调用数据库、浏览器、内容服务或其他程序提供的能力。

举个简单例子:

  • MCP Server 提供“读取资讯源”的工具;
  • Skill 告诉 Agent什么时候调用、参数怎么填、失败后检查什么、输出要整理成什么格式。

第12章会创建一份能被 DSH 实际发现的项目 Skill,并连接一个只允许访问练习目录的 MCP 文件服务。我们会检查它是否出现在目录中、是否真的被加载,再用一次范围内写入和一次越界拒绝证明授权边界,而不只是让 Agent 普通地读取一个 Markdown 文件。

7. 把独立工作交给子智能体

当一项任务里包含多个相互独立的问题时,主 Agent 可以把部分工作委派出去。例如:

  • 一个智能体分析第一个数据源;
  • 一个智能体分析第二个数据源;
  • 另一个智能体检查测试覆盖;
  • 最后由主 Agent 汇总结论并修改项目。

这里的并行发生在“完成开发任务的过程中”,而不是让普通 Node.js 程序自动拥有 Agent 能力。程序里的 Promise.all 是代码并发;Harness 的 Subagent 是多个智能体之间的任务委派,两者不能混为一谈。

第13章会实际创建两个子智能体完成并行审查,并比较 Subagent、Workflow 与实验性 Agent Team 的适用边界。主线不会启用 Agent Team,因此不把它写进“学完即会”的承诺。

8. 让 Agent 跨多个回合持续推进

如果任务包含多步检查、修改和验证,一条提示词不一定能在单个回合里可靠完成。Goal 可以让 Agent 围绕一个明确目标持续推进,并保留进度。

它适合“结果明确,但中间步骤需要根据实际情况调整”的任务。例如把日报助手从能运行的练习项目,打磨成有测试、有文档、失败时能给出清楚提示的小工具。

第14章会重点练习四件事:目标怎么写、如何观察进度、什么时候需要暂停或纠偏,以及最后如何独立验收。

9. 定时运行,或者完全离开界面

自动化有两种常见需要:

  • 到时间自动触发:使用产品内置的定时任务创建提醒或周期任务,并查看运行记录;
  • 由其他程序触发:使用 Headless 从命令行接收任务,完成后输出结果并退出。

当前版本的定时任务在 Web 和桌面端默认关闭,需要先在插件管理中启用;任务在应用重启后仍会保留。Headless 则支持从标准输入读取任务、用 --session-id 继续会话,以及用 --json 输出逐行 JSON 事件。v0.1.7-rc.2 更新说明

第15章会先用 Headless 完成一次离线检查,再启用内置定时任务完成两分钟测试,并由你决定是否保留“每天生成日报”。操作系统的 cron 和任务计划程序只作为服务器或 CLI 场景的补充方案。

还有一些能力,为什么不放进主线

当前版本还提供或正在试验更多能力,例如 Office 文件预览与处理、侧边栏浏览器、语音转写、SSH 远程工作区、Playwright/Chrome DevTools/Stagehand 浏览器后端以及 Computer Use。

它们并非不重要,而是会引入额外的运行环境、权限或实验性依赖。为了让第一次学习保持稳定,主线只在第18章说明入口和适用场景,不要求每位读者都配置。等你掌握模型、预设、插件和审批以后,再进入这些能力会更安全。

哪些任务不应该直接交给它

DSH 能执行真实操作,不代表适合不经检查地处理所有事情。以下任务至少需要更严格的权限和人工复核:

  • 删除或批量覆盖重要文件;
  • 直接操作生产环境和真实用户数据;
  • 发送消息、发布内容或触发付费操作;
  • 处理未脱敏的密钥、身份信息和公司机密;
  • 在没有测试和备份的情况下大范围重构项目。

更稳妥的顺序是:先让 Agent 只读调查,再审查计划,然后开放最小写入范围,最后由独立测试或人工检查确认结果。

这套教程会让你真正完成什么

后续实战不是九个互不相干的功能演示。它们会把日报助手从空目录逐步推进到下面的状态:

能运行、能测试
→ 能切换数据源和限制条数
→ 有可复用的 Skill 和外部工具
→ 能借助多个智能体完成开发工作
→ 能作为长目标持续改进
→ 能定时或以 Headless 方式运行
→ 能把配置与经验沉淀下来

下一章先做第一个决定:你的电脑应该安装桌面端,还是使用 CLI/Web。选对路线以后,后面的安装会简单很多。


← 上一章:DeepSeek Harness 是什么 | 回目录 | 下一章:选择桌面端还是 CLI/Web →


04 安装前准备

本文属于《DeepSeek Harness 入门教程(实战版)》· 第二部分 · 安装并完成第一次启动

第 3 章 选择桌面端还是 CLI/Web

旧版本的教程只有一条安装路线:先安装 Node.js,再通过 npm 启动 DSH。官方桌面端发布以后,这个前提已经发生了变化。

现在需要先回答的是:你准备怎样使用 DSH?

这一章不安装任何东西。我们先选定路线、确认环境和准备凭证,下一章再按操作系统执行。选对路线以后,不必为了“学得更完整”而把另一套也安装一遍。

两条路线的差别

桌面端 CLI/Web
启动方式 打开 DeepSeek Harness 应用 在终端运行 dsh web 或 npx @deepseek-ai/dsh@0.1.7-rc.2 web
DSH 自身是否需要系统 Node.js 不需要,应用携带匹配的运行时 需要
工作区选择 原生文件夹选择器 Web 中的 Host 目录选择器
插件安装环境 使用 Desktop 内置 pnpm 使用 CLI 所在的 Node/npm 环境
适合场景 本机日常使用、第一次体验 Linux、Headless、脚本、服务器、自定义 Profile
Profile 独立的 desktop Profile web、headless 等 CLI Profile

桌面端本质上是在 Electron 外壳中运行完整 Web 应用,并携带与桌面版本匹配的 DSH 运行时。它不是一个只有部分功能的“简化版”。不过,桌面端和 CLI 不共享插件激活、依赖锁文件和 node_modules,公共 CLI 也不能直接管理 Desktop Profile。桌面端官方说明

用三个问题选路线

1. 你的系统是什么

  • macOS 或 Windows:优先考虑桌面端;
  • Linux:本教程走 CLI/Web;
  • 远程服务器或只有 SSH 的环境:走 CLI/Web,不要依赖桌面窗口。

桌面安装包的系统和处理器支持范围可能随版本变化。真正下载前,以官方 Releases 页面当期提供的资产为准,不要从不明网盘或第三方软件下载站获取安装包。

2. 你是否需要命令行自动化

如果你明确需要下面任意一项,建议同时保留 CLI/Web 路线:

  • 使用 Headless 在脚本或 CI 中运行任务;
  • 在没有图形界面的机器上使用;
  • 创建和管理自定义 CLI Profile;
  • 调试插件或从源码开发 Harness;
  • 通过标准输入和 JSON 事件流驱动任务。

如果你当前只是想完成本教程,不必提前安装两套。桌面端用户会在第15章需要 Headless 时再补 CLI 环境。

3. 你只是运行 DSH,还是还要运行项目

这是最容易被忽略的一点。

桌面端自带的 Node.js 和 pnpm 是给 DSH 自身及插件安装使用的私有运行环境,不会自动加入 Agent Shell 的 PATH。也就是说:桌面端可以在系统没有 Node.js 时启动,但 Agent 不一定能在终端里运行一个 Node.js 项目。

本教程的「日报助手」正是 Node.js 项目,因此无论选择哪条 DSH 路线,都需要让系统终端能够执行:

$ node -v
$ npm -v

二者都显示版本号,才说明日报助手具备运行条件。区别只是:

  • 桌面端用户安装 Node.js 是为了运行练习项目;
  • CLI/Web 用户安装 Node.js 既是为了运行 DSH,也是为了运行练习项目。

Node.js 应该装哪个版本

以 v0.1.7-rc.2 对应的官方仓库配置为准,DSH 的 Node.js 要求是:

^22.19.0 或 >=24.0.0

因此,本教程推荐安装符合要求的 Node.js 22 LTS 版本,并确认小版本不低于 22.19.0;如果你使用更新的 24 或更高版本,也要留意第三方插件的兼容性。官方 package.json

不要继续沿用旧教程中“Node.js 20 或更高”的说法。当前 DSH 的版本约束已经更高,Node 20 即使能执行部分命令,也不属于官方声明的兼容范围。

开始前准备四样东西

1. 一个专门的练习目录

不要把个人主目录、整个“文档”目录或正在工作的公司仓库直接交给 Agent。先准备一个空目录,例如:

Documents/dsh-learning/daily-report

第7章会把这个空目录添加为工作区,并在里面创建日报助手。目录中不要放密钥、私人文件或其他不希望 Agent 读取的内容。

2. 可用的模型访问方式

后面第一次真正发送任务前,需要在下面两种方式中至少准备一种:

  • 可以登录 DeepSeek Harness 的账号;
  • 一个可用的模型 API Key。

API Key 可以来自 DeepSeek 官方 Provider、内置第三方 Provider 或兼容 API。现在不需要把密钥复制到文本文件,更不要放进项目目录;第7、8章会在产品提供的凭证界面中配置。

3. 可以访问必要服务的网络

根据所选路线,安装过程可能访问:

  • DeepSeek Harness 官方发布页;
  • npm 包仓库;
  • 模型 Provider 的 API;
  • 后续插件使用的官方源或国内镜像。

如果网页能打开但下载或 npm 安装失败,不要反复重装系统环境。先记录失败的域名和报错,第4~6章会给出对应检查方法,第10章还会说明插件镜像的选择。

4. 一点可恢复空间

安装前确认系统磁盘不是接近写满状态。桌面端包含应用运行时,CLI 首次通过 npx 启动也会下载并缓存包;后续插件、会话和工作区文件还会继续占用空间。

不需要为了教程关闭杀毒软件或系统安全功能。遇到拦截时,应先核对文件来源、签名和具体权限,而不是把所有保护永久关闭。

先检查你现在的状态

打开系统终端,运行:

$ node -v
$ npm -v

可能出现三种情况:

情况 A:两条命令都有符合要求的版本

例如:

v22.19.0
10.x.x

说明 Node.js 项目环境已经具备。下一章只需安装或启动 DSH。

情况 B:提示找不到命令

说明系统还没有可用的 Node.js。进入对应系统章节安装:

  • macOS:第4章;
  • Linux:第5章;
  • Windows:第6章。

情况 C:有版本,但不满足 DSH 要求

先不要急着全局安装 DSH。按对应系统章节使用版本管理器或官方安装方式升级,然后重新打开终端验证。

如果电脑上有其他项目依赖旧版 Node.js,优先使用版本管理器,不要直接删除原项目依赖的环境。

选定路线并记录下来

继续之前,应该能完成下面这张检查表:

  • 我选择了桌面端或 CLI/Web 作为当前主路线;
  • 我知道桌面端与 CLI 的插件状态不会自动同步;
  • 我准备了一个不含私人文件的空练习目录;
  • 我知道后面使用账号登录还是 API Key;
  • 系统终端中的 Node.js 满足练习项目需要,或者我知道去下一章安装;
  • 安装包只从 DeepSeek 官方页面或官方 GitHub Releases 获取。

下一章从 macOS 开始。macOS 用户会先安装桌面端,再补齐练习项目需要的 Node.js;选择 CLI/Web 的用户则直接准备 Node.js 和 DSH 命令。


← 上一章:DeepSeek Harness 能做什么 | 回目录 | 下一章:macOS 安装 →

版本与桌面 CLI 的区别

公共 npm CLI 与桌面附带的 dsh 命令不是同一条安装路线。官方 dsh-v0.2.0-rc.2 已增加桌面应用菜单中的 dsh 命令安装/管理入口,可管理桌面插件,不需要为此另装 Node 或 pnpm;菜单文案按该发行版实际语言显示。本文后续公共 CLI 实验继续使用显式固定的旧基线,桌面用户不要拿它直接管理 Desktop Profile。若迁移到新版,先备份配置并在独立 Profile 验证,而不是把部分参数混入旧命令。

参考:官方发行说明。


05 macOS安装

本文属于《DeepSeek Harness 入门教程(实战版)》· 第二部分 · 安装并完成第一次启动

第 4 章 macOS 安装

这一章提供两条路线:

  • 想尽快开始,安装 DeepSeek Harness 桌面端;
  • 明确需要 Headless、自定义 Profile 或命令行环境,安装 CLI/Web。

两条路线任选其一即可。不过,「日报助手」是一个 Node.js 项目,即使你选择桌面端,也要在本章最后确认系统终端能够运行 Node.js。

4.1 先确认 Mac 的处理器架构

点击屏幕左上角的苹果菜单,打开“关于本机”,查看“芯片”或“处理器”:

  • 显示 Apple M 系列芯片,选择 Apple Silicon / arm64 安装包;
  • 显示 Intel,选择 Intel / x64 安装包。

也可以在“终端”中执行:

$ uname -m

输出 arm64 表示 Apple Silicon,输出 x86_64 表示 Intel。下载错误架构的安装包,常见结果是无法启动或直接提示不兼容。

4.2 推荐路线:安装桌面端

第一步:从官方发布页下载

打开 DeepSeek Harness 官方 Releases 页面,进入本教程基线版本 v0.1.7-rc.2 或更新的正式发布项,在 Assets 中选择与你的 macOS 架构匹配的安装包。

版本仍处于快速迭代期,文件名和可用架构可能变化,所以不要照抄第三方文章里的旧下载地址。只从 DeepSeek 官方页面或 deepseek-ai/deepseek-harness 官方仓库获取安装包。

第二步:安装应用

下载完成后:

  1. 双击下载的 macOS 安装包;
  2. 如果看到应用图标和“Applications”文件夹,把 DeepSeek Harness 拖入“Applications”;
  3. 打开“应用程序”,双击 DeepSeek Harness;
  4. macOS 第一次提示“这是从互联网下载的应用”时,确认来源无误后选择打开。

如果系统提示应用损坏、签名异常或开发者无法验证,先停止操作,重新确认文件来自官方发布页并重新下载。不要一上来就执行网上流传的 xattr、关闭 Gatekeeper 或其他绕过系统验证的命令。

第三步:完成首次启动引导

应用第一次启动时会进入欢迎与初始化流程。当前版本会引导你了解可用额度、选择主要用途,以及设置工作过程显示的详细程度;中途关闭后可以继续完成。v0.1.7-rc.2 更新说明

这一章只确认应用能够启动,不必急着研究所有选项:

  1. 按欢迎页提示继续;
  2. 遇到账号或 API Key 选择时,可以完成登录,也可以选择稍后配置;
  3. 进入主界面后,确认左侧出现工作区区域,中间出现空白会话或新任务入口;
  4. 如果系统要求选择目录,暂时选择第3章准备的 daily-report 空目录。

全新安装会创建默认工作区和空白会话,因此没有立刻出现文件夹选择器也属于正常情况。第7章会重新确认工作区,再发送第一条真正的任务。

第四步:核对版本

在 macOS 顶部菜单栏打开“DeepSeek Harness”菜单,选择“关于 DeepSeek Harness”,确认能够看到当前安装版本。

版本可以比教程的 v0.1.7-rc.2 更新,但如果跨度较大,后续按钮名称可能不同。遇到差异时,先阅读安装版本对应的发布说明。

4.3 桌面端关闭以后,任务是否还在运行

macOS 左上角的红色窗口按钮只是关闭窗口,不等于退出应用。当前版本中,关闭桌面窗口后,正在执行的任务可以继续在后台运行;真正退出应用前,系统会提示对运行中任务的影响。v0.1.7-rc.2 更新说明

可以用下面的方法判断:

  • Dock 中应用图标下仍有运行标记:应用通常还在后台;
  • 再次点击图标,原工作区和会话重新出现:说明刚才只是关窗;
  • 使用菜单栏“DeepSeek Harness → 退出 DeepSeek Harness”或按 Command + Q:才是退出应用。

以后执行长任务时,不要因为窗口关闭就立刻重复提交同一任务;先重新打开应用查看原任务状态。

4.4 CLI/Web 路线:先准备 Node.js

如果你选的是桌面端,可以先跳到 4.6;如果选择 CLI/Web,Node.js 必须满足 DSH 当前要求:^22.19.0 或 >=24.0.0。

方式 A:Node.js 官方安装包

对只需要一个 Node.js 版本的初学者,这是最直接的方式:

  1. 打开 Node.js 官方下载页;
  2. 选择 macOS 安装包;
  3. 选择符合 DSH 要求的 Node.js 22 LTS,并确认版本不低于 22.19.0;
  4. 双击 .pkg,按安装向导完成;
  5. 关闭并重新打开“终端”。

方式 B:nvm

如果你的其他项目还依赖不同 Node.js 版本,使用 nvm 官方仓库给出的最新安装方法。nvm 生效后执行:

$ nvm install 22
$ nvm use 22
$ nvm alias default 22

nvm install 22 会安装当前可用的 Node.js 22.x。安装后仍要检查实际小版本是否满足要求。

验证 Node.js

重新打开终端,执行:

$ node -v
$ npm -v

示例结果:

v22.19.0
10.x.x

具体 npm 版本不必与示例相同。关键是两条命令都存在,并且 Node.js 满足版本范围。

4.5 CLI/Web 路线:启动 DSH

第一次体验建议直接使用 npx,不必全局安装:

$ npx @deepseek-ai/dsh@0.1.7-rc.2 web

首次运行会下载官方 npm 包。终端随后应打印本地访问地址,并自动打开默认浏览器;默认地址通常是:

http://127.0.0.1:3080

页面能打开并显示 DSH 主界面,说明 CLI/Web 已经可以使用。此时不要关闭运行命令的终端,否则 Web 服务会停止。

如果不希望自动打开浏览器,可以使用:

$ npx @deepseek-ai/dsh@0.1.7-rc.2 web --no-open

需要长期使用 dsh 短命令时,可以在 nvm 管理的 Node.js 环境中安装:

$ npm install -g @deepseek-ai/dsh
$ dsh --version
$ dsh web

不要用 sudo npm install -g ... 解决权限错误。它容易在 npm 缓存和全局目录中留下 root 所有的文件。出现 EACCES 时,优先使用 nvm,或者继续用无需全局安装的 npx 路线。

4.6 为日报助手准备 Node.js

如果你选择桌面端,DSH 本身已经能运行,但还需要检查练习项目能不能运行。

打开 macOS“终端”,执行:

$ node -v
$ npm -v
  • 有符合要求的版本:可以继续;
  • 找不到命令:按 4.4 安装 Node.js;
  • 版本较旧:使用官方安装包或 nvm 升级。

桌面端内置的私有 Node.js 不会自动进入 Agent Shell 的 PATH,所以不能用“应用能打开”代替这一步验证。

然后在 Finder 中建立以下空目录,或者使用你自己的等价位置:

文稿/dsh-learning/daily-report

确认目录中没有私人文件、密钥或其他项目。第7章会把它添加为工作区。

4.7 常见问题

现象 先检查什么 处理方法
桌面应用无法打开 安装包来源与芯片架构 从官方 Releases 重新下载匹配架构的安装包,不要先关闭系统安全校验
关闭窗口后 Dock 仍显示运行 只是关窗,没有退出 需要彻底停止时用应用菜单退出或按 Command + Q
node: command not found 系统 Node.js 未安装或终端未刷新 安装后重开终端;使用 nvm 时确认 shell 初始化已生效
npm install -g 报 EACCES npm 全局目录权限不属于当前用户 改用 nvm 或 npx,不要使用 sudo npm
npx 下载失败 包名或 npm 网络 确认包名是 @deepseek-ai/dsh,保留完整报错并检查 npm 连接
浏览器没有自动打开 自动打开被系统阻止 手动打开终端打印的地址;或检查命令是否仍在运行
端口 3080 被占用 本机已有服务使用该端口 根据 dsh web --help 查看当前版本的端口选项,再换一个未占用端口

4.8 完成检查

选择桌面端时:

  • DeepSeek Harness 能从“应用程序”正常打开;
  • “关于 DeepSeek Harness”能显示版本;
  • 主界面能显示工作区和会话区域;
  • 系统终端中的 node -v 与 npm -v 可用。

选择 CLI/Web 时:

  • Node.js 版本满足要求;
  • npx @deepseek-ai/dsh@0.1.7-rc.2 web 能启动;
  • 浏览器能打开终端打印的本地地址;
  • 关闭该终端进程后,Web 页面停止连接。

macOS 用户可以跳过接下来的 Linux 和 Windows 安装章节,直接前往第7章创建日报助手。


← 上一章:选择桌面端还是 CLI/Web | 回目录 | 下一章:Linux 安装 →


06 Linux安装

本文属于《DeepSeek Harness 入门教程(实战版)》· 第二部分 · 安装并完成第一次启动

第 5 章 Linux 安装:用 Web UI 跑起 DSH

Linux 版 DeepSeek Harness 的使用路线和 macOS、Windows 略有不同:目前官方桌面客户端主要面向 macOS 和 Windows,Linux 用户更适合用命令行启动 DSH,再在浏览器里操作 Web UI。

这并不意味着 Linux 版只有一块黑色终端。终端只是负责启动服务,真正的对话、配置和任务执行仍然在图形化页面里完成。本章会分别处理两种情况:

  • 你的 Linux 电脑有桌面和浏览器;
  • 你通过 SSH 连接一台没有图形界面的 Linux 服务器。

以下步骤以 Ubuntu、Debian 为主。其他发行版只在安装 Node.js 时有所不同,DSH 的安装和启动命令完全相同。

5.1 先确认 Node.js 版本要求

DSH 通过 npm 分发,因此系统里必须先有 Node.js。按照本教程核对时的官方要求,可用的版本是:

  • Node.js 22.19.0 或更高的 22.x;
  • Node.js 24.0.0 或更高版本。

如果电脑里已经装过 Node.js,先执行:

node -v
npm -v

第一条命令应输出类似 v22.22.1 或 v24.x.x 的结果。只看到 v22 还不够,要继续确认小版本不低于 22.19.0。如果出现 node: command not found,或版本低于要求,继续完成下一节。

DSH 仍处于 Developer Preview,版本要求可能继续变化。以后若安装时出现 Unsupported engine,请以 DSH 官方仓库 中 package.json 的 engines.node 为准。

5.2 安装 Node.js:优先使用 nvm

nvm 会把 Node.js 安装在当前用户目录,不会修改系统自带的 Node,也不需要用 sudo npm。对个人电脑、开发机和普通云服务器来说,这条路线最省心。

第一步:准备下载工具

Ubuntu、Debian 可以这样安装 curl 和证书包:

sudo apt update
sudo apt install -y curl ca-certificates

第二步:安装 nvm

nvm 官方会不断更新安装脚本的版本号。打开 nvm 官方仓库的 Installing and Updating,复制其中最新的 curl 安装命令执行。

以本文核对时的官方命令为例:

curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.8/install.sh | bash

这条命令会下载脚本并立即执行。如果你所在的团队不允许直接执行网络脚本,应先从官方仓库下载并审查 install.sh,再在本地运行;不要从不明博客复制同名脚本。

安装结束后,最稳妥的做法是关闭当前终端,再打开一个新终端。也可以根据自己使用的 Shell 手动重新载入配置:

# Bash
source ~/.bashrc

# Zsh
source ~/.zshrc

两组命令只执行与你所用 Shell 对应的一组。然后验证:

command -v nvm

正常结果是 nvm。这里不要用 which nvm 判断,因为 nvm 是 Shell 函数,不是普通的可执行文件。

第三步:安装符合要求的 Node.js

本教程统一使用 Node.js 22:

nvm install 22
nvm use 22
nvm alias default 22

再检查一次:

node -v
npm -v
command -v node

你应看到不低于 v22.19.0 的版本;command -v node 返回的路径通常位于 ~/.nvm/ 下。这样以后打开新终端,也会默认使用刚安装的 Node.js。

如果你坚持使用系统包管理器

服务器管理员有时会要求所有软件都由 apt 管理。可以先查看软件源准备安装哪个版本:

sudo apt update
apt-cache policy nodejs

找到输出中的 Candidate。只有它不低于 22.19.0 时,才继续安装:

sudo apt install -y nodejs npm
node -v
npm -v

Ubuntu、Debian 的稳定软件源可能提供较旧的 Node.js。如果候选版本不满足要求,不要勉强安装,也不要随手执行第三方网站提供的 curl | sudo bash 命令;改用前面的 nvm 路线,或遵循你所在组织批准的软件源方案。

5.3 第一次运行 DSH

初次体验不必先全局安装。npx 会下载当前版本并直接运行,既方便试用,也避免全局命令的 PATH 问题。

先准备一个课程目录:

mkdir -p ~/dsh-learning
cd ~/dsh-learning

检查 DSH 是否能正常启动:

npx @deepseek-ai/dsh@0.1.7-rc.2 --version

第一次运行时,npm 可能询问是否下载 @deepseek-ai/dsh,输入 y 并回车。随后应该看到 DSH 的版本号。版本可能比本文使用的 0.1.7-rc.2 更新,这是正常现象。

接下来启动 Web UI:

npx @deepseek-ai/dsh@0.1.7-rc.2 web

正常情况下,终端会显示一个以 http://127.0.0.1:3080 开头的地址:

  • 有桌面环境时,DSH 会尝试打开默认浏览器;
  • 浏览器没有自动打开时,手动输入终端显示的地址即可;
  • 这个终端需要保持运行,关闭终端或按 Ctrl+C 会停止 DSH。

页面能正常打开,就说明 Node.js、npm、DSH 和本机 Web 服务这四个环节都已通过验证。此时先不急着配置模型,后面的章节会统一完成。

可选:全局安装

如果你确定会长期使用,也可以安装全局命令:

npm install -g @deepseek-ai/dsh
dsh --version
dsh web

使用 nvm 安装的 Node.js 时,全局包仍然属于当前用户,一般不会遇到权限问题。请不要在命令前加 sudo;一旦混用 sudo npm,后续很容易留下 root 所有的缓存和配置文件。

全局安装不是后续学习的前提。拿不准时,继续使用 npx @deepseek-ai/dsh@0.1.7-rc.2 ... 就可以。

5.4 在没有桌面的服务器上使用

假设 DSH 装在远程服务器,而你正在自己的电脑上通过 SSH 操作。服务器没有浏览器,此时应让 DSH 只负责启动服务,再用 SSH 隧道把页面安全地带回本机。

第一步:从本机建立 SSH 隧道

在你自己的电脑上打开终端,执行:

ssh -L 3080:127.0.0.1:3080 用户名@服务器地址

把 用户名 和 服务器地址 换成真实值。登录成功后不要关闭这个 SSH 窗口。

第二步:在服务器上启动 DSH

仍在刚才登录后的远程 Shell 中执行:

cd ~/dsh-learning
npx @deepseek-ai/dsh@0.1.7-rc.2 web --no-open

--no-open 表示只启动服务,不尝试调用服务器上的浏览器。SSH 场景下,DSH 也可能只打印地址而不自动打开页面,这不是故障。

第三步:在本机浏览器访问

在你自己的电脑上打开:

http://127.0.0.1:3080

如果页面能打开,说明隧道已经生效。结束使用时,先在远程 Shell 按 Ctrl+C 停止 DSH,再输入 exit 关闭 SSH 连接。

如果本机的 3080 端口已被占用,可以只更换隧道左侧的本地端口:

ssh -L 3081:127.0.0.1:3080 用户名@服务器地址

这时浏览器访问 http://127.0.0.1:3081,服务器上的 DSH 仍然使用 3080。

不要为了省一步,把 DSH 的 3080 端口直接暴露到公网。SSH 隧道让服务继续监听服务器本机回环地址,同时只对经过认证的 SSH 用户开放访问,边界更清楚。

5.5 常见问题:按现象排查

nvm: command not found

先关闭终端并重新打开。如果仍然无效,确认自己的 Shell:

echo $SHELL

Bash 执行 source ~/.bashrc,Zsh 执行 source ~/.zshrc。再用 command -v nvm 检查。不要用 which nvm 作为判断依据。

装了 Node 22,node -v 仍显示旧版本

执行:

nvm use 22
command -v node
node -v

如果路径没有指向 ~/.nvm/,通常是当前 Shell 没有正确载入 nvm,回到上一项处理。

npm 提示 EACCES: permission denied

不要改用 sudo npm install -g ...。先运行:

command -v node
npm config get prefix

如果 Node 不是来自 ~/.nvm/,切回 nvm 安装的 Node;如果暂时不想处理全局目录,直接使用 npx @deepseek-ai/dsh@0.1.7-rc.2 web,它已经足够完成本教程。

npx 下载失败或长时间没有进度

先分别检查 DNS、HTTPS 和 npm 仓库:

curl -I https://github.com
npm ping
npm view @deepseek-ai/dsh version

前两项失败通常是网络、DNS、代理或证书问题;最后一项失败则要继续检查 npm 的 registry 设置:

npm config get registry

公司网络或镜像站的配置各不相同,优先按组织的网络规范处理。不要把代理密码或访问令牌直接贴进聊天窗口。

终端显示已启动,浏览器却打不开

先确认你在哪台机器上运行了 DSH:

  • 本机 Linux:打开终端打印的 127.0.0.1 地址;
  • 远程服务器:不能在自己电脑上直接访问“服务器的 127.0.0.1”,要按 5.4 建立 SSH 隧道;
  • 页面曾经能打开,后来失联:检查运行 DSH 的终端是否被关闭,或进程是否已被 Ctrl+C 停止。

3080 端口被占用

先查看当前版本提供的参数:

npx @deepseek-ai/dsh@0.1.7-rc.2 web --help

使用帮助中列出的端口选项启动到其他端口。不要凭旧文章猜参数名,因为 DSH 仍在快速迭代。若问题只发生在 SSH 隧道的本机一侧,则按 5.4 把本地端口改为 3081 即可。

5.6 本章验收

进入下一章前,请确认下面几项都成立:

  • node -v 不低于 v22.19.0,或使用 Node.js 24 及以上版本;
  • npm -v 能正常输出版本号;
  • npx @deepseek-ai/dsh@0.1.7-rc.2 --version 能输出 DSH 版本;
  • npx @deepseek-ai/dsh@0.1.7-rc.2 web 能启动服务;
  • 本机或经过 SSH 隧道后,浏览器能打开 DSH 页面;
  • 你知道 Ctrl+C 会停止服务,也没有把 3080 端口直接暴露到公网。

做到这些,Linux 安装就算真正完成了。下一章处理 Windows;如果你只使用 Linux,可以直接读完 Windows 章节的路线差异,再进入首次配置。


← 上一章:macOS 安装 | 回目录 | 下一章:Windows 安装 →


07 Windows安装

本文属于《DeepSeek Harness 入门教程(实战版)》· 第二部分 · 安装并完成第一次启动

第 6 章 Windows 安装

Windows 用户现在不必先装 WSL,也不必为了打开 DeepSeek Harness 配置一整套 Node.js 环境。最省事的路线是直接安装官方桌面端:它自带运行 DSH 所需的环境,装好就能进入图形界面。

不过,本教程后面要做一个 Node.js 版“日报助手”。桌面端能启动,不代表 Agent 所在的系统 Shell 已经能执行 node。因此本章会完成两件事:

  1. 安装并验证 DeepSeek Harness 桌面端;
  2. 为练习项目准备系统级 Node.js。

如果你明确需要命令行、自动化或 WSL,本章后半部分也保留对应路线。三条路线不需要同时安装。

6.1 先确认 Windows 架构

打开“设置 → 系统 → 系统信息”,在“系统类型”一项查看处理器架构:

  • 显示“基于 x64 的处理器”,可以安装当前官方 Windows x64 桌面端;
  • 显示“基于 ARM 的处理器”,不要直接假设 x64 安装包一定兼容,优先使用后面的 CLI/Web 路线,或查看最新发布是否已经提供 Windows ARM64 包。

当前官方构建目标是 win-x64。版本仍在快速迭代,下载前应以 DeepSeek Harness 官方 Releases 页面 中实际列出的安装包为准。

6.2 推荐路线:安装桌面端

第一步:从官方发布页下载安装包

打开官方 Releases 页面,进入本教程基线版本 v0.1.7-rc.2 或更新版本,在 Assets 中下载文件名带有 win-x64、扩展名为 .exe 的安装程序。

下载前确认两件事:

  • 仓库所有者是 deepseek-ai,仓库名是 deepseek-harness;
  • 下载地址来自官方发布页或 download.deepseek.com,而不是搜索结果中的第三方网盘或社区重新打包版本。

网上已经出现过多个同名的非官方桌面客户端。它们未必恶意,但版本、更新机制和签名都不属于 DeepSeek 官方教程的验证范围,不要与本章的桌面端混用。

第二步:完成安装

双击下载的 .exe 文件。当前 Windows 安装程序只为当前用户安装,一般不需要以管理员身份运行。桌面端官方说明记录了安装、更新和数据保留边界。按安装向导完成下面几步:

  1. 确认安装目标目录;没有特殊要求时保留默认位置;
  2. 点击“安装”;
  3. 等待进度完成;
  4. 保留完成页上的“立即启动”选项,再点击“完成”。

如果你手动选择新目录,请使用空目录。安装程序会拒绝把新安装写入一个已有其他文件的普通目录,这是为了避免覆盖个人文件。

第三步:正确处理 Windows 安全提示

安装包可能经过 Microsoft Defender、SmartScreen 或公司终端安全软件检查。遇到拦截时,不要先关闭 Defender,也不要把整个下载目录加入白名单。按这个顺序处理:

  1. 再次核对文件是否来自官方发布页;
  2. 右键安装包,打开“属性 → 数字签名”,检查签名状态;
  3. 在“Windows 安全中心 → 病毒和威胁防护 → 保护历史记录”查看具体原因;
  4. 公司电脑被策略阻止时,把官方发布链接和告警信息交给管理员确认。

如果签名缺失、无效,或者发布者与官方来源对不上,应停止安装并重新下载。不要因为教程需要继续,就绕过来源不明的安全警告。

第四步:完成首次启动

桌面端第一次打开时,会先准备本地运行环境,然后进入欢迎引导。当前版本会介绍可用额度,并让你选择主要用途和工作过程的展示方式;中途关闭后可以继续。v0.1.7-rc.2 更新说明

这一章只做最小配置:

  1. 按欢迎页提示继续;
  2. 出现账号登录或 API Key 入口时,可以先登录,也可以稍后再配;
  3. 进入主界面后,确认左侧能看到工作区区域,中间能看到新任务或空白会话入口;
  4. 暂时不要安装第三方插件,也不要随意选择包含私人资料的大目录。

账号、Provider 和模型会在第8章统一解释。现在能进入主界面,就说明桌面端的安装和 Host 启动已经成功。

第五步:核对版本和更新

Windows 版顶部有“应用”菜单。打开“应用 → 检查更新”:

  • 没有更新时,更新窗口会显示当前安装版本;
  • 有更新时,先结束重要任务并保存工作,再按提示安装和重启。

桌面壳、内置 DSH 运行时和包管理器是同一个更新单元,不需要再单独升级桌面端内部的 @deepseek-ai/dsh。官方的 Desktop 和 CLI/Web 可以装在同一台电脑上,但它们使用各自的 Profile 和插件依赖,不要把“CLI 已更新”当成“Desktop 已更新”。

6.3 关闭窗口,不等于退出应用

Windows 版会常驻系统托盘。点击右上角的“×”时,第一次会提示窗口将被隐藏;确认后,窗口消失,但正在运行的任务不会因此中断。这个行为属于 Desktop 的后台生命周期设计,而不是程序没有成功关闭窗口。

可以这样判断应用是否还在运行:

  • 查看任务栏右侧的系统托盘,必要时点击“显示隐藏的图标”;
  • 单击 DeepSeek Harness 托盘图标,原窗口会重新显示;
  • 右键托盘图标,选择“退出 DeepSeek Harness”,才会真正停止应用;
  • 也可以在窗口顶部使用“应用 → 退出”。

真正退出前,如果存在运行中的任务或已经启用的定时任务,桌面端会提示退出造成的影响。以后执行长任务时,不要因为关窗后没看到界面,就重复提交同一个请求;先从托盘恢复窗口检查状态。

6.4 为日报助手安装 Node.js

桌面端自带一套私有运行时,但这套 Node.js 不会自动加入 Windows 的 PATH,也不会替你配置项目 Shell。后面要让 Agent 执行 node 和 npm,仍需安装系统级 Node.js。

DSH 当前支持的 Node.js 范围是 ^22.19.0 或 >=24.0.0。为了让桌面端项目和 CLI/Web 都能使用同一套环境,建议安装符合该范围的 LTS 版本。

方式 A:Node.js 官方安装包

对初学者来说,这条路线最直接:

  1. 打开 Node.js 官方下载页;
  2. 选择 Windows Installer(.msi),并选择与你电脑匹配的 x64 或 ARM64 架构;
  3. 确认版本满足前面的范围;
  4. 双击安装包,保留“Add to PATH”等默认选项完成安装;
  5. 关闭已经打开的 PowerShell,再新开一个窗口。

方式 B:winget

如果系统已有 winget,也可以在普通 PowerShell 中执行:

winget install OpenJS.NodeJS.LTS

安装结束后关闭 PowerShell,再重新打开。winget 找不到命令时,无需先修复它,直接使用方式 A 即可。

验证系统 Node.js

在新开的 PowerShell 中执行:

node -v
npm -v
Get-Command node

你应看到不低于 v22.19.0 的 22.x,或 v24.0.0 以上版本。Get-Command node 还应显示一个 Windows 文件路径,这能证明当前 Shell 找到的是系统 Node,而不是“桌面应用能打开”带来的错觉。

接着创建练习目录:

$coursePath = Join-Path ([Environment]::GetFolderPath('MyDocuments')) 'dsh-learning\daily-report'
New-Item -ItemType Directory -Force -Path $coursePath
Set-Location $coursePath
Get-Location

最后一条命令应显示位于“文档”目录下的 dsh-learning\daily-report。先保持这个目录为空,第7章会把它选为工作区并创建第一批文件。

6.5 可选路线:在 PowerShell 中运行 CLI/Web

需要 Headless、脚本化启动或自定义 CLI Profile 时,可以直接复用刚安装的系统 Node.js。先在普通 PowerShell 中执行:

npx @deepseek-ai/dsh@0.1.7-rc.2 --version

第一次运行可能询问是否下载 @deepseek-ai/dsh,输入 y 并回车。随后启动 Web UI:

npx @deepseek-ai/dsh@0.1.7-rc.2 web

正常情况下,终端会打印本地地址并打开默认浏览器,默认地址通常是:

http://127.0.0.1:3080

运行命令的 PowerShell 需要保持打开。按 Ctrl+C 后,服务停止,页面也会断开。

PowerShell 提示“禁止运行脚本”怎么办

部分电脑的执行策略会阻止 npx.ps1,常见报错包含 running scripts is disabled。不必为了运行 DSH 永久放宽全系统策略,直接调用 Node 安装附带的 .cmd 入口:

npx.cmd @deepseek-ai/dsh --version
npx.cmd @deepseek-ai/dsh web

如果这样能运行,说明 Node 和 DSH 本身没有问题,只是 PowerShell 拦截了 .ps1 命令包装器。公司电脑是否允许调整执行策略,应遵循组织要求。

可选:安装全局命令

确定长期使用 CLI 时,可以执行:

npm install -g @deepseek-ai/dsh
dsh --version
dsh web

如果 npm 或 dsh 同样被 PowerShell 的脚本策略拦截,可以改用 npm.cmd、dsh.cmd。全局安装不是本教程的前提,拿不准时继续使用 npx 即可。

6.6 可选路线:在 WSL2 中运行

WSL2 适合已经在 Linux 环境里开发,或者明确需要 Linux 命令、依赖和自动化脚本的用户;它不再是普通 Windows 用户运行 DSH 的默认前提。

如果你选择 WSL2:

  1. 以管理员身份打开 PowerShell,执行 wsl --install;
  2. 按系统提示重启并创建 Linux 用户;
  3. 在 WSL 终端中执行 wsl 版本对应的 Linux 命令,而不是 PowerShell 命令;
  4. 完整按照第5章在 WSL 内安装 nvm、Node.js 和 DSH;
  5. 在 WSL 中执行 npx @deepseek-ai/dsh@0.1.7-rc.2 web,再用 Windows 浏览器打开终端打印的 localhost 地址。

用下面的命令确认发行版运行在 WSL2:

wsl --list --verbose

输出表格的 VERSION 一列应为 2。若 WSL 安装失败或要求启用虚拟化,请以 Microsoft 官方 WSL 安装文档 为准,不要从不明脚本修改系统组件。

还有两个容易混淆的边界:

  • PowerShell 和 WSL 是两套环境。Windows 里装过 Node,不代表 WSL 里也有;反过来也一样;
  • Desktop、PowerShell CLI 和 WSL CLI 的运行配置与插件可能彼此独立。课程主线只选一条路线,不要求三边重复配置。

如果主项目放在 WSL 中,建议放在 Linux 用户目录下,例如 ~/dsh-learning/daily-report,而不是在 Windows 与 Linux 两边来回改同一份依赖目录。

6.7 更新、卸载与数据边界

桌面端更新优先使用应用内的“应用 → 检查更新”。安装更新前先结束运行中的任务;更新需要重启时,界面会给出提示。

需要卸载时,打开“设置 → 应用 → 已安装的应用”,搜索 DeepSeek Harness,点击右侧菜单并选择“卸载”。如果安装程序提示应用仍在运行,先从系统托盘真正退出,而不只是关闭窗口。

当前官方卸载程序会删除桌面壳的浏览器数据、缓存和更新下载缓存,但保留 Harness 主目录中的会话、设置、凭据和插件。默认主目录通常是:

%USERPROFILE%\.dsh

保留它便于以后重装恢复,但也意味着“卸载应用”不等于“删除所有账号与凭据”。如果你准备转让电脑或确实要清空数据,应先备份需要的会话,再打开该目录核对内容;不要在没确认路径时整目录删除。

6.8 常见问题:按现象处理

双击安装包没有反应,或被 Defender 拦截

先核对来源和数字签名,再到“Windows 安全中心 → 保护历史记录”查看原因。不要关闭实时保护。如果是公司策略,应交给管理员确认;如果文件来源或签名异常,删除该安装包并从官方 Releases 重新下载。

点击“×”后找不到应用

它通常只是隐藏到了系统托盘。点击任务栏右侧的上箭头,找到 DeepSeek Harness 图标并单击。如果托盘中也没有,再从开始菜单重新打开。

安装更新时提示应用仍在运行

右键系统托盘中的 DeepSeek Harness,选择“退出 DeepSeek Harness”,确认任务中断提示后再继续安装。只关闭主窗口不能结束后台 Host。

node 或 npm 无法识别

关闭所有旧 PowerShell 窗口,再开一个新窗口执行:

Get-Command node
Get-Command npm

仍找不到时,重新运行 Node.js 官方安装包并确认启用 PATH 选项。桌面端自带 Node 不能替代这一步。

dsh 无法识别

如果你只使用 npx,系统本来就不会有全局 dsh 命令,继续执行 npx @deepseek-ai/dsh@0.1.7-rc.2 web 即可。如果已经全局安装,关闭并重开 PowerShell,再检查:

npm config get prefix
Get-Command dsh -ErrorAction SilentlyContinue

不要为了修复 PATH,随意把不明目录加入系统环境变量。

Web 页面打不开

确认启动 DSH 的 PowerShell 仍在运行,并以终端实际打印的地址为准。若提示端口占用,先查看当前版本的帮助:

npx @deepseek-ai/dsh@0.1.7-rc.2 web --help

使用帮助中列出的端口选项换一个端口,不要凭旧教程猜参数名。也不要因为本机回环地址打不开,就直接把 3080 端口开放到公网。

Agent 不能在“文档”目录创建文件

先确认工作区确实选中了 daily-report,再查看 Windows 安全中心中的“勒索软件防护/受控文件夹访问”是否拦截。只为可信的官方应用和明确的项目目录授予必要权限,不要直接关闭整项保护。

6.9 本章验收

选择桌面端时,请确认:

  • DeepSeek Harness 能从开始菜单打开;
  • 主界面能显示工作区和新任务区域;
  • “应用 → 检查更新”能显示当前版本或更新结果;
  • 关闭窗口后能从系统托盘恢复,真正退出时知道使用托盘菜单;
  • 新开的 PowerShell 中,node -v 和 npm -v 可用;
  • “文档”目录下已经有空的 dsh-learning\daily-report 文件夹。

选择 CLI/Web 时,请确认:

  • Node.js 版本满足当前要求;
  • npx @deepseek-ai/dsh@0.1.7-rc.2 --version 能输出版本;
  • npx @deepseek-ai/dsh@0.1.7-rc.2 web 能启动本地页面;
  • 按 Ctrl+C 后,Web 页面停止连接。

完成这些检查,安装阶段就结束了。下一章不再讲配置表,而是直接把 daily-report 设为工作区,让 DSH 完成第一次真实任务。


← 上一章:Linux 安装 | 回目录 | 下一章:第一次对话:让 DSH 接手日报助手 →


08 案例一-第一次对话

本文属于《DeepSeek Harness 入门教程(实战版)》· 第二部分 · 安装并完成第一次启动

第 7 章 第一次对话:让 DSH 接手日报助手

前面六章把 DSH 和项目运行环境准备好了。现在先不研究 Provider、Agent 预设和插件配置,直接完成一次足够小、又能认真验收的任务:让 DSH 在空工作区中创建“日报助手”的项目说明和资讯源配置。

这一章结束时,daily-report 目录里应该只有两个新文件:

daily-report/
├── PROJECT.md
└── sources.json

我们暂时不让 Agent 一口气写完整程序。第一次任务如果同时涉及联网、代码、测试和多次修复,出了问题很难判断卡在哪一层。先用两个文件走通“选择工作区 → 新建会话 → 审查权限 → 执行任务 → 独立验收”的闭环,后面再逐步加功能。

7.1 确认起点

开始前请确认:

  • DeepSeek Harness Desktop 已经打开,或者 CLI/Web 页面仍能访问;
  • 系统终端中的 node -v、npm -v 能输出版本;
  • 已经准备好一个空的 daily-report 目录;
  • 目录中没有私人文件、真实密钥和其他项目。

前面章节使用的默认位置是:

系统 课程目录
macOS “文稿”中的 dsh-learning/daily-report
Linux ~/dsh-learning/daily-report
Windows “文档”中的 dsh-learning\daily-report

如果跳过了安装章节,现在新建这个空目录即可。目录位置可以不同,但后面都要选中同一个目录。

7.2 先分清:启动目录不等于已选工作区

在 CLI/Web 路线中,dsh 会把启动命令所在目录当作文件选择器的默认位置,但全新的 Web UI 仍然没有自动选中工作区。没有工作区时,输入框通常不可用。这一点在 官方 Web UI 指南 中有明确说明。

工作区可以先理解成“这次项目任务允许围绕哪个目录展开”。它既是侧边栏里持续保存的项目记录,也是新会话创建时的工作目录。会话一旦创建,它的工作目录就随会话确定;所以应先选工作区,再新建会话。

不要把用户主目录、整块磁盘或装满私人资料的“文档”目录直接设为工作区。我们专门准备 daily-report 空目录,就是为了把第一次写入限制在一个清晰、可恢复的范围内。

7.3 把 daily-report 添加为工作区

Desktop 和 Web UI 的页面结构基本一致:左侧是工作区与会话,中间是当前任务。按下面的顺序操作:

  1. 在主界面点击“选择工作区”(界面为英文时是 Choose workspace);
  2. 如果列表里还没有 daily-report,选择“添加工作区”或带加号的入口;
  3. 在目录选择器中找到前面创建的 daily-report 文件夹;
  4. 确认添加,并在工作区列表中选中它;
  5. 检查页面上显示的工作区名称或路径确实指向 daily-report。

Desktop 会调用系统原生的文件夹选择窗口。Web UI 则由运行 DSH 的那台 Host 选择目录:如果 DSH 跑在远程 Linux 服务器上,这里要选服务器上的 ~/dsh-learning/daily-report,不是你笔记本电脑上的同名目录。

选中后,新任务输入区域应该从不可用变为可以操作。侧边栏里也应出现 daily-report 工作区。

如果文件夹选错了

先不要发送消息。重新打开工作区选择器,选中正确目录后再创建新会话。删除侧边栏中的工作区记录并不会自动删除磁盘上的文件,但第一次练习没有必要测试这项管理功能。

7.4 确认模型已经可用

Agent 必须有一个可用模型才能回答。你在首次启动时可能已经完成了 DeepSeek 账号登录,也可能填过官方 API Key;只要会话顶部的模型入口能选到可用模型,就可以直接继续。

如果模型列表为空、发送按钮不可用,或发送后提示缺少凭证,先完成一条最短配置路径:

  • Desktop 欢迎页仍提供账号登录时,可以完成登录并使用账号模型;
  • 或打开“设置 → 模型”,在 DeepSeek 卡片中填入官方 API Key 并保存;
  • CLI/Web 通常使用“设置 → 模型”的 API Key 路线。

不要把 API Key 发进聊天输入框,也不要写进 daily-report 项目文件。模型页保存的 Key 是只写凭证,保存后界面只显示配置状态,不会重新展示原始密钥。

这里只要让一个模型可用,不必现在研究全部字段。账号模型、官方 API Key、内置 Provider 和自定义 Provider 的差异,会在下一章完整解释。当前版本中,账号任务与 API Key 任务的模型入口彼此独立,因此要以这个会话实际选中的模型为准,而不是只看“我已经登录”或“我已经保存 Key”。v0.1.7-rc.2 更新说明

7.5 新建一个边界清楚的会话

在 daily-report 工作区下点击“新建任务”或空白的新会话入口。第一次练习保留下面两项设置:

  • Agent 预设使用默认的标准模式;
  • 权限使用 Workspace Write(工作区内修改),不要选择 Full access(完全权限)。

当前版本把新任务的 Agent 模式放在“设置 → 代码工作工具”中统一管理。如果你从未改过,保留默认值即可;如果之前做过实验,确认新任务使用标准模式后,再重新创建这个会话。

“工作区内修改”允许工具读写当前工作区,并在需要时询问具体操作;“完全权限”会扩大可操作范围,这个两文件任务用不到。权限选择器修改的是当前会话,设置页中的默认权限则影响以后新建的会话。官方默认权限的含义可参考 Permission Presets 说明。

可以先记住一个简单区别:

  • 权限范围回答“Agent 最多能碰到哪里”;
  • 审批请求回答“这一次具体操作是否允许执行”。

权限范围合适,不代表所有操作都会自动通过;出现审批卡片时仍要看清命令和路径。

7.6 发送第一次任务

把下面这段话完整发送给 Agent:

我们要在当前空工作区启动一个“日报助手”项目。请只完成项目初始化,不要开始写程序。

请创建且只创建两个文件:

1. PROJECT.md
   - 包含“项目目标”“输入与输出”“技术约束”“首版验收标准”四个二级标题;
   - 说明项目将读取 sources.json,用 Node.js 原生 fetch 抓取资讯,最后生成 daily-report.md;
   - 技术约束写明:使用 ES Modules、零第三方依赖、Node.js 内置 test 模块。

2. sources.json
   - 顶层是 JSON 数组;
   - 包含下面两个对象,每个对象只有 name 和 url:
     - DeepSeek Harness Releases
       https://api.github.com/repos/deepseek-ai/deepseek-harness/releases?per_page=5
     - Node.js Releases
       https://api.github.com/repos/nodejs/node/releases?per_page=5

创建后,请只运行一条本地 Node.js 命令,验证 sources.json 能解析、数组长度为 2,而且每项都有非空的 name 和 url。不要访问网络,不要安装依赖,也不要创建其他文件。

最后告诉我:创建了哪些文件、验证命令的实际输出是什么。不要只说“应该可以运行”。

这段任务看上去比“帮我创建日报助手”更长,但每一部分都有用途:

  • “只创建两个文件”限制改动范围;
  • 明确标题和 JSON 结构,减少模型自由发挥造成的偏差;
  • “不要访问网络、不要安装依赖”排除第一次任务不需要的外部行为;
  • 要求展示实际验证输出,避免用一句“应该没问题”代替执行。

它没有指定 Agent 必须调用哪个文件工具或哪条 Shell 命令,因为具体工具属于运行时实现;我们约束的是结果和风险边界。

7.7 看执行过程:计划、工具和审批

标准模式通常会先检查工作区,再创建文件,最后运行 Node.js 验证。你可能看到几类内容:

  • 普通文字:Agent 对当前步骤的说明;
  • 文件工具卡片:读取、创建或修改文件;
  • Shell/终端卡片:运行本地验证命令;
  • 审批卡片:等待你决定是否允许一次具体操作;
  • 代码变更或差异视图:展示文件新增、删除和修改。

不要要求每个模型都以完全相同的顺序行动。你真正需要判断的是:它是否始终围绕两个目标文件工作,以及是否完成了真实验证。

审批出现时,先核对四件事

这次任务允许的范围很小:

  1. 路径应位于当前 daily-report 工作区;
  2. 可以创建或修改 PROJECT.md、sources.json;
  3. 可以执行只读取 sources.json 的本地 node -e ... 验证;
  4. 不需要 npm install、联网请求、删除命令,也不需要访问工作区外的目录。

符合这些边界,可以选择“允许一次”。如果审批内容出现其他目录、安装依赖、下载脚本或删除操作,先拒绝,然后在同一会话中指出偏差。

审批的“允许一次”只授权卡片里那次操作,不等于把后续所有命令永久放行。DSH 的审批结果是按具体请求记录并默认失败关闭的。官方审批机制说明

7.8 审查实际改动

Agent 说完成以后,先看界面中的文件树或代码变更区域:

  1. 文件列表应只有 PROJECT.md 和 sources.json 两个新增文件;
  2. PROJECT.md 应包含约定的四个二级标题;
  3. sources.json 顶层应是数组,不是带 sources 字段的对象;
  4. 两个对象都只能有 name、url 两个字段;
  5. 差异视图应只有新增内容,不应修改工作区外文件。

这里的关键不是挑模型的文笔,而是确认“实际文件”与任务边界一致。工具卡片显示成功,只能证明工具返回了成功;文件内容是否符合要求,还要看产物本身。

如果多了文件,不要急着手工删。继续在同一会话发送:

这次任务约定只创建 PROJECT.md 和 sources.json,但当前工作区还出现了其他文件。请先列出多余文件及其用途,不要继续修改;等我确认后再处理。

这能让你先判断额外内容是否由 Agent 创建,避免误删原来就存在的文件。

7.9 用自己的终端独立验收

最后不要只相信 Agent 报告的验证结果。打开系统终端,进入 daily-report 目录,亲自执行:

node -e "const s=JSON.parse(require('fs').readFileSync('sources.json','utf8')); const ok=Array.isArray(s)&&s.length===2&&s.every(x=>x.name&&x.url); if(ok===false) process.exit(1); console.log('sources.json OK:',s.length)"

这条命令在 macOS、Linux 的常见 Shell 和 Windows PowerShell 中都可以使用。成功时应看到:

sources.json OK: 2

还可以列出目录内容,确认文件数量:

macOS、Linux:

ls -la

Windows PowerShell:

Get-ChildItem

除了操作系统可能显示的隐藏元数据外,课程创建的文件应只有 PROJECT.md 和 sources.json。打开两个文件再读一遍;这是对“内容正确”的检查,而 Node 命令只验证 JSON 结构。

验收失败时怎么继续

保留真实输出,把它原样交回同一会话。例如:

我在系统终端执行验收命令后没有得到 sources.json OK: 2。下面是完整输出:

(粘贴错误信息)

请只检查 PROJECT.md 和 sources.json,先解释根因,再做最小修改并重新运行同一条验证命令。不要创建新文件,也不要访问网络。

“同一会话”很重要:前面的任务、工具结果、审批和改动都在这条会话的记录里。新开会话会丢掉这段近距离上下文,需要重新解释问题。

7.10 三个概念,现在可以记住了

完成第一次任务后,再回头看 DSH 的三个核心对象会更直观:

  • 工作区(Workspace):一个持续保存的项目目录记录。它决定新会话从哪个目录开始工作;它不是一张只用于分类的标签。
  • 会话(Session):一次任务的持续记录,包含用户消息、模型响应、工具调用、审批和结果。修复同一问题时优先留在原会话。
  • 权限与审批:权限控制可触达范围,审批控制某个具体动作。第一次练习用“工作区内修改 + 按需审批”,不需要完全权限。

模型负责判断下一步,标准模式提供完整的 Agent 工作方式,文件和 Shell 能力负责实际操作,工作区与权限则限制这些能力的边界。DSH 的价值不只是“生成一段文字”,而是把这些层组合成一条可观察、可审查、可继续的任务过程。

7.11 本章验收

进入下一章前,请确认:

  • daily-report 已经添加并选为工作区;
  • 新会话使用标准模式和 Workspace Write(工作区内修改)权限;
  • 工作区中存在 PROJECT.md、sources.json,没有课程意外创建的其他文件;
  • 你实际查看过文件内容或代码差异;
  • 自己运行验证命令后看到 sources.json OK: 2;
  • 你知道模型配置、工作区、会话、权限和单次审批分别解决什么问题。

现在项目已经有了明确边界和第一份可验证配置。下一章会系统梳理模型的三种 Provider 配置方式,并用这个工作区做一次只读对比,避免“换模型”和“换 Agent 工作方式”混为一谈。


← 上一章:Windows 安装 | 回目录 | 下一章:模型 Provider:官方、内置与自定义 →


09 配置模型提供方

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

第 8 章 模型 Provider:官方、内置与自定义

上一章已经让一个模型完成了第一次任务。这一章把“模型从哪里来”讲清楚,并走通 DeepSeek Harness 提供的三种 API 配置方式:

  1. 官方 DeepSeek API Key;
  2. 内置的第三方 Provider;
  3. 自定义模型 API,包括中转平台、公司网关和本地兼容服务。

Desktop 用户还可能看到 DeepSeek 账号模型。它与 API Key 模型是两条独立路线,本章会先把这层关系理顺。

不必为了完成教程购买三家的 API。至少保留一条已经能正常请求的模型路线,再把其他配置步骤当作以后接入时的操作地图即可。

8.1 先分清三个概念

DSH 中的 Provider、模型和 Agent 预设分别解决不同问题:

层级 回答的问题 例子
Provider 请求发到哪里、用什么协议和凭证 DeepSeek 官方、Kimi、公司网关
模型 这次请求具体由哪个模型处理 某个 Provider 下的一个 model ID
Agent 预设 模型以什么工作方式使用工具 标准、PTC、极简、创造

换 Provider 或模型,通常不会凭空增加新的文件、终端或搜索工具;换 Agent 预设,也不会自动替你获得另一家模型服务的账号和额度。

可以把它们想成“接入线路、具体引擎、工作方法”三层。下一章再研究工作方法,本章只处理前两层。

8.2 DeepSeek 账号和官方 API Key 不是一回事

在支持账号登录的 Desktop 中,“设置 → 模型”最前面可能出现 DeepSeek 账号(DeepSeek Account),下一行才是 DeepSeek。两个入口虽然都使用 DeepSeek 模型,但凭证和计费来源彼此独立:

  • deepseek-account 使用桌面端保存的账号授权;
  • deepseek-official 只使用模型页保存的 API Key;
  • 任一路线都不会在请求失败时偷偷回退到另一条路线;
  • 退出账号会移除账号授权,但不会删除已经保存的 API Key。

这是当前版本刻意做出的隔离。DeepSeek 适配器官方说明也明确区分了两种路由。

因此,“我已经登录 Desktop”不一定等于“API Key 模型已配置”;反过来,填过 API Key 也不等于当前会话正在消耗账号额度。判断依据始终是会话输入区实际选中的 Provider 和模型。

账号模型只在账号授权和模型目录可用时显示;退出登录后,对应行会隐藏。CLI/Web 用户通常直接走 API Key。如果你的 Desktop 没有登录入口或账号模型行,也不用排查半天,使用下面的官方 API Key 路线即可。

切换或退出账号前先结束账号模型正在运行的任务。当前桌面端会对受影响的任务给出确认提示,但不要把提示当作自动保存点。

8.3 路径一:配置官方 DeepSeek API Key

这是最短、也最适合第一次配置的 API 路线。DSH 已经内置 DeepSeek 的端点、协议和模型目录,通常只需保存密钥。

第一步:准备密钥

在 DeepSeek 开放平台 创建或取得 API Key,并确认账号有可用额度。Key 只在提供方网站和 DSH 的凭证表单之间传递:

  • 不要贴进 Agent 对话;
  • 不要写进 PROJECT.md、.env 示例或截图;
  • 不要发到群聊里让别人帮忙排错。

如果密钥曾经出现在不该出现的地方,应去提供方平台撤销并重新生成,而不是仅从聊天记录中删除。

第二步:在模型页保存

打开 DSH 左下角或侧栏中的“设置”,进入“模型”,找到名为 DeepSeek 的卡片:

  1. 点击卡片进入编辑;
  2. 把 API Key 粘贴到“API 密钥”输入框;
  3. 暂时不要修改“自定义设置”中的 Base URL 和模型目录;
  4. 点击“应用”或“保存”。

成功后,Provider 行会显示已配置状态,通常是绿色实心状态点。这个状态只证明凭证引用已经保存,不证明余额、网络和服务端鉴权一定正常;真实请求才是最后验证。

密钥采用只写方式保存。页面把原始值交给本地凭证服务后,只能读回脱敏状态,不能把明文重新展示出来。凭证默认保存在 DSH 主目录的 .credentials.yaml,Profile 配置只保留凭证引用。模型配置官方指南

第三步:在新会话中选中模型

回到 daily-report 工作区,点击新建任务,在输入区的模型选择器中找到 DeepSeek Provider 下的模型并选中。模型名称会随版本和账号能力变化,不必为了与截图一致而手工造一个 model ID。

保存 Provider 后无需重启 DSH;有效设置会在下一次请求时读取。为了让本章的比较更干净,仍建议新建会话后再选择模型。

8.4 路径二:添加内置第三方 Provider

“内置”指 DSH 已经知道该服务的端点、协议和模型目录,不表示模型免费,也不表示可以复用 DeepSeek 账号。

打开“设置 → 模型”,点击 添加模型提供商,保持顶部方式为 第三方模型提供商。当前内置目录会显示 Provider ID,例如:

  • moonshotai:Kimi;
  • zai:GLM;
  • openai;
  • anthropic。

对中国用户,优先选择自己已经在用、网络和付款方式都合适的服务;不需要为了看一遍界面临时注册海外云平台。

操作顺序如下:

  1. 在 Provider 列表中选择目标服务;
  2. 确认卡片标题和 Provider ID;
  3. 填入该服务自己的 API Key;
  4. 查看模型目录中是否包含你账号实际可用的模型;
  5. 点击“应用”或“保存”;
  6. 新建会话,在模型选择器中找到该 Provider 并选择一个模型。

内置目录会提供端点、协议和模型列表,所以一般不需要手工猜 Base URL。它也不会代替服务方验证账号权限:目录中出现某个模型,不保证你的 Key 已经开通它。

还有一个边界容易误会:模型设置页目前不负责通过 OAuth 登录 Codex 这类 Provider。不能因为列表里出现相关名称,就拿 ChatGPT 订阅账号代替 API Key。以 官方 Provider 指南 当前说明为准。

8.5 路径三:添加自定义模型 API

自定义 Provider 适合下面几种情况:

  • 你在使用模型中转平台;
  • 公司提供统一模型网关;
  • 本机或局域网运行兼容 API;
  • 目标服务不在 DSH 的内置目录中。

它不是“随便填一个地址就能兼容”的万能开关。你需要从服务方文档确认:基础 URL、协议、模型 ID、密钥和工具调用兼容性。

在“设置 → 模型”中点击“添加模型提供商”,再切换到 自定义模型 API。表单至少需要这些信息:

字段 应该填什么
Provider ID 唯一、稳定的小写标识,例如 company-gateway
显示名称 给人看的名称,可按团队习惯填写
基础 URL 服务方文档给出的 HTTP/HTTPS 接口根地址
API 协议 网关真正支持的消息协议
API Key 该网关自己的凭证
模型 至少一个准确的 model ID

Provider ID 一开始就要想清楚

Provider ID 会进入请求、默认模型、已保存会话和凭证引用。创建后,显示名称、基础 URL、协议、密钥和模型可以编辑,但 Provider ID 不适合直接重命名。

不要使用 test1、new-api 这类几周后看不懂的名字。更合适的例子是:

  • company-gateway;
  • local-vllm;
  • team-relay-openai。

如果确实要改 ID,正确做法是新建一个 Provider,验证成功后把默认模型切过去,再删除旧 Provider。

基础 URL 与协议必须配套

当前表单提供三种协议:

界面名称 配置标识 适用情况
OpenAI Chat Completions openai-completions 服务实现 /chat/completions 风格接口
OpenAI Responses openai-responses 服务明确支持 Responses API
Anthropic Messages anthropic-messages 服务实现 Messages 协议

不要因为服务商宣传“OpenAI 兼容”,就默认它同时支持 Chat Completions 和 Responses。查看它给出的请求示例和路径,再做选择。

表单的地址示例也有区别:OpenAI 两种协议通常形如 https://gateway.example/v1;Anthropic Messages 的基础地址通常形如 https://gateway.example,适配器会追加对应消息路径。这里的 gateway.example 只是格式示意,不能照抄使用。

一个自定义 Provider 只绑定一种协议。如果同一网关需要同时走两种协议,应创建两个不同 Provider ID,例如 team-relay-chat 和 team-relay-responses,这样排错时不会混淆。

获取可用模型,不等于自动配置完成

在“模型目录”区域点击 获取可用模型,DSH 会用表单中当前的 URL、协议和 Key 询问端点。成功后会打开可搜索的模型列表:

  1. 搜索目标 model ID;
  2. 勾选需要的模型;
  3. 点击“添加所选”;
  4. 回到表单检查模型行;
  5. 最后再创建或保存 Provider。

模型发现只是便利功能。它可能因为端点没有模型列表接口、返回格式不同或权限不足而失败。此时只要服务方文档给出了准确 model ID,就可以手工添加,不必反复改协议碰运气。

如果你把内置 Provider 的 Base URL 改成中转站,模型发现仍可能从 DSH 的内置目录回答,而不是显示中转站的真实列表。需要探测中转站时,应新建自定义 Provider。

先按纯文本模型处理

手工添加的新模型没有可继承的能力目录时,默认按文本输入处理。只有上游确实支持图片时,才在 Provider 的“自定义设置 → 模型选项 → 输入类型”中勾选“图片”。这个勾选是你对端点能力的声明,不是 DSH 替你做的检测;声明错了,请求仍会被提供方拒绝。

第一次接入中转平台时,先把纯文本和工具调用跑通,再调整图像、上下文窗口、输出上限和推理等级。一次改太多字段,失败后很难定位到底是密钥、地址、协议还是能力声明出了问题。

8.6 用同一条只读任务验证模型

模型页的绿色状态点只能证明“配置已保存”。真正的闭环是:新建会话、选中模型、发出真实请求,并确认它正确读取当前项目。

回到 daily-report 工作区。对每条你确实已经配置好的 Provider 路线分别执行一次:

  1. 新建会话,不复用上一章的写入会话;
  2. Agent 预设继续使用标准模式;
  3. 权限切换为 Read Only(仅可查看);
  4. 在发送第一条消息前选中要验证的 Provider 和模型;
  5. 发送完全相同的测试任务。

测试任务如下:

请只读检查当前工作区中的 PROJECT.md 和 sources.json。不要修改文件,不要运行 Shell,不要访问网络。

请回答:
1. 这个项目的目标、输入和输出分别是什么;
2. sources.json 中有几个来源,逐项写出 name;
3. PROJECT.md 的首版验收标准要求了什么;
4. 目前还缺哪些文件,才能开始实现第一版程序。

最后明确写出“本次未修改任何文件”。

一个合格结果至少应满足:

  • 正确读出两个来源的名称;
  • 没把“未来要生成 daily-report.md”说成已经生成;
  • 能区分当前已有文件和后续待实现文件;
  • 工作区没有新增或修改文件。

如果只配置了一条 Provider 路线,做一次就够了。如果有两条以上,可以记录下面四项,而不是只比较谁写得更长:

  • 是否准确理解两份文件;
  • 是否遵守只读和不联网要求;
  • 首次响应是否稳定;
  • 是否出现模型不支持工具参数、上下文或协议的错误。

完成后再次查看代码变更区域,应该没有任何改动。这个“零改动”就是本章独立于模型自述的验收。

8.7 默认模型、当前会话和历史记录

模型设置或凭证修改在下一次请求生效,不需要重启 DSH。但“配置更新”和“会话历史使用了哪个模型”是两回事。

在输入区选择模型时,DSH 会把它保存为以后新会话的默认选择;已经发过请求的会话则保留日志中记录的模型。你可以在会话中进行明确切换,但旧消息不会被改写成新模型生成,也不能据此做严格的横向对比。

因此,本教程采用一个简单规则:

  • 修同一个问题,留在原会话;
  • 比较不同模型,每个模型新建一个会话,并在第一条消息前完成选择。

如果删除了默认模型所属的 Provider,新会话输入区会要求重新选择模型,并在选择前阻止发送。删除旧 Provider 之前,先切换并验证新的默认模型。

8.8 常见问题:先按错误所在层排查

Provider 行是绿色,真实请求仍报 401

绿色只表示凭证已保存。401 通常表示 Key 无效、过期、属于另一个环境,或该账号无权访问当前端点。回提供方平台检查 Key,不要反复删除 DSH 配置。

提示 MISSING_CREDENTIAL

当前模型引用的 Provider 没有可用凭证。回“设置 → 模型”,确认你编辑的是会话实际选中的 Provider,而不是另一个同名的账号/API Key 路线。

提示 UNKNOWN_MODEL 或 model not found

先核对模型选择器和 Provider 模型目录中的 model ID,再到服务方文档确认账号可用模型。显示名称可以友好,真正发送的是 model ID,大小写和分隔符都要准确。

“获取可用模型”返回 401 或空列表

  • 401:优先检查 Key;
  • 提示没有 data 数组或 models 对象:端点列表格式不在探测范围;
  • 服务压根不提供模型列表接口:按文档手工添加 model ID。

模型发现失败不等于聊天接口一定不可用。

Key、地址都正确,但请求格式错误

最常见原因是协议选错,或网关只兼容协议的一部分。例如服务只实现 Chat Completions,却选成 Responses;或者它不接受标准的工具调用、developer 角色和输出上限字段。

先用服务方最小文本示例确认协议,再对照 官方 Provider 指南的兼容性部分。不要用随机切换协议、模型和高级字段的方式碰运气。

配置成功,但会话仍像在用旧模型

查看当前会话输入区显示的模型,并确认切换发生在这一条请求之前。做对比时直接新建会话,比追溯一个混合了多个模型的长会话更清楚。

请求提示余额不足、限流或网络失败

这类问题发生在提供方或网络层,不是 DSH 表单格式问题。确认当前会话使用的是账号路线还是 API Key 路线,再去对应平台检查额度、账单、限流和网络可达性。

8.9 本章验收

进入下一章前,请确认:

  • 能解释 DeepSeek 账号与官方 API Key 是两条独立模型路线;
  • 至少有一个 Provider 能完成真实请求;
  • 知道“内置 Provider”提供目录和协议,但不提供免费账号或权限;
  • 能为自定义 API 正确选择 Provider ID、Base URL、协议和 model ID;
  • 知道模型发现失败时可以手工添加 model ID;
  • 已用只读任务验证至少一个模型,并确认工作区零改动;
  • 知道配置更新无需重启,但模型对比应使用独立新会话。

现在“谁来思考、请求发到哪里”已经明确。下一章保持模型不变,专门比较标准、PTC、极简和创造四种 Agent 预设,并用创造模式做出一个真正的自定义预设。


← 上一章:第一次对话:让 DSH 接手日报助手 | 回目录 | 下一章:Agent 预设:标准、PTC、极简与创造 →


10 智能体预设与自定义预设

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

第 9 章 Agent 预设:标准、PTC、极简与创造

上一章解决了“由哪个模型来做事”。这一章保持模型不变,只改变 Agent 预设,看看同一个模型怎样以不同方式使用工具。

你会完成两件事:先用同一条只读任务看清标准模式与 PTC 模式的执行差异,再用创造模式做出一个能在新任务中选用的自定义预设。

开始前,请确认 daily-report 工作区里仍有上一章的两个文件:

daily-report/
├── PROJECT.md
└── sources.json

本章不会修改这两个文件。四种预设的比较都使用同一个模型、Read Only 权限和独立新任务,否则结果差异无法归因到预设。

9.1 预设究竟改变了什么

Agent 预设不是模型,也不是权限档位。它是一套会话级的插件组合,决定模型能看见哪些工具、提示词和运行能力。

这三个概念不要混在一起:

设置 主要决定什么 本章怎么控制变量
模型 谁来推理和生成 全程使用同一个模型
Agent 预设 模型以什么工具组合和工作方式做事 分别创建四个新任务
权限 文件、命令等操作能否执行或需要审批 比较阶段都用 Read Only

因此,极简模式不天然只读,创造模式也不会自动获得无限权限。真正的安全边界仍由工作区、沙箱和审批策略控制。

当前版本把预设入口放在“代码工作工具”之下。若新任务页面看不到模式选择器:

  1. 打开“设置 → 通用设置”;
  2. 开启“代码工作工具”;
  3. 返回新任务页面重新查看模式选择器;
  4. 也可以在“设置 → Agent 预设”中查看内置和自定义预设。

v0.1.7-rc.2 已移除旧版单独的“模式选择”开关。“代码工作工具”现在统一控制执行轨迹、代码差异和新任务的模式选择;保存的默认预设会用于之后的新任务。版本说明

预设在任务创建时组装。更改默认值只影响之后创建的任务,已经开始的任务不会被改造成另一套工具环境。Agent 预设界面官方说明

9.2 四种内置预设的分工

先用一张表建立直觉,后面再动手验证:

预设 工具如何呈现给模型 适合的任务 不要把它误解成
标准模式 模型直接逐个调用文件、Shell、搜索等原生工具 日常开发、排错、文档和不确定性较高的任务 “简单模式”
PTC 模式 模型先写一段 TypeScript,再通过 run_code 中的 SDK 组合工具调用 批量读取、筛选、分类、循环和并行处理 更强模型或缓存开关
极简模式 只保留持久 bash 与 str_replace_editor 基准测试、最小环境实验 更安全或一定更省时
创造模式 在标准能力上增加运行时检查、插件实验和预设创作指导 创建或调整自定义预设、扩展 DSH 本身 日常任务的“增强版标准模式”

这是产品当前给出的四种定位。DeepSeek Harness 产品页还明确说明:标准模式提供完整工具组合;PTC 用模型生成的代码组合多轮工具调用;极简模式用于最小环境下的模型基准测试;创造模式用于检查运行时并创作新模式。

设置页的“查看配置”会以只读 YAML 显示一个预设声明的插件列表。以后如果安装了插件或版本更新后怀疑实际能力发生变化,以这里显示的当前配置为准,不要只凭预设名称猜测。

9.3 标准模式:让模型一步一步决定

新建一个任务,保持上一章已经验证过的模型不变,选择“标准模式”,权限设为 Read Only。发送下面的任务:

请实际读取当前工作区中的全部 .md 和 .json 文件,完成一次只读盘点。

要求:
1. 列出实际读取的文件;
2. 统计每个文件的行数,并概括其结构;
3. 解析 sources.json,检查它是否为数组、每项是否只有 name 和 url、url 是否以 https:// 开头;
4. 对照 PROJECT.md,判断现有文件是否足以开始实现首版日报助手;
5. 用表格给出结论和证据。

不要修改文件,不要访问网络,也不要只根据历史对话作答。

标准模式通常会把动作拆成一连串直接工具调用:先列出文件,再读取 PROJECT.md 和 sources.json,必要时调用 Shell 做统计,最后让模型根据返回结果继续判断。具体工具名和调用次数可能随模型而变化,不必追求与示例完全一致。

你真正要观察的是执行轨迹的形状:模型发起一个原生工具调用,结果回到模型,模型再决定下一步。可以概括为:

模型 → 列文件 → 结果回到模型 → 读文件 → 结果回到模型
     → 解析与判断 → 输出报告

检查最后的报告。sources.json 应有两个来源,每项包含 name 和 url;现有两个文件只完成了需求和数据源配置,还没有程序、测试和输出文件。

最后打开代码变更区域,确认没有新增或修改文件。模型说“没有修改”不是验收依据,零差异才是。

9.4 PTC 模式:让模型用程序编排工具

PTC 在这里指程序化工具调用,不是 DeepSeek API 的前缀缓存开关,也不是另一种模型。

它和标准模式最关键的区别不在任务答案,而在工具怎样交给模型:

  • 标准模式把每个可见工具作为独立函数直接交给模型;
  • PTC 模式只把 run_code 作为直接入口,同时生成一份 Code Mode SDK;
  • 模型在临时的 TypeScript 程序里通过 await tools.<工具名>(...) 调用原有工具;
  • 内层工具调用仍会经过原来的权限、审批和执行链路,并不会因为包在代码里就绕过安全控制。

工具系统官方说明把两种呈现方式称为 native 和 ptc:前者直接暴露工具定义,后者暴露 run_code 与自动生成的 SDK。

现在新建第二个任务,使用与刚才完全相同的模型和 Read Only 权限,只把预设改为“PTC 模式”。再次发送上一节同一条盘点任务。

这次轨迹通常更接近下面这样:

模型 → run_code(TypeScript)
          ├─ 列出候选文件
          ├─ 读取多个文件
          ├─ 统计与解析 JSON
          └─ 返回整理后的结构化结果
     → 模型输出报告

在工具卡片或轨迹中,你应该看到外层的 run_code。展开后,可以看到模型生成的程序以及其中触发的工具子调用。PTC 的优势正出现在“先拿到列表,再循环读取、筛选、并行处理、汇总”的任务中:中间结果可以先留在程序变量里,不必每一步都返回模型再做一次决定。

这不代表 PTC 必然更快、更便宜或答案更好。它要求模型不仅会做任务,还要写对工具编排代码。只读一个文件或改一行文字时,额外写一段程序反而可能增加成本;面对几十个文件的相同检查时,循环和并行才更有价值。

完成后做三项对照:

检查项 标准模式 PTC 模式
最终事实 应该一致 应该一致
轨迹入口 多个原生工具调用 外层 run_code + 内层工具调用
工作区差异 无 无

如果 PTC 没出现 run_code,先确认这确实是新任务,任务标题或会话头显示的是 PTC 预设,而不是在旧的标准模式任务里继续发消息。如果答案正确但轨迹很短,也不代表 PTC 失效;这个项目目前只有两个文件,任务规模还不足以产生巨大的时间差。

一句话记住两者:

标准模式让模型边看结果边决定下一步;PTC 模式让模型先写一个小程序,再由程序组织多步工具调用。

9.5 极简模式:减少工具变量,不等于降低风险

新建第三个任务,选择“极简模式”,仍保持 Read Only。发送一个范围很小的检查:

只读检查 sources.json 是否为合法 JSON,并报告数组长度和两个 name。不要修改文件,也不要访问网络。

极简模式没有标准模式那套完整的计划、搜索、Skills、子智能体和工作流能力。它主要依靠持久 bash 查看环境、运行命令,再用 str_replace_editor 编辑文件。当前任务是只读的,所以你更可能看到它通过 Bash 或编辑器读取 sources.json。

这种受控工具环境适合比较不同模型的基础工具使用能力:模型、任务、项目都不变,只给相同的两个工具,变量更少。但它并不是日常工作的“极速模式”。真实项目需要检索、规划或子智能体时,主动删掉这些能力通常只会让任务更难。

也不要因为“极简”二字放松警惕。Bash 和文件编辑器已经足以删除或改坏文件;如果把权限切到 Workspace Write 或 Full Access,风险仍然存在。

9.6 选修:主线完成后,在独立 Profile 创建预设

创造模式的任务对象不是“日报助手代码”,而是 DSH 自己的运行配置。它可以检查当前运行时、设计插件组合,并通过持久化 bundle 安装新的预设。安装会修改当前 Profile,而且可能影响之后创建的其他任务,所以不要直接在主项目里边试边改。

先完成第 11~13 章,再按第 16 章创建并验证独立 daily-report-lab Profile。确认当前连接的是实验 Profile 后,才创建下列空目录;只换工作区不会隔离配置:

macOS 或 Linux:

mkdir -p "$HOME/dsh-preset-lab"

Windows PowerShell:

New-Item -ItemType Directory -Force "$HOME\dsh-preset-lab"

在 DSH 中把这个目录添加为独立工作区,然后打开“设置 → Agent 预设”。在“自定义”区域点击“用创造模式创作自定义预设”。系统会创建一个使用“创造模式”的新任务;设置页本身只负责查看和选择,不直接编辑预设。

我们要做一个“日报审阅”预设:保留标准模式的常用能力,但增加一组稳定的审阅规则。它不是安全沙箱,真正要限制写入时仍应搭配 Read Only 权限。

把下面这段需求发给创造模式:

请为当前 Profile 创建一个新的自定义 Agent preset,要求如下:

- preset id:daily-report-review
- 显示名称:日报审阅
- 以当前内置的标准模式为基础,不修改、覆盖或删除任何内置 preset;
- 保留标准模式的原生工具呈现和常用能力;
- 增加一段明确的工作规则:处理日报助手任务时,先读取 PROJECT.md 与 sources.json;输出结论时按“结论、证据、风险、下一步”组织;没有文件或工具证据时,不得声称任务已经完成;
- 不安装外部依赖,不联网,不增加 MCP、UI 插件或新的系统命令;
- 不把它设为默认 preset。

先检查当前可用的 preset 与配置格式,给我展示计划、将创建的 bundle/文件和持久化影响。等我确认后再安装。安装后请验证它能够出现在 Agent 预设列表中,并报告保存状态与实际启用状态。

先不要急着批准。检查创造模式给出的方案是否满足三条底线:

  1. 创建的是新 ID daily-report-review,不是改写 standard、ptc、minimal 或 cordis;
  2. 没有为了这段简单规则引入网络包、未知脚本或 Full Access 常驻设置;
  3. 明确区分“文件已生成”“bundle 已安装”“新预设已能创建任务”,不能把三者混为一谈。

方案没有越界后,再回复“确认按这个方案安装”。持久化安装可能出现一次权限审批,因为预设 bundle 会写入当前 Profile,并可能加载拥有 Host 权限的代码。审批卡片中应能看出操作目的是安装刚才审阅过的本地 bundle;如果理由含糊、出现陌生网络地址或要求长期 Full Access,先拒绝并让它解释。

创造模式当前通过插件管理器安装持久化 bundle;保存后的配置会跨重启存在,并可能通过热更新进入当前 Profile。官方实现说明也强调,这类 Profile 变更需要 Full Access 或一次明确审批。

9.7 验证自定义预设,而不是相信“创建成功”

创造模式报告完成后,按下面顺序独立验收:

  1. 打开“设置 → Agent 预设”;
  2. 在“自定义”分组找到“日报审阅”,确认 ID 为 daily-report-review;
  3. 点击“查看配置”,确认它没有覆盖内置预设,也没有意外加入外部依赖;
  4. 不要先把它设为全局默认;回到 daily-report 工作区新建任务;
  5. 在新任务的预设选择器中选择“日报审阅”,模型保持不变,权限选择 Read Only;
  6. 发送下面的验证任务。
请评估当前日报助手是否已经达到 PROJECT.md 中的首版验收标准。只读检查,不要修改文件,不要访问网络。

正确的表现不是机械复述预设名称,而是:

  • 先实际读取 PROJECT.md 和 sources.json;
  • 说明当前只有项目约定和来源配置,尚无实现、测试与 daily-report.md;
  • 按“结论、证据、风险、下一步”组织结果;
  • 没有把尚未完成的功能说成已经完成;
  • 工作区代码差异仍为空。

再看任务头部或预设标签,确认当前任务记录的是 daily-report-review。至此才算完成了“保存 → 出现在列表 → 能创建任务 → 行为生效 → 零文件改动”的闭环。

验证通过后,如果你确实希望以后新任务都用它,再到“设置 → Agent 预设”选择它作为默认。默认值不会改造已有任务。

如果自定义预设导致新任务无法创建,不要重装 DSH,也不要继续修改内置配置。因为我们没有把它设为默认,直接在新任务选择器或“设置 → Agent 预设”切回标准模式即可;随后回到插件管理或创造模式,检查 bundle 的加载诊断并移除或修正这份自定义配置。

9.8 用四个问题选择预设

以后不必背功能表,按下面顺序判断即可:

  1. **这是普通的开发、分析或文档任务吗?**先用标准模式。
  2. **任务是否包含大量重复、可程序化的工具操作?**考虑 PTC 模式。
  3. **我是否在做模型基准或最小工具实验?**使用极简模式。
  4. **我是否要改变 Agent 自己的插件组合或工作规则?**进入创造模式;若流程会反复使用,再把结果保存为自定义预设。

不要因为 PTC 或创造模式看起来更高级,就把它们设成所有任务的默认答案。标准模式最适合处理未知情况;PTC 的收益来自可程序化的工具链;极简用于控制变量;创造模式则面向 DSH 本身。

9.9 本章验收

进入下一章前,请确认:

  • 能解释模型、Agent 预设与权限的区别;
  • 已用同一模型和同一任务比较标准模式与 PTC 模式;
  • 能从轨迹中认出原生工具调用与 run_code 的差异;
  • 知道 PTC 适合批量、循环、筛选和并行操作,但不保证所有任务更快;
  • 知道极简模式用于最小工具环境,不等于只读或低风险;
  • 已通过创造模式安装并验证 daily-report-review 自定义预设;
  • 自定义预设尚未被贸然设为默认,失败时可以切回标准模式;
  • daily-report 工作区仍只有原来的两个文件,代码差异为空。

下一章开始进入 DSH 的核心:插件系统。我们会先认清内置插件配置,再安装和验证一个代表性插件,并把“预设是插件组合”这句话真正落到操作上。


← 上一章:模型 Provider:官方、内置与自定义 | 回目录 | 下一章:插件系统:配置、启停与验证 →


11 插件系统

本文属于《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、极简与创造 | 回目录 | 下一章:案例二:从需求到可运行的第一版 →


12 案例二-改造代码

本文属于《DeepSeek Harness 入门教程(实战版)》· 第四部分 · 沿着项目掌握核心能力

第 11 章 案例二:从需求到可运行的第一版

现在的 daily-report 还不是一个程序。它只有上一次实战创建的两个文件:

daily-report/
├── PROJECT.md
└── sources.json

这一章要让 DSH 把它变成能真实运行的 Node.js 日报助手:读取两个 GitHub Releases 数据源,生成 daily-report.md,同时留下不依赖网络的自动测试。

我们练的不是“请 AI 帮我写代码”这一句话,而是一条可以复用的工作流:

读取现状 → 先做计划 → 审批执行 → 查看差异
         → 跑聚焦测试 → 跑完整验证 → 亲自验收产物

章节结束时,你不仅会得到一版程序,还应该能判断 Agent 的改动是否合理。

11.1 先确认真实起点

请选中第 7 章使用的 daily-report 工作区,打开文件树确认:

  • PROJECT.md 中有“项目目标”“输入与输出”“技术约束”“首版验收标准”;
  • sources.json 顶层是数组,包含 DeepSeek Harness Releases 和 Node.js Releases 两项;
  • 目录中还没有 package.json、src/、test/ 和 daily-report.md。

如果你是从本章直接开始,请先回到第 7 章,按那里的提示创建这两个文件。不要让 Agent 在本章里凭空补写一份不同的需求,否则后面的验收基准会不一致。

继续使用:

  • 标准模式:这次需要读文件、搜索、编辑和运行命令;
  • Workspace Write(工作区内修改):允许写入当前项目,但不需要完全权限;
  • 与前几章相同的可用模型:先不换模型,避免同时改变太多变量。

11.2 这次为什么先用 Plan mode

写两个配置文件时,我们可以直接下达任务。现在要同时决定文件拆分、错误处理、测试边界和输出格式,先看计划更划算。

DSH 的 Plan mode 是一种协作状态:它引导 Agent 先探索和设计,再把完整计划交给你审查。它不是安全沙箱,也不会自动禁用写文件或 Shell 工具;真正的强制边界仍然由权限模式和审批策略提供。官方 Plan mode 说明

这个区别很重要:

  • Plan mode 回答“我们先怎么想清楚”;
  • Workspace Write 回答“实际执行时最多能写到哪里”;
  • 审批卡片回答“这一次具体操作是否允许”。

如果当前组合已加载 Plan 插件,在输入框中输入:

/plan

界面应该显示计划模式已开启。你也可以通过会话页面中与计划相关的控件进入;如果界面标签随版本改变,/plan 是更容易核对的入口。

11.3 先让 Agent 读需求并提交计划

在同一个任务中发送下面这段话:

请先读取当前工作区的 PROJECT.md 和 sources.json,为“日报助手”设计一个可运行的首版。目前只有这两个文件。

请遵守以下实现约定:

1. 使用 ES Modules 和 Node.js 内置 fetch,零第三方依赖;
2. 提供 npm start 和 npm test 两个脚本;
3. 从 sources.json 加载并校验数据源,请求每个 GitHub Releases API;
4. 请求 GitHub API 时带上能识别本工具的 User-Agent,检查 response.ok,再将每条 release 统一为标题、页面链接和发布时间;
5. 所有数据源都获取成功后,再一次性写入 daily-report.md;任一数据源失败时显示包含源名称的错误并以非零状态结束,不要用空报告冒充成功。每源请求及响应体读取最多 10 秒,全部数据源总预算 25 秒;本课不自动重试。使用 AbortController/AbortSignal 取消底层 fetch,清理定时器。用遵守 signal 的永不响应假 fetch 验证超时后能结束且不覆盖旧报告;
6. daily-report.md 至少包含生成时间、按数据源分组的二级标题,以及带链接的 release 列表;
7. 将配置解析、网络请求和 Markdown 渲染拆成可单独测试的模块;
8. 测试使用 node:test 和伪造的 fetch,不访问真实网络;
9. README.md 写清运行、测试、输出文件和常见失败;
10. 不要修改 sources.json 中现有的两个数据源,不要安装依赖,不要初始化 Git。

现在只做读取和设计。请提交一份可审查的计划,说明:
- 打算新建或修改哪些文件,每个文件负责什么;
- 数据从配置到 Markdown 的流转过程;
- 会测试哪些正常与失败路径;
- 会运行哪些验证命令,哪一步会真实访问网络。

未经我批准计划前,不要写文件、不要运行网络请求。

要求“伪造的 fetch”有一个很实际的理由:测试应该在断网时也能稳定重现,不能把 GitHub 网络、限流或上游数据变化当成本地代码的测试结果。Node.js 的 fetch 和 node:test 都是内置能力,这个项目不需要为 HTTP 或测试安装额外包;GitHub REST API 则要求请求包含有效的 User-Agent。Node.js fetch 文档 · Node.js Test runner 文档 · GitHub REST API 入门

11.4 怎样审一份实现计划

Agent 读取两个文件后,应该通过计划审查界面提交完整方案。不要因为“看起来很专业”就直接批准,先核对下面五点。

文件边界是否清楚

具体文件名可以有小幅差异,但职责应该至少覆盖:

package.json       项目类型与 start/test 脚本
src/               配置、请求、报告渲染和 CLI 入口
test/              不依赖真实网络的测试
README.md          用法与排错
daily-report.md    只在真实运行后生成

不要强求每个人都得到完全相同的 src 文件名。判断标准是模块边界是否让配置、请求和渲染能被独立测试,而不是文件越多越好。

测试是否覆盖真正的边界

首版至少要验证:

  • 正确配置能通过,空数组或缺少 name / url 会失败;
  • HTTP 成功响应能被解析为统一 release 结构;
  • HTTP 404/500 会被当成失败,不是继续解析 JSON;
  • Markdown 中有生成时间、两个数据源标题和 release 链接;
  • 测试不请求 GitHub API,也不留下 daily-report.md。

fetch() 在收到 404 或 500 时会返回一个 HTTP 响应,而不是仅因状态码就自动抛出异常;因此计划中应该明确检查 response.ok。这正是上一章网页搜索得到的结论在代码中的落点。

失败时是否“明确失败”

不要接受“某个源错了就用空数组,依然输出成功”的计划。对学习项目来说,这会把网络错误伪装成“今天没有内容”。

更合理的首版是:先在内存中拿到所有数据、组装 Markdown,全部成功后才写文件。这也为后面接入新数据源和工具留出稳定的处理接口。

是否偷偷增加了额外复杂度

首版不需要 TypeScript 编译、Web 界面、数据库、测试框架、日志库或 GitHub SDK。如果计划中出现 npm install,先让 Agent 说明为什么 Node.js 内置能力不够。本章的约束已经说明零依赖,通常应直接删掉这部分。

验证顺序是否合理

一份合格计划应该先运行不联网的测试,再运行一次真实网络验收。这样即使 GitHub 不可访问,也能判断本地逻辑是否正常。

如果计划还不具体,在评审界面选择继续规划,并补充反馈,例如:

请把计划补充到文件级,并明确列出 HTTP 失败、非法 sources.json 和 Markdown 渲染的测试方式。测试不得访问网络。

当计划能回答“改哪里、为什么、怎么证明成功”时,再选择批准。

11.5 批准后,让 Agent 完成最小实现

批准计划后,Agent 会离开 Plan mode 并进入执行。如果界面在评审后停在等待输入状态,发送:

按刚才批准的计划执行。请先完成实现和无网络测试;在运行会访问 GitHub 的 npm start 前,单独告诉我。

标准模式中,你通常会看到这样的轨迹:

  1. 用 read、glob 或 grep 核对现有文件;
  2. 用 write 创建新文件,或用 edit 做针对性修改;
  3. 运行某个聚焦测试,例如 node --test test/report.test.js;
  4. 修复聚焦测试暴露的问题;
  5. 运行 npm test 做完整回归验证;
  6. 总结新增文件、验证结果和尚未执行的联网验收。

具体的文件工具名和调用次数会因实现结构而不同,不用求它完全一致。DSH 当前的文件能力会把读取、精准编辑、原子写入和搜索分开,读前编辑策略还会防止 Agent 基于过时内容盲改。官方文件系统包说明

审批时只看实际请求

这一章合理的操作边界是:

请求 是否符合本章任务
读写 daily-report 工作区内的源码、测试和 README 符合
运行 node --test ... 或 npm test 符合,不应联网
运行 npm start 符合,但会访问 GitHub API 并写入报告
运行 npm install 不符合,本项目零第三方依赖
读取工作区外的密钥、主目录或其他项目 不符合
删除旧文件、修改全局 npm 配置、用管理员权限执行 不符合

遇到审批卡片时,核对完整命令、工作目录、联网行为和写入目标。对本章任务,选择“允许一次”已经足够;不需要为省一次点击而扩大后续全部权限。

11.6 先审差异,再看总结

Agent 说“完成”之后,打开会话页面的“代码更改”或差异审查区域。当前版本由“代码工作工具”统一控制工作过程、代码差异和新任务模式;差异可在卡片和侧边栏审阅。官方 v0.1.7-rc.2 更新说明

请逐项检查:

  1. sources.json 中的两个对象没有被改名或替换 URL;
  2. package.json 声明了 "type": "module",start 和 test 不依赖额外包;
  3. 请求代码检查 response.ok,错误信息能指出失败的数据源;
  4. 网络请求函数可接收注入的 fetch 实现,或用等价方式避免测试联网;
  5. 程序在所有数据都准备好之后才写 daily-report.md;
  6. 测试至少覆盖配置、HTTP 失败和 Markdown 渲染,而不是只断言“函数存在”;
  7. README 中的命令与 package.json 实际脚本一致;
  8. 没有新增 API Key、.env 真实密钥、node_modules 或不必要的锁文件。

看差异时,不要把“整个文件都是绿色”当成问题:新文件本来就是全量新增。更值得警惕的是未约定的删除、工作区外路径、不必要依赖和测试中真实联网。

如果发现偏差,不要只说“重写一遍”。指出具体事实,例如:

测试轨迹显示请求了 api.github.com,这与“测试不访问真实网络”的约定不符。
请只调整网络模块和相关测试,通过注入假 fetch 覆盖成功、500 和响应格式错误,不要改动其他文件。

这类反馈比“还是不对”有效,因为它给了 Agent 新的、可验证的信息。

11.7 分三层验证

差异没有明显越界后,不要直接跳到“报告生成了”。按下面三层逐步验证,问题会更容易定位。

第一层:聚焦测试

Agent 在实现过程中应该已经运行过某个直接相关的测试文件。例如渲染模块的测试文件是 test/report.test.js,你可以在系统终端中进入 daily-report 目录后执行:

node --test test/report.test.js

如果 Agent 采用了其他文件名,用它实际创建的测试路径替换命令。成功时应看到通过数为正数、失败数为 0。

第二层:完整回归测试

继续执行:

npm test

这一步应运行 test/ 下全部测试,且不需要网络。结果格式会随 Node.js 版本有差异,核心验收点是:

pass > 0
fail 0

如果测试在 GitHub 不可访问时失败,说明它们仍然依赖真实网络,还不符合本章要求。

第三层:真实运行

最后才执行:

npm start

这条命令会访问 sources.json 中的两个 GitHub API URL,并在当前工作区写入 daily-report.md。如果由 Agent 代为执行,审批时应能看到正是这条命令;如果你在自己的系统终端执行,则不经过 DSH 的 Agent 审批。

成功时,终端应该明确提示写入了 daily-report.md,而且进程返回成功状态。现在文件树中才应该出现这个报告。

11.8 独立验收生成的报告

即使 npm start 返回成功,也还要检查产物。先在 DSH 的文件侧边栏打开 daily-report.md,确认:

  • 第一行是日报的一级标题;
  • 页面上有生成时间;
  • 存在 DeepSeek Harness Releases 和 Node.js Releases 两个二级标题;
  • 两个分组下都有可读标题和 GitHub 页面链接,不是原始 JSON;
  • 文件中没有 undefined、[object Object] 或错误堆栈。

再在系统终端中执行一条独立检查:

node -e "const fs=require('node:fs'); const s=fs.readFileSync('daily-report.md','utf8'); const ok=['DeepSeek Harness Releases','Node.js Releases'].every(x=>s.includes(x)) && s.includes('https://github.com/'); if(!ok) process.exit(1); console.log('daily-report.md OK')"

成功时应看到:

daily-report.md OK

这条命令不证明所有文字都完美,但它独立证明了两个必要分组和至少一条 GitHub 页面链接确实落在文件中。

项目应该处于什么状态

你的具体 src 和 test 文件名可能略有不同,但项目应该大致是:

daily-report/
├── PROJECT.md
├── README.md
├── package.json
├── sources.json
├── daily-report.md
├── src/
│   └── ...
└── test/
    └── ...

不应该出现 node_modules/,因为本项目没有第三方依赖;也不要因为平时的 npm 习惯就先运行 npm install。

11.9 三个最容易卡住的地方

npm test 提示找不到模块

先打开 package.json,确认它有 "type": "module",再检查源码中的相对导入路径是否包含 .js 扩展名。不要通过安装一个新包来解决本地文件路径错误。

可以把原始错误交回同一任务:

npm test 失败了,下面是完整输出:

(粘贴输出)

请先定位是 package.json 的 ES Modules 配置还是相对导入路径问题,只做最小修改,不要安装依赖。

npm start 返回 403 或 API rate limit

这通常不是 Markdown 渲染问题,而是 GitHub API 访问受限。先确认代码有明确的 User-Agent 请求头,然后等限流窗口恢复或换一个可以访问 GitHub API 的网络再试。

不要把真实 GitHub Token 直接写进 sources.json、源码、README 或聊天消息。首版练习不要求 Token;如果你所在网络必须认证,先保留已通过的无网络测试,把凭证注入放到后续的专门改造中。

Agent 说已完成,但看不到新文件

先确认会话仍属于正确的 daily-report 工作区,然后展开工具卡片检查实际路径。如果计划被批准后没有进入执行,发送“按已批准的计划执行”即可。

若工具报告“成功”但文件树没刷新,用系统终端的 ls 或 PowerShell 的 Get-ChildItem 直接查看磁盘;界面显示与实际磁盘结果冲突时,以磁盘为准并重新打开预览。

11.10 本章验收

进入下一章前,请确认:

  • 你是从 PROJECT.md 和 sources.json 两个文件开始,没有假设项目早已存在;
  • 使用 Plan mode 审查过文件级实现计划,并理解它不等于安全沙箱;
  • 新程序使用 Node.js 内置能力,没有第三方依赖;
  • 测试使用假 fetch,npm test 在不联网时也能通过;
  • 已在差异界面核对真实改动和权限范围;
  • npm start 成功生成 daily-report.md;
  • 亲自打开报告,并用独立命令确认两个数据源和链接都存在;
  • 能分清聚焦测试、完整回归和真实联网验收各在证明什么。

现在,日报助手已经有了稳定的配置、请求、渲染和测试边界。下一章会在这个可运行基线上,把一份真实 Skill 和一个可验证的 MCP 工具接入 DSH,并继续用同一套权限和验收方法判断它们是否生效。


← 上一章:插件系统:配置、启停与验证 | 回目录 | 下一章:案例三:接入外部工具 →


13 案例三-接入工具

本文属于《DeepSeek Harness 入门教程(实战版)》· 第四部分 · 沿着项目掌握核心能力

第 12 章 案例三:用 Skill 固化方法,用 MCP 接入工具

上一章结束时,日报助手已经是一个可运行、可测试的 Node.js 项目。现在会遇到两个很实际的问题:

  1. 每次维护项目,都要重复说“不安装依赖、测试不联网、同步 README”;
  2. DSH 自带的工具之外,以后还可能需要连接数据库、文件服务或公司内部系统。

第一个问题用 Skill 解决,第二个问题用 MCP 解决。本章不停留在概念上,你会完成两个闭环:

  • 在项目中创建真正能被 DSH 发现的 daily-report-maintainer Skill,再用它完成一次小改动;
  • 在隔离的 CLI/Web Profile 中接入官方 MCP Filesystem Server,只授予一个练习目录,完成工具调用和越界拒绝验证。

这里不接入需要账号、付费或密钥的外部服务。我们先把机制和边界学清楚,以后换成真实业务系统时,判断方法不变。

12.1 先分清四个名词

Skill、MCP、插件和 Agent 预设经常同时出现,但它们处在不同层。

机制 它解决什么 会不会自动增加能力
Skill 告诉 Agent 一类任务应怎么做 不会;它是指令,仍使用现有工具
MCP Server 对外提供标准化的工具或资源 会;连接后模型获得新工具
插件 向 DSH 运行时提供或组合能力 取决于插件角色
Agent 预设 为新任务选定插件、工具与指令组合 本身是组合,不是外部协议

DSH 里的 MCP 其实正好跨越两层:外部程序是 MCP Server,@deepseek-ai/dsh-mcp-client 则是把它接入 DSH 工具注册表的插件。所以“配了 MCP”不等于“写了一份 Skill”,也不等于“创建了 Agent 预设”。

12.2 确认项目起点

回到 daily-report 工作区。本章默认你已完成第 11 章,因此至少应该看到:

daily-report/
├── PROJECT.md
├── README.md
├── package.json
├── sources.json
├── daily-report.md
├── src/
└── test/

具体的 src 和 test 文件名可能不同,这不影响继续。先在系统终端进入该目录,执行:

npm test

只有基线测试通过才继续。如果这里已经失败,先回第 11 章修复;否则后面无法判断是 Skill 引导的改动出了问题,还是原项目本来就是坏的。

12.3 创建一份真正的项目 Skill

DSH 的本地 Skill 不是随便放在 skills/ 下的 Markdown。当前文件系统提供方会扫描几个明确的根目录,项目级 DSH Skill 的首选位置是:

<projectRoot>/.dsh/skills/<skill-name>/SKILL.md

它也支持在 .dsh/skills 顶层使用平铺的 <name>.md,但目录 bundle 更适合以后增加 references/、scripts/ 或 assets/。Skill 名称必须使用 kebab-case,文件必须有 name 和 description frontmatter;嵌套更深的 **/SKILL.md 不会被递归发现。官方 Skill 文件系统说明

在标准模式、Workspace Write 权限的当前任务中发送:

请在当前 daily-report 项目中创建一份项目级 Skill,路径必须是:
.dsh/skills/daily-report-maintainer/SKILL.md

文件内容必须与下面一致。不要创建脚本,不要改动项目其他文件。

```markdown
---
name: daily-report-maintainer
description: 修改日报助手的配置、输出格式或命令行为,并保持测试与 README 同步。
user-invocable: true
---

# Daily Report Maintainer

处理日报助手的行为变更时,请遵守:

1. 先读取 PROJECT.md、package.json、README.md 和相关源码,再修改。
2. 保持 ES Modules 和零第三方依赖;不要运行 npm install。
3. 行为变更必须补充或更新测试,用法变更必须同步 README.md。
4. 自动测试使用假 fetch,不访问真实网络,不在项目根目录留下测试报告。
5. 先运行直接相关的聚焦测试,再运行 npm test。
6. 除非用户单独批准,不要运行会访问 GitHub 的 npm start。
7. 最终报告列出改动文件、实际测试结果,并单列“未执行的外部操作”。
```

创建后重新读取该文件,确认 frontmatter 和 7 条规则都完整。

这份 Skill 只是文本指令,没有脚本和新工具,因此不会绕过工作区权限或审批。它真正的价值是把项目约定从每次的长提示词中抽出来,让后续任务可复用、可更新。

12.4 验证 Skill 已被发现,而不是只创建了文件

本地 Skill 提供方会监视根目录,新增或更改有效 Skill 后通常不用重启 DSH。为了避免旧任务已有上下文干扰,在 daily-report 工作区下新建一个标准模式任务。

在输入框中输入 /daily-report-maintainer。如果内联建议里出现这个名称,说明目录已发现它。把下面的完整任务作为同一条消息发送:

/daily-report-maintainer

请在当前日报 Markdown 的生成时间下方增加一行汇总,显示“数据源数量”和“release 总数”。

要求:
1. 根据当前实际源码做最小改动,不改数据获取策略;
2. 更新渲染相关测试和 README.md;
3. 只运行无网络测试,本次不批准 npm start;
4. 完成后按 Skill 要求报告。

DSH 的 tool-skill 会给 Agent 提供可用 Skill 的名称与描述目录,完整正文按需加载。用户在消息中显式写出 /name 时,该 Skill 的完整内容会注入当前步骤,无需模型再调用一次 skill 工具。官方 Skill 加载工具说明

一次合格执行应该出现下面的特征:

  • Agent 先读当前项目文件,而不是凭空假设渲染函数名;
  • 实际差异集中在 Markdown 渲染、相关测试和 README;
  • 先跑相关测试,再跑 npm test;
  • 轨迹中没有 npm install、npm start 或 GitHub 网络请求;
  • 最终报告单列“未执行的外部操作”,并注明 npm start 未运行。

最后在系统终端亲自执行:

npm test

再打开代码差异,确认 sources.json 和网络请求模块没有被改动。这次不运行 npm start,因为我们要验证 Skill 中的“外部操作需单独批准”确实影响了执行边界。

Skill 没出现时先查什么

  1. 检查路径是 .dsh/skills/daily-report-maintainer/SKILL.md,不是 skills/daily-report-maintainer.md;
  2. 检查 frontmatter 两侧的 ---,以及 name 是否与目录名一致的 kebab-case;
  3. 新建任务再试,避免旧目录投影造成误判;
  4. 在“设置 → 插件 → 插件列表”中确认 Skill registry、filesystem provider 和 tool-skill 没有加载错误。

无效 frontmatter 的 Skill 会被跳过并记录警告,模型目录未必会把具体解析错误直接展示给你。所以排查顺序应该先看路径和 frontmatter,不是反复让模型“再搜一遍”。

12.5 MCP 部分为什么使用隔离 Profile

Skill 会被按需加载;MCP Server 连接成功后,它的工具名称、描述和参数 schema 会加入模型的工具列表。连接的 Server 越多,模型每次要理解的工具定义就越多。

为了不把练习 Server 永久加到你的 Desktop 或日常 Web Profile,本章采用一个临时组合:

独立 mcp-lab Profile + 项目内 patch + 一个 mcp-scratch 允许目录

这条路线需要系统 Node.js 和 npx。只安装了 Desktop 的读者,请先按 macOS 或 Windows 安装章的 CLI/Web 小节确认:

npx @deepseek-ai/dsh@0.1.7-rc.2 --version

官方 MCP Client 的可复现配置方式,就是为每个 Server 插入一条 @deepseek-ai/dsh-mcp-client 配置。本地程序使用 stdio,远程服务使用 streamable-http;连接后工具名称是 mcp__<serverName>__<rawName>。官方 MCP Client 说明

12.6 为 MCP 准备一个最小权限目录

在 daily-report 项目根目录创建一个空目录 mcp-scratch。

macOS 与 Linux:

mkdir -p mcp-scratch

Windows PowerShell:

New-Item -ItemType Directory -Force mcp-scratch

接下来需要它的绝对路径。

macOS 与 Linux:

cd mcp-scratch
pwd
cd ..

Windows PowerShell:

(Resolve-Path .\mcp-scratch).Path

记录输出。Windows 用户写入 YAML 时可以把路径改为正斜杠,例如 C:/Users/mei/dsh-learning/daily-report/mcp-scratch,避免反斜杠转义带来混淆。

为什么不把整个用户主目录交给 Filesystem Server?因为 MCP Server 是 DSH 之外的进程。Workspace Write 是 DSH 原生文件和 Shell 路径的边界,不应被当成所有外部 Server 的通用沙箱。这次的强边界来自 Filesystem Server 启动参数中唯一允许的 mcp-scratch 目录。

12.7 创建 MCP patch,但先不启动

在项目中新建 .dsh/mcp-filesystem.yml,内容如下。请把 <MCP_SCRATCH_ABSOLUTE_PATH> 替换成上一步得到的绝对路径,不要保留尖括号。

- insert:
    - id: mcp-daily-report-fs
      name: '@deepseek-ai/dsh-mcp-client'
      config:
        serverName: daily_report_fs
        transport: stdio
        command: npx
        args:
          - '-y'
          - '@modelcontextprotocol/server-filesystem@2026.7.10'
          - '<MCP_SCRATCH_ABSOLUTE_PATH>'
        toolCallTimeoutMs: 60000
        failOnStartupError: true

本练习固定使用官方已发布的 @modelcontextprotocol/server-filesystem@2026.7.10,而不是每次随机获取 latest,这样便于复现教程环境。它是 Model Context Protocol 官方参考 Server,能读写启动参数列出的目录。官方 Filesystem Server 源码 · 2026.7.10 发布记录

第一次启动时,npx -y 会从 npm 下载并执行该固定版本及依赖。这是真实的外部代码执行,不是一条无害的配置读取。如果你的环境不允许从 npm 执行包,就不要继续这一部分;可以仅完成前面的 Skill 实操,再由管理员审核和预装 MCP Server。

12.8 先做配置检查,再起服务

打开新的系统终端,确认当前目录是 daily-report。首次创建隔离 Profile 时执行:

npx @deepseek-ai/dsh@0.1.7-rc.2 --profile mcp-lab --from-default-profile web --patch ./.dsh/mcp-filesystem.yml --dump-config

这条命令会从官方 web 模板初始化 mcp-lab Profile,组合 patch 并输出最终配置,不启动 Web 服务。在输出中搜索 mcp-daily-report-fs、daily_report_fs 和你的绝对路径,三者都应出现。

如果你之前已经创建过 mcp-lab,--from-default-profile web 会明确拒绝覆盖已有 Profile。此时不要删目录,只需去掉初始化参数后重试:

npx @deepseek-ai/dsh@0.1.7-rc.2 --profile mcp-lab --patch ./.dsh/mcp-filesystem.yml --dump-config

配置检查通过后,再启动它:

npx @deepseek-ai/dsh@0.1.7-rc.2 --profile mcp-lab --patch ./.dsh/mcp-filesystem.yml --port 3081

启动器参数 --profile 和 --patch 必须放在 Web 应用参数 --port 前面。正常情况下,终端会打印服务地址并打开页面;没有自动打开时,手动访问 http://127.0.0.1:3081。如果 3081 已被占用,换一个未占用的本地端口。官方 CLI 启动与 patch 说明

第一次启动会下载 MCP Server,可能需要一些时间。failOnStartupError: true 会让这条 MCP 配置在连接或工具同步失败时明确激活失败,而不是让我们对着一个空工具列表猜原因。

12.9 验证 MCP 工具真的进了 Agent

在新打开的 mcp-lab Web 页面中选中 daily-report 工作区。这是一个新 Profile,如果模型列表为空,按第 8 章的最短路线配置一个模型;不要把 API Key 写入项目 patch。

新建标准模式任务,发送:

请检查当前任务可用的工具,只列出名称以 mcp__daily_report_fs__ 开头的工具。
不要调用它们,不要读写文件。

工具清单中应该出现类似:

mcp__daily_report_fs__list_allowed_directories
mcp__daily_report_fs__list_directory
mcp__daily_report_fs__write_file
mcp__daily_report_fs__read_text_file

具体数量会随 Filesystem Server 版本变化,但前缀应该稳定。只在设置里看到 dsh-mcp-client 不算验证成功;模型的实际工具目录中有这组限定名称,才说明 Server 已连接并完成工具发现。

如果列表为空,先回看启动终端的错误,再打开“设置 → 插件 → 插件列表”查找 mcp-daily-report-fs 的加载状态。

12.10 用 MCP 写入文件,再独立验收

继续在同一任务中发送:

这一次只允许使用名称以 mcp__daily_report_fs__ 开头的 MCP 工具,不要使用原生文件工具或 Shell。

1. 先调用 list_allowed_directories,报告 Server 唯一允许的目录;
2. 列出该目录的当前内容;
3. 在该目录中创建 mcp-check.txt,内容必须是:MCP connection verified
4. 通过 MCP 再读回该文件,原样报告内容。

不要修改其他文件。

执行轨迹中应该明确出现 mcp__daily_report_fs__... 工具卡片。write_file 具有覆盖文件的能力,如果当前批准策略显示确认卡片,要同时核对工具名、绝对路径和内容;不同组合的审批呈现可能不同,不要把“没弹卡片”当成服务端边界已经安全的证明。

工具返回成功后,在系统终端的 daily-report 目录中独立执行:

node -e "const fs=require('node:fs'); const p='mcp-scratch/mcp-check.txt'; const s=fs.readFileSync(p,'utf8'); if(s!=='MCP connection verified') process.exit(1); console.log('MCP file OK')"

成功时应看到:

MCP file OK

这条命令不经过 MCP,所以它独立证明了外部 Server 的调用确实落到了磁盘,而不是 Agent 只用文字回答“写好了”。

12.11 故意做一次越界失败

现在反过来验证 Server 不能读取 mcp-scratch 之外的项目文件。发送:

请只使用 mcp__daily_report_fs__read_text_file,尝试读取 mcp-scratch 的上级目录中的 PROJECT.md。
不要改用原生 read、Shell 或其他工具绕过这个限制。
请保留实际错误并解释它证明了什么。

预期结果是 MCP 工具调用失败,错误指向路径不在允许目录内。这次失败是成功验收的一部分:

  • 前一步证明“允许范围内能工作”;
  • 这一步证明“允许范围外会拒绝”。

如果 Agent 改用原生文件工具读到了 PROJECT.md,那不能证明 MCP 边界失效,只能说明 Agent 没有遵守这次验收的工具限制。请重新发送任务,并在轨迹中确认实际调用的是 MCP 限定名工具。

12.12 停用与回退

实验完成后,回到运行 mcp-lab 的终端,按 Ctrl+C 停止该 Web Profile。终端应返回命令提示符,3081 页面随后无法继续连接。

因为 MCP 条目是通过这次启动的 --patch 叠加进去的:

  • 你的官方 Desktop Profile 没有被修改;
  • 平时使用的 web Profile 也没有被修改;
  • 不带 --patch 启动 mcp-lab 时,不会加载这个 MCP Server;
  • .dsh/mcp-filesystem.yml 与 mcp-scratch/mcp-check.txt 作为练习产物保留,便于以后复盘。

如果你想再次验证回退,可以不带 patch 启动同一 Profile,新建任务后再查工具列表:

npx @deepseek-ai/dsh@0.1.7-rc.2 --profile mcp-lab --port 3081

这一次不应再出现 mcp__daily_report_fs__... 工具。不要在旧任务中判断:工具调用历史会保留在会话中,只有新任务的当前工具列表能证明 MCP 已不再加载。

12.13 这两种扩展该怎么选

现在可以用一个很实际的问题来判断:Agent 缺的是方法,还是缺的是工具?

  • 已经有读文件、写代码和跑测试的工具,只是每次容易忘记项目约定:写 Skill。
  • 现有工具无法访问某个数据库、文档系统或内部 API:评估 MCP Server。
  • 需要改变 DSH 的运行时服务、界面或组合方式:评估插件。
  • 需要为一类任务固定一套工具和行为方式:创建 Agent 预设。

还要多问一句:不接这个外部工具,任务是否已能可靠完成?本章的 Filesystem MCP 和 DSH 原生文件工具有意重复,是为了在不引入账号和密钥的情况下学会连接、限权、调用和回退。真实项目里没有新需求时,不应保持这种重复工具长期启用。

12.14 常见问题

patch 提示 YAML 解析失败

先检查尖括号占位符是否已替换,路径是否保持在引号内,以及缩进是否使用空格。再运行 --dump-config,不要通过反复启动 Web 来试错。

启动时提示找不到 npx

MCP Client 是 DSH 进程,Filesystem Server 则是它要启动的外部子进程。确认在同一个系统终端中 node -v、npm -v、npx -v 都能输出版本。Windows 若受 PowerShell 执行策略影响,参考第 6 章的 npx.cmd 路线,不要改成管理员权限运行整个 DSH。

首次连接一直等待或失败

先在系统终端确认 npm 能访问当前 registry。不要把 DSH 模型 API 可用当成 npm 也一定可用,这是两条不同的网络路径。保留启动终端中第一条完整错误,根据包下载、子进程启动或 MCP 握手阶段分层排查。

工具出现了,调用却失败

先展开工具卡片看实际错误。MCP Client 在连接中断期间可能仍保留最后已知工具名,但调用会失败,直到重连成功。同时检查路径是否真的在 mcp-scratch 内;对越界路径的拒绝不应通过扩大到用户主目录来“修复”。

12.15 本章验收

进入下一章前,请确认:

  • .dsh/skills/daily-report-maintainer/SKILL.md 已被 DSH 发现,不是普通的散落 Markdown;
  • 已用 /daily-report-maintainer 完成一次真实小改动,并独立运行 npm test;
  • 能解释 Skill 只增加指令,不增加工具或权限;
  • 已用 --dump-config 检查过隔离的 mcp-lab 配置;
  • 模型工具列表中出现 mcp__daily_report_fs__... 限定名工具;
  • MCP 成功写入 mcp-scratch/mcp-check.txt,并已用系统终端独立验收;
  • 已证明 MCP Server 不能越界读取 PROJECT.md;
  • 已停止实验 Profile,并知道不带 patch 即可回退该 MCP 工具组;
  • 能根据“缺方法还是缺工具”选择 Skill 或 MCP。

项目现在多了一份可复用维护 Skill,你也完成了一次有真实工具、有权限边界、有独立验收和可回退路径的 MCP 接入。下一章会改变任务的执行结构:让主 Agent 把两个相互独立的评审任务委派给子智能体,再审查他们的依赖、输出和失败边界。


← 上一章:案例二:从需求到可运行的第一版 | 回目录 | 下一章:案例四:把两项审查交给子智能体 →


14 案例四-多智能体

本文属于《DeepSeek Harness 入门教程(实战版)》· 第四部分 · 沿着项目掌握核心能力

第 13 章 案例四:把两项审查交给子智能体

到上一章为止,日报助手已经能运行、能测试,也有了项目 Skill 和一套隔离的 MCP 练习配置。接下来我们不急着继续加功能,而是先做一次小型项目审查。

这次审查有两个相互独立的方向:

  • 一名审查者只看源码和测试,寻找实现风险;
  • 另一名审查者只看文档、配置和安全边界,寻找使用风险。

把两个方向都塞给当前 Agent,它当然也能从头看到尾。不过,这正适合用来学习 Subagent(子智能体):主 Agent 负责拆分和汇总,两个子智能体各自在独立上下文中完成一项聚焦任务。

本章结束时,你会得到一份 AUDIT.md,并能从界面中证明两项审查确实由两个子智能体完成。更重要的是,你会分清三件容易混在一起的事:

  1. 子智能体是 DSH 执行任务时的协作结构,不是日报助手运行时的一部分;
  2. 两项简单委派用 Subagent 就够了,不必上 Workflow;
  3. 并行不会自动带来正确性,仍要控制写入、核对证据并由主 Agent 验收。

审查前的恢复点

在自己的外部终端检查 git status --short。尚未建立仓库时运行 git init -b main,先配置 .gitignore 排除 node_modules、凭证及生成报告,再只暂存课程源码、配置和测试,检查 git diff --cached 后提交审查基线。已有未提交工作先保存,不能把其混入本次审查。

记录 git rev-parse HEAD,要求审查阶段 git status --short --untracked-files=all 为空;这才检查到未跟踪文件、暂存和未暂存变化。

13.1 先纠正一个容易出现的误解

“让每个数据源交给一个子智能体抓取”听起来很自然,却把两个运行阶段混到了一起。

写代码时:DSH 的主 Agent 可以委派子智能体审查、研究或实现
程序运行时:Node.js 进程读取 sources.json,并发出普通网络请求

子智能体属于 DSH 的任务执行能力。它可以帮助你改造抓取代码,但不会因为程序里有两个数据源,就在以后每次执行 npm start 时自动出现两个 Agent。真要让运行中的程序并发请求,应使用 Promise.allSettled()、任务队列或其他程序设计手段,而不是把 DSH 的委派关系写进业务需求。

因此,本章选择“并行审查项目”作为练习。它能真实体现子智能体的价值,又不会给日报助手引入一个不存在的运行时依赖。

13.2 确认起点,并让 MCP 实验留在上一章

回到 daily-report 工作区。本章默认你已完成第 12 章,项目至少包含:

daily-report/
├── .dsh/
│   ├── mcp-filesystem.yml
│   └── skills/
│       └── daily-report-maintainer/
│           └── SKILL.md
├── PROJECT.md
├── README.md
├── package.json
├── sources.json
├── daily-report.md
├── src/
├── test/
└── mcp-scratch/

src 和 test 下的具体文件名可能不同,以你的项目为准。第 12 章的 mcp-lab 只是隔离实验,本章不要求重新启动它,也不依赖 mcp__daily_report_fs__... 工具。

先在系统终端进入项目目录,运行基线测试:

npm test

测试应全部通过。再确认项目中还没有本章的交付文件:

macOS 与 Linux:

test ! -e AUDIT.md && echo "audit file not created"

Windows PowerShell:

if (-not (Test-Path .\AUDIT.md)) { "audit file not created" }

看到 audit file not created 后再继续。如果文件已经存在,请先改名保存,避免本章覆盖你自己的内容。

13.3 检查子智能体设置

打开 DSH 的“设置 → 插件 → 子智能体”。不同窗口宽度下,这一项可能显示为插件设置中的一张卡片。

先看两个值:

  • 最大委派深度保持 1。它允许主 Agent 创建直接子级,但不让子智能体继续向下层层委派;
  • 本章不强制开启“允许 Agent 为子智能体选择模型”。关闭时,进程内子智能体通常沿用父 Agent 当前可用的模型路线;开启后,还要在允许列表中明确授权 provider 和 model。

设置是为新建的顶层任务采样的。若你刚修改过这里,请稍后新建任务,不要在旧任务里判断是否生效。官方文档还说明,默认深度 1 只允许直接子级,改为 0 会禁用继承该设置的委派工具。Subagent 服务说明 · 委派工具说明

为什么本章不专门为子智能体挑“便宜模型”?因为我们首先要验证任务拆分方式。模型路线、推理强度和提示词同时变化,就很难判断结果差异来自哪里。等你熟悉委派后,再为低风险检索任务选择成本更低的模型会更稳妥。

13.4 这次为什么选两个全新子智能体

DSH 的进程内委派主要有两种上下文起点:

方式 子智能体开始时看到什么 适合什么任务
subagent(spawn) 一份全新的上下文,依靠委派提示了解任务 自包含的研究、审查和限定实现
subagent_fork(fork) 父 Agent 已完成的历史快照,不包含当前尚未结束的这一轮 必须承接长对话背景的后续分析

本章的两项审查都能用“路径、范围、输出格式”完整描述,不需要继承前面对话,所以应优先使用全新的 subagent。这还能迫使主 Agent 把任务交代清楚,而不是依赖一句“你应该知道我说的是哪个项目”。

无论哪一种,子智能体都有自己的 Session。父任务最终只接收委派结果;子智能体的中间步骤和工具调用保留在子会话中,不会整段塞进父对话。官方 Subagent 架构说明

13.5 先做一轮严格只读的并行审查

在 daily-report 工作区新建一个标准模式任务,把权限设为 Read Only(仅可查看)。这一步很重要:第一轮只收集证据,不允许任何 Agent 一边审查一边顺手重构。

发送下面这条完整指令:

请对当前 daily-report 项目做一次双视角只读审查。

执行要求:
1. 必须使用 subagent 工具,同时启动两个全新的子智能体;不要使用 subagent_fork,也不要使用 workflow。
2. 两项委派必须互相独立,子智能体不得修改、创建或删除任何文件,不得访问网络,也不得运行 npm install 或 npm start。
3. 主 Agent 在两个结果返回前也不要修改文件。

委派 A:代码与测试审查
- 读取 package.json、src/ 和 test/;
- 可以运行 npm test;
- 检查配置解析、请求失败、Markdown 渲染和 CLI 边界;
- 最多给出 5 条发现。每条必须包含严重程度、文件或测试证据、影响和最小建议;
- 没有证据的问题不要猜。

委派 B:文档与安全审查
- 读取 PROJECT.md、README.md、sources.json、.dsh/skills/daily-report-maintainer/SKILL.md 和 .dsh/mcp-filesystem.yml;
- 不得读取任何凭证文件;
- 检查文档与实际命令是否一致、示例是否可能误导、Skill 约束是否清楚、MCP 练习是否把权限限制在 mcp-scratch;
- 最多给出 5 条发现,格式与委派 A 相同;
- 遇到本机绝对路径时只说明是否需要由读者替换,不要在结果中复述完整用户名路径。

两个子智能体完成后,由主 Agent:
- 分别列出 A、B 的结论;
- 合并重复项,把发现分为“已确认”“需要人工判断”“未发现问题”;
- 明确指出每一条结论来自哪个子智能体;
- 只在对话中汇总,不要写文件,不要实施修复。

这里有三个刻意的约束:

  • “同时启动”用于验证真正的并行委派;如果模型先等待 A 完成再启动 B,那仍是两个子智能体,却没有并行;
  • “最多 5 条且必须有证据”避免两个 Agent 为了显得有用而制造一长串猜测;
  • “只读后汇总”把发现问题和改动项目分开,防止并行写入冲突。

标准模式通常会在一次主 Agent 步骤中出现两个 subagent 工具调用。当前官方工具指导也要求相互独立的可继续委派一起启动,父 Agent 可以在它们运行时继续做不依赖结果的工作。官方 tool-subagent 说明

13.6 不只看最终答案:打开两个子会话

子智能体开始后,父任务标题附近会出现一个带数量的子级入口。普通工作区会话列表不会把子会话当成独立顶层任务混在一起;应从父任务顶部的子智能体目录进入。

依次打开两个子会话,核对下面几件事:

  1. 目录中确实有两个直接子级,而不是主 Agent 自己假装了两份报告;
  2. 两个子级的运行时间有重叠,或至少两个委派工具在同一主 Agent 步骤中启动;
  3. A 的轨迹集中在源码、测试和 npm test;
  4. B 的轨迹集中在文档、Skill 和 MCP patch;
  5. 两边都没有写文件、联网、安装依赖或启动真实抓取。

你可以点每个子级行尾的箭头,把会话放到右侧栏对照查看。一次性子会话完成后是只读记录;如果当前组合把 spawn 子级配置为可继续模式,运行中和结束后的状态、用量与持续时间也会显示在这里。官方 Web 子智能体界面说明

别用“两个回答看起来不同”判断是否真的委派。子会话目录、工具调用卡片和各自的执行轨迹才是证据。

13.7 检查主 Agent 的汇总质量

两个结果到齐后,主 Agent 应给出一份带来源的合并结论。理想结果不是一定找出严重 bug,而是满足下面四点:

  • 不把同一问题重复计算两次;
  • 不把“可能如此”写成“已经确认”;
  • 引用实际文件、命令或测试作为证据;
  • 如果没有高可信问题,敢于明确写“未发现需要立即修复的问题”。

子智能体并不会互相自动校验。主 Agent 收到的是各自的最终输出,不是某种天然正确的投票结果。两个 Agent 同时犯同一种错误,结论仍然是错的。因此,主 Agent 的职责不是把两段文字粘起来,而是审查冲突、回到项目核对关键证据,再形成一份可执行的判断。

在系统终端再次运行:

npm test

然后检查 AUDIT.md 仍不存在。此时项目功能应该与本章开始时完全相同;这两项只验证部分行为。还必须比较审查前后的 HEAD,并确认 git status --short --untracked-files=all 为空,才能确认没有项目文件变更。

13.8 由主 Agent 写交付物,而不是让两个子智能体抢写

确认汇总可信后,把当前任务权限切换为 Workspace Write(工作区内修改)。继续发送:

现在由主 Agent 独立完成收尾,不要再委派子智能体。

请把刚才经你核对后的审查结论写入项目根目录 AUDIT.md,结构如下:
1. 审查范围与本次未执行的外部操作;
2. 已确认的问题,包含严重程度、证据、影响和最小建议;
3. 需要人工判断的事项;
4. 两个子智能体均未发现问题的检查项;
5. 验收记录。

如果存在一项证据充分、低风险且不改变数据获取策略的问题,可以实施一项最小修复,并补充或更新对应测试;如果没有这样的事项,不要为了展示修改能力而改代码。

完成后运行相关测试和 npm test,重新读取 AUDIT.md,并报告:
- 实际改动文件;
- 是否实施了修复以及理由;
- 测试结果;
- npm start、网络访问和依赖安装是否执行。

这一步故意由主 Agent 串行执行。并行适合读取和分析,但两个执行者同时修改同一份代码、测试或文档时,容易互相覆盖,甚至各自基于不同的旧状态得出结论。更稳妥的结构是:

并行读取与分析 → 主 Agent 合并判断 → 单一写入者修改 → 统一测试

如果最终没有改代码,只新增 AUDIT.md,完全可以接受。审查的目标是发现真实问题,不是制造 diff。

13.9 独立验收交付结果

不要只接受 Agent 的完成报告。在系统终端运行:

npm test

然后检查 AUDIT.md 确实存在且包含关键段落。

macOS 与 Linux:

grep -E "审查范围|已确认|人工判断|验收记录" AUDIT.md

Windows PowerShell:

Select-String -Path .\AUDIT.md -Pattern "审查范围|已确认|人工判断|验收记录"

你还应该在 DSH 的改动视图中确认:

  • 一定存在的改动只有 AUDIT.md;
  • 若主 Agent 实施了修复,源码和测试必须成对出现;
  • sources.json、MCP 允许目录和 Skill 规则没有被无理由放宽;
  • 没有 node_modules、凭证、临时日志或联网生成物混入改动。

若报告声称修复了问题,却没有对应测试或测试失败,请撤销该项修复后回到审查结论,不要把“子智能体建议”当成修改依据本身。

13.10 Subagent、Workflow 和 Agent Team 怎么选

本章没有使用 Workflow,不是因为它不支持并行,而是因为两个固定任务用普通委派更清楚。

判断点 Subagent Workflow
任务数量 一两项聚焦委派 多项同构任务或多阶段编排
编排方式 主 Agent 直接发起并接收结果 模型生成 JavaScript 编排脚本
常见结构 “分别审查 A 和 B,再汇总” 批量并行、流水线、分阶段聚合
结果 每个委派各自结算 整个脚本返回一个最终 JSON 值
额外成本 每个子级一份独立上下文 子级上下文之外,还有脚本、阶段和聚合复杂度

官方给出的边界很直接:一两项委派优先普通 Subagent;跨很多文件的审计、迁移或多角度研究,且用户明确要求工作流式编排时,再使用 workflow。Workflow 脚本可调用 agent()、parallel()、pipeline()、phase() 和 log(),但它不是“更高级所以总该用”的模式。官方 Workflow 工具说明 · Workflow 能力说明

如果以后把审查扩大为“对 30 个源配置逐项检查,再经过安全复核和最终归类”,Workflow 才开始有明显价值:第一阶段批量检查,第二阶段复核高风险项,第三阶段返回结构化汇总。本章只有两个固定视角,用脚本编排反而增加理解和排错成本。

Agent Team解决的是另一类问题:Lead 与具名 teammate 需要在同一工作区持续协作,用持久消息和共享任务板维护分工。当前官方实现仍以 experimental 包名发布;成员共享同一个工作目录,任务的 writeScopes 只是冲突提示,不是文件锁,也不支持为每位成员分配独立工作区。Agent Team 官方说明

因此,本章的两项一次性只读审查使用 Subagent 就够了,不要求你为了看任务板而启用实验性 Team。等任务真的需要具名成员、成员间消息和可恢复任务状态时,再在隔离 Profile 中学习 Agent Team。

13.11 并行的收益、成本和边界

并行不等于一定更快

两个子任务足够独立、每个都需要明显推理时间时,并行才可能缩短等待。任务只有几十秒,创建子上下文、传递提示和汇总结果的开销可能抵消收益。

每个子智能体都会产生模型消耗

子级有独立上下文,也会发起独立模型请求。并行改变的是墙上时间,不会把两份推理成本变成一份。启用子级模型选择时,可以为低风险任务限定较轻模型,但应先用 list_subagent_models 核对真实 provider、model 和推理强度,而不是猜模型 ID。

并行写入比并行读取危险

让多个子级同时读不同文件通常问题不大;让它们同时编辑共享文件,则需要清晰的文件所有权、合并顺序和冲突处理。初学阶段优先采用本章结构:子级只读,父级写入。

失败不会自动变成“部分成功”

一个委派失败时,主 Agent 应明确指出哪个子任务没有结果,以及哪些结论因此缺失。不要让它用另一名子智能体的意见填补空白,更不要让最终报告暗示“双视角审查已完成”。需要时可以重新委派失败的那一项,而不是把两项都重跑。

13.12 常见问题

Agent 没有调用 subagent

先确认使用的是标准模式的新任务,再打开“设置 → 插件 → 插件列表”检查 Subagent 服务、spawn provider 和委派工具是否正常加载。回到“设置 → 插件 → 子智能体”确认最大深度不是 0。若刚改设置,新建任务后再试。

不要只把提示词改成“请更加并行”。工具没有加载时,模型不可能靠文字创造真正的子会话。

两个子智能体变成了先后执行

检查两个委派是否在同一主 Agent 步骤中发起。如果主 Agent 先等待 A,再调用 B,把要求收紧为“在同一条 assistant 消息里同时发起两个独立的 subagent 调用,等待前不要启动后续依赖工作”。

也要确认两个任务真的没有依赖。若 B 必须读取 A 生成的内容,它们本来就不应并行。

子智能体说看不到前文

这是全新 spawn 子级的正常行为,不是故障。委派提示必须自包含:写清工作目录、允许读取的文件、禁止操作、输出格式和验收标准。只有任务确实依赖父对话已经完成的历史时,才考虑 subagent_fork。

子级开始改文件

先停止该子级当前轮次,并检查父任务是否真的处于 Read Only。然后重新委派,明确“不得创建、修改或删除文件”。权限控制和任务约束要同时存在;只写一句“请谨慎”不构成边界。

父 Agent 汇总了不存在的证据

打开对应子会话,找到原始结论和文件位置。如果父汇总无法追溯到任一子级,要求它删除该项或重新读取项目验证。多 Agent 的可观察性不是为了看起来热闹,而是为了让结论可以追责。

13.13 本章验收

进入下一章前,请确认:

  • 能解释 DSH 子智能体与日报助手 Node.js 运行时并发的区别;
  • 最大委派深度允许主 Agent 创建直接子级,且本章使用了新建任务;
  • 两个 subagent 在同一主 Agent 步骤中启动,并分别完成代码测试审查和文档安全审查;
  • 能从父任务顶部的子级目录打开两个真实子会话;
  • 审查阶段没有文件写入、依赖安装或外部网络请求;
  • 主 Agent 对结论去重、区分确定性并标明来源;
  • AUDIT.md 由主 Agent 串行写入,任何可选修复都有测试;
  • 已在系统终端独立运行 npm test 并检查 AUDIT.md;
  • 能说明 Subagent、Workflow 与实验性 Agent Team 分别解决什么问题;
  • 知道并行可以减少等待,但不会减少模型请求成本,也不会自动解决写冲突。

现在,日报助手多了一份可追溯的审查记录。你也完成了一个真实的多智能体闭环:拆分独立任务、并行委派、查看子会话、合并证据、控制写入并独立验收。下一章会把注意力从“同时做两件事”转向“让一个较长目标跨多轮持续推进”。


← 上一章:案例三:用 Skill 固化方法,用 MCP 接入工具 | 回目录 | 下一章:案例五:让 Agent 持续推进一个长目标 →


15 案例五-长目标

本文属于《DeepSeek Harness 入门教程(实战版)》· 第四部分 · 沿着项目掌握核心能力

第 14 章 案例五:让 Agent 持续推进一个长目标

上一章的两个子智能体适合同时完成两项独立审查。如果任务不是“分给两个人”,而是“同一个 Agent 要经过实现、测试、文档和验收,可能一轮做不完”,更合适的机制是 Goal(目标)。

本章会给日报助手增加一个离线配置检查命令 npm run check。它需要改 CLI、补测试、更新文档并完成最终验收,规模足以观察 Goal 如何跨 Round(轮次)继续,又不会大到失去控制。

完成后,你应该能做到:

  • 创建一个带明确边界和 Round 上限的 Goal;
  • 从界面或 /goal 查看真实状态,暂停并由用户恢复;
  • 分清 Goal、后台任务、定时任务和普通长提示词;
  • 用系统终端独立验收 Agent 的成果,而不是看到 complete 就算完成。

14.1 Goal 到底保存了什么

Goal 不是一个“更努力地回答”的提示词。DSH 会在当前 Session 中持久保存一项目标,以及它的阶段、修订号、已经开始的 Round 数和上限。配套的续行驱动器会在 Agent 空闲、目标仍为 active、续行已启用且还有 Round 额度时,再发起下一轮推进。

可以把它理解为:

持久目标状态 + 顺序续行的多个模型轮次

它不等于下面几件事:

  • 不是后台进程:每个 Goal Round 仍在同一 Agent 会话中依次执行;
  • 不是定时任务:它不会约定“明早八点再做”,定时能力在后面的章节介绍;
  • 不是并行执行:要把独立任务同时扇出,应使用上一章的 Subagent 或 Workflow;
  • 不是权限豁免:文件、Shell、网络和审批仍受当前 Session 权限约束;
  • 不是完成证明:模型可以标记完成,但你仍需独立运行测试和检查产物。

官方 Goal 服务每个 Session 只保留一个当前目标。目标状态可以跨恢复和进程重启保留,但自动续行的启用状态不会悄悄复活;恢复会话后,需要用户显式恢复才继续。官方 Goal 服务说明

14.2 确认项目起点

回到 daily-report 工作区。本章假设第 13 章已经生成 AUDIT.md,但不会重复审查其中的问题,也不会使用第 12 章的 MCP 实验 Profile。

先在系统终端进入项目目录,运行:

npm test

测试应全部通过。再确认当前还没有 check 脚本:

node -e "const p=require('./package.json'); console.log(p.scripts?.check ?? 'check script not created')"

预期看到:

check script not created

如果已经存在,请先打开 package.json 核对来源。本章的目标不是覆盖你已有的同名能力。

接着记录现有日报文件的哈希,稍后用它证明离线检查没有重写报告。

macOS、Linux 与 Windows PowerShell 都可执行:

node -e "const fs=require('node:fs'),c=require('node:crypto'); const p='daily-report.md'; console.log(c.createHash('sha256').update(fs.readFileSync(p)).digest('hex'))"

把这串值临时记在别处,不要写进项目文件。

14.3 选择一个适合 Goal 的任务

这次要做的不是“把项目全面优化一下”,而是一个边界清楚的完整能力:

npm run check
  ├─ 只读取 sources.json
  ├─ 按现有配置格式做离线校验
  ├─ 有效时输出数据源数量并以 0 退出
  ├─ 无效时给出可读错误并以非 0 退出
  └─ 不访问网络,不修改 daily-report.md

它适合 Goal,因为要跨越实现、失败路径测试、文档和验收几个阶段;它又足够聚焦,能够写出明确的“完成”标准。

反过来,以下任务不值得创建 Goal:

  • 改一行文案;
  • 只解释一个错误;
  • 单次运行 npm test;
  • 等待一个后台下载结束。

Goal 的判断标准不是“听起来很重要”,而是:一个明确结果是否很可能需要多个顺序轮次才能可靠完成。

14.4 新建任务并确认 Goal 能力存在

在 daily-report 工作区新建一个标准模式任务,权限选择 Workspace Write(工作区内修改)。先输入:

/goal

如果当前没有目标,界面会显示用法;这条命令直接由命令层处理,不消耗一次模型请求。Web 中的 Goal 状态条位于输入框上方的上下文区域,存在目标后会显示目标文本、阶段和可用操作。官方 /goal 命令说明 · 官方 Goal 界面说明

如果 /goal 被当成普通聊天文字,先检查“设置 → 插件 → 插件列表”中的 Goal service、Goal tool、Goal round driver 和 Goal command 是否正常加载。极简模式不提供完整 Goal 体验,因此本章固定用标准模式。

14.5 创建一个有上限的真实 Goal

/goal <objective> 可以直接创建目标,但会采用部署的默认 Round 上限。为了让练习成本可控,我们让模型显式调用 create_goal,并把上限设为 8。

发送下面这条消息:

请调用 create_goal 创建一个长期目标,max_goal_rounds 设为 8。目标内容如下:

为当前 daily-report 项目实现一个完全离线的配置健康检查命令 npm run check。

完成标准:
1. 先读取 PROJECT.md、README.md、package.json、sources.json、相关 src 和 test 文件,以现有配置格式为准,不猜字段;
2. npm run check 只校验默认 sources.json,不访问 GitHub 或其他网络,不生成或修改 daily-report.md;
3. 有效配置时打印明确成功信息和数据源数量,进程退出码为 0;
4. 至少覆盖 JSON 语法错误、顶层类型错误、缺少当前实现所需字段三类失败,错误应可读且退出码非 0;
5. 复用或抽取现有配置解析逻辑,避免 check 与 npm start 各维护一套冲突规则;
6. 使用 node:test 和临时目录完成离线测试,不安装第三方依赖;
7. 更新 README.md,说明用途、用法、成功与失败示例;
8. 最终运行相关测试、npm test 和 npm run check,并重新核对 daily-report.md 未被修改。

边界:
- 不运行 npm start,不访问网络,不修改 sources.json;
- 不处理 AUDIT.md 中与本目标无关的建议;
- 不使用 Subagent、Workflow、后台 job 或 MCP;
- 每轮以当前工作区和实际测试结果为准;
- 只有所有完成标准都被实际验证后才能把目标标记为 complete;遇到需要我选择的行为时先暂停,不要自行扩大范围。

执行轨迹中应出现 create_goal,返回状态里能看到目标为 active、Round 上限为 8、续行已启用。Goal 工具允许模型读取、创建和更新目标;模型自主标记 blocked 前,默认还要求同一阻塞条件持续多个 Round,避免第一次遇到困难就草率停工。官方 Goal 工具说明

这里的 8 是最多允许的 Round 数,不是要求必须跑满 8 轮,也不是 token、时间或费用预算。任务两轮完成就应停止;把轮数跑满并不代表做得更好。

14.6 观察自动续行,而不是不停追加提示词

目标建立后,先不要连续发送“继续”。当当前轮结束且目标仍然 active 时,Goal round driver 会在 Agent 空闲后安排下一轮。每个被正式接纳的 Goal Round 才计入上限,普通的人类消息不计入。

观察三个位置:

  1. 输入框上方的 Goal 状态条是否仍显示 active;
  2. 对话中是否出现新的 Goal Round 请求头,而不是你手动发送的“继续”;
  3. /goal 输出中的 roundsStarted 是否递增,并且没有超过 maxGoalRounds。

官方续行驱动器只在整个 Agent 处于 idle 时启动下一轮,并在 complete、paused、blocked、取消、插件卸载或轮数耗尽时停止。官方 Goal Round Driver 说明

实际轮数会受模型、项目结构和单轮输出长度影响。若 Agent 在一轮内完成全部工作并通过验证,它可以直接标记 complete;不要为了“看到多轮”而要求它把一个动作拆成几轮。反过来,如果每轮都重复运行同一条命令却没有新进展,应暂停检查,而不是让它继续消耗额度。

14.7 练习一次暂停与恢复

在目标仍为 active 时,等 Agent 完成一个自然步骤或刚进入下一轮,然后点击 Goal 状态条上的“暂停”,也可以输入:

/goal pause

Web 中暂停会立即停止正在运行的模型轮次,目标本身仍保留。因为停止可能发生在一次文件修改或测试之间,暂停后先不要立刻恢复,先做三件事:

  1. 查看改动列表,确认没有半截文件或大范围无关改写;
  2. 在系统终端运行 npm test;
  3. 输入裸 /goal,确认 phase 为 paused,Round 数不再增长。

如果测试失败,把失败现象作为恢复后的第一条补充要求;不要在暂停期间另开一个 Agent 同时修改同一项目。

恢复只能由用户发起。点击状态条中的“恢复”,或输入:

/goal resume

恢复后,续行驱动器会从当前项目状态和同一个目标继续,而不是回滚到暂停前。Goal 的状态会持久化,但如果你关闭应用、重启或恢复会话,自动续行会保持停用,仍需显式 /goal resume。这个设计避免一个旧目标在你重新打开 DSH 时自行运行。

14.8 什么情况下应该编辑、暂停或清除

你的意图 操作 结果
目标没变,只是临时停下 /goal pause 保留目标和进度,停止续行
继续已暂停或恢复后的目标 /goal resume 在剩余 Round 额度内继续
目标文字需要收紧 /goal edit <新目标> 更新目标,不自动改变当前 phase
彻底放弃这项工作 /goal clear 移除当前目标,历史仍留在会话日志

如果只是 Agent 走偏,优先暂停、检查,再编辑目标。不要用“再发一条相反指令”让旧目标与新要求长期并存。

一个 Session 只有一个当前 Goal。需要并行推进两个独立长期任务时,应拆成不同任务或重新设计工作流,而不是把两个目标挤进一段含糊文字。

14.9 完成状态不是验收结果

当 Agent 认为所有条件已满足,会调用 Goal 工具把状态标记为 complete,自动续行随即停止。此时先输入:

/goal

确认状态确实是 complete,并记录实际使用的 Round 数。然后回到系统终端,独立执行:

npm run check
npm test

预期 npm run check 打印成功信息和当前数据源数量,两条命令都以退出码 0 结束。

再重新计算 daily-report.md 的哈希:

node -e "const fs=require('node:fs'),c=require('node:crypto'); const p='daily-report.md'; console.log(c.createHash('sha256').update(fs.readFileSync(p)).digest('hex'))"

它应与 14.2 记录的值一致。最后检查代码差异:

  • package.json 新增了 check 脚本;
  • 配置校验逻辑被复用,而不是出现两套互相矛盾的规则;
  • 测试确实覆盖失败退出码和不联网行为;
  • README 的命令、输出与实际运行一致;
  • sources.json、daily-report.md、MCP patch 和 AUDIT.md 没有被目标无关地修改。

如果任何一项不成立,complete 只是模型的判断,不是交付通过。你可以直接指出失败证据并要求修复;若当前 Goal 已完成,可以创建一个范围更小的新 Goal,或用普通一轮任务收尾,不要为了保留“完成”标签而接受错误结果。

14.10 Goal 遇到等待任务时要谨慎

本章明确禁止后台 job、子智能体和网络请求,因为 Goal driver 会在 Agent 空闲时尝试继续。若 Agent 实际是在等待一个已经发起的外部任务,盲目续行可能产生没有新信息的 Round。

实际项目中,看到下面这些状态时应先暂停 Goal:

  • 正在等待人工审批或必要选择;
  • 后台命令还没有结束;
  • 子智能体尚未返回;
  • 外部服务暂时不可用,只能稍后再试。

暂停表示“保留目标,暂不继续”,blocked 则表示目标遇到持续阻塞,含义不同。不要让模型因为一次暂时网络错误就立即宣布 blocked,也不要让它在没有新状态时反复声称“继续等待”。

14.11 常见问题

创建 Goal 后没有自动继续

输入 /goal,依次看 phase、续行启用状态和 Round 余量。目标若为 paused、blocked、complete,或恢复会话后处于 active 但续行未启用,都不会自动推进。需要继续时由用户执行 /goal resume。

很快触发 round-limit

这表示目标在允许的 Round 内没有完成,系统应把它记为带 round-limit 原因的 blocked,而不是无限循环。先检查是否每轮都在重复同一动作、是否等待外部状态、目标是否过大。收紧范围后再决定恢复或新建目标,不要只把上限改得更高。

暂停后测试失败

暂停会停止当前模型轮次,不保证恰好停在提交边界。先查看实际差异和失败测试;确认没有危险改动后,再恢复并把失败输出交给 Agent。必要时撤销本轮局部改动,但不要删除整个工作区。

Goal 已完成,界面仍看不到状态条

当前 Web 界面不渲染已完成 Goal 的上下文条。输入 /goal 查看持久状态即可。目标完成后可以创建新目标;不需要为了让卡片出现而把旧目标恢复。

Agent 没有调用 create_goal

确认你是在顶层标准模式任务中直接提出请求。创建、编辑、暂停和恢复需要当前顶层轮次中有用户直接输入,子智能体或定时触发不能替你偷偷创建 Goal。再检查 Goal tool 是否正常加载。

14.12 本章验收

进入下一章前,请确认:

  • 能解释 Goal 是持久状态加顺序续行,不是后台、定时或并行机制;
  • 已在新的标准模式任务中创建 Round 上限为 8 的 Goal;
  • 能用 /goal 查看 phase、Round 进度和续行状态;
  • 已暂停一次,检查项目与测试后再由用户恢复;
  • npm run check 完全离线,成功时退出码为 0;
  • 配置失败路径有离线测试,README 与实际行为一致;
  • npm test 通过,daily-report.md 哈希未变化;
  • 能区分 pause、blocked、complete 和 clear;
  • 知道应用重启或会话恢复后,必须显式恢复才会继续;
  • 没有把 Goal 的 complete 当成独立验收。

日报助手现在多了一条可脚本化的离线健康检查命令,也经过了一次完整的 Goal 生命周期:创建、自动推进、暂停、检查、恢复、完成和独立验收。下一章会离开交互界面,用 Headless 入口从系统命令行运行 DSH;npm run check 正好可以先成为一个安全、无网络的自动化任务。


← 上一章:案例四:把两项审查交给子智能体 | 回目录 | 下一章:案例六:定时任务与 Headless 自动化 →


16 案例六-无界面运行

本文属于《DeepSeek Harness 入门教程(实战版)》· 第四部分 · 沿着项目掌握核心能力

Windows 前提:使用 PowerShell 7.4+,先检查 $PSVersionTable.PSVersion;不要在 Windows PowerShell 5.1 直接复制本章重定向。将 $OutputEncoding = [Console]::OutputEncoding = [System.Text.UTF8Encoding]::new($false) 用于中文管道;调用 DSH 后立即保存 $dshExit = $LASTEXITCODE,非零时停止后续解析。对照 macOS/Linux bash 的 $? 含义,不能混用。

第 15 章 案例六:定时任务与 Headless 自动化

前面的操作都发生在 Desktop 或 Web 对话中。本章换两个入口:

  • 用 Headless 从系统终端发起一次 DSH 任务,拿到结果和退出码后自动结束;
  • 用 DSH 的内置定时任务把指令按时投递回原对话,让日报助手每天运行。

这两条路线都能用于自动化,但不是一回事。Headless 适合外部脚本、CI 和操作系统调度器;内置定时任务由正在运行的 DSH Host 管理,触发时恢复原 Session 并投递一条后续消息。

我们先让 Headless 执行第 14 章新增的离线 npm run check,确认命令、日志和退出码都可靠,再创建真正的每日任务。这样即使网络抓取暂时失败,也能先证明自动化链路本身是通的。

15.1 先分清四种入口

入口 谁启动工作 适合什么 本章是否实操
Web / Desktop 人在界面中发消息 交互、审批、观察过程 已经熟悉
Headless Shell 启动一次 DSH 进程 脚本、CI、系统调度器 是
内置 Schedule DSH Host 到点向原 Session 投递消息 提醒、定时 Agent 任务 是
SDK 你的程序通过 JSON-RPC 驱动 DSH 子进程 二次开发、程序集成 只说明边界

Headless 不是“把现有 Desktop 对话隐藏起来运行”。它默认创建一个新的 Session,完成一个任务后进程退出,不打开浏览器和端口,也不会留下后台进程。需要继续同一段 Headless 历史时,可以显式使用 --session-id,但每次调用仍只处理一个任务。官方 Headless 说明

15.2 确认项目和 CLI 起点

在系统终端进入 daily-report 项目,先绕过 Agent 直接验证项目命令:

npm run check
npm test

两条命令都应成功,而且 npm run check 不访问网络、不修改 daily-report.md。如果这里失败,先回第 14 章修复;Headless 只会多加一层 Agent 和模型调用,不会替项目命令消除故障。

接着检查 CLI:

npx @deepseek-ai/dsh@0.1.7-rc.2 --version
npx @deepseek-ai/dsh@0.1.7-rc.2 --profile headless --help

第二条应显示 Headless 自己的任务、--json 和 --session-id 选项,然后直接退出,不运行模型。

Headless 需要可用的 API 模型路线。只登录了 Desktop 账号不等于 CLI Headless 能复用账号模型;中国大陆读者通常按第 8 章配置官方 DeepSeek API Key、内置 Provider 或自定义模型 API。不要把 Key 写进下面的任务文字、Shell 历史或调度命令。

15.3 第一次 Headless:只做离线检查

确认当前工作目录仍是 daily-report,执行:

npx @deepseek-ai/dsh@0.1.7-rc.2 --profile headless "在当前工作区只运行 npm run check。不要修改文件,不要运行 npm start,不要访问网络。命令退出码为 0 时报告 CHECK_OK;否则如实报告错误。"

这段任务刻意把工作目录、允许动作、禁止动作和成功标准都写清楚。Headless 默认是新 Session,不知道你在 Web 中完成过哪些章节;它能看到当前工作区,但不会自动拥有旧对话里的解释。

正常情况下:

  • 推理增量可能以 dsh: reasoning: 写到 stderr;
  • stdout 最后打印 Agent 的最终答案;
  • 进程返回系统命令提示符;
  • 完成时退出码为 0,中止或错误时为 1。

macOS 与 Linux 查看上一条命令的退出码:

echo $?

Windows PowerShell:

$LASTEXITCODE

这里要区分两层退出码:Headless 的 0 说明 DSH 轮次正常完成;项目的 npm run check 是否真的成功,还要看工具轨迹和最终报告。我们的提示明确要求二者一致,但自动化场景仍应保留项目自己的独立检查。

15.4 用 stdin 提交较长任务

任务很长、包含引号或由其他命令生成时,可以从 stdin 输入。省略位置参数或传单独的 -,Headless 就从标准输入读取任务。

macOS 与 Linux 示例:

printf '%s\n' '在当前工作区运行 npm run check;不要修改文件;最后只报告命令、退出码和数据源数量。' | npx @deepseek-ai/dsh@0.1.7-rc.2 --profile headless

Windows PowerShell:

"在当前工作区运行 npm run check;不要修改文件;最后只报告命令、退出码和数据源数量。" | npx.cmd @deepseek-ai/dsh --profile headless

不要同时传位置任务又指望 Headless 读取管道;只要位置参数存在,stdin 就不会成为任务内容。空位置参数和空管道会在模型运行前直接报错。

15.5 用 --json 留下机器可读记录

普通模式适合人看最终答案。自动化程序若要知道调用了什么工具、如何结束,应使用按行 JSON(NDJSON)事件流。

在项目根目录执行:

npx @deepseek-ai/dsh@0.1.7-rc.2 --profile headless --json "只运行 npm run check,不修改文件、不联网;如实报告结果。" > headless-check.ndjson

stdout 现在只保存 JSON 事件;诊断仍在 stderr。文件第一条通常是带 Session 标识的 session 事件,最后成功结束时有 final,中间可能出现 status、text、thinking、tool_call 和 tool_result。

用 Node.js 做一个不依赖额外工具的检查:

node -e "const fs=require('node:fs'); const rows=fs.readFileSync('headless-check.ndjson','utf8').trim().split(/\r?\n/).map(JSON.parse); console.log({first:rows[0]?.type,last:rows.at(-1)?.type,sessionId:rows[0]?.sessionId});"

你应该至少确认首条类型为 session、末条类型为 final,并记录输出中的 Session ID。字段的附加内容会随事件类型变化,不要用正则从整行日志里猜状态。

还要同时检查 Headless 进程退出码。官方约定允许“格式完整但运行失败”的事件流:某些轮次失败仍可能写出 final,真正的失败信号是退出码 1 与结束原因,而不只是“文件最后一行能解析”。--json 是运行投影,也不是完整 Session 日志的无损副本。官方 Headless JSON 事件约定

headless-check.ndjson 是本章的临时验收文件。它可能包含模型推理、工具参数和工作区信息,不要提交到公开仓库。检查完可移到项目外或用普通文件操作删除。

15.6 显式继续同一个 Headless Session

默认每次运行都会创建新 Session。若确实需要第二次调用基于第一次历史继续,把上一步 session 事件里的 ID 替换到下面命令:

以下为参数模板,执行前先将尖括号占位符替换为实际值:

npx @deepseek-ai/dsh@0.1.7-rc.2 --profile headless --session-id <SESSION_ID> "根据上一轮结果,只总结 npm run check 的验证结论,不运行命令、不修改文件。"

不要保留尖括号。沿用要求:

  • 使用同一个 Headless Profile;
  • 从同一个工作目录运行;
  • 该 Session 已被持久化且当前没有另一个进程占用;
  • 它不是子智能体或 fork Session。

ID 不存在或工作目录不匹配时,Headless 会在运行前失败,不会偷偷创建一段空历史。这种严格性对自动化是好事:脚本不会以为自己接上了旧任务,实际却从零开始。

普通定时检查通常不需要续用历史。每次任务都写成自包含文本,更容易重试、审计和迁移。

15.7 先认识 DSH 内置定时任务

从 v0.1.7-rc.2 起,发布版 Web/Desktop 可以创建持久定时任务并查看运行记录,但该功能默认关闭。它支持一次性、固定间隔、每日、每周和五字段 cron 规则;触发时不是直接执行一条 Shell,而是向原 Session 投递一条普通 follow-up,让 Agent 再处理这条指令。官方发布说明 · 官方 Schedule 说明

这意味着:

  • 任务继承的是原 Session 的工作区、Agent 预设、模型与权限上下文;
  • 到点后仍会产生模型调用和费用;
  • 如果指令要求网络抓取,就会产生真实外部请求;
  • 它依赖 Web/Desktop Host 与 Session 持久化,不能塞进一次性 Headless 进程里当作常驻调度器;
  • 关闭 Desktop 窗口时任务可以继续由后台应用处理,但彻底退出应用后,要等 Host 再次运行。

重复任务在 Host 重启后仍会保留;错过多次时只补发最近一次发生点。它不是操作系统级“保证准点”的守护进程。

15.8 启用 Schedule,并先做两分钟测试

回到日常 Desktop 或 Web Profile,打开左侧“插件”页面,找到内置定时任务(Schedule)并启用。若界面提示重新加载或新建任务,请照做。然后在 daily-report 工作区新建标准模式任务,选择 Workspace Write 权限。

先创建一个一次性测试任务,而不是直接创建每天运行的任务:

请创建一个两分钟后触发的一次性定时任务:
- 标题:日报配置自动检查测试
- 到期后只运行 npm run check;
- 不修改文件,不运行 npm start,不访问网络;
- 最后报告命令退出码和检查到的数据源数量。

创建完成后列出当前定时任务,并告诉我任务 id 和预计触发时间。不要创建重复任务。

执行轨迹中应出现 schedule_create,然后用 schedule_list 返回同一任务。你也可以打开“任务”页面查看标题、下次运行时间和状态。

等待触发后,原对话会收到一条定时来源的后续消息,Agent 执行 npm run check 并留下运行记录。核对:

  • 执行发生在 daily-report 工作区;
  • 没有 npm start、网络或文件改动;
  • npm run check 成功;
  • 一次性任务已经结束,不会再次运行。

如果两分钟后没有动静,先确认 DSH Host 仍在运行,再检查任务页的预计时间和最近投递记录;不要立即创建第二个同名任务。

15.9 创建真正的每日日报任务

测试通过后,在同一个 daily-report Session 中发送:

请创建一个每日定时任务:
- 标题:每天生成技术日报
- 每天北京时间 08:00 触发,时区必须显式使用 Asia/Shanghai;
- 到期后先运行 npm run check;
- 检查成功后运行 npm start 生成 daily-report.md;
- 任一步失败都停止后续动作,如实报告错误,不修改 sources.json,不安装依赖;
- 不把 API Key、访问令牌或其他凭证写入任务内容。

创建后立即调用任务列表核对标题、规则、时区和下一次运行时间。本次不要提前运行 npm start。

Schedule 的 daily 规则使用本地钟表时间和显式 IANA 时区。不要用 every_seconds: 86400 代替“每天 08:00”,固定 24 小时间隔与本地每日时刻不是同一种语义。

这条任务会真实访问配置的数据源,并可能每天覆盖 daily-report.md。如果你不希望产生这些外部副作用,就把指令改为只运行 npm run check,或在创建后立即删除任务。教程不能替你决定是否长期运行它。

15.10 定时任务的停用与删除

内置 Schedule 提供更新和删除工具,而不是让你编辑系统 crontab。要停止本章的每日任务,发送:

请先列出当前定时任务,找到标题完全等于“每天生成技术日报”的任务。
只删除这一条,并在删除后再次列出任务,证明它已经不存在。

删除前一定先列出并核对 ID、标题与规则,避免名称相近时删错。删除会移除任务和已保存的投递记录;如果你只想改时间或指令,应使用更新,而不是先删后盲建。

15.11 什么时候改用操作系统调度器

如果你需要 CI、服务器 cron 或 Windows 任务计划程序统一管理,就让外部调度器调用已验证的 Headless 命令。此时要额外处理:

  • 使用 npx/dsh 的绝对路径,不能假设调度器加载登录 Shell 的 PATH;
  • 显式设置工作目录;
  • 把 stdout 与 stderr 写入访问受控的日志,并设置保留周期;
  • 防止上一次任务未结束时再次启动;
  • 依赖 DSH 已保存的凭证或安全的 Secret Store,不把 Key 直接写进 crontab、命令参数或脚本;
  • 同时检查进程退出码与产物,不把一段自然语言“成功”当作唯一信号。

不同操作系统的安全凭证和锁机制差异很大,本教程不提供一条看似通用、实际会泄密的 cron 行。先把 15.3 的 Headless 命令手动跑通,再按你所在环境的调度规范接入。

15.12 SDK 不是另一种 Headless 参数

Python SDK 会通过 stdio 上的 JSON-RPC 启动并复用一个 DSH 子进程,适合你的程序需要连续创建 Session、接收结构化事件或管理多个调用时使用。它不是“给定时任务加个 Python 外壳”,也不是本章每日任务的必需品。

当前 SDK 通过 deepseek-harness-sdk 安装,并要求显式指定隔离的 dsh_home 或 DSH_HOME;它不会自动发现 ~/.dsh。这些约束适合二次开发,却会把凭证、Profile 和生命周期管理带进入门主线,因此本章不安装。官方 Python SDK 说明

选择原则很简单:

  • Shell 里跑一次任务:Headless;
  • DSH 对话到点继续:内置 Schedule;
  • 你的程序长期驱动 DSH:SDK。

15.13 常见问题

Headless 提示没有模型或凭证

Desktop 账号路线与 CLI API Key 路线不是一回事。按第 8 章核对当前 DSH Home 中的 Provider、默认模型和凭证引用;不要把 Key 临时拼到任务字符串里。

Headless 一直没有输出

默认模式在模型产生第一个非空推理增量前没有心跳。先检查网络、Provider 额度和 stderr;自动化需要进度事件时使用 --json。不要因为几秒静默就并发启动多个相同任务。

--session-id 无法继续

核对 ID 是否来自该 Headless Profile 的 session 事件、工作目录是否相同、Session 是否仍被其他进程占用。未知 ID 会明确失败,不会自动新建。

定时任务到点没有运行

确认 Schedule 插件已启用、Host 正在运行或已重新启动、任务状态仍为活动、下一次时间使用 Asia/Shanghai。再看任务页的最近投递记录和原 Session 是否可恢复。

定时任务重复创建

先用 schedule_list 按标题和 ID 核对,再更新或删除。不要在“没看到回复”时重复发送创建指令;第一次调用可能已经成功,只是界面消息尚未刷新。

15.14 本章验收

进入下一章前,请确认:

  • 能解释 Headless、内置 Schedule 与 SDK 的不同职责;
  • 已从 daily-report 目录用 Headless 成功运行 npm run check;
  • 已检查 Headless 的系统退出码;
  • 已生成并解析一份 --json NDJSON 事件流;
  • 知道 --session-id 的 cwd、归属和独占限制;
  • 已启用 Schedule,并完成一次两分钟后的离线测试;
  • 已创建或明确选择不保留“每天生成技术日报”任务;
  • 每日规则显式使用 Asia/Shanghai,任务内容不含凭证;
  • 知道如何列出并精确删除本章的定时任务;
  • 不会把 Headless 最终文字、Goal complete 或 Schedule 投递当成独立验收。

到这里,日报助手已经从交互式项目变成了可被终端、任务调度和后续程序集成调用的工具。下一章不再增加运行入口,而是整理哪些配置值得沉淀到 Profile、Skill 或插件中,哪些仍应留在具体项目里。


← 上一章:案例五:让 Agent 持续推进一个长目标 | 回目录 | 下一章:案例七:把经验沉淀到项目、Skill 与 Profile →


17 案例七-沉淀配置

本文属于《DeepSeek Harness 入门教程(实战版)》· 第四部分 · 沿着项目掌握核心能力

Windows 前提:使用 PowerShell 7.4+,先检查 $PSVersionTable.PSVersion;不要在 Windows PowerShell 5.1 直接复制本章重定向。将 $OutputEncoding = [Console]::OutputEncoding = [System.Text.UTF8Encoding]::new($false) 用于中文管道;调用 DSH 后立即保存 $dshExit = $LASTEXITCODE,非零时停止后续解析。对照 macOS/Linux bash 的 $? 含义,不能混用。

第 16 章 案例七:把经验沉淀到项目、Skill 与 Profile

日报助手现在已经可以开发、测试、审查和定时运行。最后一步不是再加一个功能,而是把这些经验放到正确的地方:下次打开项目时仍然有效,换一个项目时又不会带过去无关限制。

本章会完成两件事:

  1. 把第 14 章新增的 npm run check 写进项目 Skill;
  2. 从官方 Web 模板创建一个隔离的 daily-report-lab Profile,只在其中启用时间上下文,然后用配置 dump 证明日常 web Profile 没有被改动。

第二个实验故意重用第 10 章已经熟悉的 time-context。这次不是重学插件开关,而是验证 Profile 隔离。

16.1 先决定“该放在哪里”

“一切皆插件”描述的是 DSH 如何组装能力,不等于每条经验都应做成插件。先用下表判断:

要沉淀的内容 放置位置 日报助手示例
项目事实、命令和可验收规则 项目文件、README、测试 sources.json 格式、npm run check
处理某类任务时应遵守的方法 项目级 Skill 先跑离线检查,再报告未执行的外部操作
某个 DSH 运行实例的组合和配置 Profile 只给实验环境启用时间上下文
现有 DSH 根本没有的服务、工具或界面 Plugin / bundle 新的数据接入能力或界面面板

一个实用的顺序是:先用项目文档和测试固定事实,再用 Skill 固定方法;只有运行时组合真的需要隔离时才建 Profile,缺少新能力时才写或安装插件。

Skill 不会增加工具或绕过权限,Profile 也不会自动让一条错误的项目规则变正确。它们解决的是不同问题。

16.2 确认项目起点

在系统终端进入 daily-report 目录,先跑基线:

npm run check
npm test

两条命令都应以 0 退出。然后查看项目 Skill 的当前内容:

node -e "console.log(require('node:fs').readFileSync('.dsh/skills/daily-report-maintainer/SKILL.md','utf8'))"

如果文件不存在,说明你跳过了第 12 章。先回去建立完整 Skill,不要为了跟本章而临时创建一份空文件。

此时第 5 条规则应还是“先运行直接相关的聚焦测试,再运行 npm test”。它没有错,但还不知道后来新增的离线健康检查。

16.3 把新约定写回项目 Skill

回到 daily-report 工作区的标准模式任务,使用 Workspace Write 权限,发送:

/daily-report-maintainer

请只修改 .dsh/skills/daily-report-maintainer/SKILL.md 的第 5 条规则,
在“再运行 npm test”之后增加“和 npm run check”。

要求:
1. 不改 frontmatter、其他规则和项目文件;
2. 不运行 npm start,不访问网络;
3. 修改后重新读取整个 Skill,确认仍有完整 frontmatter 和 7 条规则;
4. 最后只报告实际差异和验证结果。

预期只有一行差异:

-5. 先运行直接相关的聚焦测试,再运行 npm test。
+5. 先运行直接相关的聚焦测试,再运行 npm test 和 npm run check。

在系统终端独立验收:

node -e "const s=require('node:fs').readFileSync('.dsh/skills/daily-report-maintainer/SKILL.md','utf8'); if(!s.includes('npm test 和 npm run check')||(s.match(/^\d+\./gm)||[]).length!==7) process.exit(1); console.log('SKILL_OK')"
npm run check
npm test

看到 SKILL_OK,且两条项目命令均成功,才算沉淀完成。这次没有修改程序行为,因此不需要为了“看起来更完整”再改 README 或测试。

16.4 Profile 实际保存什么

一个正在运行的 DSH 是由多层配置组装出来的插件树。Profile 是这份组合在 Harness Home 下的命名记录,包含:

  • package.json:记录外部依赖和有序的 bundle 列表;
  • cordis.patch.yml:记录该 Profile 自己的配置覆盖。

官方的 web、headless、sdk、sdk-minimal 和 acp 是随附模板。desktop 则是 Electron 应用保留的 Profile,公共 CLI 不允许启动、dump 或用 dsh plugin 管理它。所以本章创建的是 CLI/Web Profile,不会替换 Desktop 里已有的模型和插件设置。CLI 官方说明

更容易误解的是:“从 web 模板创建”只复制官方模板当前的 bundle 列表,不会复制你本机 web Profile 已安装的依赖和 cordis.patch.yml。这正是我们要的隔离起点。

16.5 创建隔离的 daily-report-lab Profile

先确认当前使用的 CLI 版本:

npx @deepseek-ai/dsh@0.1.7-rc.2 --version

本教程按 v0.1.7-rc.2 核对。如果你的版本不同,先查看对应版本发布说明,不要盲目照抄 patch。

在 daily-report 目录中建立一个只用于本章比较的目录:

node -e "require('node:fs').mkdirSync('profile-audit',{recursive:true})"

下面的第一条命令会创建新 Profile,但不启动 Web 服务:

npx @deepseek-ai/dsh@0.1.7-rc.2 --profile daily-report-lab --from-default-profile web --dump-default-config > profile-audit/lab-default.yml
npx @deepseek-ai/dsh@0.1.7-rc.2 --profile daily-report-lab --dump-config > profile-audit/lab-before.yml
npx @deepseek-ai/dsh@0.1.7-rc.2 --profile web --dump-config > profile-audit/web-before.yml

Windows PowerShell 可以使用同样的参数;如果系统找不到 npx,把命令头换成 npx.cmd。

三个文件各有不同用途:

  • lab-default.yml 只包含官方 bundle 各层;
  • lab-before.yml 还包含 Profile patch、Home 级 patch 和本次命令的 overlay;
  • web-before.yml 是日常 CLI/Web Profile 的对照快照。

用 Node.js 确认三次 dump 都真的有输出:

node -e "const fs=require('node:fs'); for(const f of ['lab-default.yml','lab-before.yml','web-before.yml']){const n=fs.statSync('profile-audit/'+f).size; if(!n) process.exit(1); console.log(f,n+' bytes')}"

如果创建命令提示 Profile 已存在,不要直接删目录。这通常说明你之前已做过实验;去掉 --from-default-profile web 后重新 dump 即可。如果你不确定里面是什么,换一个新名字比删除旧 Profile 更安全。

16.6 只在实验 Profile 中启用时间上下文

启动自定义 Profile,使用 3081 避开可能正在使用的默认端口:

npx @deepseek-ai/dsh@0.1.7-rc.2 --profile daily-report-lab --port 3081 --no-open

启动器应打印本地地址。在浏览器打开 http://127.0.0.1:3081,然后按下列顺序操作:

  1. 打开“设置 → 插件 → 插件列表”,搜索 time-context;
  2. 确认条目 ID 为 time-context、包名为 @deepseek-ai/dsh-time-context;
  3. 打开左侧边栏的“插件”管理页,只启用这一项;
  4. 回到只读插件列表,确认它已启用且没有加载错误。

如果界面提示需要重启,在终端按 Ctrl+C,再用同一条命令启动。不要转到 Desktop 里操作;那是另一个保留 Profile,不能验证 daily-report-lab 的隔离。

本次不需要发送模型消息。我们要验证的是配置作用域,不必为此产生一次模型调用。

16.7 用两组快照证明隔离生效

在终端按 Ctrl+C 停止实验 Web Host,再生成两份快照:

npx @deepseek-ai/dsh@0.1.7-rc.2 --profile daily-report-lab --dump-config > profile-audit/lab-after.yml
npx @deepseek-ai/dsh@0.1.7-rc.2 --profile web --dump-config > profile-audit/web-after.yml

现在计算四个文件的 SHA-256,并直接判断两组是否发生变化:

node -e "const fs=require('node:fs'),c=require('node:crypto'); const h=f=>c.createHash('sha256').update(fs.readFileSync('profile-audit/'+f)).digest('hex'); const a=h('lab-before.yml'),b=h('lab-after.yml'),x=h('web-before.yml'),y=h('web-after.yml'); console.log({labChanged:a!==b,webUnchanged:x===y,labBefore:a,labAfter:b,webBefore:x,webAfter:y});"

如果你从第 10 章的停用状态出发,预期看到:

labChanged: true
webUnchanged: true

这比“界面说已保存”更可靠:第一个值只说明实验 dump 的字节变化,第二个值说明 web dump 的字节未变。还需用文本 diff 定位 time-context 条目,核对 disabled 从 true 变为 false(或该版本对应的明确启用状态);来源注释或其他元数据变化不能算启用成功。保存这项差异与 web 未变的证据,哈希仅作辅助。

如果 labChanged 为 false,先确认你在 3081 的界面中点击了实际的启用/保存操作,而不是只打开只读列表。如果 webUnchanged 为 false,不要立刻判定 DSH 串了配置;先检查比较期间是否有另一个 web 实例、页面或脚本正在保存设置。

profile-audit 中的 dump 是诊断文件,可能暴露本机路径、Provider 配置或凭证引用。不要提交到仓库、上传网盘或原样发给别人;验收完成后可用文件管理器删除这个明确的临时目录。删除 dump 不会删除 daily-report-lab Profile。

16.8 配置层的真实优先级

当某一行配置在多层都出现时,当前启动器依次应用:

bundle patches
    ↓
Profile 的 cordis.patch.yml
    ↓
Harness Home 级 cordis.patch.yml
    ↓
本次命令的 --patch(可重复,按参数顺序)

后应用的层对同一行优先。但这里有一个很重要的细节:patch 会替换目标行完整的 config,不是只深度合并你写出来的那个字段。

所以,不要只看一篇旧教程就手写半行覆盖。安全顺序是:

  1. 用 --dump-config 找到当前完整行和来源;
  2. 用 --dump-config-schema 核对可用字段与类型;
  3. 先用一次性 --patch <path> 试运行;
  4. 验证无误后,再通过界面或 Profile 自己的 patch 持久化;
  5. 保留变更前 dump,方便回退。

--dump-default-config 适合看“官方 bundle 给了什么”,--dump-config 适合看“我这台机器实际会启动什么”。排错时不要把两者混用。Profile 与 bundle 架构说明

16.9 什么时候才用 dsh plugin

本章启用的 time-context 已经随 DSH 发布,不需要下载陌生包。当你确定需要一个当前 Profile 没有的外部 bundle 时,CLI 语法才是:

以下为参数模板,执行前先将尖括号占位符替换为实际值:

npx @deepseek-ai/dsh@0.1.7-rc.2 plugin --profile <PROFILE_NAME> add <TRUSTED_BUNDLE>
npx @deepseek-ai/dsh@0.1.7-rc.2 plugin --profile <PROFILE_NAME> remove <TRUSTED_BUNDLE>

这里的尖括号是占位符,不能原样运行。dsh plugin 会在 Profile 目录中调用 pnpm,所以系统 PATH 里必须有 pnpm;它会改变依赖、锁文件和 bundle 列表。添加、移除或更新 bundle 后,正在运行的 Profile 仍保持启动时的组合,必须重启才能获得新集合。CLI 插件管理约定

外部 bundle 可以在 DSH Host 进程中运行代码。安装前要核对来源、完整包名、版本、许可证、源码、依赖、构建脚本和 DSH 兼容范围。“试试看”不是安装一个未审查 Host 插件的充分理由。

16.10 常见问题

--from-default-profile 报目录已存在

这个选项只能创建全新的非随附 Profile。已存在时去掉该选项使用原 Profile,或改用一个新名称;不要为了重试而删除不明目录。

自定义 Profile 里没有日常 web 的模型或插件设置

这是预期行为。模板初始化只复制官方 bundle 列表,不复制本机同名 web Profile 的依赖和 patch。只补实验真正需要的配置,不要整份复制包含凭证的文件。

dump 成功,启动却失败

dump 只证明 patch 能组合,不代表所有插件在运行时都能激活。检查 stderr 中的模块解析、schema、服务依赖和端口错误;启动前也要确认 3081 没被其他进程占用。

Profile 改了,已打开的任务却没反应

普通 Profile/Home patch 在 Web 组合中可以热重载,但 bundle 成员的添加、移除或更新需要重启 Profile。已创建 Agent 还可能保留旧的预设或会话上下文,所以配置验收优先使用新任务。

Desktop 中看不到 daily-report-lab

daily-report-lab 是 CLI/Web Profile,Desktop 使用保留的 desktop Profile。两者共享部分产品数据,但可执行包、锁文件、依赖和启用选择不是同一份。这不是同步失败。

16.11 本章验收

进入下一章前,请确认:

  • 能根据作用域选择项目文档/测试、Skill、Profile 或 Plugin;
  • daily-report-maintainer 的第 5 条已包含 npm run check;
  • 修改 Skill 后已独立运行 npm run check 和 npm test;
  • 已从官方 web 模板创建 daily-report-lab;
  • 能解释“复制模板”为什么不等于“复制本机 web Profile”;
  • 已只在实验 Profile 中启用 time-context;
  • 快照比较结果为 labChanged: true 且 webUnchanged: true;
  • 知道 bundle、Profile patch、Home patch 和 --patch 的顺序;
  • 知道 patch 会替换目标行完整 config,不是深度合并;
  • 没有将可能包含本机配置的 dump 文件对外分享。

到这里,项目内的方法已收进 Skill,DSH 运行时的实验变更也收进独立 Profile。下一章不再引入新机制,而是把安装、模型、工具、会话和项目中最容易阻塞学习的问题收拢成一套排查方法。


← 上一章:案例六:定时任务与 Headless 自动化 | 回目录 | 下一章:常见问题排查:先定位哪一层坏了 →


18 常见问题排查

本文属于《DeepSeek Harness 入门教程(实战版)》· 第五部分 · 排错与进阶

第 17 章 常见问题排查:先定位哪一层坏了

排查 Agent 产品最容易犯的错,是看到“任务失败”就立刻重装、换模型或放宽权限。DeepSeek Harness 同时包含界面、Host、Profile、模型 Provider、Agent 预设、工具、审批和项目代码;不同层的故障,表面上都可能只是“它没完成”。

这一章不做一张越来越长的报错对照表,而是建立一条固定路径:

保留现场 → 确认失败层 → 做最小只读检查 → 只修一处 → 独立复验

你会得到一份可以直接套用的排查模板,并能处理本教程主线最常见的阻塞:Desktop/CLI 启动、模型路线、权限审批、插件与 Profile、Skill/MCP、Goal/子智能体、Schedule/Headless,以及日报助手自身。

17.1 出错后先别做三件事

先不要:

  1. 连续点击重试,制造多个相同任务、审批或定时任务;
  2. 直接升级、重装或删除 Profile,把原始证据和可回退状态一起抹掉;
  3. 把 API Key、完整配置 dump、崩溃日志或会话导出原样贴到公开渠道。

先记录以下信息:

  • 使用 Desktop 还是 CLI/Web,操作系统与 CPU 架构;
  • DSH 的完整版本号,包括 alpha、beta 或 rc 后缀;
  • 当前 Profile、Agent 预设、权限模式和工作区;
  • 最后一项成功操作,以及第一项失败操作;
  • 原始错误码、退出码、失败工具名和发生时间;
  • 是否能在“新任务 + Read Only + 最小提示词”中复现。

“界面卡住了”信息太少;“v0.1.7-rc.2 Desktop,标准模式、Read Only,新任务读取 PROJECT.md 时工具卡片返回某错误”才是可定位的问题。

17.2 用五层模型快速分流

从最外层往里查,每次只问一个问题:

层 最小检查 能排除什么
应用/Host 能否启动、打开设置、创建空任务 安装、端口、Host 与界面故障
模型路线 新建 Read Only 任务,只让模型回复固定文字 账号/API Provider、凭证、模型 ID
Agent/工具 查看执行轨迹与插件列表 预设、工具注册、审批、插件加载
工作区/权限 读取一个已知文件,再尝试受控写入 目录选错、沙箱、审批策略
项目 绕过 DSH,直接运行 npm run check 与 npm test 项目自身代码、配置与网络问题

最外层失败时,不要让内层背锅。例如 Desktop 根本没启动,就没有必要先改模型 Key;npm test 在系统终端已经失败,也不能先责怪 Agent 预设。

17.3 做一次五分钟健康检查

在没有故障时先知道“正常是什么样”,以后更容易比较。

第一步:记录版本

CLI/Web 路线在系统终端运行:

node --version
npm --version
npx @deepseek-ai/dsh@0.1.7-rc.2 --version

Windows PowerShell 找不到 npx 时使用 npx.cmd。Desktop 路线从应用菜单的“关于”或更新界面记录完整版本,不要拿系统里的全局 CLI 版本代替 Desktop 内置运行时版本。

第二步:验证最小模型请求

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

只回复 MODEL_OK,不调用工具,不解释。

看到 MODEL_OK 只证明当前任务的模型路线可用,不证明文件工具或项目正常。

第三步:验证只读工具

再新建一个 Read Only 任务,发送:

只读取当前工作区的 PROJECT.md,并报告第一行标题。
不要运行 Shell,不要访问网络,不要修改文件。

核对执行轨迹中确实发生了文件读取,回答也与文件一致。最后绕过 DSH,在系统终端进入 daily-report 并运行:

npm run check
npm test

四项结果——版本、模型、只读工具、项目检查——构成你的健康基线。某次故障只破坏其中一项时,排查范围会立刻缩小。

17.4 Desktop 启动失败、白屏或反复恢复

先读原生错误弹窗,不要只记住“打不开”。当前 Desktop 在首次致命错误前会尝试写入 crash-<UTC 时间>-<source>.log;弹窗成功写入时会显示准确路径。macOS 的默认日志目录是 ~/Library/Logs/DeepSeek Harness,Windows 位于该应用 userData 目录下的 logs。Desktop 官方说明

按以下顺序处理:

  1. 记录弹窗中的 source、应用版本、运行时版本和首个错误;
  2. 若错误含 EADDRINUSE,先完全退出其他 DSH 实例,再重启,不要先重装;
  3. 若刚安装或启用第三方插件后才失败,使用原生恢复操作“停用第三方 bundle、备份 Profile patch 并重启”;
  4. 只有应用能正常进入后,再使用菜单中的“检查更新”;不要用下载页上不明版本覆盖当前安装。

原生恢复会保留已安装包,把 Desktop Profile 的 cordis.patch.yml 重命名为带时间戳的备份,并创建空 patch;Home 级 patch 不会随之重置。因此恢复后能启动,只能说明问题位于第三方 bundle 或 Desktop Profile patch,不能证明 Home 级配置一定正确。

崩溃报告可能包含本机路径、Session ID、提示词、工具输出或第三方插件消息。分享前先复制一份并脱敏,不要直接编辑唯一原件。

17.5 CLI/Web 启动失败或浏览器打不开

先把“找不到命令”和“应用启动失败”分开。

dsh 找不到,但 npx 可用

这通常只是全局 PATH 问题。入门阶段直接验证:

npx @deepseek-ai/dsh@0.1.7-rc.2 --version
npx @deepseek-ai/dsh@0.1.7-rc.2 --help

两条命令成功,就没有必要立刻修改全局 npm 前缀或使用管理员权限。后续继续用 npx @deepseek-ai/dsh@0.1.7-rc.2 ... 即可。

Web 报端口占用

保留原始错误,换一个明确的本地端口验证:

npx @deepseek-ai/dsh@0.1.7-rc.2 web --port 3100 --no-open

终端打印就绪地址后,手动打开 http://127.0.0.1:3100。如果新端口成功,故障在旧端口占用,不在模型或项目。不要为了远程访问把 Host 随意暴露到公网地址;远程场景回第 5 章使用 SSH 隧道。

Profile 组合失败

先在不启动应用的情况下检查有效配置:

npx @deepseek-ai/dsh@0.1.7-rc.2 --profile web --dump-config

--dump-config 失败时,错误通常已经指向 YAML、schema、模块解析或插件加载层。它成功也只证明配置可以组合,不保证运行时端口、网络和服务激活都成功。CLI 行为参考

如果需要把输出保存到文件,先假设里面含有本机路径、Provider 配置和凭证引用;不要把完整 dump 当成普通截图公开。

17.6 模型不回答:先区分账号路线与 API 路线

Desktop 登录账号模型与 API Key Provider 是两条独立入口。账号余额不足,不代表 API Key 失效;API Provider 的 401,也不代表登录账号异常。先看当前任务模型选择器使用的是哪条路线,再处理对应配置。

症状 最小检查 修复方向
MISSING_CREDENTIAL “设置 → 模型”中凭证是否显示已设置 为当前 Provider 保存凭证或修复环境变量引用
INVALID_CREDENTIAL / 401 Provider、端点与凭证是否配套 重新保存正确凭证;不要把 Key 发进对话
UNKNOWN_MODEL 当前任务选中的模型 ID 是否仍在 Provider 中 选择已配置模型,或补回准确模型 ID
模型发现返回 401 端点的 GET /models 是否接受该凭证 检查 Key;不支持模型发现时手动录入
模型列表格式无法识别 返回是否既无 data 数组也无 models 对象 手动录入模型,不把“发现失败”当成“推理一定失败”
只有某些中转模型失败 协议与请求形状是否匹配 核对 OpenAI/Anthropic/DeepSeek 协议与兼容设置

修复后一定新建 Read Only 任务,重新执行 17.3 的 MODEL_OK。旧任务可能仍绑定旧模型选择或已有失败上下文;只在旧消息上点重试,不能证明新配置已经用于新 Agent。模型 Provider 官方排错

17.7 卡在审批、工具缺失或“明明允许却没执行”

审批是一次性的敏感操作决策,不是永久授权。ask 策略会等待应答,never 会直接拒绝;审批通道缺失或应答失败时也会失败关闭,而不是默认放行。审批服务官方说明

按症状判断:

  • 界面有待审批卡片:先读动作、路径和理由,再允许或拒绝;
  • 已经拒绝:该次请求不会因你后来改主意自动执行,让 Agent 重新提出具体操作;
  • 没有卡片却返回 approval unavailable:检查当前 Profile 是否加载审批应答器,以及界面连接是否仍有效;
  • Read Only 下要求写文件:这是权限边界生效,不是工具损坏;换成 Workspace Write 之前先确认任务确实需要写;
  • 工具完全不在轨迹中:检查 Agent 预设、插件作用域和新任务的工具列表,不要先放宽沙箱。

如果只有一个动作被拦,不要把整场任务切到更宽权限。保持原权限,让 Agent 缩小操作范围或再次请求单次审批,通常更容易审查。

17.8 插件显示“已启用”,能力却不可用

“已启用”表示配置选择了它,不等于模块成功加载。打开“设置 → 插件 → 插件列表”,同时看:

  • 条目 ID 与完整包名;
  • 启用/停用状态;
  • 实际运行状态;
  • 加载错误;
  • 它属于 Profile、Agent 预设还是 Client 界面。

第三方 bundle 加载失败时,插件管理页会保留条目和错误,允许停用或修复。诊断日志位于所选 Profile 的 .plugin-manager/logs 下;日志可能包含 registry、代理、路径和包管理器输出,分享前必须脱敏。插件管理器官方说明

排查顺序:

  1. 先停用最近新增或更新的第三方 bundle;
  2. 按界面提示重启当前 Profile;
  3. 在只读插件列表确认核心条目无加载错误;
  4. 新建任务验证能力;
  5. 仍失败时再查看诊断日志,不要连续重复安装。

Desktop 与 CLI/Web Profile 的依赖、锁文件和启用选择相互独立。在 Desktop 中坏掉的插件,要在 Desktop 插件页或原生恢复里处理;运行 dsh plugin --profile web 不会修复 Desktop。

17.9 Skill 找不到,或 MCP 工具没有出现

Skill 找不到

先检查四项:

  1. 项目级路径是否为 .dsh/skills/<name>/SKILL.md;
  2. frontmatter 是否同时有合法的 name 与 description;
  3. name 是否使用 kebab-case,并与调用名一致;
  4. 新建任务后,输入 /name 是否出现内联建议。

Skill 文件存在但没有被发现,优先检查路径和 frontmatter;已经被发现但行为没遵守,才检查描述是否触发、是否显式调用,以及正文规则是否互相冲突。

MCP 工具没有出现

先确认 MCP Server 的启动命令在系统终端能运行,再检查当前 Profile 的配置和插件列表。工具出现时应带 Server 命名空间,例如 mcp__daily_report_fs__...;只看到一个泛化工具名,不能证明连到了预期 Server。

最后做一正一反两个检查:

  • 在已授权目录中读取或写入一个练习文件;
  • 尝试访问授权目录外的无敏感测试路径,确认被拒绝。

正向失败通常指向进程、配置或路径;反向竟然成功则是权限边界过宽,不能因为“工具能用”就验收通过。具体步骤回第 12 章。

17.10 Goal、子智能体、Schedule 与 Headless 看起来“不工作”

这四种机制的停顿原因不同,先看它们各自的状态入口。

Goal 没继续

用 /goal 查看 phase、Round 和剩余轮数。paused 需要用户明确恢复;达到 Round 上限不会偷偷扩容;Host 或进程重启后也不能把“持久状态”误解为“后台一定仍在运行”。先恢复,再观察下一 Round 是否启动。

子智能体没有结果

打开父任务顶部的子级目录,确认子任务究竟是运行中、需要输入、失败还是已完成。父 Agent 说“我已委派”不是独立证据;没有子会话或工具轨迹时,先检查当前预设是否真的包含 subagent 工具。

定时任务没触发

依次检查 Schedule 插件是否启用、任务是否活动、下一次时间与 Asia/Shanghai 是否正确、原 Session 是否仍可恢复、Desktop/Web Host 是否正在运行。不要在没看任务列表和投递记录前重复创建同名任务。

Headless 没有输出或脚本误判成功

默认模式在首个非空推理增量前可能静默。自动化需要进度时用 --json,但仍要同时检查进程退出码:0 表示轮次完成,1 表示中止或错误;有 final 事件也不保证运行成功。详细边界回第 15 章。

17.11 日报助手失败:先绕过 Agent

进入 daily-report 目录,按成本从低到高运行:

npm run check
npm test
  • npm run check 失败:先修 sources.json 或配置解析,不要访问网络;
  • npm run check 成功、npm test 失败:问题在代码或测试回归;
  • 两者都成功、npm start 失败:再检查真实数据源、网络、代理、速率限制和输出文件权限;
  • 系统终端成功、Agent 中失败:回到工作区、权限、Shell 工具和审批层。

只有前两项成功且你接受真实外部请求时,才运行:

npm start

npm start 会访问配置的数据源并覆盖 daily-report.md,不是普通只读诊断。不要为了确认 DSH 是否在线就拿它当第一条探针。

17.12 把证据交给 Agent,而不是让它猜

需要 DSH 帮忙分析时,在新的 Read Only 任务中使用下面模板:

请只诊断,不修改文件、不安装软件、不改变配置、不访问外部网络。

环境:
- 操作系统与架构:<填写>
- DSH 入口与完整版本:<Desktop 或 CLI/Web;填写版本>
- Profile / Agent 预设 / 权限:<填写>
- 工作区:<只写目录名,必要时隐藏上级路径>

现象:
- 最后一项成功操作:<填写>
- 第一项失败操作:<填写>
- 原始错误码或退出码:<填写>
- 是否能在新任务复现:<填写>

请输出:
1. 最可能失败层及依据;
2. 两个最小只读检查,按顺序列出;
3. 每个检查的预期结果与下一分支;
4. 当前证据不足时,明确还缺什么。

粘贴日志前删除 API Key、Authorization 头、Cookie、账号标识、完整本机路径和私有仓库地址。脱敏时保留错误码、时间、版本、失败阶段和调用顺序,否则日志会安全但失去诊断价值。

17.13 什么时候应该回退,而不是继续试

遇到以下情况先停:

  • 修复动作要求删除整个 Harness Home、Profile 或工作区;
  • 不清楚一条管理员或 sudo 命令会改哪些文件;
  • 第三方插件来源、构建脚本或兼容版本无法确认;
  • 日志显示凭证可能已经进入对话、脚本或公开仓库;
  • 同一个写操作被重复执行,无法确认是否已经部分成功;
  • 修复需要扩大到工作区之外,但当前没有明确授权。

优先回退最近一项可识别变更:停用新插件、恢复 Profile patch 备份、切回已知模型、改用新任务、撤销项目差异。不要把“重装一切”当作通用回退方案。

17.14 本章验收

请确认你现在能够:

  • 用“应用 → 模型 → Agent/工具 → 权限/工作区 → 项目”五层模型定位问题;
  • 完成版本、最小模型、只读工具与项目命令四项健康检查;
  • 从 Desktop 原生弹窗找到崩溃报告,而不是先删除配置;
  • 区分账号模型问题与 API Provider 问题;
  • 区分审批拒绝、审批通道不可用与工具根本不存在;
  • 判断插件“已启用”与“已成功加载”不是一回事;
  • 分别检查 Skill、MCP、Goal、子智能体、Schedule 和 Headless 的状态入口;
  • 用 npm run check、npm test、npm start 的顺序判断日报助手失败层;
  • 能生成一份不含凭证、但保留版本和错误码的诊断材料;
  • 在修复后用新任务或独立命令复验,而不是只相信原任务的文字结论。

排错的目标不是“让红色提示消失”,而是知道哪一层恢复了、用什么证据证明、是否引入了新的权限或副作用。下一章会把本教程已经覆盖的能力与尚未展开的进阶方向分开,给出学完之后的继续学习路线。


← 上一章:案例七:把经验沉淀到项目、Skill 与 Profile | 回目录 | 下一章:进阶学习路线:从“跟着做”到独立完成任务 →


19 进阶学习路线

本文属于《DeepSeek Harness 入门教程(实战版)》· 第五部分 · 排错与进阶

第 18 章 进阶学习路线:从“跟着做”到独立完成任务

走到这里,你不需要再用“看过多少菜单”衡量自己。更有意义的问题是:离开教程以后,你能不能把同一套方法迁移到自己的项目,并用证据说明任务真的完成了?

这一章先验收主线,再把后续学习分成几条路线。你不必把所有高级能力都学一遍;先选眼前任务真正需要的一条,通常进步更快,也更安全。

18.1 先做一次主线验收

打开本教程使用的 daily-report 工作区,分别从 DSH 和系统终端检查结果。

在 DSH 中确认四件事

  1. 新建一个标准模式、Read Only任务,只让模型读取 PROJECT.md 并概括项目边界;
  2. 打开模型选择器,能指出当前任务走的是账号模型还是某个 API Provider;
  3. 打开任务的执行轨迹,能分辨模型回复、文件工具、Shell、审批和子智能体记录;
  4. 打开“设置 → 插件”,能说明一个插件属于哪个 Profile、是否启用、是否成功加载。

这四项证明的是模型、工作区、Agent 和插件四层都能被你独立辨认,而不是某次对话碰巧成功。

在系统终端确认项目状态

进入 daily-report 目录,运行:

npm run check
npm test

两条命令都应以退出码 0 结束。然后检查下列成果仍然存在:

PROJECT.md
sources.json
src/
test/
AUDIT.md
.dsh/skills/daily-report-maintainer/SKILL.md

如果还保留了定时任务,再到 Schedule 列表确认它的启用状态、下一次执行时间和时区;不准备继续运行,就应停用或删除练习任务,避免以后产生意外网络请求。

只有 DSH 说“已完成”而终端检查失败,不能算通过;项目检查通过,但你不知道任务用了哪个模型、权限和工具,也还不能算真正掌握 Harness。

18.2 已经掌握什么,哪些只是见过

完成前面的实操后,你已经亲手用过这些主线能力:

  • Desktop 或 CLI/Web 的安装、启动与工作区选择;
  • 账号模型、官方 API Key、内置 Provider 和自定义模型 API;
  • 标准、PTC、极简模式的任务选择,以及自定义 Agent 预设;
  • 插件的配置、发现、启停、加载检查与 Profile 隔离;
  • 文件修改、Shell、计划、审批、差异审查和独立测试;
  • 项目级 Skill、MCP、子智能体、Goal、Schedule 与 Headless;
  • 按应用、模型、工具、权限和项目五层排错。

下面这些能力在课程里只做了定位或边界说明,不等于你已经会用:

进阶方向 适合解决什么问题 目前应保持的认识
Browser Use 让 Agent 检查、操作网页 当前后端仍属实验性能力;网页状态、登录态和已发生的操作不一定能撤销
Computer Use 操作本机桌面应用并获取截图 需要图形会话、系统权限和支持图像的模型;属于高权限实验能力
Agent Team 让具名成员用持久消息和共享任务板持续协作 当前仍以实验性插件发布;本教程只实操了 Subagent,没有启用 Team
SSH 远程工作区 DSH 留在本地,文件和命令在远端执行 当前版本发布说明已列出这项能力;远端路径、凭证、Shell 和网络边界都要重新验收
Office 创建或修改 DOCX、PPTX、XLSX Desktop 已带相关 Skill 和运行时,但仍需结构检查与必要的视觉检查
Python SDK 由 Python 程序启动并驱动 Harness 面向程序化集成,不是更方便的聊天入口
ACP 让受信任的外部控制器管理 Agent Session 是自动化协议面,刻意不提供完整 DSH 界面能力
自定义插件 新增服务、工具、界面或替换实现 需要理解 Cordis、Profile、bundle、生命周期和发布安全

这些方向都值得学,但不应该因为“看起来高级”就一起开启。尤其是 Browser Use 和 Computer Use:取消一次调用,并不能撤回已经送到网页或桌面应用的点击、输入和提交。

18.3 先迁移到一个真实的小项目

最好的下一步不是继续装插件,而是把日报助手的工作方法搬到你真正在维护的项目。项目可以是一段脚本、个人网站、笔记整理工具,甚至是一个只有十几个文件的小仓库。

第一次迁移时,仍按同一个顺序:

只读盘点 → 写清目标和边界 → 计划一次小改动
→ 审查差异 → 运行项目自己的检查 → 记录结论

建议选择能在一两个小时内验收的任务,例如“给个人脚本增加一种输出格式”,而不是“重构整个项目”。先让标准模式完成只读盘点,再切到 Workspace Write 实现;只有当任务确实需要大量结构化查询或批处理时,再拿同一任务与 PTC 对照。

完成后至少留下三样东西:

  • 一段准确的项目说明,写清入口、边界和验证命令;
  • 一项小而完整的改动,以及你审查过的实际差异;
  • 一条绕过 Agent 也能重复运行的验收命令。

如果这三样都没有,换了项目也只是重新聊了一次天。

18.4 定制时遵循“够用就停”

遇到重复工作时,从最轻的机制开始,而不是直接写插件:

  1. 项目文档与测试:所有协作者都应遵守、并且能用代码验证的规则,先留在项目里;
  2. Skill:需要 Agent 按固定流程工作,但不需要新增底层能力时,用项目级 Skill;
  3. Agent 预设:需要固定系统指令、工具组合和行为方式时,再创建自定义预设;
  4. Profile:需要隔离插件、Provider、服务组合或运行入口时,创建独立 Profile;
  5. MCP:需要连接已有外部服务,并能把授权范围限制清楚时,再接 MCP Server;
  6. 插件:只有现有服务和工具表达不了能力,或你要替换 Harness 的某个实现时,才进入插件开发。

每增加一层,都问三个问题:它解决了哪个已发生的重复问题?如何证明它加载并生效?如何一键停用或回退?答不上来,就暂时不要增加。

官方架构说明把 Harness 描述为由 Cordis 插件、Profile 和 bundle 组合而成;这解释了它为什么容易扩展,也解释了为什么配置错误会跨越多个层次。官方架构说明

18.5 接入外部能力时,先做正反两次验收

网页搜索、MCP、Schedule、浏览器和远程工作区都会把任务带到项目目录之外。接入时不要只验证“能访问”,还要验证“不该访问的地方确实访问不到”。

一项外部能力至少要完成下面的闭环:

明确授权对象和范围
→ 在隔离 Profile 或练习目录中启用
→ 完成一个最小正向任务
→ 尝试一个范围外的无敏感反向任务
→ 查看轨迹和真实结果
→ 停用后再验证能力已经消失

例如 MCP 文件服务的正向检查是读取授权练习目录,反向检查是读取该目录外的无敏感测试路径并确认被拒绝。浏览器任务则应先在测试账号或可丢弃页面中验证,不要把“第一次点击”安排在付款、发布、删除或发送消息上。

官方 Browser Use 文档目前把 Playwright MCP、Chrome DevTools MCP 和 Stagehand 后端标为需要显式启用的实验性包;会话释放后,浏览器状态也不会从 Session 日志自动恢复。Browser Use 官方说明 Computer Use 的原生驱动同样标为实验性,并明确要求桌面权限和图形会话。Computer Use 原生驱动说明

18.6 想做程序化集成,再选 SDK 或 ACP

如果你的目标是“定时运行一条提示词”,第 15 章的 Schedule 或 Headless 已经够用。只有外部程序需要创建、复用和管理 Session、消费结构化事件,才需要 SDK 或 ACP。

  • Python SDK适合在 Python 程序中启动同版本 Harness 运行时、运行任务并读取结果。它要求显式的 DSH_HOME,便于隔离 Profile、插件、凭证和会话;Python SDK 官方说明
  • ACP适合测试运行器、外部智能体或其他受信任控制器通过标准协议驱动持久 Session。它故意不暴露计划卡片、终端视图等 DSH 专属界面;ACP 官方说明
  • 自定义插件适合新增或替换 Harness 内部能力。先在本地 patch 中验证,再做 bundle;安装来自 Git 的插件可能执行构建脚本,因此要审查来源并固定提交版本。插件打包与安装指南

三者解决的不是同一个问题。SDK 和 ACP 是“从外面驱动 Harness”,插件是“改变 Harness 里面有什么”。

18.7 一份不注水的 7 天练习

每天只做一个可以检查的小结果。项目可以继续用 daily-report,也可以从第二天开始换成你自己的小项目。

天数 练习 当天通过条件
第 1 天 建立健康基线 记录版本、模型路线、Profile、权限;npm run check 和 npm test 通过
第 2 天 只读盘点真实项目 Agent 输出入口、风险和验证命令;你手动核对至少三处事实
第 3 天 完成一项小改动 审查 diff;聚焦测试和完整测试都通过
第 4 天 沉淀项目级 Skill 新任务能发现并显式调用;停用或移走 Skill 后行为恢复
第 5 天 做一次配置隔离 实验 Profile 中启用一项能力,日常 Profile 的配置与加载状态不变
第 6 天 接一个受控外部能力 正向任务成功、范围外反向任务被拒绝,并完成停用回退
第 7 天 从全新 Session 重做任务 不依赖旧对话也能完成;终端验收、差异和操作记录齐全

某一天失败,不必为了“打卡”跳过。先按第 17 章定位失败层,修复并独立复验,再继续下一天。

18.8 毕业任务:独立完成一次可复现的改造

最后选一个你愿意保留的个人小项目,完成下面的任务:

让 DeepSeek Harness 在明确边界内,为项目增加一项真实可用的小功能;把维护流程沉淀为项目级 Skill,并用项目自身命令独立验收。若任务确实需要,再接入一种受控外部能力。

具体要求如下:

  1. 在新的工作区和新 Session 中开始,先用 Read Only 做项目盘点;
  2. 在 PROJECT.md、README.md 或等价文件中写清目标、禁止改动区和验收命令;
  3. 选择合适的 Agent 预设并说明原因,默认从标准模式开始;
  4. 只实现一项可以独立交付的改动,不顺手重构无关代码;
  5. 审查真实差异,并运行聚焦检查与完整回归;
  6. 创建一个项目级 Skill,让全新 Session 能重复维护流程;
  7. 如接入 MCP、搜索、Schedule 或其他插件,记录授权范围、费用或副作用以及停用方法;
  8. 在系统终端重新执行验收,不以 Agent 的最终回复代替结果。

如果继续使用日报助手,独立验收仍是:

npm run check
npm test

如果换了项目,把这两条替换成该项目真实存在的检查和测试命令,不要照抄不存在的脚本。使用 Git 的项目还可以补一条只读检查:

git diff --check

毕业任务通过时,你应该能交出五份证据:任务边界、执行轨迹、实际差异、终端测试结果,以及能在新 Session 中调用的 Skill。外部能力不是必选项;为了凑齐功能而扩大权限,反而不合格。

18.9 接下来只选一条路线

  • 想把 DSH 变成日常开发搭档:继续做 18.3 和 18.7;
  • 想沉淀团队或个人工作流:重点练 Skill、预设和 Profile;
  • 想连接数据源与服务:学习 MCP,并坚持正反向权限验收;
  • 想做网页、桌面或远端自动化:先在隔离环境学习 Browser Use、Computer Use 或 SSH 远程工作区;
  • 想把 Harness 嵌进自己的程序:选择 Python SDK 或 ACP;
  • 想改变产品本身:先读架构和插件生命周期,再从最小本地插件开始。

不要同时开六条线。能够把一项能力用于真实任务、验证结果、解释边界并安全回退,比记住全部包名更接近“掌握 DeepSeek Harness”。


← 上一章:常见问题排查 | 回目录


20 附录-术语、命令与项目状态速查

本附录按 DeepSeek Harness v0.1.7-rc.2 整理,适合学完正文后查阅。它只收录正文中已经解释或实际验证过的内容,不能代替对应章节的操作步骤与安全说明。

A. 容易混淆的术语

术语 在本教程中的准确含义
DSH / DeepSeek Harness 面向 Agent 的开源运行框架。它把模型、工具、审批、插件、工作区、会话和界面组织成可运行的系统。
Host / Client Host 是实际运行 Agent、插件和会话的后端进程;Desktop、Web 等 Client 负责展示与交互。关闭一个界面不一定等于 Host 已退出。
Workspace(工作区) 当前会话选中的项目目录,也是许多文件与终端操作的默认位置。它有助于限定任务范围,但不自动代表所有外部进程都被关在这里。
Model Provider 模型调用路线,例如 DeepSeek 官方 API、内置第三方 Provider 或兼容协议的自定义 API。不要和插件系统中的 Provider 角色混为一谈。
Agent 预设 决定 Agent 采用哪些工具和工作方式的插件组合。课程实操了标准、PTC、极简和创造模式。
标准模式 模型直接调用文件、终端等原生工具;轨迹直观,适合多数日常任务。
PTC 模式 模型主要通过 run_code 编排工具 SDK;适合需要在一次代码执行中批量处理、循环或聚合大量工具结果的任务。它不是“更强的标准模式”。
极简模式 工具更少、执行路径更短,适合只需推理或少量操作的任务;工具少不等于权限天然更安全。
创造模式 用自然语言组合并保存自定义 Agent 预设的入口。创建后仍要检查实际 bundle、工具和权限。
Profile 一套可独立保存的运行配置,包含插件组合、补丁和依赖状态。Desktop 的保留 Profile 与 CLI/Web 自建 Profile 不应视为同一份配置。
Plugin / Bundle Plugin 是一个能力模块;Bundle 是可被 Profile 加载的一组插件配置。第三方 bundle 会在 Host 中运行代码,因此应像依赖包一样审查来源与权限。
Cordis DSH 的插件框架,负责插件生命周期、服务注册和依赖关系。
Service Definition / Provider / Consumer 插件系统中的接口定义、接口实现和接口使用方。这里的 Provider 不是模型 Provider。
Skill 一份可发现、按需加载的任务说明,告诉 Agent 应遵循什么流程。Skill 本身不会凭空增加工具、模型权限或系统权限。
MCP 连接外部 MCP Server 的标准协议。课程实操的是一个受限目录的 MCP 工具;没有把所有 MCP Resource 能力都当作已掌握内容。
Subagent 由主 Agent 派出的子任务执行者,适合并行进行边界清晰的读取、研究或审查。最终结论仍需主 Agent 汇总和核证。
Workflow 把多个步骤或 Agent 组织成显式流程的机制,适合结构稳定、需要复用的编排。
Agent Team 当前仍属实验性能力。正文只解释了它与 Subagent、Workflow 的边界,没有把它作为主线实操。
Goal 让同一个长期目标跨多个 Round 自动推进的机制。它不是后台服务、定时器、并行系统或权限豁免。
Schedule 由运行中的 DSH Host 在指定时间触发任务。Host 未运行、时区错误或任务重复都会影响结果。
Headless 不打开交互界面,以命令行方式执行一次任务并返回退出状态或事件流。
审批 对一次敏感操作是否放行的用户决定。批准一条命令,不等于永久授权同类命令。
权限 / 沙箱 限制 Agent 或进程能够访问什么的边界。工作区、DSH 原生工具和外部 MCP Server 可能各有不同的边界。
Trajectory(轨迹) 一次任务中模型思考、工具调用、结果和错误组成的执行记录,是审查 Agent 是否按要求工作的主要证据。
Python SDK / ACP 两种程序化集成入口:SDK 用 Python 代码驱动 DSH;ACP 用协议让兼容客户端连接 DSH。它们不是同一种接口。

如果只记住一条:预设决定 Agent 怎么工作,Profile 决定一套环境加载什么,Skill 提供做事说明,Plugin 与 MCP 才会真正接入能力。

B. 常用命令

B.1 DSH 与 CLI/Web

以下命令使用课程推荐的临时运行方式,不要求全局安装。请在系统终端执行;Windows PowerShell 如果无法解析 npx,可把它替换成 npx.cmd。

用途 命令 结果或注意事项
查看版本 npx @deepseek-ai/dsh@0.1.7-rc.2 --version 输出当前实际运行版本。排错时先记录它。
查看总帮助 npx @deepseek-ai/dsh@0.1.7-rc.2 --help 以本机输出为准,不要凭旧教程猜参数。
启动 Web npx @deepseek-ai/dsh@0.1.7-rc.2 web 启动 Web Profile;终端进程需要保持运行。
指定端口且不自动开浏览器 npx @deepseek-ai/dsh@0.1.7-rc.2 web --port 3100 --no-open 适合端口冲突、服务器或 SSH 隧道场景。不要直接把服务暴露到公网。
查看 Web Profile 的最终配置 npx @deepseek-ai/dsh@0.1.7-rc.2 --profile web --dump-config 输出可能含本机路径与 Provider 信息,不要未经脱敏上传。
查看 Headless 帮助 npx @deepseek-ai/dsh@0.1.7-rc.2 --profile headless --help 先用帮助确认当前版本的选项。
执行一次 Headless 任务 npx @deepseek-ai/dsh@0.1.7-rc.2 --profile headless "任务描述" 任务结束后进程退出,可用退出码判断成功与否。
输出 Headless 事件流 npx @deepseek-ai/dsh@0.1.7-rc.2 --profile headless --json "任务描述" 输出 NDJSON,适合脚本逐行处理,不是一个普通 JSON 数组。
继续已有 Headless 会话 npx @deepseek-ai/dsh@0.1.7-rc.2 --profile headless --session-id <SESSION_ID> "任务描述" 把 <SESSION_ID> 换成真实会话 ID,尖括号只是占位符。
从 Web 模板创建隔离 Profile 并检查配置 npx @deepseek-ai/dsh@0.1.7-rc.2 --profile daily-report-lab --from-default-profile web --dump-config 创建或使用 daily-report-lab;它不会自动同步到 Desktop 的保留 Profile。

第三方插件安装没有列入“常用命令”。这类操作会改变 Profile 的依赖、锁文件和 bundle,并让外部代码进入 Host;需要时应回到第 16 章,先核验来源,再在隔离 Profile 中操作。

B.2 日报助手项目

下面三条命令要在 daily-report 项目根目录执行:

命令 是否联网 是否写入报告 用途
npm run check 否 否 校验默认 sources.json 和项目配置;成功时应以退出码 0 结束。
npm test 否 否 使用伪造的 fetch 做完整回归测试。
npm start 是 是 请求两个 GitHub Releases API,并在全部数据获取成功后生成或覆盖 daily-report.md。

如果项目使用 Git,还可以运行 git diff --check 检查空白错误;它不验证程序逻辑,也不能替代测试。

C. 日报助手的最终状态

完成第 7~16 章后,项目应大致包含这些产物:

daily-report/
├── .dsh/
│   ├── mcp-filesystem.yml
│   └── skills/
│       └── daily-report-maintainer/
│           └── SKILL.md
├── mcp-scratch/
│   └── mcp-check.txt
├── src/
├── test/
├── AUDIT.md
├── PROJECT.md
├── README.md
├── daily-report.md
├── package.json
└── sources.json

src/ 和 test/ 中的具体文件名可能因 Agent 批准的实现计划而不同,这不影响验收。.dsh/mcp-filesystem.yml 与 mcp-scratch/mcp-check.txt 是第 12 章留下的 MCP 实验产物;如果你按文中说明清理了实验,也可以不存在。

最终验收关注行为,而不是目录是否和示意图逐字一致:

  1. npm run check 能离线检查配置,不修改 daily-report.md;
  2. npm test 能离线通过,测试不会真的请求 GitHub;
  3. npm start 会真实联网,并生成含两个数据源和有效链接的报告;
  4. .dsh/skills/daily-report-maintainer/SKILL.md 已包含测试、检查和外部操作边界;
  5. AUDIT.md 记录了子智能体审查后由主 Agent 核证的结论。

另外还有两类状态不在项目树中:

  • daily-report-lab 是 DSH Home 下的隔离 Profile,不是项目文件;
  • 第 15 章创建的 Schedule 任务是否保留,由你在章末明确选择。它不能通过查看项目目录来确认。

D. 官方资料入口

想继续了解 官方入口 正文对应位置
项目源码、版本和已知变化 官方仓库 · Releases 第 1~3 章
Desktop 安装与生命周期 Desktop 中文说明 第 4、6 章
CLI 参数与 Profile CLI 中文参考 第 4~6、15~17 章
模型 Provider Provider 中文指南 第 8 章
插件与整体架构 架构说明 第 9、10、16 章
项目级 Skill Skill 文件系统 第 12、16 章
MCP 接入 MCP Client 中文说明 第 12 章
Headless 自动化 Headless 中文说明 第 15 章

产品仍在快速迭代。遇到界面名称、参数或默认行为与教程不同,先运行 --version 和 --help,再查对应版本的 Release 与官方文档;不要为了“跟教程一致”而降级、清空配置或放宽权限。


上一篇:第 18 章 进阶学习路线:从会用走向会设计
返回:封面与导读


21 进阶学习

实战课

从会用一套 Harness,到能自己选一套 Harness

最近整理了一套《DeepSeek Harness 入门教程(实战版)》知识库。

写完之后的感受是:Agent 工具的学习,难点从来不在“装上”,而在“敢不敢用它做真事”。

这套知识库围绕一个叫「日报助手」的小项目展开,从空目录开始,一路做到能运行、能测试、能审查、能 Headless 自动化。

它没有堆概念,而是把 DSH 拆成五层——模型与 Provider、Agent 预设、插件、Profile、交互入口 ——然后让读者在每一层都留下可检查的证据:文件、diff、测试输出、退出码、配置 dump、子会话轨迹。

它反复强调一件事

Agent 说“完成了”不算完成,系统终端里的结果才算。

所以这套知识库适合谁?

适合已经决定要用 Agent 做点真事、但不想停留在“聊聊天、生成一段代码”的人。

它教的是怎么选工作区、怎么控权限、怎么看审批、怎么用 Skill 固化方法、怎么用 MCP 接外部工具、怎么让子智能体并行审查、怎么让一个长目标跨多轮推进、怎么在 Headless 里跑自动化。

学完一遍,你至少能独立判断:这次任务该用哪个预设、权限开到哪一档、出了问题先查哪一层。

但它也有一件事没有解决

它解决的是“把 DSH 这一套 Harness 用起来”。

它不解决“如果我想自己选一套 Agent 脚手架、自己搭一个能上业务的项目,应该怎么选、怎么拆、 怎么交付”。

这两件事之间,其实隔着一层很实际的坎:

你已经会用一个 Harness 了,但换一个框架、换一个业务场景,你还能不能独立选型、独立搭起来?

比如同样是 Harness 思路,Smolagents、Claude Agent SDK、DeepAgents、Pi-Mono 各自适合什么场景?

数据洞察、投研、知识库、合同审查这些真实业务,Agent 项目应该怎么拆、怎么编排、怎么把安全和交付边界做进去?

这就不是单靠一套 DSH 教程能覆盖的了。

如果你正好走到这一步

可以看看邢云阳老师的专栏《Harness Agent 脚手架实战课》。

它沿着 Smolagents、Claude SDK、DeepAgents、Pi-Mono 四条路线,把数据洞察、投研、知识库、 合同审查四个场景从头到尾做了一遍。

重点不是再教你一个工具,而是帮你建立一套可迁移的 Agent 工程判断——框架选型、业务流重构、 合规安全交付,这些在一个具体项目里是绕不开的。

原文图片

不用急着现在决定

先把这套知识库的项目验收做完。

等你真正开始想“下一个 Agent 项目我要自己选型”的时候,再去翻它,可能会更顺。

会用一套,是入门;能选一套、搭一套、交付一套,才是工程能力。