前言
前面我们已经聊过:
- 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基础?
回到我的开源项目:
再次强调:
当前项目还没有独立完整的 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. 总结
最后把整篇文章压缩成一张表:
| 层级 | 核心指标 | 推荐方式 |
|---|---|---|
| Result | Task Success | 规则 / 专家标注 |
| Result | Answer Correctness | 规则 + LLM Judge |
| Result | Groundedness | Evidence + LLM Judge |
| Process | Tool Selection | 确定性规则 |
| Process | Tool Arguments | Schema / Expected Args |
| Process | Trajectory | Trace + 路径规则 |
| Process | Retry / Loop | Trace 统计 |
| Engineering | Latency | Metrics |
| Engineering | Token / Cost | Metrics |
| Engineering | Error Rate | Metrics |
可以看到:
真正需要 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转型实践