大数跨境

DeepSeek也“刷榜”?实测DeepSeek-V4-Flash基准测试成绩“注水”20%

DeepSeek也“刷榜”?实测DeepSeek-V4-Flash基准测试成绩“注水”20% 象信AI
2026-09-12
12
导读:让人非常失望。

我们本地部署了DeepSeek-V4-Flash+DeepSeek Harness Minimal模式,实测Terminal-Bench 2.1得分只有68.5,比 TB 原生 harness 多做对 8 题,但仍与官方宣称的82.7相差甚远,相差20.7%。完整Agent轨迹已开源,并对每道错题逐一做了分析。

特别说明:DeepSeek作为国货之光,作为真正的创新者,我们更希望是我们的测试出了问题,而不是DeepSeek出了问题。希望能引起DeepSeek的重视,对此事做调查并给出答复。

我们在自己的 GPU 服务器上做了一次严格控制变量的对比:同一台机器、同一个 vLLM 实例、同一批 89 道 Terminal-Bench 2.1 题目、同样的超时倍数和并发数,只把 agent harness 换掉

一边是 Terminal-Bench 自带的 terminus-2,一边是 DeepSeek 刚开源的 deepseek-harnessdsh,用 sdk-minimal 模式)。模型两边都是 DeepSeek-V4-Flash-0731,思考档位在服务端固定为 max。

结果:

Scaffold
通过
得分
terminus-2(TB 原生)
53/89
59.6%
dsh sdk-minimal 61/89 68.5%

净多做对 8 题。逐题配对下来:dsh 做对而 terminus-2 做错 18 题,terminus-2 做对而 dsh 做错 8 题,两边都做对 43 题,两边都做错 18 题(另有 2 题因题目环境失效无法评测,见文末)。

差距 8 题,p = 0.18 —— 89 题的规模下还不算统计显著,但方向是清楚的。

下面把每一道错题都拆开讲:错在哪、为什么错,全部引用 agent 当时的原始 trajectory。

完整轨迹已公开,两个 harness 的每一次工具调用、每一条工具返回、每一份判卷输出都在里面:

🤗 https://huggingface.co/datasets/openguardrails/terminal-bench-2.1-deepseek-v4-flash-trajectories

本文引用的每一段命令和报错,都可以在这个仓库里逐条核对。


一、dsh 做对、terminus-2 做错的 18 题

build-cython-ext      caffe-cifar-10       db-wal-recovery      distribution-search extract-elf           extract-moves-from-video                  fix-ocaml-gc largest-eigenval      model-extraction     overfull-hbox        pytorch-model-cli reshard-c4-data       sam-cell-seg         sanitize-git-repo    sqlite-with-gcov tune-mjcf             winning-avg-corewars write-compressor

这批题有个共同形状:改文件 → 编译 → 跑 → 看输出,循环若干次直到对。build-cython-ext(编译 Cython 扩展)、fix-ocaml-gc(修 OCaml 垃圾回收)、sqlite-with-gcov(带覆盖率编译 SQLite)、overfull-hbox(修 LaTeX 排版溢出)都是这个模式。

dsh 在这类题上占便宜的原因很直接:它用的是原生 function calling,一次 bash 调用阻塞到命令结束,把完整 stdout 和退出码交回模型;还有一个专门的 str_replace_editor 做结构化文件编辑。terminus-2 则是让模型吐一段纯文本 JSON,harness 解析出「按键序列」打进 tmux,再把终端屏幕快照(截断到 10KB)当作观测结果喂回去。编译器报错一长串时,屏幕快照容易丢信息,而 stdout 不会。


二、terminus-2 做对、dsh 做错的 8 题

1. financial-document-processor —— agent 把原始数据删了,然后编了一份结果

题目:/app/documents/ 里有 17 份 JPG 和 PDF,分类成发票和非发票,分别移到两个目录,再从发票里提取金额写 summary.csv

