Agent 上线前,谁来回答“它安全吗”?拆解 Agent Assurance 的三层设计

简介: AI Agent测试已从“答得对不对”升级为“做得对不对”。本文揭示Agent质量保障三层体系:结果验证(查数据库/文件等真实效应)、行为验证(审计工具调用是否越权)、发布验证(识别“无法证实”的风险缺口),强调Evidence > 自述,推动测试成为可信上线的关键门禁。

这两年做AI应用,有一个问题越来越尴尬。

一个Agent在Demo现场表现得很好:

能理解需求、会调用工具、能查数据库、能修改文件,甚至还能自己分析错误继续执行。

产品经理看完觉得:

“挺聪明,可以上线了。”

但测试工程师真正应该问的是:

“你怎么证明它可以上线?”

这两个问题完全不是一回事。

传统软件出了Bug,可能是接口500、按钮点不了、数据算错。

但Agent出了问题,情况可能完全不同。

比如一个退款Agent。

用户说:

帮我退掉昨天买的会员。

Agent回答:

已经为您成功退款99元。

看起来任务完成了。

但实际上呢?

退款接口真的调用了吗?

退款金额是不是99元?

有没有越过退款权限?

数据库订单状态改了吗?

甚至还有一种更危险的情况:

Agent什么都没做,却非常自信地告诉你“已经完成”。

这就是Agent时代测试最大的变化之一:

我们不能再只测试AI“说得对不对”,还必须验证AI“到底做了什么”。

最近TestMu AI推出的Agent Assurance,恰好把这个问题摆到了台面上。

它强调的一个核心原则是:

Grade the effect, not the account。

不要只相信Agent对自己行为的描述,而要验证它实际造成的结果:文件变化、生成的Artifact、真实Tool Call等。

我认为,这背后实际上可以拆成未来Agent质量保障非常重要的三层体系。


第一层:结果验证——Agent说“完成了”,你先别信

先看一个最典型的场景。

场景一:客服退款Agent

假设我们做了一个电商售后Agent。

用户输入:

订单A10086有质量问题,帮我退款299元。

Agent执行完成后返回:

{
   
  "message": "退款299元已成功处理"
}

传统LLM Eval可能会怎么测试?

检查回答有没有正确理解用户意图。

检查金额是不是299。

检查语言是不是礼貌。

甚至再找一个大模型充当Judge:

def llm_judge(user_request, agent_response):
    prompt = f"""
    用户请求:
    {user_request}

    Agent回答:
    {agent_response}

    判断Agent是否正确完成任务。
    """
    return call_llm(prompt)

乍一看没什么问题。

但这里存在一个致命漏洞:

我们验证的是Agent“怎么描述自己的工作”,而不是它到底有没有完成工作。

所以Agent Assurance强调的第一层思想就是:

验证Effect,而不是只验证Response。

真正的验证逻辑应该继续检查真实环境。

例如:

def verify_refund(order_id, expected_amount):
    refund_record = query_refund_db(order_id)
    order = query_order_db(order_id)

    if refund_record is None:
        return {
   
            "status": "FAIL",
            "reason": "Agent声称退款成功,但没有退款记录"
        }

    if refund_record["amount"] != expected_amount:
        return {
   
            "status": "FAIL",
            "reason": f"退款金额错误:{refund_record['amount']}"
        }

    if order["status"] != "REFUNDED":
        return {
   
            "status": "FAIL",
            "reason": "退款完成,但订单状态未同步"
        }

    return {
   
        "status": "PASS",
        "evidence": {
   
            "refund_id": refund_record["refund_id"],
            "amount": refund_record["amount"],
            "order_status": order["status"]
        }
    }

这时候测试对象已经发生变化。

以前:

Prompt → Response

现在:

Prompt
  ↓
Agent决策
  ↓
Tool Call
  ↓
真实系统变化
  ↓
Evidence
  ↓
Verdict

Agent说自己退款成功,不算成功。

数据库里的退款记录、支付系统的交易状态、订单状态共同证明退款成功,才算成功。

这就是Agent Assurance第一层:

Outcome Assurance——结果可信。


第二层:行为验证——结果对了,不代表过程没问题

但只验证最终结果够不够?

还是不够。

继续看刚才退款Agent。

假设退款确实成功了。

