前端进阶之旅前端进阶之旅
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片NEW
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 业务场景题真实业务问题与追问
  • 查漏补缺常见问题解析
  • AI 模拟面试NEW模拟真实面试 + 报告
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
    • AI 定制路线NEW按你的简历现排
    • AI 知识地图NEW串起全站知识点
  • 动态
    • AI 热点NEWAI 每日动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
AI 助手NEW
旧版
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片NEW
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 业务场景题真实业务问题与追问
  • 查漏补缺常见问题解析
  • AI 模拟面试NEW模拟真实面试 + 报告
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
    • AI 定制路线NEW按你的简历现排
    • AI 知识地图NEW串起全站知识点
  • 动态
    • AI 热点NEWAI 每日动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
AI 助手NEW
旧版
返回 AI 情报前线
All News · 全部资讯8336
  • Perplexity 用 GPT-6 Astra 接管端到端系统
  • OpenAI 用 AI 写代码再用 AI 审查:Codex 安全门禁实践
  • 生产环境 LLM 推理性能与可靠性优化实战
  • 多 AI 协作必须设计交接机制而非仅靠上下文
  • deepseek-harness 体验:22 万星的开源 AI 插件框架
  • Cognition 发布 SWE-2:低成本对标 Fable 5.1 的代码模型
  • 边缘 AI 部署:LLM 优化最佳实践
  • 边缘设备 LLM 扩展:完整技术指南
  • VS Code 1.137:AI 自动化、语音模式与 GitHub 深度集成
  • Real-SWE:基于私有企业代码库的 AI 模型基准测试
  • OpenResearch:本地优先的多 Agent 研究工作台
  • Check:给 Claude Code 加幻觉防护层
  • Postman 集合一键转为 MCP 工具:实操路径
  • NestJS 测试覆盖提升与安全加固实战
  • Next.js Serverless 下 PDFKit 字体缺失修复
  • 评测编码Agent前,先用同一组任务跑两遍
  • LLM Wiki:文档自动构建可维护知识库的开源桌面应用
  • 深入解析结构化输出:让 AI 生成绝对可解析的 JSON
  • MCP安全核心是权限体系重设计,而非传统边界防护
  • GPT-6 Astra 在机器人基准测试中展现空间推理飞跃
  • Auterix:零依赖通用协议,跨 21 个 AI 工具统一上下文规范
  • 后量子 TLS 是平台迁移工程,不是密码学研究
  • Anthropic 发布 AI-Native SDLC 实践手册:代码不再是瓶颈
  • OpenAI 建议 GPT-6 Astra 提示词应精简,减少安全限制
  • Claude Code 创始人:AI 编程要守住代码质量标准
  • Hyperresearch:Agent 驱动的研究知识库,单次跑 250+ 信源
  • 12 个已落地的 B2B 营收 AI Agent 用例,附代码
  • LLM 项目上线后才会暴露的 6 个隐蔽 Bug
  • OpenAI 代理向 RubyGems 上传两千恶意包
  • AI 时代缓存失效难题复发:LLM 推理的隐性成本
  • Google发布TimesFM-3:单次前向传播即可完成多步时间序列预测
  • 阿里 Qoder CLI 开放自定义模型接入
  • 开源项目 Minitap 指控谷歌盗用代码用于 Artemis,许可证违规引热议
  • GPT-6 Astra 刷穿 FrontierMath Tier 4,AI 数学能力达新里程碑
  • Kimi K2.8发布:性能逼近K3百万上下文全员开放
  • DeepSeek v4.1-Flash发布:763B参数新型因果编解码架构
  • AI Agent 何时该停:成本控制的核心工程问题
  • 三大AI编程工具实战对比:Claude Code六个月生产级使用报告
  • Trail of Bits开源Coop:用隔离VM安全运行Claude Code和Codex
  • OpenAI代理今年5月攻击RubyGems详情披露
  • Google Tunix:TPU上的自主LLM后训练框架
  • GitLab CVE-2026-85706:CVSS 10.0 路径遍历漏洞正被主动利用
  • RAG 检索失效的根源:分块策略正在毁掉你的 AI 应用
  • CPython 字节码缓存导致测试失效的隐藏bug
  • OpenAI代理攻击RubyGems:技术细节与行业反思
  • Anthropic 内部调查:七成公司无法衡量 AI 工具实际回报
  • 已加载 46 / 8336
