把串行工具调用改成分层并行执行的任务图
36.5/100
综合分
2
GitHub 星标
—
npm 周下载
—/5
用户评分
数据截至 2026/11/3 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。
自动兼容检查有告警:未发布到 npm registry,仅可从源码安装。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add zyn19940107/dsh-refine-loop该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)
状态速览
判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态信任档位:仅索引
是什么
dsh 原生插件 · tool
装得上吗
静态安装检查有提示项,装前建议看一眼 README
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 0 天前
档位由哪些信号合成
本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。
社区实装还没有人打卡 · 装过的第一个就是你
安装兼容性检查⚠ 装前注意未发布到 npm registry,仅可从源码安装
展开查看检查明细 ↓
以下结论由程序自动检查 npm 包、engines 声明与入口文件得出,未做人工实机验证——能装不等于用着没问题。
✗npm 包@zyn19940107/dsh-refine-loop(未发布到 npm,仅可源码安装)
✓Node 引擎未声明 engines.node
✓dsh CLI 依赖未声明 dsh 版本约束
✓入口文件main/exports/bin 已声明
验证方式:npm registry 存在性 + package.json 静态校验 · 最后检查 2026/11/3 15:17:02
安全扫描自动 · 静态分析源码v2.7.0🔵 扫描:含敏感能力尚无人工评估展开查看扫描说明与证据 ↓
安全扫描自动 · 静态分析源码
v2.7.0静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。
读写/删除本地文件
查看扫描证据(共 3 处,展示前 3 条)
- 读取本地文件build.mjs:17
const manifest = JSON.parse(await readFile(join(root, 'package.json'), 'utf8')) - 删除本地文件递归build.mjs:23
await rm(outDir, { recursive: true, force: true }) - 写入本地文件build.mjs:24
await mkdir(outDir, { recursive: true })
扫描于 2026/11/3(0 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库
静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。
依赖的 DSH / Cordis 模块
@deepseek-ai/cordis@deepseek-ai/dsh-agent@deepseek-ai/dsh-commands@deepseek-ai/dsh-llm@deepseek-ai/dsh-tools@deepseek-ai/schemastery给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个
DeepSeek Harness 插件:把「想→做→看→再想」的串行链换成「规划一次→并行做N件→一次性收N个结论」
README
由 DeepSeek 最新模型翻译生成dsh-refine-loop
把「想一步、做一步、再看一步」的串行链,换成「每一轮:想图 → 交图 → 跑图 → 判断」。
一句话
模型不再一步一步地调工具。
每一轮它要做的是画一张图:这一轮有哪些活、哪些能同时跑、每个节点由什么组成。
插件按依赖分层执行这张图 —— 同层并行,跨层串行 —— 把所有结果一起还给模型。
然后模型只看结果做判断:能回答了,就写结论结束;还不能,就画下一张图。
flowchart TD
U["用户提问"] --> R1
subgraph ROUND["每一轮 —— 四步"]
R1["① 想图这一轮有哪些活、哪些能并行、每个节点由什么组成"] --> R2["② 交图refine_plan(criteria, nodes)"]
R2 --> R3["③ 执行图插件按层跑:同层并行 / 跨层串行"]
R3 --> R4{"④ 判断结果能回答了吗?
展开完整文档(README 剩余 1 节)
dsh-refine-loop
把「想一步、做一步、再看一步」的串行链,换成「每一轮:想图 → 交图 → 跑图 → 判断」。
一句话
模型不再一步一步地调工具。
每一轮它要做的是画一张图:这一轮有哪些活、哪些能同时跑、每个节点由什么组成。
插件按依赖分层执行这张图 —— 同层并行,跨层串行 —— 把所有结果一起还给模型。
然后模型只看结果做判断:能回答了,就写结论结束;还不能,就画下一张图。
flowchart TD
U["用户提问"] --> R1
subgraph ROUND["每一轮 —— 四步"]
R1["① 想图这一轮有哪些活、哪些能并行、每个节点由什么组成"] --> R2["② 交图refine_plan(criteria, nodes)"]
R2 --> R3["③ 执行图插件按层跑:同层并行 / 跨层串行"]
R3 --> R4{"④ 判断结果能回答了吗?"}
end
R4 -->|"能"| DONE["✅ 写结论循环结束,用户拿到回答"]
R4 -->|"不能"| R1
每一轮到底发生了什么
sequenceDiagram
participant M as 模型 participant P as 插件 participant T as 工具
Note over M: ① 想图(可以先调工具把这轮该画什么搞清楚) M->>P: ② refine_plan(判据 + 节点) P->>T: ③ 第 1 层:互不依赖的节点同时跑
T-->>P: 结果
P->>T: ③ 第 2 层:等第 1 层的节点
T-->>P: 结果
P-->>M: 全部结果一次回来,这一轮结束
Note over M: ④ 只看结果判断 alt 能回答了 M->>M: 写结论 → 循环结束 ✅ else 还不能 M->>P: 下一轮:② refine_plan(下一张图) end
关键点:模型在「判断」这一步只能做两件事 —— 写结论,或者交下一张图。它不能在这一步继续一个一个地调工具干活。那是图中的活。
图是什么
flowchart TD
subgraph L1["第 1 层 —— 同时跑 ✅"]
A["节点 A(tools)grep 找引用"]
B["节点 B(tools)统计行数"]
end
subgraph L2["第 2 层 —— 等第 1 层"]
C["节点 C(tools)read @@A@@ 命中的文件"]
end
A --> C
B --> C
| 节点类型 | 里面是什么 | 额外模型调用 | 什么时候用 |
| tools | 一批事先写死的调用 | 0 ✅ | 参数现在就能写死的活 |
| subagent | 一个从零开始的子代理 | 一份上下文 + 一份报告 | 要靠它自己边看边判断的活 |
| subagent_fork | 一个继承本对话的子代理 | 同上(每步重发历史) | 活要用到已经读过/说过的内容 |
- 节点用 after: ["A"] 声明依赖;不依赖任何节点的节点同时跑 ✅
- 下游参数写 @@A@@,插件把 A 的整段输出塞进去,并自动算作依赖 ✅
- 子代理之间不能互相依赖 —— 它们是并行分支,依赖另一个子代理的图会被直接拒绝 ✅
插件强制了什么(这是它区别于「建议」的地方)
提示词写在系统提示词里会被模型当成背景;插件把三条强制做在机制上:
| 强制 | 怎么做 | 为什么 |
| 每轮开始就想图 ✅ | 每一轮的第 1 步之前,插件把「四步循环」作为最后一条消息塞给模型 | 系统提示词在最前面,模型说话前最后读到的才是它真正会照做的东西(实测:改位置没用,改消息有用) |
| 每轮必须交图 ✅ | 一轮结束了却没交图 → 插件把它拽回来(最多 3 次) | 「没有图的一轮」等于用串行链回答了请求 |
| 图跑完只能判断 ✅ | 图跑完之后,模型自己发起的工具调用一律拒绝 | 那是「判断」阶段:要么写结论,要么画下一张图 |
| 派发只能走图 ✅ | harness 自带的 subagent / subagent_fork 直调被拒绝,并提示改成图里的节点 | 直调会绕过这一轮的图和它的预算 |
注意:规划设计阶段是允许调工具的。工具调用用来搞清楚「图里的节点该写什么」;不允许的是用工具把活干完、跳过图。
实测
同一份代码、同一个 profile、同一个模型、同一个任务,只切插件的 enabled。
原始记录在 bench/results/。每个场景单次抽样 —— 方差很大,看趋势,不要看小数。
profile 只有 harness + 被测插件(dsh-sandbox/home/profiles/bench)。这一点是硬要求:沙盒里如果还装着别的会注册「派发」工具的插件,被测模型会拿到两套互相竞争的指令,测出来的就是那个插件的行为,不是这个插件的。
时间、步数与编队
| 场景 | 条件 | 耗时 | 主步 | 编队 | 编队步 |
| fanout(5 个文件各读第一行) | off | 12s | 3 | 1 | 3 |
| fanout | on | 16s | 2 ✅ | 1 | 2 ✅ |
| sweep(跨文件扫一个模式) | off | 197s | 10 | 1 | 10 |
| sweep | on | 133s ✅ | 7 ✅ | 1 | 7 ✅ |
| coverage(spec↔模块覆盖盘点) | off | 60s | 13 | 1 | 13 |
| coverage | on | 56s ✅ | 4 ✅ | 1 | 4 ✅ |
| review(评审 5 个文件) | off | 211s | 31 | 1 | 31 |
| review | on | 153s ✅ | 11 ✅ | 1 | 11 ✅ |
| coveragewide(14 个文件全读一遍) | off | 73s | 11 | 1 | 11 |
| coveragewide | on | 99s | 6 ✅ | 1 | 6 ✅ |
| panel(三方独立评审,必须互相看不见) | off | 1235s | 76 | 4 | 273 |
| panel | on | 1326s | 18 ✅ | 6 | 214 ✅ |
| greenspecs(长程修复:跑→看红→改→再跑,直到全绿) | off | 82s ❌ | 18 ❌ | 1 | 18 ❌ |
| greenspecs | on | 299s | 33 | 1 | 33 |
拆开看 token
| 场景 | 条件 | 输入 | 缓存输入 | 输出 | 合计 |
| fanout | off | 13k | 20k | 1k | 34k |
| fanout | on | 14k | 11k ✅ | 1k | 27k ✅ |
| sweep | off | 75k | 354k | 4k | 433k |
| sweep | on | 86k | 221k ✅ | 10k | 317k ✅ |
| coverage | off | 29k | 248k | 4k | 281k |
| coverage | on | 38k | 59k ✅ | 5k | 103k ✅ |
| review | off | 74k | 1,427k | 17k | 1,518k |
| review | on | 77k | 542k ✅ | 17k | 636k ✅ |
| coveragewide | off | 56k | 391k | 7k | 454k |
| coveragewide | on | 53k | 108k ✅ | 10k | 171k ✅ |
| panel | off | 762k | 31,827k | 222k | 32,812k |
| panel | on | 779k | 21,923k ✅ | 218k | 22,919k ✅ |
| greenspecs | off | 55k | 660k | 8k | 723k |
| greenspecs | on | 123k | 2,060k | 42k | 2,225k |
(合计 = 输入 + 缓存输入 + 输出。其中 90% 以上是缓存输入 —— 每一步把变长的对话重新发一遍,不是新读进来的内容。真正的新输入和输出,on 和 off 几乎一样。)
结论
| 指标 | 结果 |
| 缓存输入(最多的一栏) | 6/6 场景全降 ✅(−31% ~ −76%) |
| 主 agent 步数 | 6/6 全降 ✅ |
| 新输入 / 输出 | 基本持平 ✅(on 略高,是做规划本身的那点开销) |
| 正确性 | 12/13 持平 ✅(只有 greenspecs 不同:off 0/1 → on 1/1) |
| 耗时 | 3 个降 ✅(sweep −32%、coverage −7%、review −27%),3 个升或平(fanout +4s、coveragewide +26s、panel +91s) |
| greenspecs 的正确性 | off 0/1 ❌ → on 1/1 ✅(唯一一个「任务能不能做成」出现差别的场景) |
原因很直接:一份材料读一次、理解一次、判一次,比「读一点→想一点→再读一点」省 token,但每轮多一次图的往返。缓存输入省下来的量等于「少走的步数 × 每步的上下文」,任务越大越明显;任务小的时候,这层固定开销会盖过省下来的那点。
注意「合计 token」不是「花的钱」。 缓存输入的价格通常只有新输入的十分之一左右,而输出最贵。按上面的数粗算,review 的真实成本大约降 25%,panel 大约降 20% ——比「合计降 30%~60%」要小,但仍然是真的降。
赢和输的分界线
flowchart LR
A["图里放什么"] --> B{"有子代理吗"}
B -->|"没有全是 tools 节点"| C["✅ 赢调用本身就是活,0 次额外模型往返"]
B -->|"有subagent / fork"| D["看任务需要独立判断时该派,不需要就是纯开销"]
tools 节点是插件最省的形状:图的节点就是那批调用,结果一次性回来,判断只发生一次。
长程任务:插件唯一把「做不成」变成「做成」的场景
greenspecs 借的是长程基准的形状 —— Long-Horizon-Terminal-Bench 把这类任务定义成「跑 → 量 → 调 → 再跑」的反馈循环,瓶颈不是单步能力,而是能不能坚持到收敛。
这里把它落到本仓库:一份源码副本里植入 2 个 bug,specs 有 4 个检查红,要求只改 src/、不许改 verify/、跑到 all checks passed。
| | off | on |
| 耗时 | 82s | 299s |
| 主步 | 18 | 33 |
| 结果 | ❌ 提前收工,specs 仍然红 | ✅ all checks passed |
off 在第 18 步就收工了,改了点东西但没让 specs 变绿。on 被「交图 → 看结果 → 判断能不能给结论」按在循环里,一直跑到验证器说全绿。
代价是 3.6 倍时间和 3 倍 token —— 这是唯一一个「多花时间换正确性」的场景,也是插件最该被用的场景。
subagent / subagent_fork 只在一种任务上划算:需要多个互相看不见的判断(panel)。
同一个 agent 读两遍同一份代码,第二遍会被第一遍的结论污染 —— 要独立性只能开新上下文。
这也解释了 panel 的两种条件:关插件时 harness 自己也在派 4 个子代理,开插件只是把主 agent 的 76 步压到 18 步,正好是插件声称的那件事。
单片抽样,方差很大。 图里放不放子代理、放几个,是模型自己的判断,差别就是几倍。
这个插件保证的是「每一轮的形状」,不是「一定更快」。
公开评测集上的 A/B(HumanEval / QuixBugs)
上面那些场景是手工设计的:题目按插件的形状挑,判据是「答案里有没有这几个字」。
这一节把两件事都换成真的 —— 题目来自公开评测集,判据是跑出来的。
两个沙盒
| 配置档 | bundles | 用途 |
| bench-off | dsh-base + dsh-headless | 不带插件 |
| bench-on | 同上 + @zyn19940107/dsh-refine-loop | 带插件 |
两个配置档只差一个 bundle —— 这是「带插件 / 不带插件」唯一可测的差别。
bench-on 里的插件是没被改过的原版,只配了部署参数:enabled: true、 shellTool: pwsh(基准配置档里实际的 shell 工具叫 pwsh;插件默认写的是 dsh-ops 的 ops_bash,不改这一项的话它的只读-shell 规则是空的,每次 shell 调用都独占)。
node bench/setup-profiles.mjs # 建这两个沙盒
node bench/probe-judge.mjs humeval humeval-hard quixbugs # 先证明判据是对的
node bench/compare.mjs 5 humeval humeval-hard quixbugs # 跑 A/B(顺序跑,不并行)
node bench/pubeval-table.mjs # 出表
样例从哪来
| 评测集 | 出处 | 取的题 | 判据 |
| HumanEval | openai/human-eval | 10 道原题(prompt 与 test 都是数据集原文),分成两组各 5 道 | 跑数据集自己的 check() |
| QuixBugs | jkoppel/QuixBugs(MIT) | 4 个程序里的 bug | 跑数据集自己的用例 + 3 条留出用例 |
题面和用例逐字 vendored 在 bench/data/(带 sha256),判据脚本从 vendored 副本读,不从工作区读 —— 改测试不算通过;工作区里的 check.py 被指纹记录,改了就判失败。
QuixBugs 的用例本来就是公开的、智能体看得见,所以判据里另外加了 3 条留出用例 (留出用例先跟数据集自己的正确程序对过才拿来用),专治「按可见用例硬编码」。
判据本身要先证明是对的:bench/probe-judge.mjs 拿一份正确答案、一份错误答案、一份被改过的判据各跑一遍 —— 正确 5/5、错误 0/5、改判据被抓,三项都过才开始跑模型。
结果(每场景 5 次 × 2 臂,中位数)
| 场景 | 指标 | 关掉插件 | 开着插件 | 变化 |
| humeval(5 道独立实现题) | 总耗时 | 327s | 112s | -66% |
| | 总 token | 528k | 83k | -84% |
| | ├ input / cacheRead / output | 38k / 470k / 19k | 29k / 51k / 16k | -22% / -89% / -18% |
| | 主智能体上下文 | 36k | 35k | -2% |
| | 主智能体往返步数 | 19 | 4 | -79% |
| | 编队人数 | 1 | 1 | 0% |
| | 正确性 | 5/5 | 5/5 | — |
| humeval-hard(5 道难题) | 总耗时 | 107s | 76s | -29% |
| | 总 token | 222k | 152k | -32% |
| | ├ input / cacheRead / output | 22k / 196k / 12k | 17k / 97k / 12k | -23% / -50% / +3% |
| | 主智能体上下文 | 26k | 29k | +11% |
| | 主智能体往返步数 | 10 | 6 | -40% |
| | 编队人数 | 1 | 1 | 0% |
| | 正确性 | 5/5 | 5/5 | — |
| quixbugs(4 个要跑用例才定位的 bug) | 总耗时 | 80s | 167s | +108% |
| | 总 token | 240k | 137k | -43% |
| | ├ input / cacheRead / output | 24k / 200k / 10k | 15k / 111k / 17k | -40% / -44% / +63% |
| | 主智能体上下文 | 25k | 34k | +40% |
| | 主智能体往返步数 | 11 | 6 | -45% |
| | 编队人数 | 1 | 1 | 0% |
| | 正确性 | 4/4 | 4/4 | — |
每次运行的原始记录在 bench/results/,表是 bench/pubeval-table.mjs 生成的,不是手打的。
读数
token 三个场景都降,降的是缓存输入。 少走几步,每一步就不用把变长的历史重发一遍:缓存输入 -89% / -50% / -44%,往返步数 -79% / -40% / -45%。真正新读的 input 只降 22% / 23% / 40%,输出基本持平 —— 这和 README 前面那批场景是同一个结论。
耗时看形状。 两组实现题省时间(-66% / -29%),修 bug 那组反而慢了 +108%:修 bug 的下一步取决于上一步跑出来的输出,每一轮都要重新画一张图,输出 token 因此涨了 63%,主上下文也涨了 40%。要跑一遍才知道下一步的活,插件的「一轮一图」纪律是把双刃剑。
「开着插件」不等于「真的用了插件」。 插件只在图跑完之后才拦模型的直接调用;画图之前模型可以先调工具把节点摸清楚,所以模型完全可以不交图自己干。
这次 30 次运行里,开着插件的那 15 次中有 12 次真的交了图(humeval 4/5、humeval-hard 3/5、 quixbugs 5/5),剩下 3 次只是多了插件的提示词段。表里「其中真的交了图的运行」那一行是这个比例;只看交了图的那些次,数字比上表更好(humeval:耗时 -72%、总 token -85%)。
正确性 30 次全对。 两个评测集、两个臂、每一道题,插件一次都没让题做不成,也没让它多做对 —— 插件改的是代价,不是能不能做成。
编队人数全是 1。 模型自己选的节点全是 tools 节点,一次也没派子代理。插件给的「派发」能力在这三个任务上没被用上,所以这里的「编队」测的是要不要分叉,不是分叉之后省了多少。要测分叉,得用那种「多个判断必须互相看不见」的任务(比如前面那个 panel)。
单次抽样,方差很大。 humeval 关掉插件那五次是 81.5s / 164.1s / 327.3s / 918.1s / 618.8s —— 中位数只是中位数。看趋势,不要看小数。
长程设计题(LHTB:2048 与 N 体优化)
前面那些题都是「能一次列全」的活 —— 几个函数、几个 bug。这一节换成 LHTB (Long-Horizon Terminal-Bench)的两道长程设计题:题来自公开评测集,本机改编(这台机器没有 Docker,上游容器里的东西在本地重做)。
| 题目 | 出处 | 形状 | 评分 |
| 2048 | silrlab/2048 | 一直玩到预算用完 | 连续分:最大 tile 的 band + 棋盘进度(上限 11) |
| N 体优化 | silrlab/nbody-accel-iterative | 把 O(N²) 改快,物理不变 | 加权分:4 档 × min(加速比 / 上限, 1) |
改编了什么
- 2048:上游是容器里的游戏守护进程,这里是本地 CLI(g2048.py)—— 规则、引擎、种子、记谱格式都是上游的。评分器用一台全新引擎重放 moves.log 取峰值,和上游一样;进度没法伪造,只有真合并出来的 tile 才算数。
- N 体:上游的隐藏验证器在本机重写(judge_nbody.py):同样的 4 档、同样的权重和加速比上限、同样是全新随机生成的留出世界(id 打乱、质量/初速/截断半径/步长都变),参照系是上游的 numpy O(N²) 基线。参照系和提交在同一个进程里跑 —— 跨进程跑同一份 numpy 代码会有 1e-6 的漂移,一步混沌放大就超过上游 1e-2 的位置容差了(这是踩过的坑)。
- 两道题都按上游的做法按时间截断:到点就停,磁盘上留下什么就评什么。
- LHTB 的素材(引擎、基准 CLI、判据、参考答案)放在仓库外的沙盒(D:\codeibe\dsh-sandbox\lhtb\),仓库里只留跑它们的脚本 —— 判据是 oracle,仓库不能顺手送一份现成的答案。
结果
2048(5 次 × 2 臂,中位数)
| 指标 | 关掉插件 | 开着插件 | 变化 |
| 总耗时(秒) | 584s | 293s | -50% |
| 整个编队的 token | 1510k | 409k | -73% |
| ├ input | 66k | 66k | +1% |
| ├ cacheRead | 1401k | 291k | -79% |
| └ output | 48k | 52k | +8% |
| 主 agent 的 context(最后一次请求的 prompt) | 74k | 76k | +3% |
| 主 agent 的往返步数 | 26 | 7 | -73% |
| 编队人数 | 1 | 1 | 0% |
| 分数(band / 11) | 4 | 4 | — |
| 连续分(原始 band 值) | 4.79 | 4.79 | 0% |
off 1: 776.1s agents=1 tokens=902156 mainCtx=65682 band=4/11 score=4.7852 plan=n
off 2: 712.7s agents=1 tokens=1136594 mainCtx=68852 band=4/11 score=4.7852 plan=n
off 3: 584.3s agents=1 tokens=3168012 mainCtx=79259 band=4/11 score=4.7812 plan=n
off 4: 580.2s agents=1 tokens=2281977 mainCtx=79449 band=4/11 score=4.7852 plan=n
off 5: 361.1s agents=1 tokens=1510339 mainCtx=73872 band=4/11 score=4.7852 plan=n
on 1: 293.2s agents=1 tokens=626990 mainCtx=47432 band=4/11 score=4.7852 plan=n
on 2: 387.0s agents=1 tokens=408877 mainCtx=76320 band=4/11 score=4.7852 plan=y
on 3: 243.0s agents=1 tokens=519914 mainCtx=69973 band=4/11 score=4.7852 plan=y
on 4: 261.7s agents=1 tokens=288344 mainCtx=78508 band=4/11 score=4.7852 plan=y
on 5: 311.2s agents=1 tokens=332707 mainCtx=77231 band=4/11 score=4.7852 plan=y
N 体优化(3 次 × 2 臂,中位数)
lhtb-nbody (off 3 次 / on 3 次,中位数)
| 指标 | 关掉插件 | 开着插件 | 变化 |
| 总耗时(秒) | 1200s | 1200s | -0% |
| 整个编队的 token | 3405k | 2217k | -35% |
| ├ input | 115k | 86k | -25% |
| ├ cacheRead | 3199k | 2064k | -35% |
| └ output | 92k | 71k | -22% |
| 主 agent 的 input | 113k | 86k | -24% |
| 主智能体的 cacheRead | 3086k | 1971k | -36% |
| 主智能体的 output | 92k | 71k | -22% |
| 主智能体的上下文(最后一次请求的提示词) | 115k | 97k | -15% |
| 主智能体的往返步数 | 38 | 30 | -21% |
| 编队步数 | 39 | 31 | -21% |
| 编队人数 | 1 | 1 | 0% |
| 通过的档(加权分见下) | 4/4 | 4/4 | — |
| 连续分(原始 band 值) | 1.00 | 1.00 | 0% |
| 其中真的交了图的运行 | — | 1/3 | — |
只看真的交了图的那 1 次(样本太少,只当个例看):
| 指标 | 关掉插件(全部) | 开着插件(交图的) |
| 总耗时(秒) | 1200s | 704s |
| 整个编队的 token | 3405k | 593k |
| ├ input | 115k | 86k |
| ├ cacheRead | 3199k | 436k |
| └ output | 92k | 71k |
| 主智能体的 input | 113k | 86k |
| 主智能体的 cacheRead | 3086k | 436k |
| 主智能体的 output | 92k | 71k |
| 主智能体的上下文(最后一次请求的提示词) | 115k | 97k |
| 主智能体的往返步数 | 38 | 8 |
| 编队步数 | 39 | 8 |
| 编队人数 | 1 | 1 |
off 1: 1199.9s agents=1 tokens=815232 mainCtx=61169 correct=4/4 plan=n/0 profile=bench-off
off 2: 1200.0s agents=1 tokens=3404962 mainCtx=114903 correct=4/4 plan=n/0 profile=bench-off
off 3: 1200.0s agents=1 tokens=4840592 mainCtx=122625 correct=4/4 plan=n/0 profile=bench-off
on 1: 1199.9s agents=1 tokens=2217022 mainCtx=93938 correct=4/4 plan=n/0 profile=bench-on
on 2: 1200.0s agents=1 tokens=3116955 mainCtx=113687 correct=4/4 plan=n/0 profile=bench-on
on 3: 704.1s agents=1 tokens=593042 mainCtx=97331 correct=4/4 plan=y/0 profile=bench-on
读数
- 同样的结果,更便宜。 2048 那题 10 次运行全部打到 band 4(512 的 tile),分数一模一样;差的是代价:开着插件耗时 -50%、总 token -73%、往返步数 -73%。省下来的几乎全是缓存输入(-79%)—— 少走几步,每一步就不用把变长的历史重发一遍。
- 机制看得见。 关掉插件时,智能体自己做 12~23 次 pwsh 调用、4~6 次写文件;开着插件时(5 次里有 4 次真交了图),这些活被收进图里,顶层只剩 1~2 次 pwsh 和几次 refine_plan。工具调用从顶层搬进图里,就是插件做的事。
- 关掉插件会打转。 off 那 5 次里有 2 次跑飞了:56 步 / 3.17M token、47 步 / 2.28M token (on 那 5 次最多 17 步 / 627k)。串行链的病在长程任务上最明显。
- 上下文没变。 主智能体最后一次请求的提示词两边都是 74k~76k —— 图把活收进去了,但结果最后还是要回到主上下文。
- 这道题对 MiniMax-M3.1-Flash 不够硬 —— 它被做满了。 6 次运行全部 4/4 档、加权分 1.00:智能体在 20 分钟里写出了两个内核(均匀网格 + 3×3 stencil 的稀疏局部解,和对称化分块的稠密全局解),三档加速比分别做到 13.3× / 8.66× / 25.3×,全部越过上游的上限。
这是真实结果,不是测量失败:上游自己的榜单上 MiniMax M3 的平均分只有 0.357(77 题里严格通过 1 题),本机改编明显比上游容易 —— 留出世界的对抗性没有完全搬过来(上游的全局档是 13 万粒子、且世界分布专门为「固定网格退化」设计)。要复现上游的难度,得把那一档也搬过来。
- 于是这道题只能测代价。 代价上:开着插件 token -35%、缓存输入 -35%、输出 -22%、步数 -21%、主上下文 -15%。耗时两臂都是 1200s —— 因为 6 次运行里 5 次都撞到 20 分钟预算,时间这一列被预算封顶了,看不出差别。
- 这题上插件几乎没被用上。 3 次开着插件的运行里只有 1 次真交了图:这类活的形状是「写代码 → 测 → 改 → 再测」,下一步取决于上一步的输出,没有可以并行的节点。
2048 那题 5 次里有 4 次交了图 —— 差别就在这。
单次抽样,方差很大。 2048 关掉插件那五次是 776s / 713s / 584s / 580s / 361s ——中位数只是中位数。看趋势,不要看小数。
哪几道题能让插件派生子代理
前面那几道题里编队人数一直是 1 —— 插件一次子代理都没派出去。原因不是插件不行,是题目的形状里没有可以并行的节点。这一节先在 LHTB 的 77 道题里把「能并行」的形状筛出来,再挑两道跑 A/B。
筛的标准是三条同时成立:(1) 题面里有互不依赖的子活;(2) 每个子活能单独判分;
(3) 子活之间不需要互相看对方的产物。
| 题目 | 子活 | 互不依赖? | 单独判分? | 能不能并行 |
| commit0-multilib-tdd | 三个库(tinydb / sortedcontainers / cachetools) | 完全独立 | 各自一套隐藏测试(204/297/283) | 能 |
| matpower-opf-regression | manifest 里十个算例 | 完全独立 | 同一套判据逐字段比 | 能 |
| apex-law433-matter | 四个案件 | 独立,但阶段全局解锁 | 分阶段给分 | 只能顺序 |
| apex-management-consulting-matter | 两个案件 | 同上 | 同上 | 只能顺序 |
| apex-investment-banking-matter / apex-ib244-matter | 19 / 38 个阶段 | 阶段互相依赖 | 分阶段 | 不能 |
| 2048 / chess-mate / sudoku-recovery | 一局一关 | 严格串行 | 连续分 | 不能 |
| tasks-2.0 的 31 道 "Reconstruct X" | 一个产物 | — | 隐藏场景 | 不能 |
| nbody-accel-iterative | 一份实现 | — | 加权分 | 不能 |
结论:「一份规格、多个产物」的长程题才是插件能派子代理的地方 —— 三个库、十个算例,每个都是一份能单独交、能单独判分的活。而「一局一关」「阶段解锁」这类再长的题,结构上就是一条链,只能一条链跑到底。这解释了 2048 和 N 体那两道题里编队人数为什么一直是 1。
下面两道都是从 LHTB 拿的,本机改编(没有 Docker,上游容器里的东西在本地重做),判据都是可执行的。
commit0-multilib-tdd:三个库从零实现
上游的题:三个真实的 Python 库(tinydb 4.8.2 / sortedcontainers 2.4.0 / cachetools 7.1.4) 每个函数体都被换成 raise NotImplementedError,评测用的测试套件不给你 —— 你得从 docstring 和 docs 里读懂行为,自己写测试,再实现到自己的测试全过。打分是隐藏的三套真实测试(784 个)里通过的比例。
本机改编做了三件事:
- 上游是容器里的镜像,这里在本地重建工作区(上游的 stub_library.py 原样用,所以活下来的 docstring 是上游的),判据是上游 tests/fixed_tests 的同一套测试(784 个)。
- 上游给 agent 5 小时、专家 8 小时;本地给 30 分钟,两臂一样。到了就停,磁盘上留下什么就评什么。
- 上游用禁网防止"直接把真库拉下来抄"(network_mode: none)。这台机器封不住 ——本地代理能挡 pypi/github,但挡不住会绕的模型(--noproxy)。所以判据改成检测:判据存了上游每个函数体的 AST 指纹,agent 的文件只要函数体和上游逐个 AST 一样就算"抄的",这部分不计入「自写分」,并在记录里点名。
lhtb-commit0 (off 2 次 / on 2 次,中位数)
| 指标 | 关掉插件 | 开着插件 | 变化 |
| 总耗时(秒) | 1606s | 1800s | +12% |
| 整个编队的 token | 27405k | 14355k | -48% |
| ├ input | 597k | 1469k | +146% |
| ├ cacheRead | 26499k | 12141k | -54% |
| └ output | 310k | 746k | +141% |
| 主智能体的 input | 189k | 68k | -64% |
| 主智能体的 cacheRead | 9932k | 450k | -95% |
| 主智能体的 output | 93k | 35k | -63% |
| 主智能体的上下文(最后一次请求的提示词) | 189k | 73k | -62% |
| 主智能体的往返步数 | 86.5 | 15 | -83% |
| 编队步数 | 213 | 256 | +20% |
| 编队人数 | 4 | 19.5 | +388% |
| 命中的判据(隐藏测试) | 703/784 | 376/784 | — |
| 自写分(去掉抄来的库) | 0.152 | 0.259 | +71% |
| 连续分(判据原始分) | 0.90 | 0.48 | -47% |
| 其中真的交了图的运行 | — | 2/2 | — |
只看真的交了图的那 2 次:
| 指标 | 关掉插件(全部) | 开着插件(交图的) |
| 总耗时(秒) | 1606s | 1800s |
| 整个编队的 token | 27405k | 14355k |
| ├ input | 597k | 1469k |
| ├ cacheRead | 26499k | 12141k |
| └ output | 310k | 746k |
| 主智能体的 input | 189k | 68k |
| 主智能体的 cacheRead | 9932k | 450k |
| 主智能体的 output | 93k | 35k |
| 主智能体的上下文(最后一次请求的提示词) | 189k | 73k |
| 主智能体的往返步数 | 86.5 | 15 |
| 编队步数 | 213 | 256 |
| 编队人数 | 4 | 19.5 |
off 1: 1411.9s agents=4 tokens=36471757 mainCtx=122377 correct=622/784 plan=n/0 profile=bench-off
off 2: 1800.0s agents=4 tokens=18339035 mainCtx=255830 correct=784/784 plan=n/0 profile=bench-off
on 1: 1800.0s agents=22 tokens=16436222 mainCtx=65875 correct=376/784 plan=y/3 profile=bench-on
on 2: 1800.0s agents=17 tokens=12273936 mainCtx=79335 correct=376/784 plan=y/3 profile=bench-on
读数
- 插件在这道题上真的派了子代理,而且派得对。 开着插件的两次运行,插件建的图里有 3 个 subagent 节点,一个库一个(cachetools / sortedcontainers / tinydb),外加一个准备性的工具节点;整个编队从 4 人涨到 19.5 人。
- 省的是主上下文,不是总 token。 主智能体的往返步数 86.5 → 15(-83%),主上下文 189k → 73k(-62%),总 token -48%;但 input 和 output 反而涨了(+146% / +141%)—— 活被搬到子代理身上去了,子代理各自读各自的文档、再回话,这部分 token 是新花的钱。
- 自写分:关掉插件 0.152,开着插件 0.259。 也就是说开着插件那次,真正自己写的部分更多(on 的两次都是自己写的 sortedcontainers:203/297)。
- 原始分反而是关插件高(0.90 vs 0.48) —— 因为关插件那两次抄得更彻底(off-2 三个库全抄了, 784/784 全过)。这说明在这道题上,「分数高」不等于「干得多」,判据必须把抄的部分摘出来。
- 这道题上插件的开销更大:耗时 1606s → 1800s(+12%),两次开着插件的都撞到 30 分钟预算。
派 20 个代理要协调成本,省下的主上下文未必抵得上。
matpower-opf-regression:十个算例各算各的
上游的题:实现一个审计流水线,对 manifest 里的每一个算例跑 AC 潮流、DC OPF、AC OPF,写出七份确定性的报告(列名、JSON 键、单位都是规格的一部分),评分器会自己重跑一遍 PYPOWER,拿公开和隐藏的 manifest 逐字段比。
本机改编:上游的 verifier 原样用(它通过 APP_DIR 读工作区,一行都不用改),10 个算例(case9/14/30/57/118 + 缩放和压力变体),30 分钟预算。
lhtb-matpower (off 2 次 / on 2 次,中位数)
| 指标 | 关掉插件 | 开着插件 | 变化 |
| 总耗时(秒) | 853s | 538s | -37% |
| 整个编队的 token | 5565k | 2013k | -64% |
| ├ input | 211k | 133k | -37% |
| ├ cacheRead | 5278k | 1817k | -66% |
| └ output | 75k | 63k | -16% |
| 主智能体的 input | 131k | 133k | +2% |
| 主智能体的 cacheRead | 4575k | 1817k | -60% |
| 主智能体的 output | 66k | 63k | -3% |
| 主智能体的 context(最后一次请求的 prompt) | 137k | 134k | -2% |
| 主智能体的往返步数 | 55 | 23.5 | -57% |
| 编队步数 | 64 | 23.5 | -63% |
| 编队人数 | 1.5 | 1 | -33% |
| 通过的档(加权分见下) | 12/12 | 11.5/12 | — |
| 连续分(判据原始分) | 1.00 | 0.96 | -4% |
| 其中真的交了图的运行 | — | 1/2 | — |
只看真的交了图的那 1 次:
| 指标 | 关掉插件(全部) | 开着插件(交图的) |
| 总耗时(秒) | 853s | 596s |
| 整个编队的 token | 5565k | 1025k |
| ├ input | 211k | 137k |
| ├ cacheRead | 5278k | 806k |
| └ output | 75k | 82k |
| 主智能体的 input | 131k | 137k |
| 主智能体的 cacheRead | 4575k | 806k |
| 主智能体的 output | 66k | 82k |
| 主智能体的 context(最后一次请求的 prompt) | 137k | 137k |
| 主智能体的往返步数 | 55 | 14 |
| 编队步数 | 64 | 14 |
| 编队人数 | 1.5 | 1 |
off 1: 564.2s agents=2 tokens=4176601 mainCtx=133122 correct=12/12 plan=n/0 profile=bench-off
off 2: 1141.0s agents=1 tokens=6953325 mainCtx=140957 correct=12/12 plan=n/0 profile=bench-off
on 1: 596.1s agents=1 tokens=1024860 mainCtx=137339 correct=11/12 plan=y/0 profile=bench-on
on 2: 480.3s agents=1 tokens=3002110 mainCtx=130040 correct=12/12 plan=n/0 profile=bench-on
读数
- 这道题对 MiniMax-M3.1-Flash 太容易:四次运行三次 12/12 全过(上游的参考解本身就是 pypower 的薄封装,最快的一次 9.4 分钟收工)。所以它只能测代价,测不了「能不能做成」。
- 代价上照样有差别:耗时 -37%、总 token -64%、主智能体往返步数 -57%,而分数持平(两边中位数都是 12/12)。开插件那次少花了一半的钱,交出来的东西一样对。
- 但编队人数是 1(off 是 1~2 人):十个算例虽然独立,这道题太短 —— 智能体十分钟就能写完,没有值得分派的活。「能并行」和「值得并行」是两件事。
两道题合起来的读数
- 形状决定一切。 同一套插件,在「一局一关」的 2048 上编队 1 人、在 N 体上 1 人、在三个库和十个算例上编队 4 → 19.5 人。插件不是不派,是没地方派。
- 派起来之后省的是主上下文。 主智能体的往返步数和上下文大幅下降(2048: -73%/-3%、 commit0: -83%/-62%),总 token 也降(-48% ~ -73%),但 output/input 在 commit0 上反而涨 ——子代理的读文档和回话是新花的钱。
- 代价要一起看。 commit0 上开着插件更慢(+12%,两次都撞预算),2048 上更快(-50%)。
差别在于前者是「派了 20 个人去干三件事」(协调成本 > 收益),后者是「少走几步、少重发历史」。
- 正确性上,长程题给不出信号。 2048 两边都是 band 4/11;N 体两边都满分;matpower 两边都满分。
真正能分出高下的只有 commit0 的自写分(0.152 vs 0.259),而它要靠判据把「抄来的」摘干净才看得出来。
- 一个诚实的警告:本地改编的 commit0 没有真正禁网,智能体抄上游真库是可能的(两臂都抄了)。
判据靠 AST 指纹把抄的部分摘出来,两臂条件相同,所以对比仍然成立;但绝对分数不能当真。
改设置
- insert:
- id: refine-loop
name: '@zyn19940107/dsh-refine-loop'
config:
enabled: true # 整个插件挂不挂 maxBatchSize: 8 # 一张图最多几个节点 maxBatchTimeoutMs: 900000 # 一张图的时间预算 maxAgentDepth: 3 # 最多派到第几层子代理 agentNodeTimeoutMs: 540000 # 单个子代理节点的预算 maxRounds: 16 # 一个请求最多几轮 respectConcurrencySafety: true # 认不认工具自己声明的「不能并发」
concurrentTools: [glob, grep] # 插件放行的只读工具
concurrentShell: true # 只读 shell 命令也可并行 shellTool: ops_bash
| 字段 | 默认 | 说明 |
| maxBatchSize | 8 | 一张图的节点上限 |
| maxBatchTimeoutMs | 900000 | 一张图的时间预算 |
| maxAgentDepth | 3 | 子代理还能不能再派子代理。harness 自己有 subagent.maxDepth(默认 1),两边都放行才真的能派下一层 |
| agentNodeTimeoutMs | 540000 | 单个子代理节点的预算,超了报这个节点失败,其余结果照常回来 |
| maxRounds | 16 | 一个请求最多几轮,用完就停 |
| respectConcurrencySafety | true | 认不认工具自己声明的独占性 |
| concurrentTools | [glob, grep] | 纯读工具,随便并行;写操作永远不要加 |
| concurrentShell | true | 只读 shell 命令是否并行 |
并发安全
插件默认认工具自己声明的并发安全性:没声明 isConcurrencySafe 的一律独占。
补充判定:glob / grep 直接放行;shell 命令由插件自己判断 —— 必须是简单命令(无重定向、无管道、无链、无替换),可执行文件必须在只读白名单里,危险参数(find -exec、grep --pre、sort -o …)单独挡掉。
判断不了的,排队。 独占调用是屏障:它前面的先跑完、它自己单独跑、后面的再开始。
装上
dsh plugin add /path/to/dsh-refine-loop
或打包
pnpm pack
dsh plugin add ./zyn19940107-dsh-refine-loop-0.1.0.tgz
装完请开一个新会话 —— 已开着的会话不会刷新模型看到的工具表。
已知边界
- 不用改 harness 的循环结构:全部走公开扩展点(tools/register、tools/guard、agent/pre-step、 agent/turn-stopping、agent/created、systemPrompt.section、commands/register)。
- 子代理在前台同步跑:慢会拖住这一轮,但它有自己的预算(agentNodeTimeoutMs)。
- 图里的调用参数可能写错:图是在跑之前写的,所以调用失败时插件会问模型一次「这条调用应该是什么」,用修好的参数重跑那一条(最多两次),其余节点不受影响。
- 图的结果可能装不下:被截掉的部分在 spill 文件里,下一张图可以读回来。
- 占位符是 @@节点名@@,不是 {{节点名}} —— harness 的提示词渲染器把双花括号当变量引用。
- 每轮的「想图」消息会增加 token:一轮一条消息,换来的是每一轮都有图。
License
MIT预览分享卡片长什么样 ↓
分享 · DeepSeek Harness Hub
zyn19940107/dsh-refine-loop
把串行工具调用改成分层并行执行的任务图
相关插件 · 工具 / 效率
破甲管控台kingcharleslzy-ai/dsh-purge
dsh-purge Community · DeepSeek Harness 社区维护版:宿主兼容、状态诊断、提示词管理、更新与本机备份回滚。基于小杨 / YuJunZhiXue 的 dsh-purge。
★ 4,330已汉化DeepSeek 客户端
74.5
网文长卷lingfengQAQ/webnovel-writer
基于 Claude Code 的长篇网文辅助创作系统,解决 AI 写作中的「遗忘」和「幻觉」问题,支持 200…
★ 7,636已汉化DSH
72.2
多智能体协作HKUDS/AutoSwarm
AutoSwarm: Unify Your Agents. Unify Your Context (Codex · Claude Code · DeepSeek Harness · Muse · Grok · WorkBuddy· nanobot · and more)
★ 2,349已汉化DSH
71.6
Vox 拼贴视频生成Alisa0808/vox-director
🎬 Vox Director拼贴动效导演
★ 2,129已汉化DSH
71.4
Agent 演化引擎Q00/ouroboros
智能体 OS:智能体自己变聪明,我们只守住底线:面试准入、分阶段评估、带预算的进化循环。MCP 服务器,14 种运行时:Claude Code、Codex CLI、Gemini CLI、OpenCode、Copilot、Kiro 等。
★ 6,311已汉化DSH
71.4
智能体运行框架路由HarnessRouter/harnessrouter
智能体 harness 的统一接口。
★ 3,984已汉化DSH
71.3
这是你的仓库?认领条目