企业级Agent Evaluation实战:Agent能跑就能上线?AI Agent到底怎么测?

0 阅读13分钟

前言

前面我们已经聊过:

  • Tool Calling 怎么让大模型调用业务能力;
  • ReAct Agent 怎么动态决定下一步动作;
  • Graph / Workflow 怎么编排复杂 AI 流程;
  • 企业级 RAG 怎么解决引用、拒答与知识治理。

当 Agent 真正跑起来以后,下一个问题其实更加重要:

Agent 能跑,就代表它能上线了吗?

很多团队刚开始测试 Agent,方法非常直接:

准备几个问题
    ↓
人工调用 Agent
    ↓
看看最终答案
    ↓
感觉还不错
    ↓
上线

问题在于:

Agent 不只有最终答案,还有完整的执行过程。

例如用户问:

查询订单 A1001 退款失败的原因。

理想路径可能是:

queryOrder
    ↓
queryRefund
    ↓
生成结果

但实际 Agent 可能执行成:

queryOrder
    ↓
queryPayment
    ↓
queryOrder
    ↓
queryRefund
    ↓
queryRefund
    ↓
最终回答正确

如果只看最终答案:

退款失败原因是收款账户状态异常。

这次测试可能仍然会被判定为:

PASS

但从执行过程来看,它已经暴露出很多问题:

  • 选错 Tool;
  • 重复调用 Tool;
  • 多走了几轮推理;
  • Token 消耗增加;
  • 整体耗时增加;
  • 下游系统被重复调用;
  • 如果 Tool 是写操作,甚至可能产生真实业务风险。

所以整篇文章最核心的一句话其实就是:

Agent 最终答案正确,不等于 Agent 执行正确。

这也是 Agent Evaluation 和普通 LLM Evaluation 最大的区别之一。


1. 企业级Agent Evaluation到底应该评什么?

普通 LLM 应用通常可以简化成:

Input
  ↓
LLM
  ↓
Output

所以评测重点主要集中在 Output:

回答正确吗?

和问题相关吗?

有没有幻觉?

是否符合格式?

但 Agent 的链路已经变成:

Input
  ↓
Decision / Routing
  ↓
Tool Selection
  ↓
Tool Arguments
  ↓
Tool Execution
  ↓
Observation
  ↓
下一轮决策
  ↓
Final Answer

此时只检查 Final Answer 显然不够。

企业级 Agent Evaluation 至少应该拆成三层:

Result Evaluation
结果评测

Process Evaluation
过程评测

Engineering Evaluation
工程评测

也就是说,我们不仅要知道:

最后答对了吗?

还要知道:

它是怎么答对的,以及为这个答案付出了多大工程成本。


2. Result Evaluation:任务到底完成了吗?

第一层最容易理解:最终结果。

例如用户要求:

查询订单 A1001 退款失败原因。

预期业务结果:

ACCOUNT_INVALID

Agent 最终回答:

该订单退款失败,原因是收款账户状态异常。

那么从业务结果来看:

Task Success = PASS

这一层重点看三个指标。

2.1 Task Success

Task Success 不是问:

模型回答得像不像正确答案?

而是:

业务任务最终有没有真正完成。

例如:

查询订单
→ 是否返回正确订单

生成报表
→ 报表是否真正生成

创建工单
→ 工单是否真正落库

查询退款原因
→ 是否拿到正确业务状态

对于企业 Agent 来说,Task Success 往往比语言表达是否漂亮更重要。


2.2 Answer Correctness

最终答案本身是否正确。

如果结果是结构化业务状态,可以直接使用确定性规则:

expectedResult.equals(actualResult)

如果最终输出是自然语言,则可以进一步使用语义评估。


2.3 Groundedness

最终回答有没有真实依据。

例如 Tool 返回:

{
  "refundStatus": "FAILED",
  "reason": "ACCOUNT_INVALID"
}

结果 Agent 却回答:

因用户主动取消导致退款失败。

语言虽然流畅,但已经脱离了 Tool Result。

所以企业 Agent 不仅要:

Answer Correctly

还要:

Answer Based On Evidence

3. Process Evaluation:Tool、参数和轨迹是否正确?

这一层才是 Agent Evaluation 真正区别于普通 LLM Evaluation 的地方。

假设理想路径是:

queryOrder
    ↓
queryRefund

实际路径却是:

queryOrder
    ↓
queryPayment
    ↓
queryOrder
    ↓
queryRefund

即使最后答案正确,这次执行也不能简单判定为“完全通过”。

3.1 Tool Selection Accuracy

首先要看 Agent 有没有选对工具。

测试集预期:

{
  "expectedTools": [
    "queryOrder",
    "queryRefund"
  ]
}

实际调用:

{
  "actualTools": [
    "queryOrder",
    "queryPayment",
    "queryRefund"
  ]
}

说明任务虽然完成了,但 Tool Selection 已经存在偏差。


3.2 Tool Parameter Accuracy

工具选对了,参数也可能错。

例如预期:

{
  "tool": "queryOrder",
  "arguments": {
    "orderNo": "A1001"
  }
}

实际却生成:

{
  "orderNo": "A1010"
}

那么:

Tool Selection = PASS

Parameter Accuracy = FAIL

这也是为什么:

Tool 调用成功率 ≠ Tool 调用正确率。

HTTP 200 只能说明接口执行成功,不能说明 Agent 调用了正确的数据。


3.3 Trajectory、Duplicate Call和Loop

Agent 还需要关注完整执行轨迹。

例如:

queryOrder(A1001)

queryRefund(A1001)

queryOrder(A1001)

如果前两步已经拿到了足够信息,第三次调用就属于不必要执行。

这种问题会直接带来:

  • Token 增加;
  • 响应时间增加;
  • API 成本增加;
  • 下游压力增加。

如果换成创建订单、退款、审批等写操作,重复调用甚至可能产生真实业务风险。

另一个典型问题就是死循环:

Tool A
 ↓
Tool B
 ↓
Tool A
 ↓
Tool B
 ↓
Tool A
 ↓
...

因此测试用例中可以直接定义:

maxSteps = 5

超过最大步骤,即使最终得出了答案,也应该认为此次执行存在质量问题。


3.4 能确定的东西,不要全部交给LLM Judge

这里有一个非常重要的原则:

确定性问题,优先使用确定性规则。

例如:

Tool 是否选对?

订单号是不是 A1001?

有没有调用禁止工具?

执行次数是否超过 5?

耗时有没有超过 10 秒?

这些根本没必要再调用一次 LLM。

直接判断即可:

expectedTools == actualTools

expectedOrderNo == actualOrderNo

stepCount <= maxSteps

forbiddenTools ∩ actualTools == ∅

latency <= maxLatency

LLM-as-a-Judge 更适合解决:

  • 回答语义是否正确;
  • 是否完整;
  • 是否符合上下文;
  • 是否存在明显幻觉;
  • 表达是否满足要求。

所以企业 Agent Evaluation 更合理的组合应该是:

Deterministic Evaluator
        +
LLM-as-a-Judge

而不是:

Everything
    ↓
LLM Judge

一句话总结:

LLM-as-a-Judge 负责判断语义质量,确定性规则负责守住工具、参数、轨迹和工程边界。


4. Engineering Evaluation:正确还不够,还得跑得起

假设现在有两个 Agent。

Agent A:

Task Success:95%

平均耗时:3.2s

平均 Tool 调用:2.3 次

平均 Token:3200

Agent B:

Task Success:96%

平均耗时:18s

平均 Tool 调用:7.8 次

平均 Token:12000

Agent B 的任务成功率高了 1%。

但它:

  • 慢很多;
  • Token 高很多;
  • Tool 调用更多;
  • 对下游系统压力更大。

到底应该选哪个?

这已经不是单纯的“模型准确率”问题,而是企业系统必须考虑的工程取舍。

因此第三层至少应该统计:

Latency

Token Usage

Estimated Cost

Tool Call Count

Retry Count

Error Rate

Timeout Rate

如果系统还有统一 AI Gateway,还可以继续关联:

限流

重试