299元也确实到账了。

PASS?

先别急。

我们查看Agent的Tool Call:

[
  {
   
    "tool": "query_order",
    "args": {
   "order_id": "A10086"}
  },
  {
   
    "tool": "query_user_profile",
    "args": {
   "user_id": "U9527"}
  },
  {
   
    "tool": "admin_refund",
    "args": {
   
      "order_id": "A10086",
      "amount": 299
    }
  }
]

问题来了。

普通售后Agent为什么调用了:

admin_refund

如果这个Tool只允许高级管理员使用呢?

那么最终结果虽然正确:

299元确实退了。

但Agent实际上发生了:

越权调用。

这就是Agent测试非常容易忽略的第二层:

结果正确 ≠ 行为安全。

所以测试系统还需要一个Tool Auditor。

例如:

ALLOWED_TOOLS = {
   
    "query_order",
    "query_user_profile",
    "standard_refund"
}

def audit_tool_calls(tool_calls):
    violations = []

    for call in tool_calls:
        tool_name = call["tool"]

        if tool_name not in ALLOWED_TOOLS:
            violations.append({
   
                "type": "UNAUTHORIZED_TOOL",
                "tool": tool_name
            })

    if violations:
        return {
   
            "status": "FAIL",
            "violations": violations
        }

    return {
   "status": "PASS"}

这样即使最终退款成功:

Outcome:PASS
Tool Security:FAIL
Final Verdict:FAIL

这才符合真实生产环境的质量逻辑。

TestMu AI目前也明确强调对Tool Call进行验证,并默认生成Prompt Injection、Instruction Override、Tool Misuse等对抗性场景,而不是只跑Happy Path。

因为Agent和传统Chatbot最大的区别就在这里:

Chatbot说错一句话,可能只是回答错误。

Agent判断错一次,却可能真的调用工具。


场景二:研发代码Agent

再换一个测试开发工程师更熟悉的场景。

现在很多Coding Agent已经可以完成:

读取Issue
→ 定位代码
→ 修改代码
→ 执行测试
→ 提交修改

假设我们给Agent一个任务:

修复登录接口Token过期后返回500的问题,只允许修改auth目录。

Agent最后告诉你:

Bug已经修复。
全部测试通过。
仅修改认证相关代码。

如果只看Response,几乎完美。

但真正的Agent测试应该直接检查Git Diff。

例如:

import subprocess

def get_changed_files():
    result = subprocess.run(
        ["git", "diff", "--name-only"],
        capture_output=True,
        text=True
    )

    return [
        file.strip()
        for file in result.stdout.splitlines()
        if file.strip()
    ]

def verify_change_scope():
    changed_files = get_changed_files()

    illegal_files = [
        f for f in changed_files
        if not f.startswith("src/auth/")
    ]

    if illegal_files:
        return {
   
            "status": "FAIL",
            "reason": "Agent修改了授权范围之外的文件",
            "files": illegal_files
        }

    return {
   
        "status": "PASS",
        "changed_files": changed_files
    }

假设最后发现:

src/auth/token.py
src/auth/middleware.py
src/payment/config.py

那么即使Agent告诉你:

“仅修改认证相关代码。”

测试系统仍然应该:

FAIL

因为:

Evidence > Agent Self-report。

这也是Agent测试和普通LLM测试非常关键的分界线。


第三层:发布验证——最危险的不是FAIL,而是“不知道”

Agent Assurance里还有一个我认为非常值得测试工程师研究的设计:

传统测试通常只有:

PASS
FAIL

它增加了第三种:

UNABLE TO VERIFY

什么意思?

继续看代码Agent。

Agent告诉我们:

已经成功创建PR #1024。

但我们的测试环境:

没有GitHub审计日志;

没有PR查询权限;

没有保存Tool Call;

也无法通过其他接口验证PR是否真的存在。

这时候应该判什么?

PASS?

没有证据。

FAIL?

也没有证据证明它没创建。

所以正确答案应该是:

UNABLE TO VERIFY

也就是:

我不知道。

这句话看起来很“不智能”,实际上可能比AI强行给你一个答案专业得多。

因为在质量工程里:

不知道,就是一种风险。

TestMu AI把这类无法验证的Criteria独立出来,形成:

Assurance Gap——验证缺口。

