---
layout: post.njk
source: https://yage.ai/share/backendforge-adaptive-benchmark-20260717.html
speaker: yage.ai
title: |-
  BackendForge：AI 已经能写完整
  App，评测也得学会追问
date: '2026-07-17'
summary: 文章探讨了 AI 在编写完整应用代码后，如何通过改进评测机制来发现和解决测试覆盖率的漏洞。核心思想是引入 'BackendForge' 这种迭代式追问流程（co-evolution），让 Agent 不仅生成代码，还能主动寻找现有测试集中的遗漏点，从而使基准测试从单一函数扩展到完整应用级别。
area: tech-engineering
category: ai-application
tags:
  - agentic-workflow
  - benchmark
  - software-development
  - testing
people: []
companies_orgs: []
products_models:
  - BackendForge
media_books: []
draft: true
status: evergreen
---

以前测试 AI 写代码，常见做法是给它一个函数，再跑几条单元测试。现在
Agent
已经开始从空目录写整套后端。问题也随之变了：我们怎么知道这套东西真的能用？

拿一个推送服务来说。Alice 创建了一个应用，Bob 不该看到它。Alice
删除应用后，里面的消息也该一起消失。系统拒绝一次错误请求后，数据库不能悄悄多出一条脏数据。每条规则单看都不复杂。可同一组接口换个人、换个操作顺序，正确答案就会变。第一版测试很难把所有情况都想到。

BackendForge
想解决的就是这个问题。研究者先写了 7,250 项测试，再让 Agent
专门寻找这套测试漏掉了什么，最后补进 640 项。测试数量只多了
+8.8%，同一批 GPT-5.5 代码却从 31/56 个任务全通过，降到 16/56。

这批代码没有改变，变的是评分用的题库。BackendForge
带来的启发也在这里：当 AI 开始写整套应用，benchmark
不能只把题目变大。出题方式也要从一次写完的笔试，变成一场会继续追问的面试。

## Benchmark 是怎么一步步变大的

HumanEval
测的是一个函数。模型读一段需求，写出几十行代码，然后跑单元测试。

SWE-bench
把模型放进真实代码仓库。它要读
issue、找到相关文件，再提交一个修复补丁。FEA-Bench
测得更大：Agent 不只修 bug，还要实现一个跨越多个文件的新功能。

现在，评测对象又变成了整套
App。模型要自己处理数据库、接口、登录和权限，最后交出一个能启动、能接收请求的系统。BackendForge
就属于这一代 benchmark。

AI 编程 benchmark 的任务单位从函数、仓库
bug、跨文件 feature，扩大到完整 app/service；每一代对应
HumanEval、SWE-bench、FEA-Bench 和 BackendForge 等代表。

任务每变大一级，测试也会多一层难度。一个函数通常调用一次就能判断对错。整套服务要连续做完一串动作，才能知道哪里出了问题。

## BackendForge 不是第一个

完整应用的 benchmark 已经有不少。BaxBench
让模型生成后端，同时检查功能和安全问题。AppForge
测安卓应用，会把成品装进模拟器，真的点开界面操作。Vibe Code Bench
测网页应用，再让浏览器 Agent 按照用户流程一步步验收。

这些 benchmark 已经在测整套产品。BackendForge
多做的一步，是让题库在发布前继续找漏。

它收录了 56 个后端任务，一共有 2,345 个 API
操作。模型生成代码后，研究者把服务装进 Docker，再用真实 HTTP
请求测试。整套评测一共发出了 24,798 次请求。

这些请求会串在一起。第一次请求创建数据，第二次换成另一个用户读取，第三次再删除，最后检查数据库里还剩下什么。前面
Alice 和 Bob 那类规则，只有这样才能测出来。

原来的 7,250
项测试已经会检查这些跨越多次请求的规则。类似思路也不是新发明，微软的 RESTler
很早就在自动尝试不同的 API 调用顺序。BackendForge 的变化，是让测试在构建
benchmark 时主动寻找自己的遗漏。

## 让题库继续追问

