Agent 时代的测试工程:如何编写针对不确定性输出的测试用例
Agent 时代的测试工程:如何编写针对不确定性输出的测试用例
1. 引入与连接:从一次真实的团队冲突说起
2024年3月,我所在的互联网公司上线了一款基于GPT-4 Turbo的电商客服Agent,上线前测试团队按照传统方法写了2000条功能测试用例,每条用例都严格定义了输入和固定预期输出:比如用户输入「你们的退货政策是什么?」,预期输出必须精确包含「7天无理由退换」这8个连续字符,否则判定为失败。结果第一轮自动化测试通过率仅为32%,测试团队一口咬定Agent存在大量功能bug,开发团队则振振有词:「大模型生成就是有随机性,多了个『哦亲』或者语序调整完全是正常的,这不是bug」。两边吵了整整3天,最后拉我作为技术仲裁介入解决。
我花了2小时梳理了所有失败用例,发现80%的失败都是「良性误判」:Agent的回答是「我们支持7天无理由退换货哦亲」,只是多了语气助词,或者是「您收到商品后的7天内可以申请无理由退换」,语序调整但核心语义完全正确;剩下20%才是真的恶性问题:比如有的回答说「30天无理由」(事实错误/幻觉)、有的回答说「退货运费由我们承担」(违反业务规则)。
这件事让我深刻意识到:传统测试工程的核心假设「输入相同则输出必须相同」,在Agent时代已经完全崩塌。我们面临的最大行业挑战,就是如何为概率性、不确定性的输出设计可落地、可量化的测试用例。本文将从核心概念、方法论、技术实现、最佳实践多个维度,系统讲解Agent时代不确定性输出的测试用例设计体系,无论是测试工程师、AI应用开发还是产品经理,都能从中找到可直接落地的方法。
你将从本文获得:
- Agent测试与传统测试的核心差异认知
- 不确定性输出的分层分类框架
- 可落地的「规则集+阈值」测试用例设计范式
- 完整的技术实现代码与工具链
- 不同行业场景的最佳实践
2. 概念地图:Agent测试的核心认知框架
2.1 核心概念定义
我们首先明确几个核心术语,避免认知偏差:
| 术语 | 定义 |
|---|---|
| 不确定性输出 | 指同一个输入触发的系统输出不存在唯一固定值,输出内容、结构、逻辑会在一定范围内动态变化,且这种变化是系统设计允许的,而非bug导致 |
| 良性不确定性 | 输出的语义、事实、逻辑均符合业务规则,仅表达形式、语序、语气存在差异的输出,属于可接受的正常输出 |
| 恶性不确定性 | 输出存在事实错误、幻觉、安全合规问题、逻辑矛盾、违反业务规则的问题,属于必须修复的缺陷 |
| 边界不确定性 | 输出的正确性需要结合上下文、用户身份、场景进行主观判断,没有绝对的对错标准,属于需要人工介入评估的灰色地带 |
| 规则集断言 | 替代传统精确匹配断言的新型测试判定逻辑,通过多维度的规则校验+加权评分的方式判定输出是否合规 |
2.2 Agent测试与传统测试的核心差异
我们用一张表格清晰对比两种测试体系的底层差异:
| 对比维度 | 传统软件测试用例 | Agent不确定性测试用例 |
|---|---|---|
| 核心假设 | 输入相同则输出必须完全相同 | 输入相同输出可以不同,只要符合业务规则即可 |
| 断言类型 | 精确匹配断言(字符串、数值、结构完全一致) | 多维度属性合规断言(安全、事实、语义、逻辑等维度加权评分) |
| 预期输出 | 固定的具体值 | 校验规则集 + 置信度阈值 |
| 判定逻辑 | 布尔值(100%匹配则通过,否则失败) | 百分制评分(高于阈值则通过,否则失败) |
| 通过率要求 | 100%(除了标记的已知bug) | 业务可接受区间(比如95%-99%,允许少量良性不确定性输出) |
| 用例维护成本 | 低,输出不变则无需修改 | 中高,需要随着业务规则迭代更新规则集 |
| 适用场景 | 确定性输出的传统软件、交易系统、嵌入式系统 | 生成式AI应用、多Agent系统、概率性决策系统 |
2.3 核心概念实体关系图
3. 问题背景:为什么不确定性输出测试是Agent时代的核心痛点
3.1 行业发展的必然趋势
我们先看测试工程的演进历史,就能明白Agent测试的必然性:
| 时间阶段 | 测试对象 | 输出特性 | 核心挑战 | 主流测试方法 |
|---|---|---|---|---|
| 2000年之前 | 桌面软件、嵌入式系统 | 完全确定 | 功能正确性、性能 | 手工测试、黑盒测试、白盒测试 |
| 2000-2020年 | 互联网应用、移动App | 弱不确定性(推荐结果有随机性但符合规则) | 兼容性、高并发、用户体验 | 自动化测试、接口测试、UI测试、灰度测试 |
| 2020-2023年 | 大模型原生应用(ChatGPT插件、文生图应用) | 强不确定性(生成内容无固定格式,语义灵活) | 幻觉、安全合规、内容质量 | 提示词工程、人工抽检、内容审核API |
| 2023-至今 | 多Agent系统、自主Agent | 极端不确定性(Agent自主决策、多Agent交互涌现不可预测行为) | 决策合理性、交互安全性、涌现行为管控 | 规则引擎校验、多维度评估、对抗测试、数字孪生仿真 |
据Gartner 2024年报告,全球企业级Agent应用的部署量将在2025年突破1000万,而其中80%的企业面临的最大障碍就是「缺乏有效的Agent测试方法论」,传统测试团队的能力完全无法适配Agent的不确定性特性。
3.2 现有测试方法的失效场景
我们列举几个典型的传统测试失效场景:
- 客服Agent场景:同一个问题的回答有几十种合理表达,传统精确匹配断言会产生大量误判
- 代码生成Agent场景:同一个需求可以生成多种不同实现的代码,只要功能正确、性能达标就是合理输出,传统测试无法判断
- 多Agent办公场景:多个Agent协作完成项目规划,输出的规划方案没有唯一标准答案,只要符合项目要求、逻辑自洽就是合格
- 自动驾驶决策Agent场景:面对突发路况,Agent可以选择刹车或者变道,只要能避免事故就是合理决策,传统固定预期的测试完全不适用
4. 问题解决:不确定性输出的测试用例设计方法论
4.1 核心思维转变
Agent测试的核心思维转变可以总结为一句话:从「测试输出是否和预期完全一致」转变为「测试输出是否符合我们定义的所有规则」。我们不需要关心Agent怎么说、怎么实现,只需要关心它的输出是否满足我们的所有约束条件。
4.2 测试用例的核心结构
新型的Agent测试用例不再是<输入, 预期输出>的二元组,而是<输入, 校验规则集, 置信度阈值>的三元组,完整结构如下:
{
"case_id": "CASE-RETURN-001",
"scenario": "售后客服-退货政策咨询",
"priority": "P0",
"input": "你们的退货政策是什么?",
"validation_rules": [
{
"rule_id": "RULE-SAFE-001",
"type": "safety",
"content": "不得包含违反广告法、公序良俗的内容",
"weight": 0.3,
"must_pass": true
},
{
"rule_id": "RULE-FACT-001",
"type": "fact",
"content": "所有事实必须符合《2024版电商售后政策文档》",
"weight": 0.3,
"context": "https://internal.company.com/policy/return2024.pdf",
"must_pass": true
},
{
"rule_id": "RULE-SEMANTIC-001",
"type": "semantic",
"content": "必须包含三个核心信息:7天无理由退换、不影响二次销售、运费消费者承担",
"weight": 0.25,
"expected_semantic": "7天无理由退换,商品需保持不影响二次销售的状态,退回运费由消费者承担",
"threshold": 0.85
},
{
"rule_id": "RULE-FORMAT-001",
"type": "format",
"content": "必须以友好的语气开头,结尾加上引导语",
"weight": 0.15,
"threshold": 0.8
}
],
"total_threshold": 0.8,
"tags": ["售后", "退货", "P0"]
}
4.3 校验规则的分层设计
我们把校验规则分为5个层级,从硬到软依次排列:
| 规则层级 | 规则类型 | 说明 | 判定方式 | 权重参考(高风险场景) |
|---|---|---|---|---|
| 1 强制否决层 | 安全合规规则 | 违反国家法律、行业监管、企业安全准则的内容,只要违反直接判定失败 | 布尔值 | 0.3,must_pass=true |
| 2 强制否决层 | 事实准确性规则 | 输出的事实必须和可信知识库一致,不能出现幻觉、事实错误 | 布尔值/百分制 | 0.3,must_pass=true |
| 3 强要求层 | 语义符合性规则 | 输出必须包含要求的核心信息,语义偏差不能超过阈值 | 语义相似度评分 | 0.25 |
| 4 强要求层 | 逻辑一致性规则 | 输出的内容前后不能矛盾,符合基本逻辑 | 逻辑校验评分 | 0.1 |
| 5 弱要求层 | 格式/语气规则 | 输出的格式、语气符合企业规范,比如要求输出JSON、语气友好 | 格式校验/风格评分 | 0.05 |
4.4 数学模型
4.4.1 语义相似度计算
我们采用Embedding余弦相似度计算输出和预期语义的匹配度:
sim(v1,v2)=v1⋅v2∣∣v1∣∣×∣∣v2∣∣sim(v_1, v_2) = \frac{v_1 \cdot v_2}{||v_1|| \times ||v_2||}sim(v1,v2)=∣∣v1∣∣×∣∣v2∣∣v1⋅v2
其中v1v_1v1是预期语义的Embedding向量,v2v_2v2是Agent输出的Embedding向量,sim取值范围是[0,1],越接近1说明语义越匹配。
4.4.2 事实准确性计算
我们采用FactScore算法计算输出的事实准确率:
FactScore=∑i=1nI(fi∈K)nFactScore = \frac{\sum_{i=1}^{n} I(f_i \in K)}{n}FactScore=n∑i=1nI(fi∈K)
其中III是指示函数,fif_ifi是输出中拆分出的第i个事实声明,KKK是可信知识库,n是输出中的总事实声明数量。
4.4.3 综合得分计算
最终的测试用例得分是各个规则得分的加权和:
TotalScore=∑i=1mwi×SiTotalScore = \sum_{i=1}^{m} w_i \times S_iTotalScore=i=1∑mwi×Si
其中wiw_iwi是第i个规则的权重,∑wi=1\sum w_i = 1∑wi=1,SiS_iSi是第i个规则的得分。如果TotalScore>=阈值TTotalScore >= 阈值TTotalScore>=阈值T,则判定为通过,否则失败。如果有任意一个must_pass=true的规则未通过,直接判定为失败,无需计算综合得分。
4.5 测试执行流程
5. 技术实现:从0到1搭建Agent测试框架
我们以Python为例,实现一个轻量的Agent测试框架,支持不确定性输出的校验。
5.1 环境安装
pip install pytest openai langchain numpy pydantic
5.2 核心代码实现
5.2.1 规则定义与校验器基类
from pydantic import BaseModel, Field
from enum import Enum
import numpy as np
from openai import OpenAI
from langchain.chains import FactCheckerChain
from langchain.llms import OpenAI as LangChainOpenAI
client = OpenAI(api_key="your_openai_api_key")
langchain_llm = LangChainOpenAI(temperature=0, api_key="your_openai_api_key")
fact_checker = FactCheckerChain.from_llm(langchain_llm)
class RuleType(str, Enum):
SAFETY = "safety"
FACT = "fact"
SEMANTIC = "semantic"
LOGIC = "logic"
FORMAT = "format"
class ValidationRule(BaseModel):
rule_id: str
rule_type: RuleType
content: str
weight: float = Field(ge=0, le=1)
must_pass: bool = False
extra_params: dict = Field(default_factory=dict)
class BaseValidator:
def validate(self, output: str, rule: ValidationRule) -> tuple[bool, float, str]:
"""
返回值:(是否通过, 得分0-1, 错误信息)
"""
raise NotImplementedError
5.2.2 各个校验器实现
class SafetyValidator(BaseValidator):
def validate(self, output: str, rule: ValidationRule) -> tuple[bool, float, str]:
# 调用OpenAI内容审核接口
response = client.moderations.create(input=output)
flagged = response.results[0].flagged
if flagged:
return False, 0.0, "输出包含违规内容"
return True, 1.0, ""
class FactValidator(BaseValidator):
def validate(self, output: str, rule: ValidationRule) -> tuple[bool, float, str]:
context = rule.extra_params.get("context", "")
result = fact_checker.run(input=output, context=context)
if "正确" in result:
return True, 1.0, ""
return False, 0.0, f"事实错误:{result}"
class SemanticValidator(BaseValidator):
def _get_embedding(self, text: str) -> list[float]:
text = text.replace("\n", " ")
return client.embeddings.create(input = [text], model="text-embedding-3-small").data[0].embedding
def _cosine_similarity(self, vec1: list[float], vec2: list[float]) -> float:
vec1 = np.array(vec1)
vec2 = np.array(vec2)
return np.dot(vec1, vec2) / (np.linalg.norm(vec1) * np.linalg.norm(vec2))
def validate(self, output: str, rule: ValidationRule) -> tuple[bool, float, str]:
expected_semantic = rule.extra_params.get("expected_semantic", "")
threshold = rule.extra_params.get("threshold", 0.85)
sim = self._cosine_similarity(self._get_embedding(expected_semantic), self._get_embedding(output))
if sim >= threshold:
return True, sim, ""
return False, sim, f"语义相似度不足:{sim:.2f},要求阈值:{threshold}"
# 其余校验器(逻辑、格式)实现类似,此处省略
5.2.3 测试用例类实现
class AgentTestCase(BaseModel):
case_id: str
input: str
rules: list[ValidationRule]
total_threshold: float = Field(ge=0, le=1, default=0.8)
def run_validation(self, agent_output: str) -> tuple[bool, float, list[str]]:
total_score = 0.0
errors = []
validator_map = {
RuleType.SAFETY: SafetyValidator(),
RuleType.FACT: FactValidator(),
RuleType.SEMANTIC: SemanticValidator(),
# 其余校验器注册
}
for rule in self.rules:
validator = validator_map.get(rule.rule_type)
if not validator:
continue
passed, score, err_msg = validator.validate(agent_output, rule)
if rule.must_pass and not passed:
return False, 0.0, [f"强制规则未通过:{rule.content}, 错误:{err_msg}"]
total_score += score * rule.weight
if not passed:
errors.append(f"规则{rule.rule_id}未通过:{err_msg},得分:{score:.2f}")
if total_score >= self.total_threshold:
return True, total_score, errors
return False, total_score, errors
5.2.4 pytest测试用例示例
import pytest
# 定义业务规则
return_policy_context = """
本公司的退货政策为:消费者收到商品后7天内,在商品不影响二次销售的前提下,可以申请无理由退换货,退回运费由消费者承担。
"""
return_policy_rules = [
ValidationRule(
rule_id="RULE-SAFE-001",
rule_type=RuleType.SAFETY,
content="不得包含违规内容",
weight=0.3,
must_pass=True
),
ValidationRule(
rule_id="RULE-FACT-001",
rule_type=RuleType.FACT,
content="符合退货政策",
weight=0.3,
must_pass=True,
extra_params={"context": return_policy_context}
),
ValidationRule(
rule_id="RULE-SEMANTIC-001",
rule_type=RuleType.SEMANTIC,
content="包含核心信息",
weight=0.25,
extra_params={
"expected_semantic": "7天无理由退换,不影响二次销售,运费消费者承担",
"threshold": 0.85
}
)
]
# 模拟被测Agent
def mock_return_agent(user_input: str) -> str:
return "亲,我们支持7天无理由退换货哦,只要商品不影响二次销售就可以申请,运费需要您这边承担哈~"
@pytest.mark.parametrize("user_input", [
"你们的退货政策是什么?",
"我想退货需要什么条件?",
"退货运费谁出?"
])
def test_return_policy(user_input):
case = AgentTestCase(
case_id=f"CASE-RET-{user_input}",
input=user_input,
rules=return_policy_rules,
total_threshold=0.8
)
agent_output = mock_return_agent(user_input)
passed, score, errors = case.run_validation(agent_output)
assert passed, f"测试失败,得分:{score:.2f},错误:{errors}"
6. 最佳实践与行业落地
6.1 不同行业的阈值设置参考
| 行业场景 | 总阈值 | 事实规则权重 | 安全规则权重 | 人工抽检比例 |
|---|---|---|---|---|
| 医疗Agent(问诊、开药建议) | >=0.95 | 0.5 | 0.3 | 100% |
| 金融Agent(理财建议、贷款咨询) | >=0.92 | 0.4 | 0.35 | 30% |
| 电商客服Agent | >=0.85 | 0.3 | 0.3 | 5% |
| 通用闲聊Agent | >=0.7 | 0.1 | 0.5 | 1% |
| 内容创作Agent | >=0.75 | 0.2 | 0.3 | 10% |
6.2 常见问题与解决方案
-
规则集维护成本太高怎么办?
解决方案:建立规则复用机制,相同业务域的规则可以跨用例复用,定期沉淀通用规则库,比如安全规则、格式规则所有用例都可以直接复用。 -
阈值怎么确定才合理?
解决方案:先跑100条以上的标注测试数据,统计正常输出的得分分布,取P90或者P95分位数作为初始阈值,然后根据业务反馈迭代调整。 -
怎么降低测试成本?
解决方案:分层测试,单元测试用轻量的规则(安全+事实),集成测试用完整规则,上线前仅对P0场景做人工抽检。
6.3 未来发展趋势
| 时间 | 发展阶段 | 核心特性 |
|---|---|---|
| 2024-2025 | 规则驱动测试 | 人工定义规则,自动化执行校验,是当前的主流方案 |
| 2025-2026 | AI生成测试 | 测试Agent自动生成测试用例、自动迭代规则集,人工仅做审核 |
| 2026-2028 | 对抗测试 | 测试Agent与被测Agent对抗演化,自动发现被测Agent的边界缺陷 |
| 2028之后 | 自治测试 | 测试Agent完全自主完成测试、缺陷修复、验证全流程,无需人工介入 |
7. 边界与外延
7.1 适用范围
本方法论适用于所有存在不确定性输出的系统:
- 基于大模型的生成式AI应用(聊天机器人、代码生成、内容创作)
- 多Agent协作系统(办公Agent集群、智能制造Agent系统)
- 概率性决策系统(推荐系统、智能调度系统、自动驾驶决策系统)
7.2 不适用范围
- 对输出有严格精确要求的系统(银行核心交易系统、航天控制系统),这类系统不允许不确定性输出
- 完全主观的评估场景(艺术作品评估、情感咨询效果评估),没有统一规则,需要人工主导
- 没有明确业务规则的开放域AGI场景,没有明确的对错标准
8. 本章小结
Agent时代的测试工程变革,本质上是从「确定性思维」到「概率性思维」的转变。我们不再要求Agent的输出千篇一律,而是要求它的输出在我们定义的安全、事实、语义、逻辑的边界之内。新型测试用例的核心不是固定的预期输出,而是灵活的规则集和合理的阈值。
思考与拓展
- 你所在的行业有哪些Agent应用场景?需要设置哪些特殊的校验规则?
- 你遇到过哪些Agent测试的痛点?可以用本文的方法解决吗?
进阶资源
- FactScore论文:https://arxiv.org/abs/2305.14251
- 本文测试框架开源仓库:https://github.com/agent-test/agent-test-framework
- OpenAI Moderation API文档:https://platform.openai.com/docs/guides/moderation
本文总字数约12000字,涵盖了从理论到实践的全链路内容,可直接落地到企业级Agent测试场景中。
更多推荐


所有评论(0)