8.0
热点
AI SCORE
编程提效2026-09-13 01:33

评测编码Agent前,先用同一组任务跑两遍

dev.to · AI#AI评测#Coding Agent#基准测试
Editor brief · 编辑速览

提出一套可复现的编码Agent评测方法论:固定任务集、相同fixture、相同超时时间,避免把「修好了」和「改崩了」都算成赢。

文章思维导图
Knowledge map
拖拽缩放
Full translation

完整中文译文

你把两个 coding agent 的评分丢进周五评审。一张 PPT 写 71%,另一张写 68%。有人问该继续付费哪个技术栈,会议室瞬间安静——因为没人能说出那个百分号背后的单位是什么。

一个任务是一次失败测试、一个代码仓库,还是一次偷偷重试了一整夜的对话?如果你明天无法用完全相同的 24 个任务重新跑一遍并落在极小的漂移区间内,那就不是基准,只是一张截图。

这篇文章是一套你可以自己运行的方法论。它不是排行榜。它不会告诉你哪个模型"最好"。它会告诉你某次比较是否站得住脚。

从一个场景开始,而非一个指标

想象一个结账服务,其中有条促销规则不太稳定。你给 Agent A 和 Agent B 相同的失败测试、相同的 fixture 文件、相同的计时器。Agent A 修改了三个文件,测试变绿。Agent B 重写了一个辅助函数,测试还是红,然后第二次尝试删掉一条断言后通过了。

如果你的记分板把两种情况都算作胜利,你就混淆了"修复"和"破坏预言机"。市场喜欢这种混合。你不应该。

在写任何一个数字之前,先定义清楚三个对象。

数据集:一组冻结的任务切片,每个任务包含一个 fixture 目录和一条隐藏的测试命令。

预言机:决定 green 的那条精确命令,加上它被允许读取的文件的校验和。

分析单元:一次尝试对应一个任务,而不是一次拥有无限重试次数的对话。

这三个东西没有固定之前,通过率只是一种情绪。

构建一个你可以真正重放的 24 任务切片

你不需要 500 个任务才能做到诚实。你只需要一组小到能在一台机器上跑两遍的切片。24 个足够让你感受到方差,又小到能手工阅读每一个失败。

使用这样的目录结构:

slice24/
  TASKS.md
  controls.yaml
  tasks/
    T01_discount_rule/
      prompt.md
      repo/
      oracle/
        test_discount.py
        sha256.txt
    T02_date_parse/
      ...
  runs/
    replay_a.jsonl
    replay_b.jsonl

TASKS.md 是人类合约。每一行用一句话描述一个 bug、所使用的语言,以及预言机是否被允许查看 agent 可能编辑的生产文件。如果预言机读取了 agent 可以重写的文件,你的"通过"是不可信的。

刻意保持切片枯燥无聊。选用你能在白板上解释的 bug:off-by-one、时区解析、nil map、错误的状态码、缺失的唯一索引。任何需要联网的都跳过。任何 gold patch 已在公开训练数据集中而你无法审计的都跳过。

一张决策表有助于你在任务混入切片之前就拒绝它。

如果某一行没有通过那张表,它就不进入 tasks/。它不会有脚注。它被剔除。

像对待数据集的一部分一样固定 controls

没有 controls 的数据集只是一堆 prompt 倾倒。先写 controls.yaml,然后在 bake-off 期间拒绝修改它。

# Proposal: example controls for a 24-task replay slice.
# Label this as a template until you fill every field on your machine.
slice_id: slice24-checkout-2026-09-13
unit_of_analysis: one_attempt_per_task
max_attempts: 1
wall_clock_sec: 180
cpus: 2
memory_mb: 2048
network: denied
writable_paths: ["repo/"]
oracle_cmd: "python -m pytest oracle/ -q"
oracle_sha256_file: oracle/sha256.txt
seed_policy: fixed
language_toolchain: "python3.11"
forbidden_edits: ["oracle/", "controls.yaml"]
replay_required: 2
max_replay_drift: 0

