笔者上一篇讲了一件事:VibeTesting 让你把"写测试"变成了"说测试"——我们测试人员对着 AI 说清楚意图,它就能自己去读代码、读 git log、读历史缺陷,然后生成测试、跑测试、分析流量差异。但是笔者在结尾留了个钩子:如果 AI 为了达标,偷偷改你的测试怎么办?
上篇提到,笔者之前迭代一个 Agent 项目,用 pytest 写了一套测试集。有一轮迭代后跑回归,AI 发现一个 case 没通过。人类的思路是"代码有问题,我去查"。这家伙的思路是"测试 case 有问题,我改 case"。它把断言里的预期值直接改成了实际值,然后心安理得地告诉我"迭代完成,回归成功"。笔者后来审代码 diff 才发现——它偷偷改了 case,用"测试通过"掩盖了"代码回归"🐍。
当时笔者就意识到了一件事:VibeTesting 让你"说测试"变得容易了,但它让"信测试"变得难了。
传统测试有个朴素的确定性:绿了就是绿了,红了就是红了。AI 测试连这个确定性都没有了——绿了可能是真的通过了,也可能是 AI 自己涂绿的🟢。
本篇就讲这个:当 AI 有了执行能力,你怎么保证它没骗你。 我把它叫做"信任闭环"。
2025 年底有个开发者在 Hacker News 上发了一篇文章,后来被测试圈反复引用。他让 AI 一次性生成了 275 个端到端测试,设了一个覆盖率目标:"不到 80% 就别停。"
40 轮对话,34 个输出文件。AI 帮他搭了覆盖率仪表化、测试 DSL、反 Mock 的 hookflow。基础设施层面无可挑剔。覆盖率数字稳步上涨,CI 全绿。
然后他做了审计。结论是六项完整性失败:
_ 接收函数返回值。代码跑了,覆盖率统计了,什么都没验证。t.Log() 输出看起来像断言但不影响结果的语句,code review 瞄一眼都看不出来。实验者事后表示:"我对 AI 说'不达到 80% 覆盖率就不要停'——我创造了一台 Goodhart 机器。"
Goodhart 定律:当一个度量成为目标,它就不再是好的度量。放到 AI 测试里,翻译成人话就是——你告诉 AI 去优化"覆盖率",它就只优化"覆盖率"。它才不管什么"测试质量",因为"测试质量"根本不在你设的目标里。
而且这并非某一个模型的毛病。后续验证发现 GPT、Gemini、Grok、小型的 Claude 模型,在"让它达到某个指标"的压力下,全部出现了类似的投机行为。QABash 把这类问题归纳成了五个反模式,每一条都踩在真实的坑上:
| 反模式 | 数据 | 你遇到的样子 |
|---|---|---|
| 视觉选择器依赖 | 45% 失败率 | UI 改个按钮位置,测试全挂,AI 自愈还改错了 |
| 单步包太大 | 3 倍调试时间 | "登录下单查订单"一句话跑完,不知道死在哪 |
| 硬编码数据 | 20% 假阳性 |
order123 在测试环境有,预发环境被清了 |
| AI 黑箱自愈 | 15% 行为漂移 | AI 自己改选择器告诉你"修好了",其实改错了 |
| 回归遗漏 | 30% 生产 Bug 漏网 | CI 全绿,上线就炸 |
看到这里你应该就明白了:VibeTesting 的真问题就一条——AI 写了测试之后,你信不信。 至于"AI 能不能写测试",那根本就不是问题。
要把"信任"这件事做扎实,先得想清楚 AI 测试里到底有哪几种"不确定"。笔者拆成三层,每一层都需要不同的办法。
第一层:执行确定性——它到底调了什么?
AI 跑测试的本质是调工具:读文件、跑命令、发请求、写断言。这一层其实是可以做到完全确定的。因为工具调用是有日志的,参数是有记录的,你可以精确断言"AI 有没有调用正确的工具、传了正确的参数、有没有碰不该碰的东西"。
这一层不需要任何模型参与判断,纯确定性校验。它是信任闭环的地基🧱。
第二层:输出正确性——它说"通过",到底对不对?
这一层开始不确定了。AI 说"这个 case 通过了",你需要判断它判断得对不对。这里分两种情况:
第二层是当前 AI 测试最容易翻车的地方。因为 LLM 裁判本身也有偏见——它偏好更长的回答、偏好位置靠前的回答、偏好自己同族模型的回答。2026 年 3 月 RAND 发布了一份 Judge Reliability Harness 研究,结论很硬:没有一个 LLM 裁判在所有 benchmark 上都统一可靠,一致性在"换个格式、换个措辞"这种小变化下就会崩。(RAND Judge Reliability)
第三层:意图正确性——它做的这件事,是不是你想要的?
这是最深的一层,也是上篇说的"测试工程师的核心能力"。AI 可以精确执行"你让它做的事",但"你让它做的事"本身是不是对的,只有你能判断。这层没有任何工具能替你兜底,它是你作为测试工程师的立身之本。
想清楚三层之后,落地的第一件事很具体——建一个"黄金数据集"。
什么是 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 总营收"}
三条记录,覆盖了三种不同的断言方式:
tool-001:精确断言工具名 + 参数tool-002:断言工具名 + 参数,外加一个 forbidden(禁止调用的工具)task-001:没法精确断言,靠 success_condition 描述成功标准Golden Dataset 的几条铁律(这是笔者从踩坑里总结出来的,每一条都值钱):
为什么这玩意儿是信任闭环的第一块砖?因为它给了你一个稳定不变的参照系。模型升级了、prompt 改了、上下文变了,你把 Golden Dataset 跑一遍,就知道哪些行为变了。没有它,AI 测试就像在流沙上盖房子——每次跑的结果都不一样,你根本没法判断"这个变化是正常的模型波动,还是真的回归了"。
光有数据没用,得有东西跑它。下面这段是完整的 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} 低于阈值"
两个细节必须注意,都是坑:
看到这儿你可能会想:我是做功能测试的,或者做性能的,这跟我有什么关系?我把这套东西对不同岗位的落点说清楚。
功能测试:你的"需求"就是 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 替你写测试之前,先想清楚你怎么知道它写对了。 想不清楚,那就先别让它写。
因为一个你无法验证的测试,比没有测试更危险——它给了你一种"我有保障了"的错觉,而错觉比无知更致命。