熔断

Fallback

模型路由

所以一个 Agent 能不能上线,不仅取决于:

它能不能完成任务。

还取决于:

它能不能以可接受的成本、延迟和稳定性完成任务。


5. Agent Evaluation第一件事不是写Evaluator,而是建Dataset

很多人看到 Evaluation,第一反应是:

找个框架开始打分。

但我认为顺序反了。

Agent Evaluation 最重要的东西不是 Evaluator,而是:

Evaluation Dataset。

如果没有稳定测试集:

今天修改一个 Prompt,手工测 10 个问题;

明天换一个模型,再重新随便测几个问题。

最终所有结果都无法横向比较。

一个基础 Agent 测试用例可以这样定义:

{
  "caseId": "refund-001",
  "question": "查询订单A1001退款失败原因",
  "expectedResult": "ACCOUNT_INVALID",
  "expectedTools": [
    "queryOrder",
    "queryRefund"
  ],
  "forbiddenTools": [
    "cancelOrder"
  ],
  "maxSteps": 4
}

进一步还可以增加:

expectedArguments

expectedEvidence

allowedTools

maxLatency

maxToken

测试集来源也不应该全部靠开发人员拍脑袋。

更加合理的流程是:

真实业务问题
    ↓
脱敏
    ↓
去重
    ↓
场景分类
    ↓
专家标注
    ↓
Expected Result
+
Expected Tool
+
业务约束
    ↓
Evaluation Dataset

所以一个高质量 Dataset,本质上就是 Agent 上线前的:

能力基线。

以后换模型、改 Prompt、增加 Tool、修改 Agent Strategy,都应该重新跑同一套 Dataset。

这时候测试结果才真正具有可比性。


6. Spring AI能为Agent Evaluation提供什么?

Spring AI 当前已经提供统一的 Evaluator 接口:

@FunctionalInterface
public interface Evaluator {

    EvaluationResponse evaluate(
            EvaluationRequest evaluationRequest);
}

EvaluationRequest 核心包含:

userText

dataList

responseContent

也就是:

用户问题

上下文数据

模型回答

同时还提供了:

RelevancyEvaluator

FactCheckingEvaluator

前者适合判断回答和问题、上下文是否相关;

后者适合判断回答中的 Claim 能否被 Context 支撑。

因此 Spring AI 的 Evaluator 很适合成为整个 Agent Evaluation 中的:

Answer Judge。

但这里一定要明确一个边界:

Spring AI Evaluator ≠ 完整 Agent Evaluation。

因为企业 Agent 还需要评:

Tool Selection

Tool Arguments

Tool Result

Trajectory

Step Count

Retry / Loop

Latency

Token / Cost

所以框架可以帮我们完成“回答怎么评”,但完整 Agent 质量体系仍然需要应用自己构建。


7. Spring AI 2.0为什么更适合采集Agent Trace?

Agent Evaluation 要评执行过程,首先得能拿到执行过程。

Spring AI 2.0 对 Tool Calling 做了一个很重要的调整:

Tool Calling 循环由 ToolCallingAdvisor 管理,Tool Execution 不再只是隐藏在模型实现内部的一段黑盒逻辑。

执行链大致变成:

User
 ↓
ChatClient
 ↓
Advisor Chain
 ↓
ToolCallingAdvisor
 ↓
LLM
 ↓
Tool Call
 ↓
Tool Result
 ↓
下一轮LLM
 ↓
...
 ↓
Final Answer

这意味着应用可以更自然地观察 Tool Loop。

如果需要完全控制每一轮,还可以关闭自动 Tool Calling,由应用通过 ToolCallingManager 自己驱动执行:

while (response.chatResponse() != null
        && response.chatResponse().hasToolCalls()) {

    ToolExecutionResult result =
            toolCallingManager.executeToolCalls(
                    prompt,
                    response.chatResponse());

    prompt = new Prompt(
            result.conversationHistory(),
            chatOptions);

    response = chatClient.prompt()
            .messages(result.conversationHistory())
            .options(chatOptions)
            .advisors(
                AdvisorParams
                    .toolCallingAdvisorAutoRegister(false))
            .call()
            .chatClientResponse();
}