大声把那个文件读出来。重要的行是 max_attempts、network 和 replay_required。一次尝试意味着你在给第一个 patch 打分,而不是人类守着循环让 agent 跑出最佳 patch 后的分数。denied network 意味着 agent 不能去网上找答案。两次重放且允许漂移为零意味着环境是一台科学仪器,而不是某天下午恰好空闲的一台笔记本。

如果你后来把 max_attempts 从 1 改到 3,你就开启了一项新的研究。不要把这些运行追加到旧的 JSONL 上面然后称之为更新。

给配对差值打分,而不是一个标题百分比

你仍然会计算通过数。你不会用它来开场。

对于每个任务 t,存储四个事实:

pass_a:Agent A 的尝试让固定的预言机变绿则为 1

pass_b:Agent B 做到了则为 1

oracle_intact:预言机/仍然匹配 sha256.txt 则为 1

replay_match:该 agent 的第一次尝试和第二次尝试一致则为 1

然后报告配对情况:

A 获胜: A 通过且 B 未通过,预言机完好

B 获胜:反过来

平局:都通过或都未通过

无效:预言机被篡改、超时不一致、或重放不匹配

无效不是失败。无效是仪器坏了。如果 24 个任务中有超过两个无效,停止排名,去修测试工具。

你可以引用的数字很窄:"在 slice24 上,一次尝试加一个冻结预言机,A 赢了 5 次,B 赢了 3 次,14 次平局,2 次无效。"这句话很丑陋。但这恰恰是很难被拿来做广告的原因。

一个你可以跑两遍的测试工具

下面是带标注的提案。它不声称有生产级指标。把 run_agent 替换成你真正的 CLI。保留预言机检查。如果你跳过校验和,文件的其余部分就是表演。

# proposal_harness.py — replay gate for a 24-task slice
from __future__ import annotations

import hashlib, json, subprocess, time
from pathlib import Path

SLICE = Path("slice24")
WALL_CLOCK = 180

def sha256_tree(root: Path) -> str:
    h = hashlib.sha256()
    for p in sorted(root.rglob("*")):
        if p.is_file():
            h.update(p.relative_to(root).as_posix().encode())
            h.update(p.read_bytes())
    return h.hexdigest()

def oracle_intact(task: Path) -> bool:
    expected = (task / "oracle" / "sha256.txt").read_text().strip()
    return sha256_tree(task / "oracle") == expected

def run_oracle(task: Path) -> bool:
    proc = subprocess.run(
        ["python", "-m", "pytest", str(task / "oracle"), "-q"],
        cwd=task / "repo",
        capture_output=True,
        timeout=WALL_CLOCK,
    )
    return proc.returncode == 0

def run_agent(agent_id: str, task: Path) -> None:
    prompt = (task / "prompt.md").read_text()
    # Replace this stub with your agent CLI. Keep the timeout.
    subprocess.run(
        ["your-agent", "--id", agent_id, "--prompt", prompt, "--cwd", str(task / "repo")],
        timeout=WALL_CLOCK,
        check=False,
    )

def one_attempt(agent_id: str, task: Path) -> dict:
    if not oracle_intact(task):
        return {"task": task.name, "void": "oracle_before"}
    t0 = time.monotonic()
    run_agent(agent_id, task)
    elapsed = round(time.monotonic() - t0, 3)
    if not oracle_intact(task):
        return {"task": task.name, "agent": agent_id, "void": "oracle_mutated", "sec": elapsed}
    passed = run_oracle(task)
    return {"task": task.name, "agent": agent_id, "pass": int(passed), "sec": elapsed, "void": None}

def replay_agent(agent_id: str) -> list[dict]:
    rows = []
    for task in sorted((SLICE / "tasks").iterdir()):
        first = one_attempt(agent_id, task)
        second = one_attempt(agent_id, task)
        if first.get("pass") != second.get("pass") or first.get("void") or second.get("void"):
            rows.append({"task": task.name, "agent": agent_id, "void": "replay_drift"})
        else:
            rows.append(first)
    return rows

