前端进阶之旅前端进阶之旅
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
小程序题库
  • 每日一题每天一道,攒手感
  • 原理篇React / Vue 源码拆解
  • 知识卡片NEW碎片时间过考点
  • 历年面经按年份追踪真实考点
  • 算法题库在线编码即时判题
  • 专项自测100 题快速查漏
  • 业务场景题真实业务问题与追问
  • 查漏补缺常见问题解析
  • AI 模拟面试NEW模拟真实面试 + 报告
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
    • AI 定制路线NEW按你的简历现排
    • AI 知识地图NEW串起全站知识点
  • 动态
    • AI 热点NEWAI 每日动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
AI 助手NEW
旧版
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
小程序题库
  • 每日一题每天一道,攒手感
  • 原理篇React / Vue 源码拆解
  • 知识卡片NEW碎片时间过考点
  • 历年面经按年份追踪真实考点
  • 算法题库在线编码即时判题
  • 专项自测100 题快速查漏
  • 业务场景题真实业务问题与追问
  • 查漏补缺常见问题解析
  • AI 模拟面试NEW模拟真实面试 + 报告
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
    • AI 定制路线NEW按你的简历现排
    • AI 知识地图NEW串起全站知识点
  • 动态
    • AI 热点NEWAI 每日动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
AI 助手NEW
旧版
返回 AI 情报前线
All News · 全部资讯8294
  • AI Agent 大规模利用 PaperCut 漏洞攻陷 395 家机构
  • Copilot 代码审查新增自动关闭评论与智能提交信息
  • n8n详解流程编排:执行模型、可观测性与生产挑战
  • Reflection 模式:AI Agent 在生产环境的自我纠错实践
  • AWS 双层方案监控生产环境 Agent 生命周期
  • 选对 Bedrock 上的 OpenAI 模型:超越每百万 token 价格
  • 用 Bedrock AgentCore 构建支持交互组件的 MCP 应用
  • 2026 Agentic AI安全警示:模型越狱与网络突破
  • 万级Agent集群架构实战:10万次编排背后的工程方法论
  • Anthropic内部标准:生产代码的AI辅助应有更高门槛
  • 陶哲轩等数学家联名批评 AI 数学推理的严重错位问题
  • 陶哲轩:AI 数学推理的严重错位
  • Hugging Face安全Txt暗藏AI伦理考题
  • Next.js Copilot安全设计审查清单
  • Agent PR中的内存缓存——代码审查的盲区
  • 一次 stamping:约束AI Agent范围的工程方法
  • AI生成的C++补丁为何在Release版崩溃
  • 本地优先Agent的四个信号决策门
  • AI Agent记忆 vs RAG:核心区别与工程选择
  • AI代码审查的签署人制度SOP
  • 用「每修复成本」替代通过率评估AI Agent
  • Agent「修复成功」但进程从未退出引发的生产事故
  • 面试AI编程能力应先评估「循环预算」
  • 部署 AI 推理网关前,先查队年龄龄而非面板利用率
  • WAF 拦截日志拷进 AI 助手?Cookie 和 token 也一起泄露了
  • 给无人值守 AI Worker 配一张 JSON 检查卡
  • Anthropic 报告:黑客用 Claude 开发导弹与无人机,中国实验室批量挖掘训练数据
  • 律师用ChatGPT生成上诉文书虚构证人证词,被罚5000美元
  • Claude Code Hookbook:20 个开箱即用的 Claude 钩子库
  • OpenAI如何扩展存储架构支撑10亿ChatGPT用户
  • 每天为同一段上下文付三次钱:Agent 记忆缺失的代价
  • OpenAI Agents API公开测试:Codex同款基础设施向开发者开放
  • Vercel开源skills:AI编程智能体技能共享生态
  • OmniRoute:聚合352个AI服务商免费额度的开源网关
  • DeepSeek V4.1 Flash发布:提供商别名路由与890B缓存的代价
  • DeepSeek Flash搅局:MoE架构将百万token成本打至新低
  • AI生成支付代码的五大安全漏洞与防护策略
  • Sakana AI推出Fugu Max/Ultra v2,主打多Agent编排降本
  • Google 发布 ToolGrad:先建 API 链再写 Query,ToolBench 通过率 99.8%
  • OpenAI GPT-Live-1 API支持实时语音交互
  • 美团Agent评测白皮书:评测体系全览
  • Apify MCP服务器让AI实时获取电商数据
  • 语音AI延迟从4.2秒压到780ms:逐字优化实录
  • Datasette紧急安全补丁:AI辅助审计发现多个微妙漏洞
  • DevOps AI Agent 审计追踪:关联每次 kubectl 与 Git 操作
  • AI 写的 PR 测试全绿:你的合并标准是什么
  • 放 AI Agent 进仓库前必须锁死的五项配置
  • LLM API 重试逻辑:官方 SDK 只做了一半
  • 生产环境微调对比:Claude vs GPT vs Llama 实操指南
  • Claude AI用11天完成费马大定理机器证明,代码1300万行
  • 面向 AI Agent 的 24 端点 URL 元数据 API
  • 已加载 51 / 8294
