我给 DeepSeek Harness 做了一次"全身检查":76 条缺陷、6 篇报告、4 个插件,以及我对它的真实看法

一个普通用户(非官方人员)用一天时间,把一个刚发布的 agent 框架从里到外翻了一遍的故事。


一、起因:一个"帮我找毛病"的请求

DeepSeek Harness(以下简称 DSH)0.1.0-rc.6 发布后,我一直在用它。它是一个基于 Cordis 的 agent 框架——官方口号是 “Everything is a Plugin”,web 端是一个本地 GUI,agent 跑在浏览器旁边的 Node 进程里,模型可以读写文件、跑 shell、调工具、派生子代理。

用了一段时间,我的第一反应和大多数人一样:“刚发布的东西,肯定有不少毛病,帮我找找。”

于是我让它(一个跑在 DSH 里的 agent)对 DSH 自己做了次深度审计。结果出乎意料——它真的把整个框架翻了个底朝天。这篇文章记录的就是这一天的完整经历:审计、发布问题报告、做插件、以及我最后对 DSH 的真实看法。


二、使用体验:第一印象

先说体验,因为这是最直观的部分。

好的方面:

  • 开箱即用npx dsh web 或者 dsh --profile web 就能起一个本地 Web GUI,默认绑定 127.0.0.1,地址是 http://127.0.0.1:3080。默认配置很克制,不需要一堆环境变量。
  • 中文支持出乎意料地好:整个 GUI 默认就是中文,本地化不是"机翻糊弄"级别,而是认真做过的。
  • 架构理念清晰:Cordis 的组合式插件系统,profile 由一层层 patch 拼出来(bundle 层 → 用户层 → 覆盖层)。一旦理解了 cordis.patch.yml 的"整段替换 config"语义,就能精确地改任何行为。
  • 工程完成度比想象的高:会话日志是带 zstd 压缩、带 torn-tail 恢复的 JSONL;投影缓存承诺 “stale but never wrong”;Windows 沙箱用的是受限令牌(WRITE_RESTRICTED)+ 能力 SID——这些不是玩具级别的实现。

不那么好的方面:

  • 中文 Windows 的编码坑:系统代码页 936 下,Get-Content 读 UTF-8 文件直接乱码。DSH 自己写的所有文件都是 UTF-8,所以你在中文 Windows 上让 agent 用 PowerShell 读文件,十有八九读到乱码。官方只设置了输出编码,没管输入和文件读取。
  • 文档和实现有时打架:CLI 帮助里写着 dsh --profile tui,但发行版根本没有 tui profile 模板;--profile X --help 打印的其实是启动器自己的帮助而不是应用的帮助。
  • RC 版的小毛病:SPA fallback 把 /favicon.ico 也回退成 HTML(200 + 页面内容);硬编码的英文文案绕过 locale;热重载对"新增插件行"时灵时不灵。

三、审计:让 agent 审计 agent 框架

我让 agent 分 6 路并行审计 DSH 的 150+ 个 npm 包,每路盯一个领域:CLI/启动链路、会话与持久化、沙箱与安全、全部模型工具、Web 宿主与客户端 UI、子代理/工作流/遥测。