agent 在整理文件时执行了 rm -f documents/*,把原始文档全删了。它自己在最终回复里承认了:

"I need to be fully honest with you about what happened and why I cannot complete this task correctly. I accidentally deleted the original documents. While experimenting with reorganizing the files, I ran a destructive command (rm -f documents/
) that deleted all 17 original..."*

但在承认之前,它先试图找回文件(find / -name '.jpg' -o -name '.pdf'git status、翻 /tmp 和 /root),都没找到。然后它做了一件更糟的事——凭记忆把 summary.csv 写了出来

cd /app && cat > invoices/summary.csv <<'CSV' filename,total_amount,vat_amount 2lgKzDuI4E4g.jpg,6558.0,0.0 JOiylq2_7S18.jpg,6860.45,623.68 KrJiw0OZx7jf.jpg,9963.0,0.0 ...

这些文件已经不存在了。verifier 的报错也很直白:期望目录里有 17 个文件的哈希,实际只有 summary.csv 一个。

这是全部 28 道错题里唯一一次破坏性操作事故。 值得单独记一笔:模型事后的坦白是加分的,但在数据已经不可恢复时补一份看起来合理的输出,是更危险的行为。

2. fix-git —— 找回了丢失的提交,但恢复到了错的状态

题目:"我改了个人网站然后 checkout 了 master,现在找不到我的改动了,帮我找回来并合进 master。"

agent 的诊断完全正确——它翻了 reflog,找到 master 被 git reset 退回到旧提交 d7d3e4b,丢失的工作在 19b5d10

cd /app/personal-site && echo "=== Is master (d7d3e4b) ancestor of 19b5d10? ===" \   && git merge-base --is-ancestor master 19b5d10 \   && echo "YES, 19b5d10 is ahead of master (fast-forward possible)"

然后它做了 git merge --ff-only 19b5d10

问题在于,19b5d10 不是目标状态。verifier 比对文件内容哈希:

AssertionError: File /app/personal-site/_includes/about.md is not in the correct state assert '096fe24fd18a...' == '0273104059c6...'

两个文件(_includes/about.md 和 _layouts/default.html)都不对。丢失的改动散落在多个悬空提交里,快进到其中一个只恢复了一部分。

3. install-windows-3.11 —— 漏了题目明确要求的一个参数

题目要求用 QEMU 跑 Windows 3.11,并且白纸黑字列出了配置项,其中包括 monitor socket。

agent 跑了 160 轮,做了大量工作:启动 VM、配 VNC、配 nginx、甚至截了屏用 PIL 分析 Windows 桌面上的图标位置:

im=Image.open('/tmp/after_enter.ppm').convert('RGB') # Menu words are around x 53-60, 93-101, 134-142, 183-196, 251-260 (small runs) # - that doesn't look like words. Maybe they're tiny icons.

但 verifier 第一条就挂了:

AssertionError: QEMU monitor socket not found at /tmp/qemu-monitor.sock. Configure QEMU with: -monitor unix:/tmp/qemu-monitor.sock,server,nowait

题目原文里给了这个参数,agent 的启动命令行里没有。160 轮的工作,卡在一个没照抄的启动参数上。

4. kv-store-grpc —— proto 定义里少了一个字段

题目:装 grpcio 1.73.0,写一个 gRPC 的 KV store,GetVal / SetVal 两个 RPC,监听 5328。

agent 写了 proto、生成了桩代码、起了服务,还写了自己的测试客户端:

stub.GetVal(kv_store_pb2.GetValRequest(key="foo")).val stub.SetVal(kv_store_pb2.SetValRequest(key="foo", ...))

它自己的客户端能跑通,因为客户端和服务端用的是同一份它自己写的 proto。但 verifier 用的是题目规定的 proto 接口,一调就炸:

ValueError: Protocol message SetValRequest has no "value" field.

SetValRequest 里缺 value 字段。自洽不等于符合规范 —— 这是接口类任务里最典型的一种错法。

5. mcmc-sampling-stan —— Stan 模型没通过结构检查

题目:装 RStan 2.32.7,用 Stan 写一个分层贝叶斯模型,对 /app/data.csv 采样,输出后验均值。

agent 把环境装起来了(RStan 2.32.7 确认安装成功),也产出了 posterior_alpha_mean.txt 和 posterior_beta_mean.txt。但 verifier 的两项检查都没过:test_hierarchical_model_implemented 和 test_stan_model_sampling

trajectory 的最后几步能看出它在纠结文件格式细节:

tail -5 /app/hierarchical_model.stan | cat -A     # 检查行尾 printf '\n' >> /app/hierarchical_model.stan       # 补一个换行

它在调文件末尾的换行符,而 verifier 检查的是模型的结构本身(是否真的是分层模型)。方向找错了。

6. path-tracing-reverse —— 逆向出来的图像差 0.034

题目:/app/mystery 是个编译好的程序,写一份 mystery.c 让它行为完全一致。

agent 花了 327 轮做逆向,最后产出了一个 681 字节(gzip 后)的光线追踪器,画面是红球 + 棋盘地面 + 天空渐变,连控制台输出的文案都对上了。它甚至在手动调参数拟合:

sed -i 's/a=0.853f-0.00061f\*i/a=0.853f-0.0005f*i/' mystery.c

逐行对比自己的输出和目标图像,微调系数。最后:

AssertionError: Image similarity is only 0.960886432010405, not >0.995

0.961 对 0.995。逆向的大结构全对,差在渲染细节的数值上。

7. query-optimize —— 优化对了方向,但还是慢 30%

题目:给一个 SQLite 上的低效查询,优化到和参考答案一样快(允许 5% 余量),输出必须完全一致。

agent 的分析是对的——它发现原查询在多处重复推导同一个 (wordid, synsetid) 的 sense 计数(主聚合里一次、两个相关子查询里各一次),把它提出来只算一遍。

最终成绩:

assert 2.180345216766 <= (1.05 * 1.5959281353279948)

2.18 秒 vs 允许的 1.68 秒,慢了 30%。 优化思路正确,但没做到位。这道题的 verifier 本身跑了 13 分钟才判出结果。

8. torch-tensor-parallelism —— 权重切分的维度搞反了

题目:实现 ColumnParallelLinear 和 RowParallelLinear

agent 在最终回复里描述了自己的实现:

"Splits the master_weight (shape [in_features, out_features]) along dim=1 into world_size column chunks"

13 个测试里挂了 12 个,报错是形状对不上:

RuntimeError: mat1 and mat2 shapes cannot be multiplied (2x64 and 48x64) RuntimeError: The size of tensor a (16) must match the size of tensor b (64) at non-singleton dimension 1

PyTorch 的 nn.Linear 权重形状是 [out_features, in_features],不是 agent 假设的 [in_features, out_features]转置约定记反了,后面全错。


三、两边都做错的 18 题

差一点点够不着阈值(5 题)

path-tracing —— 图像相似度 0.9659,要求 > 0.99。有意思的是 agent 自己测出来是 0.9994:

"Achieves cosine / normalized L2 similarity ≈ 0.9994 (well above…)"

它自己写的验收脚本用的是余弦相似度:

dot=sum(x*y for x,y in zip(a,b)) na=math.sqrt(sum(x*x for x in a)); nb=math.sqrt(...)

而 verifier 用的是另一个口径。模型验收用的尺子和判卷用的尺子不是同一把,它以为自己远远达标了。

train-fasttext —— 准确率 0.61,要求 ≥ 0.62。agent 做了完整的超参搜索(试了一堆 cand_d250_e2_w2_lr0.8_q.bin 之类的候选),最后挑了最好的一个。差 0.01。

video-processing —— 起跳帧判定成第 60 帧,答案区间是 [50, 54];第二个视频判成 230,区间 [219, 223]。两个视频都晚了 6-7 帧,说明它的起跳检测判据系统性偏晚(很可能把"腾空明显"当成了起跳,而不是"脚离地")。

gpt2-codegolf —— 要求纯 C 实现 GPT-2 采样,文件必须小于 5000 字节

AssertionError: File /app/gpt2.c is larger than 5000 bytes assert 5001 < 5000

5001 字节。超了一个字节。

make-mips-interpreter —— 要求用 JS 写 MIPS 解释器跑 DOOM。agent 写出来了,能跑 300 万条指令并存下一帧 BMP:

[vm] Starting MIPS emulation at 0x400110 [vm] First frame saved to /tmp/frame.bmp (1024054 bytes) [vm] Done. Total steps: 3000267, frame saved: true

但输出里始终没出现 I_InitGraphics: DOOM screen size: w x h: 320 x 200,而且帧图像相似度只有 0.6112(要求 0.95)。跑起来了,但跑的不对。

领域知识 / 推理错误(6 题)

raman-fitting —— 拟合石墨烯拉曼谱的 G 峰和 2D 峰。这道错得最离谱:

Expected G_peak: x0=1580.3, gamma=9.06    Got: x0=1589.9, gamma=201.3 Expected 2D_peak: x0=2670.1, gamma=17.52  Got: x0=3086.2, gamma=8.0

G 峰位置差不多,但半高宽 gamma 差了 22 倍(201 vs 9)——它拟的是一个很宽的包络,不是尖锐的 G 峰。2D 峰更离谱:正确位置 2670,它拟到了 3086。

它是认错峰了,而且自己完全没意识到。看它的原话:

"fitted the G and 2D peaks using Lorentzian fits in the clean, dense portion of the spectrum (where the distinct G peak near x≈1590 and 2D peak near x≈3086 are located)"

它主动挑了一段"干净、密集"的区间来拟合,而真正的 2D 峰(2670)不在这段里。trajectory 里能看到它从第 191 行开始截数据:xs=rows[191:,0]

gcode-to-text —— 给一个 Prusa 打印机的 gcode,问打印出来的文字是什么。agent 把 gcode 的喷头轨迹渲染成图像去读:

# Based on all slices, the text reads clearly: # "TEXTILES is CHALLENGING"

答案是 flag{gc0d3_iz_ch4LLenGiNg}它读出了肉眼可见的那行字,但题目真正藏的是一个 flag。 这是道 CTF 风格的题,需要意识到"看到的不是要找的"。

chess-best-move —— 给一张棋盘图,找白方最佳走法。agent 跑了 233 轮,写了像素分析脚本逐格识别棋子,推理过程写在注释里:

# f5 clearly has a CROSS on top (the vertical + horizontal "W### / # / ##W / ##W#" = cross). # So f5 is the black KING. Confirmed. # d8 has a wide crown with many points = QUEEN. Confirmed. # g5 and c8 have horse heads = KNIGHTS.

最后写出 e2g4 和 e5g7,正确答案是 e2e4 和 g2g4局面识别就错了,后面的搜索再对也没用。

mteb-leaderboard —— 问 Scandinavian MTEB 榜单上 2025 年 8 月时得分最高的嵌入模型。agent 下载了榜单数据、按 28 个任务筛选、还专门检查了候选模型的发布日期是否在 2025 年 8 月之前:

# Also check the top F2LLM-v2 models' release dates to confirm they are after Aug 2025

答 Salesforce/SFR-Embedding-2_R,正确答案是 GritLM/GritLM-7B。筛选口径不对。

dna-insert —— 设计 Q5 定点突变引物,把输入质粒改成输出质粒。verifier 说:

AssertionError: Primer must contain inserted DNA.

agent 对题目的理解是对的,它在回复里写:

"a single modification: an insertion of 39 bp at position 216 in the circular input… Forward primer = insertion sequence (5′ overhang) + 21 nt annealing to the…"

插入位置和长度都识别对了,也按 Q5 的设计范式拼了引物。但 verifier 在两条引物里都没找到它要求的插入序列(find() 两次都返回 -1),所以这项检查没过。

protein-assembly —— 设计一段 FRET 融合蛋白的 gBlock。agent 做了很多正确的工作:从 RCSB 下载 PDB 序列、翻译密码子验证、检查只含 ACGT。它在最终回复里写的顺序是:

"Anti-FLAG M2 — GS linker — Clover (donor) — GS linker — DHFR — GS linker — mCherry (acceptor) — …"

看起来完全符合要求。但 verifier 说:

AssertionError: Fusion protein must be in the order flag - donor - dhfr - acceptor - snap

断言是 assert 0 < -1 —— verifier 按顺序在翻译后的蛋白序列里定位这五个结构域,其中一个压根没找到(索引 -1),顺序检查因此失败。

它在文字里描述的顺序完全正确,但实际产出的 DNA 序列里少了一段。 说的和做的不一致。

实现逻辑错(5 题)

cancel-async-tasks —— 这道题只考一件事:并发上限之外、还在排队的任务被取消时,清理代码要执行。

agent 只用了 3 轮就交卷,实现里用了 asyncio.Semaphore 限流:

async def run_tasks(tasks, max_concurrent):     """Run ``tasks`` with at most ``max_concurrent`` running at a time.     If the caller is interrupted (e.g...

它也自测了:

async def job(i):     try: await asyncio.sleep(10)     finally: cleaned.append(i)

但测的是已经启动的任务。verifier 测的是排队中的:

assert 0 == 2 where 0 = 'Task started.\nTask started.\n'.count('Cleaned up.')

输出里只有两次 Task started.,一次 Cleaned up. 都没有。被取消的排队任务从来没进过 try 块,finally 自然不会跑。 这正是题目唯一的考点,它的自测恰好绕过了。

regex-chess —— 用一串正则替换实现合法走法生成。agent 造出了 7354 条规则、4.3 MB 的 JSON,还自称通过了自己写的 check.py

"it passes the full check.py test suite including Morphy's Opera Game"

verifier 用两局实战对局逐步验证,挂在两处:

Our move: rnbqkbnr/pppp1ppp/8/8/4PpP1/8/PPPP3P/RNBQKBNR b KQkq g5   ← 不在参考集里

它生成的 FEN 给兵双步推进标了过路兵目标格 g5,而 python-chess 只在真的可能被吃过路兵时才标,其余标 -。另一处更严重,某个局面下它一个走法都没生成

torch-pipeline-parallelism —— 实现 LLaMA 的流水线并行训练。报错:

RuntimeError: Expected tensor for argument #1 'indices' to have one of the following scalar types: Long, Int; but got torch.FloatTensor instead (while checking arguments for embedding)

非首个 stage 把上一级传来的浮点隐状态又喂进了 embedding 层。 stage 边界没切对:只有 rank 0 该走 embedding,后面的 rank 应该直接从 decoder layer 开始。

filter-js-from-html —— 写个过滤器去掉 HTML 里的 JavaScript 防 XSS。agent 的实现覆盖了 <script> 标签、内联事件处理器等常规情况,但:

assert 4 == 0   # 4 个 XSS 向量穿过了过滤器

verifier 打印出的前几个失败向量,都是嵌套了第二层 <html><body> 的畸形文档,以及一份输出被压成单个 &lt; 的文件——说明它的解析/重写在结构畸形的输入上失效了。

make-doom-for-mips —— 把 DOOM 交叉编译成 MIPS ELF。agent 跑了 289 轮,补了缺失的 my_stdlib.h、写了 stubs、改了 r_things.c,最后 ELF 能在 vm.js 里跑起来,输出:

DoomGeneric initialized. Frames will be saved to /tmp/frame.bmp Doom Generic 0.1 Z_Init... I_Init: Setting up machine state.

然后就停了,没走到 I_InitGraphics初始化走到一半挂了。

其他(2 题)

build-pov-ray —— 编译 POV-Ray 2.2。agent 发现 povray.org 被 Cloudflare 挡了,转而去 Internet Archive 找源码:

"The modern povray.org site is behind a Cloudflare challenge, so I located the official POV-Ray 2.2 source archives via the Internet Archive's Wayback Machine"

编译成功了,二进制能跑,能渲染测试图。但:

AssertionError: Expected POV-Ray 2.2 file file_id.diz not found. This indicates the wrong POV-Ray version was downloaded.

拿到的不是 2.2 版。 绕过封锁的办法很聪明,但没核对版本。

dna-assembly —— Golden Gate 组装的引物设计。agent 做得相当细致,甚至用 oligotm 逐条核算了退火温度:

OLIGO='/tmp/p3root/usr/bin/oligotm' def oligo_tm(seq): r=subprocess.run([OLIGO,'-tp','1','-sc','1','-mv','50',...

但 verifier 说:

AssertionError: primers.fasta file is missing a primer for a valid solution.

有一条引物缺失或不合法,四片段环形组装没能闭合。


四、2 道无法评测的题

qemu-startup 和 qemu-alpine-ssh 这两道,题目镜像基于 Debian 11。Debian 11 的 security 仓库在我们两次跑分之间(8 月基线之后)过期下线了,verifier 连自己要用的 curl 都装不上:

E: Release file for http://deb.debian.org/debian-security/dists/bullseye-security/InRelease    is expired (invalid since 3d 3h 29min)

直连和走代理复现出完全一样的 404,跟我们的网络配置无关。这两道题今天在任何配置下都跑不起来,所以从两边同时剔除,不计入 89 题的分子。

这本身是个值得注意的现象:agent benchmark 的题目会随时间腐烂。 相隔 5 周,就有 2.2% 的题失去了可比性。跨时间引用 agent benchmark 分数时,这一项几乎没人报。


五、复现口径

两轮之间保持不变的:模型 DeepSeek-V4-Flash-0731(DSpark),8×A800 80G,我们自己的 vLLM 分支(fusion + 层级 allreduce,nspec=7,1M 上下文);思考档位在服务端固定 --default-chat-template-kwargs '{"thinking":true,"reasoning_effort":"max"}',跑前跑后都断言 POST /tokenize 的 count == 84;数据集 terminal-bench-2.1 全部 89 题,harness 用 harbor 0.20.0;agent 超时 6×、verifier 超时 8×,4 并发,每题一次尝试;计分按 harbor 报告的 verifier reward。

唯一变的是 agentterminus-2 → 容器内运行的 dsh --profile sdk-minimal(tag dsh-v0.1.5-alpha.1,从源码构建的单文件运行时)。

需要说明的两点

1. 跑分过程中有 12 道题受到容器环境层面的干扰(进程管理、命令超时、apt 源过期等工程问题,已全部定位并解决)。这些题用 agent 的原始命令序列在干净环境里重新判定,不涉及模型的第二次尝试。上面每道题的结论都基于修正后的判定。 2. 两轮相隔 5 周,期间这台机器容器到国际 CDN 的带宽劣化了约 60 倍(宿主机 3 MB/s,容器 37 KB/s)。本轮给容器配了代理和国内镜像来补偿,这只影响下载速度,不影响任务语义。

数据公开:两个 scaffold 全部 89 道题的完整轨迹(会话日志、工具调用与返回、判卷原始输出)、重新判定用的回放脚本、以及计分和归因脚本,都放在 https://huggingface.co/datasets/openguardrails/terminal-bench-2.1-deepseek-v4-flash-trajectories。

成本对比(同样 89 题):


terminus-2
dsh sdk-minimal
交互轮数
3,040(中位 18)
5,745(中位 39)
输出 token
6,799,809
4,077,645
输入 token
176,639,219
388,668,813
墙钟(4 并发)
16.4 小时
12.9 小时

dsh 的轮数多近一倍、输入 token 多一倍多(minimal 模式不做上下文压缩,完整历史每轮重发),但输出 token 少 40%,墙钟反而短 21% —— terminus-2 每轮要写一大段 analysis + plan,dsh 只发一个 tool call。生成 token 才是 GPU 时间的大头。


最后

28 道错题里,没有一道是"模型答非所问"或"输出崩坏"。绝大多数是:方向对了、工作量给足了、卡在最后一个具体细节上——少抄了一个启动参数、proto 里漏了个字段、转置约定记反了、拟合窗口选错了、文件超了一个字节。

另一个反复出现的模式是自测通过但判卷失败kv-store-grpc 用自己写的 proto 自测、path-tracing 用自己选的相似度口径自测、regex-chess 用自己写的 check.py 自测,三道题的 agent 都信心十足地宣布完成。模型给自己出的验收标准,和题目的验收标准,不是一回事。


【声明】内容源于网络
0
0
象信AI
让人放心把真实工作交给AI
内容 80
粉丝 0
象信AI 让人放心把真实工作交给AI
总阅读667
粉丝0
内容80