DeepSeek Harness 插件

dsh-agent-harness-audit

Audit an agent harness against the harness-evaluation criteria, with machine-enforced evidence validation.(英文原文)

跳到安装方式

来源信息

GitHub 仓库
Leeaoyin/dsh-agent-harness-audit
最近更新
2026年8月17日
分类
自动化与任务
GitHub stars
0
载体类型
plugin
目录证据
上游声明已找到 dsh.bundle
证据路径
package.json#dsh.bundle
核对版本
0.1.0-rc.8
上游核对日期
2026-08-20

该证据由上游目录提供。本站没有安装、运行或安全审核这个插件。

安装

默认先复制一段 Prompt,让 Agent 读 GitHub 仓库和源码;需要自己装时再切到命令。

复制这段 Prompt,发给 DSH、Codex 或其他 Agent,让它先读 GitHub 仓库和源码。

请先不要安装或执行任何命令。阅读这个插件的 GitHub 仓库、README 和关键源码,然后用清楚、直接的方式回答以下问题,帮助我判断它是否适合我的需求:

1. 这个插件是什么,解决什么问题;
2. 适合哪些用户和典型使用场景;
3. 安装后如何使用,并给出一个最小使用示例;
4. 有哪些已知限制,以及隐私、安全、兼容性或维护风险;
5. 给出“推荐 / 有条件推荐 / 不推荐”的明确建议和理由。

请区分仓库明确说明、根据源码推断和未知信息。证据不足时请明确说明,不要猜测或照抄 README。

GitHub:https://github.com/Leeaoyin/dsh-agent-harness-audit
插件名:dsh-agent-harness-audit
作者:Leeaoyin

检查来源文件

安装前先看这个插件目录里的 README 和其他文件。

文件资源管理器4 个文件
README.zh.md来源说明 · 只读预览
README 语言

dsh-harness-audit

English | 中文

审计 agent harness 的健壮性——并且拒绝任何拿不出代码证据的发现

它解决什么问题

Agent 跑不稳,大多数时候不是模型不够聪明,而是循环本身有洞。这些洞有个共同特征:平时不报错,出事时无法复现

  • 工具执行完了,结果没写回对话。下一次请求带着一个没有答案的调用,被模型服务拒收(通常 400)。这是 agent harness 里出现频率最高的真实故障。
  • 五个并行操作成功了四个,但整批被判定失败,成功的结果被丢弃。
  • 外部动作已经生效之后才超时,重试于是又做一遍——消息发两次,款扣两次。
  • 用户点了停止,子进程还在跑,请求还在发。
  • 请求开头的内容每次都在变,服务端前缀缓存永远命中不了。不报错,只是每次请求都更贵,没人会发现。
  • 线上出了问题,事后没法重建这次运行到底发生了什么。

这些问题共十五类,覆盖六个方面:

<!-- checks:start -->

State stays self-consistent

检查项查什么
C1Tool-call pairing completeness查工具执行的每一种结束方式(正常返回、报错、超时、取消、提前返回、权限拒绝)是否都写回了结果,以及并行批次里一个失败会不会丢掉其余成功的结果。
C2History is append-only查有没有代码在消息写入之后又去修改它,而不是只追加新消息。
C3Crash and checkpoint semantics查分成两段的写入过程中如果进程挂掉,重启时读到的是什么,以及这种半截状态能不能被识别出来。

Untrusted input is treated as untrusted

检查项查什么
C4Model output parsing查模型输出是怎么解析的:参数不合法、输出被截断、调用编号重复这些情况是被处理了,还是被当成可信输入。
C5Path and sandbox boundaries查模型给出的路径有没有解析后再与工作区根目录比对,而且必须在符号链接解析之后比对。
C6Secrets and ambient environment查模型生成的命令继承了什么环境变量,里面有没有密钥。

Failure is a first-class outcome

检查项查什么
C7Error taxonomy and retryability查失败是否带有一组封闭的错误码,并被明确分类为可重试/不可重试/致命,还是只给出一段没有分类的文字。
C8Partial success查多个独立结果会不会被合并成一个状态,导致一个失败掩盖或丢弃旁边那些成功。
C9Idempotency and side-effect safety查重试包裹的范围里有什么:如果被重试的区间包含写入、执行命令或对外发消息,重试就会重复执行它。

Boundaries can be closed

