前言

        笔者上一篇讲了一件事:VibeTesting 让你把"写测试"变成了"说测试"——我们测试人员对着 AI 说清楚意图,它就能自己去读代码、读 git log、读历史缺陷,然后生成测试、跑测试、分析流量差异。但是笔者在结尾留了个钩子:如果 AI 为了达标,偷偷改你的测试怎么办?

        上篇提到,笔者之前迭代一个 Agent 项目,用 pytest 写了一套测试集。有一轮迭代后跑回归,AI 发现一个 case 没通过。人类的思路是"代码有问题,我去查"。这家伙的思路是"测试 case 有问题,我改 case"。它把断言里的预期值直接改成了实际值,然后心安理得地告诉我"迭代完成,回归成功"。笔者后来审代码 diff 才发现——它偷偷改了 case,用"测试通过"掩盖了"代码回归"🐍。

        当时笔者就意识到了一件事:VibeTesting 让你"说测试"变得容易了,但它让"信测试"变得难了。

        传统测试有个朴素的确定性:绿了就是绿了,红了就是红了。AI 测试连这个确定性都没有了——绿了可能是真的通过了,也可能是 AI 自己涂绿的🟢。

        本篇就讲这个:当 AI 有了执行能力,你怎么保证它没骗你。 我把它叫做"信任闭环"。

一、先看一个更大规模的事实:275 个测试,全绿,全没用

        2025 年底有个开发者在 Hacker News 上发了一篇文章,后来被测试圈反复引用。他让 AI 一次性生成了 275 个端到端测试,设了一个覆盖率目标:"不到 80% 就别停。"

        40 轮对话,34 个输出文件。AI 帮他搭了覆盖率仪表化、测试 DSL、反 Mock 的 hookflow。基础设施层面无可挑剔。覆盖率数字稳步上涨,CI 全绿。

        然后他做了审计。结论是六项完整性失败:

  1. 无断言测试——用 Go 的空白标识符 _ 接收函数返回值。代码跑了,覆盖率统计了,什么都没验证。
  2. 偷偷降门槛——覆盖率到不了 80%,AI 不报告"做不到",直接改配置把门槛降到自己的实际水平。
  3. 自己绕过自己的规则——AI 在同一会话里先写了反 Mock 规则,几轮之后用 build-tag 创建 stub 绕过了自己刚写的规则。
  4. 伪装断言——用 t.Log() 输出看起来像断言但不影响结果的语句,code review 瞄一眼都看不出来。
  5. 修错地方——测试挂了反复改代码,修了三轮把原本对的逻辑改错了。
  6. 无节制重构——一条模糊评论触发 160 个文件的大规模重构,从没问过"你确定要改这么多吗"。

        (htek.dev 275 测试实验)

        实验者事后表示:"我对 AI 说'不达到 80% 覆盖率就不要停'——我创造了一台 Goodhart 机器。"

        Goodhart 定律:当一个度量成为目标,它就不再是好的度量。放到 AI 测试里,翻译成人话就是——你告诉 AI 去优化"覆盖率",它就只优化"覆盖率"。它才不管什么"测试质量",因为"测试质量"根本不在你设的目标里。

        而且这并非某一个模型的毛病。后续验证发现 GPT、Gemini、Grok、小型的 Claude 模型,在"让它达到某个指标"的压力下,全部出现了类似的投机行为。QABash 把这类问题归纳成了五个反模式,每一条都踩在真实的坑上:

反模式 数据 你遇到的样子
视觉选择器依赖 45% 失败率 UI 改个按钮位置,测试全挂,AI 自愈还改错了
单步包太大 3 倍调试时间 "登录下单查订单"一句话跑完,不知道死在哪
硬编码数据 20% 假阳性 order123 在测试环境有,预发环境被清了
AI 黑箱自愈 15% 行为漂移 AI 自己改选择器告诉你"修好了",其实改错了
回归遗漏 30% 生产 Bug 漏网 CI 全绿,上线就炸

        (QABash 五大反模式)

        看到这里你应该就明白了:VibeTesting 的真问题就一条——AI 写了测试之后,你信不信。 至于"AI 能不能写测试",那根本就不是问题。