BackendForge 先准备一套参考服务。你可以把它理解成标准答案。然后，三个
Agent 围着它反复出题、检查和修正。

第一个 Agent 负责出题，论文里叫 Test Agent。它根据需求文档和 OpenAPI
设计新测试。如果参考服务能通过，这道题没有发现新问题，直接丢掉。如果参考服务失败，它可能抓到了第一版题库漏掉的规则。

第二个 Agent 负责检查新题有没有需求依据，论文里叫 Review
Agent。它一共否决了 113 个站不住脚的候选。最后，Code Agent
修好参考服务，再把新旧测试全部跑一遍。全部通过后，新题才会进入正式题库。

论文把这个循环叫作
co-evolution，也就是测试和参考服务一起改进。最终新增的 640
项测试都从具体问题出发：

Bob 会不会看到 Alice 的数据？这类权限问题有 191 项。

系统有没有拒绝错误参数，拒绝后有没有留下脏数据？这类输入问题有 144 项。

创建、修改或删除之后，系统里的数据对不对？这类状态问题有 126 项。

删除应用后，它下面的消息还在不在？这类连带影响有 120 项。

连续做完多步操作，结果还能不能保持一致？这类完整流程有 59 项。

可以把以前的评测想成笔试。每个 task
的题目提前写好，代码交上来以后，照着固定答案打分。BackendForge
在出题阶段多加了一位面试官：它先看这个 task
的参考服务错在哪里，再沿着那个错误继续问。

## 只多 8.8%，结果差了一半

共同演化把测试从 7,250 项增加到 7,890 项。新增 640 项，只占
+8.8%。它们数量不多，却都是先发现真实失败、再核对需求、最后通过回归测试留下来的。

BackendForge
的计分方式很严格：一个任务里的测试必须全部通过。哪怕只错一项，整个任务也算失败。

一共 56 个任务。用最初的题库评分时，GPT-5.5 生成的服务有 31
个任务全部通过。换成加固后的题库，只剩 16
个。换句话说，原来通过的任务里，只有 51.6% 还能通过。

Claude Opus 4.7 的变化更大：原来通过 33 个任务，加固题库后只剩 10
个。

模型没有重新生成代码，也没有突然变弱。同一份代码换了一套更会找问题的测试，结果就变了。第一版题库漏掉的一些问题，足以让整个任务从通过变成失败。

论文说作者计划公开完整评测材料，但截至本文核对时，公开渠道还找不到这套资源。外界暂时无法逐项检查新增的
640 项测试，所以不应把这里的改判幅度直接套到所有整套应用评测上。

## 这场面试按 task
定制，不按模型定制

BackendForge 按每个 repo 或 task 定制追问。Gotify
的参考服务在哪里出错，测试 Agent 就沿着 Gotify 的问题追问；换成另一个
task，它会从那个服务暴露的问题继续问。因此，不同 task
最后补进题库的问题可以不同。它不会针对每个参评模型临时换题。

但题库定稿以后，面试就结束了。同一个 task
的最终测试会被冻结。GPT-5.5、Claude Opus 4.7 或其他模型来做这个
task，面对的都是同一套题。这样既能针对每个项目的具体问题继续追问，又不会为了某个
candidate 临时换题。

固定笔试与面试式追问的对比：左侧固定题库保证统一评分，右侧根据参考服务暴露的错误追加问题；BackendForge
最终再冻结加固后的题库。

所以 BackendForge 仍然保留了笔试。区别只在于：试卷定稿之前，先按每个
task
的实际回答做一轮面试式追问。定稿之后，所有模型再用同一张试卷比较成绩。

以后评测整套应用，可以把这轮追问变成发布前的必做步骤。先让 Agent
对着参考服务找漏，再由人检查新题有没有需求依据。检查完，冻结一个统一版本。公开题库负责长期比较，定期更新的隐藏题目继续寻找新漏洞。

从一个函数到一套完整应用，AI 接到的任务一直在变大。BackendForge
让评测也学会了追问。标准试卷仍然要有，只是在定稿之前，应该先让它经历一场面试。