检查项查什么
C10Cancellation propagation查取消信号有没有真正传到对外请求和派生的子进程,还是只停在循环这一层。
C11Timeout layering查一次工具调用上有几层超时以及它们的大小关系 —— 工具预算必须早于底层资源超时。
C12Loop and budget limits查轮数、工具调用次数、运行时长、token、委派深度上有没有硬性上限。

Finite resources are accounted for

检查项查什么
C13Context management and truncation boundaries查会话变长时有没有上下文管理,以及截断切在哪里 —— 切开配对的调用与结果会破坏历史。
C14Prompt prefix determinism查最新消息之前的所有内容(系统提示、工具定义、历史消息)在两次运行之间是否逐字节一致,这是缓存命中的前提。

The run is observable

检查项查什么
C15Trace completeness and replay查这次运行有没有留下覆盖轮次、工具调用与结果、重试、截断、审批的事件记录,且完整到足以重建。

★ 是七个关键项 —— /harness-audit p1 跑的就是这些。

<!-- checks:end -->

它怎么工作

![三个阶段:侦察定位地标、每条检查一个子智能体、汇总由代码完成](assets/pipeline.svg)

三个阶段,前两个用模型,最后一个不用:

侦察 —— 一个子智能体先定位地标:agent 循环在哪、请求在哪组装、工具在哪派发、历史在哪追加。找不到某类地标是正常结果,不编造。

扇出 —— 每条检查交给一个独立的一次性子智能体,只给它这一条的判据和它依赖的地标。所需地标缺失的检查根本不会派发,直接记为"未覆盖"——让模型在没有目标的情况下自由发挥,是误报的主要来源。

汇总 —— 纯代码,不过模型。去重、按保守原则合并判定、排序、渲染。让模型写总结,正是 suspected 悄悄变成 confirmed、以及没有证据支撑的论断混进报告的途径。

![运行中的子智能体面板:每条检查一个条目,各自带 token 消耗和耗时](assets/subagents.png)

每条检查一个条目、各自计费。这种隔离正是报告里那份"每维度 token 消耗"能够是实测值而不是估算的原因。

为什么可以信

![一条上报要过六道校验,任何一道不过就带着原因退回子智能体](assets/validation.svg)

判据本身可以要求模型给出文件行号,但只有工具能拒绝。每条上报必须通过六道校验:

1. 检查项属于本次运行 2. 路径是第一方代码——不是 .venvsite-packagesnode_modules 3. 文件在工作区内真实存在(这同时挡住路径穿越) 4. 行号在文件范围内 5. 引用的代码确实出现在所声明行号的 ±3 行内 6. 判定为"可疑"时必须说明人工需要核实什么

第 5 条是关键。它按归一化文本比对(去缩进、压缩空白),不做逐字节比较,所以缩进差异不会造成假拒;但一段"看起来像代码却不在文件里"的内容会被退回,并告诉子智能体重查。实测中它反复生效:被拒后子智能体会重新打开文件、修正引用再提交。

范围约束同理。第一次跑一个 Python 项目时,23 个地标全部落在 .venv/site-packages/——审计的是依赖的框架而不是项目本身。仅靠提示词说明不够,加上工具层拒收之后,同一个项目的运行从 698 秒降到 147 秒,token 从 19 万降到 4.6 万。

实测

![预埋 8 个缺陷全部检出,0 误报,单维度 205 秒 / 6.1 万输入 token](assets/results.svg)

拿一份预先埋好缺陷、答案已知的代码验证:七个真实的工具调用配对缺陷、一个受环境变量门控的可疑情况、外加一个刻意写正确的对照模块。

缺陷检出8 / 8
误报0 —— 对照模块一次都没被点名
证据拒收10 次提交拒 2 次,均在重新提交后修正
成本单维度约 205 秒,输入 6.1 万 / 输出 2.4 万 token

唯一与答案卷不一致的一条,是审计器比答案卷更准:它读到那个环境变量的默认值,判断该路径默认可达,因此报为"确认"而非"可疑"——按判据它是对的。

累计已在 11 / 15 个维度上产出 70 条发现、21 次拒收,消耗约 167 万输入 token。

安装

先装 DeepSeek Harness

这是一个插件,需要有 dsh 才能挂载。装好 Node.js 之后:

npx @deepseek-ai/dsh web

Web UI 默认在 http://127.0.0.1:3080。或者从源码检出运行:

git clone https://github.com/deepseek-ai/deepseek-harness.git
cd deepseek-harness
pnpm install
pnpm run build
pnpm dsh web