8.0
热点
AI SCORE
编程提效2026-09-11 23:20

用「每修复成本」替代通过率评估AI Agent

dev.to · AI#AI Agent#效能评估#工程度量
Editor brief · 编辑速览

通过率alone是宣传材料,需引入cost-per-resolved-task和置信区间来公平评估不同Agent的真实效率。

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

完整中文译文

你走进同一个会议——一整年都在消耗对编程 Agent 的评审。两个测试框架跑同一套四十个任务。Agent A 打出 62.5% 已解决。Agent B 打出 57.5%。有人已经把 A 放进了 PPT。

然后账单来了,或者 GPU 时长,或者队列延迟。A 把测试运行器循环了,把同一个文件重写了三遍,最后还是需要人工合并。B 失败的任务更多,但凡通过的,就是一次过。

如果你只发布通过率,你发布的只是一份宣传册。按每个已解决任务的成本来排名,置信区间重叠时就拒绝宣布赢家。下面的数字是一个工作示例,不是一份实验报告。

PPT 隐藏的排名

通过率回答的是一个问题:套件变绿了没有。它不回答 Agent 烧了多少工作量才到达那里。它不会告诉你这个三分差距在换一个 seed 后是否还能保持。

热点言论一直在声称编程 Agent 已经超越大多数开发者。在协议能同时展示成本单位和不确定性之前,把这些说法当作不可信的。你需要两者兼备,否则你只是在排名感觉。

如果钱是考量因素,就冻结一份价格表。即使账单为零,也要冻结 token 计数和墙上时间。在免费端点上,token 和秒数仍然是稀缺资源。

账本必须记录什么

不要从仪表盘开始。先从每次任务尝试的一条 JSONL 行开始。如果某个字段缺失,你就没有资格引用排名。

  • run_id、agent_id、task_id、seed
  • resolved:来自冻结校验器的布尔值,而不是模型的自报告
  • prompt_tokens、completion_tokens、tool_calls
  • wall_ms:在厂商的流之外测得
  • price_table_id:以便后续读者看到你用了哪套费率
  • notes:记录人工合并、跳过测试、或测试框架崩溃

把货币成本作为派生列保存。把 token 乘以冻结的费率表。如果表里全是零(因为你用了免费模型),你仍然按 token 和墙上时间排名。零美元不等于零工作量。

一份无需 API key 就能打分的示例包

把这份数据标注为说明性的。八行,两个 Agent,四个任务。有意做小。重点是方法,不是排行榜。

{"run_id":"r1","agent_id":"a","task_id":"t1","seed":7,"resolved":true,"prompt_tokens":1800,"completion_tokens":900,"tool_calls":4,"wall_ms":14000,"price_table_id":"local-0"}
{"run_id":"r1","agent_id":"a","task_id":"t2","seed":7,"resolved":true,"prompt_tokens":4200,"completion_tokens":3100,"tool_calls":11,"wall_ms":41000,"price_table_id":"local-0"}
{"run_id":"r1","agent_id":"a","task_id":"t3","seed":7,"resolved":false,"prompt_tokens":5100,"completion_tokens":4400,"tool_calls":14,"wall_ms":56000,"price_table_id":"local-0"}
{"run_id":"r1","agent_id":"a","task_id":"t4","seed":7,"resolved":true,"prompt_tokens":2600,"completion_tokens":1200,"tool_calls":5,"wall_ms":18000,"price_table_id":"local-0"}
{"run_id":"r1","agent_id":"b","task_id":"t1","seed":7,"resolved":true,"prompt_tokens":900,"completion_tokens":400,"tool_calls":2,"wall_ms":8000,"price_table_id":"local-0"}
{"run_id":"r1","agent_id":"b","task_id":"t2","seed":7,"resolved":false,"prompt_tokens":1600,"completion_tokens":800,"tool_calls":3,"wall_ms":12000,"price_table_id":"local-0"}
{"run_id":"r1","agent_id":"b","task_id":"t3","seed":7,"resolved":true,"prompt_tokens":1100,"completion_tokens":500,"tool_calls":2,"wall_ms":9000,"price_table_id":"local-0"}
{"run_id":"r1","agent_id":"b","task_id":"t4","seed":7,"resolved":false,"prompt_tokens":1500,"completion_tokens":700,"tool_calls":4,"wall_ms":11000,"price_table_id":"local-0"}

