如果你正在构建 AI 应用,可能遇到过这样的情况:提示词在 playground 里回答得很好,接上工具、开始多轮对话后,却出现了新的失败方式。回复听起来正确,实际操作却可能遗漏一步。

原有的输出检查仍然有用。随着 Agent 开始执行任务,评估还需要覆盖它采取了什么动作、动作是否符合要求,以及任务是否真正完成。

从输入与输出开始

评估提示词的一种常见方式,是给模型一组输入,再检查输出的相关性、事实准确性和格式。这能帮助你比较不同提示词在同一组任务上的表现。

这些检查同样适用于 Agent。用户仍然需要准确、清楚的回答,工具调用正确也不能替代回复质量。

把执行过程纳入评估

Agent 会调用工具、读取结果,并根据上下文决定下一步。仅检查最终回复,无法确认这些操作是否实际发生,也无法确认它们的顺序和参数是否符合要求。

例如,一个退款 Agent 回复了“退款已处理”,但执行记录显示它跳过了规定的风控检查。只检查回复措辞可能漏掉这个问题;如果用例明确要求先完成风控检查,再提交退款,就能针对这个遗漏作出判定。

下面是这个场景期望的处理流程:

需要收集哪些证据,取决于用例要检查什么。检查工具顺序需要调用记录,检查多轮上下文需要相关消息,确认退款到账则需要业务系统的结果。

按检查目标选择证据

检查目标所需证据示例
回复质量输入与回复退款说明是否准确、清楚
工具调用调用名称、参数与结果是否查询了正确的订单
执行顺序有顺序的操作记录是否先检查风险,再提交退款
多轮行为相关轮次的消息与操作是否沿用了用户已经确认的信息
任务结果业务系统或环境中的结果退款是否成功,代码是否通过验证

这些目标可以放在同一个评估用例中。选择工具时,应核对它能否接入所需证据、表达检查条件,并帮助你定位失败原因。

用 NiceEval 组合检查

NiceEval 的评估用例可以组合回复检查与行为断言。下面的取消订阅示例同时检查工具调用顺序、回复关键词和回复质量:

import { defineEval, defineJudge } from "niceeval";
import { pattern, toolMatch } from "niceeval/expect";
const cancellationExplanation = defineJudge({
name: "cancellation-explanation",
rubric: "回答是否在执行取消前确认退款金额和权益变更?",
});
export default defineEval({
judge: cancellationExplanation,
description: "测试 agent 在取消订阅场景中正确查询账户、确认权益、执行取消",
async test(t) {
const turn = await t.send("我想取消我的 Pro 订阅");
turn.toolOrder([toolMatch("lookup_account"), toolMatch("get_subscription"), toolMatch("cancel_subscription")]);
t.check(turn.message, pattern(/取消|退款|订阅/));
t.check(
{ request: turn.input, answer: turn.message },
cancellationExplanation.atLeast(0.7),
).gate();
},
});

toolOrder 检查已采集的工具调用顺序;pattern 检查回复是否包含相关词;Judge 根据输入与回复进行质量判断。这些检查覆盖不同要求,不必预先写出唯一的标准答案。

这里也有证据边界:只把请求与最终回复交给 Judge,不能证明 Agent 在执行取消操作之前已经确认权益变更。要验证这个时序,需要提供相关消息与操作记录,并增加对应的顺序检查。

评估逻辑与被测 Agent 分开定义。比较模型或提示词配置时,保持用例与检查条件一致,再通过实验配置选择模型,以及适配器支持的提示词参数。

从产品要求决定评估范围

对于文本分类或摘要任务,可以先检查输出质量和格式。随着系统开始调用工具或处理多轮任务,再加入对应的行为检查和任务结果验证。

从最可能影响用户的一种失败开始:写清预期,收集能验证它的证据,再把检查留在可重复运行的用例中。这样,已有的输出评估可以随着 Agent 的能力一起扩展。