两点需要提前知道:

  • DeepSeek Harness 处于 developer preview,明确会有破坏性变更。 本插件因此把 peer 依赖锁在 ^0.1.0-rc.5
  • dsh plugin 是转发给 pnpm 的,所以 pnpm 必须在 PATH 上。

再装这个插件

dsh plugin --profile web add dsh-harness-audit

npm i dsh-harness-audit 只会下载包,不会激活插件——dsh plugin add 才会把它装进 profile,并让 package.json 里的 dsh.bundle 声明把配置层挂上。验证:

dsh --profile web --dump-config

应该能看到一段 # == dsh-harness-audit。卸载用包名:

dsh plugin --profile web remove dsh-harness-audit

用法

/harness-audit          # 弹出维度选择器,每项都有人话说明
/harness-audit C1       # 单个维度
/harness-audit C1,C9    # 多个
/harness-audit p1       # 七个关键项
/harness-audit all      # 全部十五项

![维度选择器:十五个选项,每个都有一行说明它查什么](assets/picker.png)

命令立即返回,审计作为后台任务运行,不阻塞会话。跑完时 agent 会被唤醒并汇报。中途想看进度,让它调 job_output <id>

![命令立刻返回并说明启动了哪些维度,agent 一句话确认](assets/announce.png)

无法解析的输入会被拒绝,不会被静默改判——早期版本只认 --checks,结果 --check c2 落到了配置默认值上,审计了另一个维度却一声不吭。

报告

每次运行产出两份文件,按本地时间和覆盖维度命名:

.harness-audit/report-2026-08-17_095736-C1.md
.harness-audit/report-2026-08-17_095736-C1.json

结构固定,两次运行可以直接对比。其中两节不可省略:

  • 未覆盖 —— 因地标缺失而没跑的检查会明确列出。没有这一节,读者会把"没查"当成"查过没问题"。
  • 成本 —— 每条检查的 token 消耗,以及证据拒收次数。拒收率高说明子智能体在编造,该改的是提示词,不是放宽校验。

配置

字段默认含义
checks[]要跑的检查项 id。空表示"询问",绝不表示"全审"。
priorityFloor2只跑优先级不高于此值的检查(1 = 仅关键项)。显式点名的检查不受此限制。
concurrency3同时进行的检查数。1 是受支持的最省也最好调试的路径。
subagentProviderspawn子智能体提供方名称。
maxTokensPerCheck120000仅供参考,见下方限制。
outputDir.harness-audit报告目录,相对工作区。
announceOnStarttrue启动时在对话里发一条通知,让全新会话有轮次可以承载任务 UI。
backgroundtrue作为后台任务运行。false 则阻塞命令直到跑完。
useLsptrue尝试 LSP 导航,不可用时降级为文本检索。
crossCheckAnalysisfalse预留,尚未产出。
languageauto输出语言。auto 依次尝试 harness 语言设置、宿主语言、英文。
excludePaths依赖目录被判为超出范围的目录名。设为 [] 可以刻意审计依赖里的框架。

已知限制

  • maxTokensPerCheck 只是建议值。 子智能体 seam 没有整轮 token 上限(AgentOptions.maxTokens 限制的是单次响应),所以这个预算只是告知子智能体并记入元信息,报告里给出的是实测消耗。它不被强制。
  • crossCheckAnalysis 尚未实现。 真做的时候,它的输出必须单独成节并标明是未经证据校验的模型推断。
  • LSP 可用性是按扩展名的。 seam 没有能力查询接口,只能靠 query() 抛出的 LspError 观测,所以探测发生在侦察之后、用检测到的主语言进行,结果只对该语言有效。
  • 成本归账需要本地子智能体提供方。 消耗是从子会话事件折叠出来的;远程提供方不发布本地子会话,其用量会读作 0。
  • 全新会话里,首个轮次出现之前看不到任何东西。 命令不产生轮次,而对话区的 UI 槽位是严格会话绑定的,任务指示器没有地方挂。announceOnStart 就是为此存在的。

它不做什么

  • 不发明判据。 十五条检查的标准写死在 src/criteria.ts 里,子智能体拿到的是原文;插件自己的名称、分组、菜单文案都是导航用的,从不代替判据。
  • 不替你下结论。 suspected 就是 suspected,报告会告诉你人工需要核实什么。
  • 不搭测试套件。 把发现变成回归测试是另一件事,这里只做审计。

许可

MIT