这样每一轮都可以记录:

调用了什么 Tool

Tool 参数是什么

执行结果是什么

耗时多少

总共执行多少轮

最终什么时候结束

而这些数据,正是:

Trajectory Evaluation 的基础。

需要注意:

Spring AI 2.0 解决的是:

怎么让 Tool Loop 更容易被观察和扩展。

它并不会自动替业务定义:

什么样的轨迹才算“正确”。

后者仍然需要 Dataset 和业务规则。


8. 当前项目已经具备哪些Evaluation基础?

回到我的开源项目:

github.com/qcodingdev/…

再次强调:

当前项目还没有独立完整的 Agent Evaluation 模块。

但项目里已经存在一些后续做 Evaluation 非常重要的基础能力。

例如 Knowledge Copilot 调用模型时,并不是简单拿一个字符串结果:

AiInvocationResult<LlmAnswerOutput> invocation =
        aiChatService.generatePromptJsonWithMetadata(
                "knowledge.answer-generation",
                prompt.content(),
                LlmAnswerOutput.class);

LlmAnswerOutput llmOutput =
        invocation.content();

AiInvocationMetadata aiMetadata =
        invocation.metadata();

这里已经把:

业务调用

AI Response

Invocation Metadata

进行了分离。

完整代码可以查看:

modules/knowledge-copilot/
src/main/java/dev/qcoding/businesscopilot/
knowledgecopilot/answer/KnowledgeAnswerService.java

这类设计本身还不能叫 Agent Evaluation。

但它解决了 Evaluation 非常重要的前置问题:

执行数据能不能被稳定记录下来。

因为如果连:

用了哪个模型

用了哪个 Prompt

最终状态是什么

耗时多少

Token 使用多少

触发了什么规则

都不知道,那么后面的回归评测、版本对比、失败分析都无从谈起。

所以从工程演进来看,我更倾向于:

先把调用链变得可观察,再在可观察数据之上构建 Evaluation。


9. 一套生产级Agent Evaluation Pipeline应该长什么样?

如果继续往 spring-ai-business-copilot 里演进,我不会一上来做一个巨大的“AI评测平台”。

更合理的是逐步增加:

现有 Copilot
    ↓
Invocation Metadata
    ↓
Tool Trace
    ↓
Evaluation Dataset
    ↓
Evaluation Runner
    ↓
┌────────────────────────┐
│ Deterministic Evaluator│
│ LLM-as-a-Judge         │
└────────────────────────┘
    ↓
Metrics
    ↓
Evaluation Report
    ↓
Release Gate

Trace 可以类似:

{
  "traceId": "trace-10001",
  "caseId": "refund-001",
  "steps": [
    {
      "step": 1,
      "tool": "queryOrder",
      "success": true,
      "durationMs": 128
    },
    {
      "step": 2,
      "tool": "queryRefund",
      "success": true,
      "durationMs": 176
    }
  ],
  "latencyMs": 3240,
  "taskSuccess": true
}

然后分别交给:

Rule Evaluator
→ Tool / Args / Step / Latency

LLM Judge
→ Correctness / Groundedness

Metrics Aggregator
→ 汇总指标

最终输出:

Task Success

Answer Correctness

Tool Selection Accuracy

Parameter Accuracy

Trajectory Pass Rate

Groundedness

Average Steps

P95 Latency

Token Usage

Error Rate


10. Evaluation最终应该变成Release Gate

如果 Evaluation 只是:

开发人员上线前手工跑一次。

那么它很难真正形成工程价值。

更合理的是把它变成固定 Pipeline:

Dataset
    ↓
Agent Runner
    ↓
Trace Collector
    ↓
Rule Evaluator
+
LLM-as-a-Judge
    ↓
Metrics Aggregator
    ↓
Evaluation Report
    ↓
Release Gate

例如项目可以根据自己的历史基线和业务风险设置门槛:

Task Success >= 95%

Tool Accuracy >= 95%

Groundedness >= 90%

Loop Rate <= 1%