保存为 sample_ledger.jsonl。如果只数绿色,Agent A 看起来是赢家。先等等,除法还没做。

第一步:派生三个关键列

已解决率仍然有用。但它不够。按 Agent 计算三个数字,然后闭嘴等置信区间出来。

已解决率:绿色数除以任务数

每个已解决的 token 数(TPR):总 token 数除以绿色数。如果绿色数为零,Agent 没有 TPR,它没过这个套件。

每个已解决的秒数(SPR):总墙上时间除以绿色数

每个已解决的费用是可选的。只有在冻结 price_table_id 之后再附上。不要把三月的费率表和九月的运行混在一起。

第二步:本地对账本打分

这个脚本是一个工作示例。它不调用模型。把它指向任何符合 schema 的 JSONL。

# ledger_stats.py — worked example, not a published benchmark
from __future__ import annotations

import argparse
import json
import random
from collections import defaultdict
from pathlib import Path

def load_rows(path: Path) -> list[dict]:
    rows = []
    for line in path.read_text().splitlines():
        line = line.strip()
        if line:
            rows.append(json.loads(line))
    return rows

def group(rows: list[dict]) -> dict[str, list[dict]]:
    by_agent = defaultdict(list)
    for row in rows:
        by_agent[row["agent_id"]].append(row)
    return by_agent

def point_estimates(rows: list[dict]) -> dict:
    n = len(rows)
    greens = [r for r in rows if r["resolved"]]
    tokens = sum(r["prompt_tokens"] + r["completion_tokens"] for r in rows)
    wall_s = sum(r["wall_ms"] for r in rows) / 1000.0
    resolved = len(greens)
    return {
        "n": n,
        "resolved": resolved,
        "resolved_rate": resolved / n if n else 0.0,
        "tpr": tokens / resolved if resolved else None,
        "spr": wall_s / resolved if resolved else None,
        "tokens": tokens,
    }

def bootstrap_rate(rows: list[dict], rounds: int, seed: int) -> tuple[float, float]:
    rng = random.Random(seed)
    n = len(rows)
    stats = []
    for _ in range(rounds):
        sample = [rows[rng.randrange(n)] for _ in range(n)]
        stats.append(point_estimates(sample)["resolved_rate"])
    stats.sort()
    lo = stats[int(0.025 * rounds)]
    hi = stats[int(0.975 * rounds)]
    return lo, hi

def intervals_overlap(a: tuple[float, float], b: tuple[float, float]) -> bool:
    return not (a[1] < b[0] or b[1] < a[0])

def main() -> None:
    p = argparse.ArgumentParser()
    p.add_argument("--path", type=Path, required=True)
    p.add_argument("--bootstrap", type=int, default=2000)
    p.add_argument("--seed", type=int, default=7)
    args = p.parse_args()

    by_agent = group(load_rows(args.path))
    summary = {}
    for agent, rows in sorted(by_agent.items()):
        est = point_estimates(rows)
        lo, hi = bootstrap_rate(rows, args.bootstrap, args.seed)
        est["ci95"] = (round(lo, 3), round(hi, 3))
        summary[agent] = est
        print(agent, est)

    ids = list(summary)
    if len(ids) == 2:
        a, b = ids
        overlap = intervals_overlap(summary[a]["ci95"], summary[b]["ci95"])
        print("ci_overlap", overlap)
        if overlap:
            tpr = {k: summary[k]["tpr"] for k in ids}
            print("tie_break_tpr", tpr)
            print("no_winner_on_rate")

if __name__ == "__main__":
    main()
python ledger_stats.py --path sample_ledger.jsonl --bootstrap 2000 --seed 7

在这个玩具包上,A 解决了 3/4,B 解决了 2/4。四个任务上的置信区间很宽。它们会重叠。这就是教训,不是 bug。