def paired_report(a: list[dict], b: list[dict]) -> dict:
    by_a = {r["task"]: r for r in a}
    wins = {"A": 0, "B": 0, "tie": 0, "void": 0}
    for r in b:
        t = r["task"]
        left, right = by_a[t], r
        if left.get("void") or right.get("void"):
            wins["void"] += 1
        elif left.get("pass") and not right.get("pass"):
            wins["A"] += 1
        elif right.get("pass") and not left.get("pass"):
            wins["B"] += 1
        else:
            wins["tie"] += 1
    return wins

if __name__ == "__main__":
    a_rows = replay_agent("A")
    b_rows = replay_agent("B")
    Path("slice24/runs/replay_a.jsonl").write_text(
        "\n".join(json.dumps(r) for r in a_rows) + "\n"
    )
    Path("slice24/runs/replay_b.jsonl").write_text(
        "\n".join(json.dumps(r) for r in b_rows) + "n"
        if False else "\n".join(json.dumps(r) for r in b_rows) + "\n"
    )
    print(json.dumps(paired_report(a_rows, b_rows), indent=2))

刻意跑两遍。外层的 replay_agent 已经把每个任务跑了两遍。但你仍然应该在重启后重新启动整个流程。如果 JSONL 变了,那你的机器也是分数的一部分。在争论模型之前先修好机器。

调试这个仪器时的有用命令:

find slice24/tasks -name sha256.txt -print
python -m pytest slice24/tasks/T01_discount_rule/oracle -q
sha256sum slice24/controls.yaml
python proposal_harness.py
diff -u slice24/runs/replay_a.jsonl slice24/runs/replay_a.jsonl.bak

如果 diff 不为空,你不讨论 Agent A 对比 Agent B。你讨论时钟、缓存和 pytest 插件。

为什么这些数字不是市场营销

供应商的 PPT 要的是一个百分比和一个大胆的赢家。这个切片在四个方面拒绝那样做。

第一,n 等于 24 个配对任务,而不是 24 次独立的抛硬币。有几个任务会共享一种语言和一种 bug 风格。你仍然可以数胜数。你不能假装你做的是人口研究。

第二,单元是一次尝试。隐藏的重试、超时后的额外工具调用、以及"我在对话中推了它一下"都是协议违规。它们属于另一篇论文。

第三,无效任务是存在的。市场把它们吸收进分母或者直接丢弃。你把它们暴露出来。一个不能在公开场合失败的方法不是方法。

第四,重放漂移是停止条件,不是脚注。如果同一个 agent 在同一个 fixture 上从通过/失败翻转了,分数就是环境噪音。在噪音上发布均值是排行榜腐化的方式。

你可以后续加上成本。你可以后续加上失败分类。在重放变得无聊之前这些都不合法。

免费服务器实际上在哪里有帮助

方法论工作在脚手架上烧 token:broken prompts、oracle 错误、路径 bug。这些流量不应该接触生产预算。

披露:本文是 MonkeyCode 产品推广的一部分。如果你需要模型访问和一台不需要自己搭建 GPU 的机器,MonkeyCode 的免费模型访问和免费服务器选项足以托管这个 24 任务切片,同时你可以在此期间加固测试工具。只用这个来跑重放循环。任何你想展示给财务团队的结论,都要迁移到你控制的硬件和你可以校验的切片上。

这就是整个产品说明。

局限性,以及谁不应该使用这个

这种方法对于几个正经的工作是错误的。

不要用 24 任务切片来选一个公司级的 coding agent。区间太宽、任务都是本地的、语言覆盖很薄。不要用它来做超过几小时的重构、GUI 工作或任何需要公网的东西。如果你的预言机是"审阅者喜欢这个 patch",不要用它。人类口味不是 sha256。

不要比较不共享同一工具表面的 agent。如果 Agent A 可以跑 pytest 而 Agent B 只能输出一个 diff,你测的是工具链。说出来,或者停下。

不要在没有 controls 文件、slice id、无效数量和重放规则的情况下发布通过数。没有这四样的数字只是一个图注。

如果你的目标是周一就能发新闻稿,这个工作流会拖慢你。这就是重点。排名很便宜。重放是过滤器,让你不会买到一个坐不住的百分比。

Original source

本文由 AI 翻译整理自 dev.to · AI,原文版权归原作者所有。

阅读英文原文
上一篇
Next.js Serverless 下 PDFKit 字体缺失修复
下一篇
LLM Wiki:文档自动构建可维护知识库的开源桌面应用