P95 Latency <= 8s

注意:以上数值只是说明 Release Gate 的设计方式,不是行业统一标准。

实际阈值应该根据业务风险、Agent 类型、历史版本基线和成本要求制定。

当我们修改:

Prompt

Model

Tool

Agent Strategy

如果新版本让核心指标明显下降,就不应该直接发布。

Evaluation 到这里才真正从:

一份测试报告

升级成:

AI系统上线门禁。


11. 线上失败样本,应该反哺下一轮Evaluation

测试集永远不可能一次建完。

Agent 上线以后一定还会遇到:

测试集没有覆盖的问题

模型升级后的能力漂移

Prompt 修改导致旧场景回退

新 Tool 影响 Tool Selection

真实线上失败 Case

所以完整闭环应该是:

Development
    ↓
Offline Evaluation
    ↓
Release Gate
    ↓
Production
    ↓
Trace / Observability
    ↓
Failure Sample
    ↓
人工审核
    ↓
加入 Dataset
    ↓
再次 Evaluation

这也是 Agent Evaluation 和 Agent Observability 应该结合起来看的原因。

Evaluation 回答的是:

这个版本上线前是否达标?

Observability 回答的是:

这个版本上线以后真实发生了什么?

而线上真实失败样本,又会成为下一轮 Dataset 最有价值的数据来源。

最终形成:

Evaluation
    ↓
Production
    ↓
Observability
    ↓
Failure
    ↓
Dataset
    ↓
Evaluation

这才是一套持续演进的 Agent 质量体系。


12. 总结

最后把整篇文章压缩成一张表:

层级核心指标推荐方式
ResultTask Success规则 / 专家标注
ResultAnswer Correctness规则 + LLM Judge
ResultGroundednessEvidence + LLM Judge
ProcessTool Selection确定性规则
ProcessTool ArgumentsSchema / Expected Args
ProcessTrajectoryTrace + 路径规则
ProcessRetry / LoopTrace 统计
EngineeringLatencyMetrics
EngineeringToken / CostMetrics
EngineeringError RateMetrics

可以看到:

真正需要 LLM-as-a-Judge 的,只是 Agent Evaluation 的一部分。

大量评测工作依然是我们熟悉的:

数据采集

规则判断

指标统计

回归测试

发布门禁

只不过测试对象已经从传统:

API

变成了:

Agent 行为

所以回到文章最开始的问题:

Agent 能跑,就能上线吗?

答案显然不是。

真正可靠的企业 Agent,至少需要同时满足三件事:

结果正确
Result

过程正确
Process

工程可接受
Engineering

Spring AI 可以帮我们完成回答评测,并让 Tool Calling 的执行过程更容易被观察。

但真正的企业级 Agent Evaluation,依然需要在框架之上补齐:

Dataset、Trace、Tool Evaluation、Trajectory Evaluation、Metrics 和 Release Gate。

所以我更愿意把 Agent Evaluation 理解成:

不是给 AI 最终答案打一个分,而是给整个 Agent 执行过程建立一套可重复验证的质量体系。

这才是 Agent 从:

“跑起来了”

真正走向:

“我敢让它进入生产”

必须补上的一步。


🧩 AI项目实战

我也在持续维护一个面向企业真实业务场景的 Java AI 开源项目:Spring AI Business Copilot。

项目基于 Java + Spring AI 构建,包含知识库、数据分析(NL2SQL)、客服、报表、招聘等典型企业 AI 场景,并持续实践 RAG、Tool Calling、Workflow、Agent、Human-in-the-loop、Guardrails、调用审计与工程治理。

如果你正在学习 Java AI 应用开发,或者想看看一个 AI 项目如何从 Demo 逐步走向完整业务系统,可以作为学习和项目实践参考。

👉 GitHub:qcodingdev/spring-ai-business-copilot

如果项目对你有帮助,欢迎 Star 支持。


👨‍💻 关于作者|QCoding

专注 AI应用开发与Java技术实践。

持续分享 Spring AI、RAG、 Agentic、Agent Evaluation、企业AI架构、工程治理与AI转型实践