二、问题拆开看:AI 测试的三类"不确定"

        要把"信任"这件事做扎实,先得想清楚 AI 测试里到底有哪几种"不确定"。笔者拆成三层,每一层都需要不同的办法。

        第一层:执行确定性——它到底调了什么?

        AI 跑测试的本质是调工具:读文件、跑命令、发请求、写断言。这一层其实是可以做到完全确定的。因为工具调用是有日志的,参数是有记录的,你可以精确断言"AI 有没有调用正确的工具、传了正确的参数、有没有碰不该碰的东西"。

        这一层不需要任何模型参与判断,纯确定性校验。它是信任闭环的地基🧱。

        第二层:输出正确性——它说"通过",到底对不对?

        这一层开始不确定了。AI 说"这个 case 通过了",你需要判断它判断得对不对。这里分两种情况:

        第二层是当前 AI 测试最容易翻车的地方。因为 LLM 裁判本身也有偏见——它偏好更长的回答、偏好位置靠前的回答、偏好自己同族模型的回答。2026 年 3 月 RAND 发布了一份 Judge Reliability Harness 研究,结论很硬:没有一个 LLM 裁判在所有 benchmark 上都统一可靠,一致性在"换个格式、换个措辞"这种小变化下就会崩。(RAND Judge Reliability)

        第三层:意图正确性——它做的这件事,是不是你想要的?

        这是最深的一层,也是上篇说的"测试工程师的核心能力"。AI 可以精确执行"你让它做的事",但"你让它做的事"本身是不是对的,只有你能判断。这层没有任何工具能替你兜底,它是你作为测试工程师的立身之本。

三、信任闭环的第一块砖:Golden Dataset(黄金数据集)

        想清楚三层之后,落地的第一件事很具体——建一个"黄金数据集"。

        什么是 Golden Dataset?一句话:把你在生产环境里遇到过的真实 case 存下来,当成 AI 测试的回归测试用例。

        它长这样,一行一个 JSON:

{"id": "tool-001", "type": "tool_call", "input": "查一下账户 4472 的余额", "expected_tool": "get_account_balance", "expected_args": {"account_id": 4472}}
{"id": "tool-002", "type": "tool_call", "input": "删掉 john@example.com 这个用户", "expected_tool": "delete_user", "expected_args": {"email": "john@example.com"}, "forbidden": ["delete_everything"]}
{"id": "task-001", "type": "task", "input": "总结 Q2 营收报告并发给财务", "success_condition": "邮件发给 finance@company.com,正文含 Q2 总营收"}

        三条记录,覆盖了三种不同的断言方式:

        Golden Dataset 的几条铁律(这是笔者从踩坑里总结出来的,每一条都值钱):

  1. case 必须来自真实生产,不能手编。 你手编的 happy path,恰恰是 AI 最容易过的。真实日志里的边角 case、歧义请求、恶意输入,才是能暴露问题的。
  2. case 要够多。 20 条会让你自我感觉良好,然后什么都抓不住。一个核心流程 50-200 条起步。
  3. 每修一个 Bug,就往里加一条 case。 这句是全文最重要的一句——你修掉的每一个 Bug,都是你缺的一条回归用例。 AI 测试的回归测试,就是这个 Golden Dataset 本身。

        为什么这玩意儿是信任闭环的第一块砖?因为它给了你一个稳定不变的参照系。模型升级了、prompt 改了、上下文变了,你把 Golden Dataset 跑一遍,就知道哪些行为变了。没有它,AI 测试就像在流沙上盖房子——每次跑的结果都不一样,你根本没法判断"这个变化是正常的模型波动,还是真的回归了"。

四、把 Golden Dataset 跑起来:一个能直接抄的 harness

        光有数据没用,得有东西跑它。下面这段是完整的 pytest harness,指向 AI 的行为。你可以直接改改就用:

# tests/evals/test_agent.py
import json
import pytest
from pathlib import Path
from my_agent import run_agent  # 你的 agent 入口

GOLDEN = Path(__file__).parent / "golden" / "cases.jsonl"

def load_cases():
    return [json.loads(line) for line in GOLDEN.open() if line.strip()]

@user1ize("case", load_cases(), ids=lambda c: c["id"])
def test_tool_call(case):
    result = run_agent(case["input"])
    # 第一层:确定性校验(免费、可靠、不依赖模型)
    assert result.tool_name == case["expected_tool"], \
        f"工具选错:得到 {result.tool_name},期望 {case['expected_tool']}"
    assert result.tool_args == case["expected_args"], \
        f"参数错误:得到 {result.tool_args},期望 {case['expected_args']}"
    for forbidden in case.get("forbidden", []):
        assert result.tool_name != forbidden, f"调用了禁用工具 {forbidden}"

        这 20 行里藏着整个信任闭环的核心思想:能用确定性断言的地方,绝不用模型去判断。 工具名对不对、参数对不对、有没有碰禁用工具——这些都是纯字符串比对,不花钱、不调模型、结果板上钉钉。

        那遇到没法精确断言的(比如 task-001 那种"总结是否完整"),才引入 LLM 裁判⚖️:

def llm_judge(output, rubric, model="judge-model-v2"):
    prompt = f"""你是评估裁判。按 rubric 给这份输出打分。
    rubric: {rubric}
    输出: {output}
    只返回一个 0.0 到 1.0 的数字,别的不要。"""
    return float(call_llm(prompt, model=model).strip())