方法:逐行读编译产物(node_modules/@deepseek-ai/*/lib/*.js),每条发现都带文件:行号,只报告亲自读代码确认的问题,还专门列了"已核实无问题"清单防止误报。6 路跑了约 60-100 分钟,最后汇总出:

76 条发现:2 条 critical、17 条 major、47 条 minor、10 条 info。

最有价值(也最吓人)的几条:

  1. Windows 沙箱的 read-only 是"纸糊"的:受限令牌的限制列表里常驻 Everyone 和登录 SID,而 Windows 的访问检查是"任一限制 SID 命中即放行"——所以 read-only 模式照样能写任何授予 Everyone 写权限的目录。代码注释自己都承认了这一点。
  2. 凭据对 agent 不构成保密边界:文件读取在所有权限模式下都不受限,agent 可以直接读 ~/.dsh/.credentials.yaml;沙箱进程还能读父进程的 /proc/<pid>/environ 拿到 API key,而且沙箱不隔离网络——三条路拼起来就是一条完整的密钥外传链。
  3. LAN 部署下审批可被旁路/api/respond 不在"钉扎到 loopback"的特权方法名单里,配了 --trusted-host 后,任何局域网设备都能订阅事件流拿到审批 ID,替用户批准工具调用。
  4. glob/grep 完全绕过沙箱:搜索工具直接跑 ripgrep,path 参数无任何约束,还能枚举隐藏文件——工作区外的 .env、密钥随便读。
  5. 匿名用户 ID 无条件外发:每个模型请求都带一个持久化的 per-home 匿名 UUID,关掉遥测也不豁免,配自定义第三方 baseURL 时这个身份照样发过去。

(完整报告后来整理成了文件,76 条全部带行号。)


四、把发现发布出去:GitHub Discussions

官方 CONTRIBUTING.md 说得直白:“We are sorry that we cannot accept external pull requests at the moment.”——目前不收外部 PR,报告问题走 GitHub Discussions。

于是我们把最值得看的几条写成结构化报告(摘要 → 证据带行号 → 复现步骤 → 影响 → 修复建议 → 诚实边界),发布了出去:

写报告本身也是学习过程:每条结论都先问"作者自己知不知道这个"——结果发现很多缺陷在代码注释里就被作者自己承认了(比如 Windows 沙箱那段,注释白纸黑字写着"check ALSO inherits the ambient write ACEs of the other restricting SIDs")。这说明团队不是不知道,而是边界的取舍没有对外讲清楚。所以报告里我尽量措辞克制:“是刻意设计就请更新文档,不是就请修复”。


五、做插件:从"找毛病"到"造东西"

光报告不够。既然官方鼓励外部插件生态(加 dsh-plugin topic 就能被找到),我们把审计发现做成了 4 个可直接安装的 npm 插件

插件 作用
dsh-plugin-search-gate 给 glob/grep 加工作区路径围栏,越界直接拒绝
dsh-plugin-credential-guard 拒绝模型读取凭据存储和密钥文件
dsh-plugin-pwsh-utf8 中文 Windows 下强制 UTF-8 文件 I/O 的 pwsh 工具
dsh-plugin-security-audit 一键安全体检:凭据权限、环境密钥、LAN 暴露、遥测等 8 项检查,输出 PASS/WARN/FAIL + 建议

做插件的过程同样踩坑不断,而且全都踩成了第一手经验

  • harness 的工具 schema 校验非常严格:每个 object 节点必须显式写 additionalPropertiestype 不支持联合数组(["string","null"] 直接报错)。这俩限制文档里没写,我们撞上后发成了避坑帖 #1040。
  • 然后自己就翻车了dsh-plugin-pwsh-utf8@0.1.0 里有一个 exitCode: { type: ["number","null"] }——正是避坑帖里写的坑 2!它会导致整个 profile 启动失败。冷启动测试抓到这个问题后,修复、升 0.1.1、重新验证。
  • 热重载对新增行不可靠:patch 文件的热更新有时候生效(search-gate 第一次就生效了),有时候不生效,最后靠"另起一个端口冷启动"才拿到确定性结论。
  • npm 发布被 2FA 折腾:账号开了两步验证,web 登录的会话 token 不能直接发布,最后是自己在终端跑 npm publish 配合认证器验证码,一次一个包。

说实话,踩坑本身比写代码更值钱——因为每一个坑都是别人将来会撞的,而我们已经有报告和插件在前面挡着了。

最后把 dsh-plugin-security-audit 建了 GitHub 仓库、打了 dsh-plugin topic:

  • 仓库:https://github.com/truelove-dreamer/dsh-plugin-security-audit
  • npm:npm i dsh-plugin-security-audit

六、对 DSH 的真实看法

它是一个认真做的框架,不是刷 KPI 的玩具。 我见过太多"发布即半成品"的项目,DSH 给我的感觉恰恰相反:它的架构决策(组合式 composition、分层 patch、作用域隔离)、工程细节(zstd 日志恢复、受限令牌沙箱、DNS rebinding 防线)都是深思熟虑的产物。文档和代码里敢于承认自己的边界这一点尤其难得——"Reads pass through untouched: every mode permits reading"这种话,很多项目不敢写。

但它也确实还在 RC 阶段。 76 条发现里,真正的设计缺陷只有少数几条,大部分是边界没讲清楚、文档和实现不一致、Windows/中文场景照顾不周、以及 RC 版的粗糙边缘。安全方面最值得担心的是 Windows 沙箱的 read-only 语义凭据对 agent 的保密边界——这两条已经在 Discussions 里,希望团队优先看。

对贡献者来说,当前最现实的路径不是 PR,而是:① 在 Discussions 发高质量报告(团队会看、upvote 决定优先级);② 做外部插件(官方明确欢迎,加 dsh-plugin topic);③ 写中文文档和教程(中文用户是 DSH 的大盘,但中文内容稀缺)。


七、最后

这一天做下来,最大的感受是:"找毛病"和"造东西"是同一件事的两面。 审计发现的每个缺口,回头都能变成插件的一个功能;插件开发踩的每个坑,回头都能变成一篇避坑帖。DSH 的插件生态还很新,任何一个认真的贡献者都能在这里留下自己的名字。

如果你也在用 DSH,我建议你也试着让它审计一下自己——让一个 agent 去审计它自己运行在上面的框架,这件事本身就足够有意思了。


工具链:DeepSeek Harness 0.1.0-rc.6 + 6 路并行子代理审计 + gh CLI + npm。文中所有发现均带文件:行号,完整清单见讨论帖 #949-#962、#1040。

Logo

欢迎加入 MCP 技术社区!与志同道合者携手前行,一同解锁 MCP 技术的无限可能!

更多推荐