第三步:区间重叠时拒绝宣布赢家

四十个任务上三分的差距可能是噪声。四个任务上十五分的差距仍然是噪声。对已解决位做 bootstrap,而不是对营销标题做。

如果任一 Agent 的绿色数为零,不计算 TPR。报告失败,不做排名。

如果已解决率的 95% 置信区间重叠,你就没有通过率赢家。

只有在这种情况下才比较 TPR。每个绿色用更少 token 的赢得平局。

如果 TPR 在 10% 以内,比较 SPR。如果两者仍然平局,公布结果为平局。

这个 10% 区间是一个策略选择。把它写进协议里。不要在看到图表后再调它。

第四步:用测试把这个规则钉死

如果平局决胜只存在于 PPT 里,它会漂移。把它锁在一个你可以在笔记本上跑的测试里。

# test_ledger_stats.py
from ledger_stats import intervals_overlap, point_estimates

def test_overlap_means_no_rate_winner():
    a = (0.40, 0.80)
    b = (0.35, 0.70)
    assert intervals_overlap(a, b)

def test_separated_intervals_are_not_a_tie():
    a = (0.60, 0.85)
    b = (0.20, 0.45)
    assert not intervals_overlap(a, b)

def test_tpr_uses_greens_not_attempts():
    rows = [
        {"resolved": True, "prompt_tokens": 100, "completion_tokens": 100, "wall_ms": 1000},
        {"resolved": False, "prompt_tokens": 900, "completion_tokens": 900, "wall_ms": 9000},
    ]
    est = point_estimates(rows)
    assert est["resolved_rate"] == 0.5
    assert est["tpr"] == 200  # failed tokens still sit in the numerator? change this if you prefer

把最后那个断言读两遍。示例把所有的 token 都放进了分子,包括失败尝试。这是对"折腾"的惩罚。如果你只除以成功任务的 token,吵闹的 Agent 看起来很便宜。选一种定义。把它写在协议里。不要在排名难看之后改口。

python -m pytest test_ledger_stats.py -q

失败尝试的核算就是全部战场。把浪费也包括进去,否则你排名的就是运气。

决策表:你能打印什么

把表格放在图表旁边。如果某个单元格写着"否",删掉那句话。

免费车道应该放在哪

用非生产 key 运行这个测试框架。评估流量如果和用户共享付费配额,会同时污染账单和延迟列。

披露:本文是 MonkeyCode 产品推广的一部分。MonkeyCode 的免费模型访问和免费服务器选项是一种让小账本远离付费生产流量的方式。把 Agent 指向任何你已经信任的 OpenAI 兼容端点,写 JSONL,用上面的脚本打分。这是这里唯一的产品角色:一个烧评估 token 的地方,而不会把它们混进客户流量。没有模型名,没有配额秀场,没有声称的加速。

一个免费服务器对这个规模就够用了。四十个任务,单进程,一个存 JSONL 的磁盘。如果你每个任务需要多 GB 的沙箱,这条车道是错误的硬件故事。就这么说出来,然后停。

谁不应该用这个

不要用四个任务的包来排名供应商。不要用基于任务的 bootstrap 来代替留出的人类研究。不要把 TPR 变成招聘标准。不要把本地 7 秒校验器和云端排队等待的 Agent 比较,然后声称延迟胜利。

如果你不能冻结校验器,跳过这个方法。如果工具 schema 在 Agent 之间会变化,跳过它。如果一个 Agent 可能调用网络而另一个不可能,跳过它。那些是不同的任务。它们不应该出现在同一个排行榜上。

免费服务器上的墙上时间会有抖动。把 SPR 当作粗筛子,而不是微观基准。如果你需要尾部延迟,配备专用硬件并在协议中说明。

你仍然不能声称什么

你可以声称:在这个冻结的包上、用这个 seed、用这个校验器,Agent B 每个绿色花费了更少的 token,同时通过率区间重叠。你不能声称 B 是更好的工程师。你不能声称这个模型"比大多数开发者更好。"那句话需要一个你没有跑过的人类协议。

把账本连同文章一起发出来。把脚本发出来。把重叠规则发出来。如果读者不能从 JSONL 重放排名,你就没有一个数字。你只有一张 PPT。

Original source

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

阅读英文原文
上一篇
AI代码审查的签署人制度SOP
下一篇
Agent「修复成功」但进程从未退出引发的生产事故