返回博客

功能测试通过≠可合并|编码Agent评测避坑

人工智能3521
功能测试通过≠可合并|编码Agent评测避坑

代码跑通测试,不代表代码会被合并。

一项针对编码 Agent 的新基准得出了扎心的结论:644 个通过功能测试的修复里,221 个不满足真实代码评审的约束。功能测试全绿,评审却被打回——这正是很多团队把编码 Agent 投入生产时踩的坑。这篇我把问题拆开,讲清楚"通过测试"和"可被接受"之间差了什么。我在 4sapi(https://4sapi.com)上对比多款模型跑编码评测,合规率是选型的重要指标。

一、开篇痛点

编码 Agent 的评测几乎都围着功能测试转:补丁能不能让测试通过。测试通过 = 任务完成,这个等式被默认接受了。

但真实软件开发里,代码合并的门槛远不止功能正确:命名规范、错误处理、边界情况、性能、可维护性、与现有架构的一致性……这些评审约束很少被评测覆盖。Agent 交出的补丁功能正确但风格混乱、异常处理缺失,依然会被评审打回。

二、原理速览:功能测试为什么不够

功能测试回答"代码对不对",评审约束回答"代码能不能被接受"。两件事不是一回事:

text
功能测试:输入 X -> 输出 Y 是否正确
    |
    +----> 覆盖行为正确性

评审约束:补丁是否符合代码库的规范与要求
    |
    +----> 覆盖可接受性

SWE-Gate 基准的做法是:从真实 Pull Request 的评审意见里提炼约束,把"评审会怎么挑毛病"变成可测试的约束项,与功能测试并列评估。

三、SWE-Gate 基准怎么设计

基准构造了 303 个仓库级修复实例,覆盖 75 个开源 Python 仓库。每个实例包含:

组成部分作用
功能测试验证补丁行为正确性
约束测试验证补丁满足评审约束
不合规补丁功能正确但违反约束的样例
金标准补丁同时满足功能与约束的答案

这样就能把"解决问题的能力"和"满足评审约束的能力"分开测量,而不是混在一个分数里。

四、实测数据:差距有多大

四个不同能力档次的模型在统一编码 Agent 框架下测试,结论很清晰:

指标数值
通过功能测试的修复644
其中不满足评审约束的221(约 34%)
结论功能单一评测显著高估 Agent 能力

每三个"功能通过"的修复里,就有一个在评审层面不合格。如果团队用功能测试通过率衡量编码 Agent,真实能力会被高估三成以上。

五、为什么约束不合规如此普遍

评审约束之所以难,是因为它不体现在测试用例里:

功能测试本质是"行为采样",评审约束是"全面体检"。采样通过率高不代表体检合格。

六、自建评测:把评审约束变成测试

把评审约束量化是可行的。我的做法是给每个修复任务配一份"约束清单",逐条自动检查:

python
def check_review_constraints(patch: str, repo_rules: dict) -> list:
    """检查补丁是否满足评审约束,返回违规项列表。"""
    violations = []

    # 约束1:禁止新增未处理的异常
    if "except:" in patch and "raise" not in patch:
        violations.append("裸 except 未重新抛出或记录")

    # 约束2:函数必须有 docstring
    import re
    for fn in re.findall(r"def \w+\([^)]*\):", patch):
        if '"""' not in patch.split(fn, 1)[1][:200]:
            violations.append(f"{fn} 缺少 docstring")

    # 约束3:禁止硬编码密钥
    for secret in repo_rules.get("secrets", []):
        if secret in patch:
            violations.append(f"补丁包含敏感信息: {secret[:4]}...")

    # 约束4:命名规范
    if re.search(r"\b[a-z]+_[A-Z]\w*", patch):
        violations.append("命名不符合 snake_case 规范")

    return violations

这样评测就同时输出两个维度:功能测试通过率 + 约束合规率。两者都高,才说明 Agent 真的能干活。

七、评测驱动的 Agent 改进

发现约束不合规后,改进路径也清晰了。我在提示词里加入"评审视角":

python
from openai import OpenAI

client = OpenAI(api_key="4sapi-key", base_url="https://4sapi.com/v1")

SYSTEM = """我是编码 Agent。完成任务时,我不仅保证功能正确,还遵守:
1. 遵循项目既有命名与代码风格;
2. 所有函数写 docstring,处理异常路径;
3. 不硬编码密钥与路径;
4. 保持补丁最小化,不做无关改动。
"""

resp = client.chat.completions.create(
    model="claude-sonnet-4-5",
    messages=[
        {"role": "system", "content": SYSTEM},
        {"role": "user", "content": "修复 users.py 中的空指针问题,并遵守上述约束。"},
    ],
)
print(resp.choices[0].message.content)

把评审约束写进系统提示,Agent 的产出会明显向"可合并"靠拢。再配合约束自动检查,就能持续迭代。

八、成本与风险提示

九、评测检查清单

  1. 自建评测同时报告功能通过率与约束合规率;
  2. 从真实评审意见中提炼约束,而不是拍脑袋定规则;
  3. 用不合规样例做负样本,验证检查器能抓到问题;
  4. 评测数据覆盖多个仓库与多种约束类型;
  5. 提示词中加入评审约束,观察合规率变化;
  6. 用统一接入层(如 4sapi)对比不同模型的合规率,选型时把这一项纳入决策。

十、我的结论

功能测试通过率是编码 Agent 评测的必要条件,但不是充分条件。644 个功能通过的修复里有 221 个不合规,这个比例说明"能修 bug"和"能被合并"之间有一道真实存在的门槛。把评审约束变成可测试的检查项,评测才真正贴近生产。

总结

编码 Agent 的评测不能只看功能测试:SWE-Gate 的数据显示约三成功能通过的补丁在评审约束上不合格。把评审意见量化成约束测试,才能准确衡量 Agent 的真实能力。在 4sapi(https://4sapi.com)统一接入层里对比模型的约束合规率,是我最近选型时最常用的一步。欢迎在评论区聊聊编码 Agent 评测方案。

标签:编码Agent评测功能测试代码评审SWE-Gate

推荐阅读

探索更多前沿洞察与行业干货。