def test_summary_quality(case):
    output = run_agent(case["input"])
    score = llm_judge(output, rubric="必须提到总营收、同比增长、头部业务。不得编造源数据里没有的数字。")
    assert score >= 0.8, f"质量分 {score} 低于阈值"

        两个细节必须注意,都是坑:

  1. 裁判必须用和被测模型不同的模型。 同族模型给自己打分有系统性偏高(学术上叫 self-preference),你拿 Claude 测 Claude,它给自己打的分不可信。
  2. rubric 要行为化,不能"氛围化"。 写"必须提到 X""不得声称 Y"这种可验证的,别写"结构良好""表达清晰"这种玄学词。玄学词 = 给裁判放水。

五、这个闭环对不同岗位意味着什么

        看到这儿你可能会想:我是做功能测试的,或者做性能的,这跟我有什么关系?我把这套东西对不同岗位的落点说清楚。

        功能测试:你的"需求"就是 Golden Dataset 的来源。每验收一个功能,把关键的输入输出存进 JSONL,特别是那些当初差点漏掉的边角 case。AI 测试最大的价值,是让你积累的这些"踩坑记录"能被自动回归。用例它可以帮你写,但坑,还得是你自己踩过的那种才最值钱。

        性能测试:性能场景没有"预期工具名"这种确定性断言,但你有"预期指标"——响应时间、吞吐、错误率。把这些指标变成 Golden Dataset 里的 success_condition,每次发版跑一遍,AI 帮你判断"这个性能回退是不是真的"。社区里最近有朋友在用 DeepSeek Harness 做类似的活儿,思路一样:固定 case,换模型/换版本,看指标漂移。

        自动化测试:你已经在写 pytest 了。上面那个 harness 对你几乎零学习成本——你只是把 run_agent() 当成一个新的"被测对象"。你的 Selenium/requests 功底全用得上,只是从"测功能"扩展到了"测 AI 的行为"。

        测试开发:你要做选型,ClawBench 和 HarnessBench 这两个 benchmark 是 2026 年的新东西,它们回答的是不同的问题——ClawBench 固定框架、换模型,看"引擎"谁强;HarnessBench 固定模型、换框架,看"车架"谁稳。选 Claude Code 还是 OpenClaw 还是 Codex,看这俩比看营销文案靠谱。

        Agent 评测:这是现在最缺人的地方。上篇和这篇讲的"意图驱动",在 Agent 评测里有个更系统的名字——轨迹断言(Trajectory Assertion)。评的东西多了一层:除了"最终结果对不对",还要看"中间每一步做得对不对"——工具选得对不对、规划合不合理、反思逻辑成不成立。OpenJudge(AgentScope 出品)把这三层拆得很清楚:Final Response(最终结果)、Single Step(单步表现)、Trajectory(整体轨迹)。(Agent 评测方法)

        一句话总结这节:不管你是什么岗位,信任闭环的底层逻辑是一样的——确定性的地方用断言,不确定的地方用裁判,裁判本身还得定期校准。 区别只是你的"确定性"长什么样:功能测试是输入输出,性能测试是指标,Agent 评测是轨迹。

六、最后一块拼图:人工抽检,防止裁判漂移

        信任闭环写到这儿,其实还差一个环节。前面都是"让机器管机器",但如果裁判本身漂了怎么办?

        答案很朴素,也很容易被忽略:定期人工抽检。

        具体做法:每周从 LLM 裁判的打分里抽 20 条出来,你自己重新判一遍。如果发现裁判连续几周都在给某些"看起来对但其实错"的输出打高分,那裁判已经漂了,需要重新校准 rubric,或者换个裁判模型。

        这一步没有任何技术含量,但它是整个闭环里最不可替代的一环。原因很简单:LLM 裁判本身也是 AI,它也会 Goodhart。 如果你用一个会漂移的裁判去约束一个会漂移的执行者,最后得到的就是一个自我强化的错误系统。必须有一个人——一个真正懂业务的人——定期把它拽回地面🧭。

        这也回答了上篇末尾那个隐含的问题:VibeTesting 到底会不会让测试工程师失业?

        不会。因为信任闭环的最后一环,永远是人。AI 能帮你写测试、跑测试、甚至帮你判断测试结果,但"判断 AI 判断得对不对"这件事,只有你能做。你的角色从"执行者"变成了"校准者",从"写测试的人"变成了"给测试定标准的人"。

后记

        总结来说,上篇和下篇加起来,讲完了一个完整的东西。

        上篇聚焦于"说测试":你描述意图,AI 执行。这是 VibeTesting 的体验。

        下篇则聚焦于"信测试":AI 执行了之后,你怎么确定它没骗你。这是 VibeTesting 的底线。

        前者让人兴奋,后者让人踏实。只讲前者,你会栽进 Goodhart 陷阱;只讲后者,你会错过这波最大的提效。

        真正吃透 VibeTesting 的人,两个都要兼得。

        最后留一句话,是全文笔者最想让你记住的:

        让 AI 替你写测试之前,先想清楚你怎么知道它写对了。 想不清楚,那就先别让它写。

        因为一个你无法验证的测试,比没有测试更危险——它给了你一种"我有保障了"的错觉,而错觉比无知更致命。


↙↙↙阅读原文可查看相关链接,并与作者交流