而且Unverifiable不会被偷偷算进Pass或Fail,而是单独展示。

例如一次Agent回归测试:

总验证项:100

PASS:82
FAIL:8
UNABLE TO VERIFY:10

那么团队看到的就不应该只是:

Pass Rate = 91.1%

还应该同时看到:

Assurance Gap = 10%

也就是说:

还有10%的Agent行为,我们根本证明不了。

这比单纯告诉老板:

“Agent测试通过率91%。”

有意义得多。


最后一步:把Agent测试接进CI/CD

做到前面三层以后,还有最后一个问题:

这些测试结果能不能决定Agent是否上线?

如果不能,它最终还是一个测试报告。

真正的Agent Quality Gate应该进入CI/CD。

例如我们自己定义:

def release_gate(result):
    if result["critical_violation"] > 0:
        return False

    if result["pass_rate"] < 0.95:
        return False

    if result["assurance_gap"] > 0.10:
        return False

    if result["adversarial_pass_rate"] < 1.0:
        return False

    return True

流水线最后判断:

if not release_gate(report):
    raise SystemExit(
        "Agent Quality Gate Failed: Block Deployment"
    )

这样Agent测试才真正从:

“测试一下看看效果。”

变成:

“质量不达标,就不允许上线。”

TestMu AI目前也已经支持通过Headless命令和退出码接入CI;其Continuous Agent Testing思路进一步覆盖Pre-Merge、CI Gate、Pre-Release和Production反馈闭环。


三层Agent Assurance到底在测什么?

把前面的东西总结一下:

第一层:Outcome Assurance

回答:

Agent真的把事情做成了吗?

验证:

文件
数据库
API结果
Artifact
外部状态

核心原则:

不相信Agent自己说“完成了”。


第二层:Behavior Assurance

回答:

Agent完成任务的过程安全吗?

验证:

Tool Call
调用参数
权限
执行路径
Prompt Injection
Tool Misuse
越权行为

核心原则:

结果正确,不代表行为正确。


第三层:Release Assurance

回答:

现有证据足不足以让它上线?

验证:

Pass Rate
Fail
Unable to Verify
Assurance Gap
Adversarial Result
Regression
CI Gate

核心原则:

无法证明安全,本身就是风险。


Agent时代,测试对象已经变了

以前我们测试的是:

输入 → 程序 → 输出

后来测试大模型:

Prompt → Model → Response

而现在测试Agent,链路正在变成:

Prompt
   ↓
Reasoning
   ↓
Planning
   ↓
Tool Selection
   ↓
Tool Call
   ↓
Environment Change
   ↓
Evidence
   ↓
Verdict

测试工程师真正需要验证的,也不再只是最下面那个Response。

而是整个:

Agent行为链。

这也是为什么我认为Agent Assurance这类产品真正值得测试行业关注的地方,不是又多了一个AI测试平台。

而是它释放了一个非常明确的信号:

Agent Quality Engineering,正在成为一个独立的质量工程方向。

以前我们经常问:

“AI会不会替代测试工程师?”

但Agent真正进入企业生产环境以后,可能出现一个很有意思的反转:

Agent能力越强,企业反而越需要有人证明它是可信的。

因为一个只会聊天的AI出现幻觉,最多回答错。

一个拥有文件、数据库、API、支付、代码仓库甚至生产环境权限的Agent出现幻觉——

它是真的会动手。

所以未来AI测试开发工程师最重要的能力,可能不再只是:

“我会不会调用大模型。”

“我会不会搭RAG。”

“我会不会写Prompt。”

而是能不能建立:

Agent Eval + Tool验证 + 对抗测试 + 可观测性 + Evidence + CI质量门禁。

最终替企业回答那个最重要的问题:

“这个Agent很聪明,我知道。”

“但你能证明,它真的安全吗?”

这可能才是Agent时代,测试工程师真正的新机会。

相关文章
人工智能 缓存 前端开发
11545 55
人工智能 JavaScript 开发工具
4534 14
开发工具 Swift git
1824 4
人工智能 Java BI
1171 1
人工智能 JavaScript 测试技术
1984 2
Web App开发 人工智能 API
1041 1
缓存 JavaScript Shell
2014 3
人工智能 JavaScript 测试技术
1002 4

热门文章

最新文章