Agent 端到端自动化评估体系
覆盖 6 个核心质量维度,通过真实 LLM 调用 + LLM-as-Judge 评分,量化证明 Agent 架构设计决策的正确性。
目标
为 dawn-ai 构建一套端到端自动化评估体系,覆盖 AI Agent 系统的 6 个核心质量维度。通过真实 LLM 调用 + LLM-as-Judge 评分,量化证明 Agent 架构的设计决策正确性,并将评估结果自动写入 Langfuse Dashboard 形成可观测闭环。
非目标
- 不替代现有单元测试(37 个测试类保持不动,评估体系是补充而非替代)
- 不做线上 A/B 测试(本方案聚焦开发阶段的离线评估)
- 不引入 Langfuse Java SDK(延续现有纯 OTel 集成风格,评估打分通过 REST API 实现)
- 不做人工标注评估(纯自动化,LLM-as-Judge 替代人工)
已锁定决策
架构
数据流
EvaluationDatasetLoader.loadByDimension() 从 JSON 加载用例
agentOrchestrator.chat() 调用真实 LLM + 工具执行,返回 AgentResult
从 AgentResult.steps() 提取 actualTools / retrievedDocs / answer
JudgeService 加载 Prompt 模板 → 填充变量 → 调用 Judge LLM → 解析 JSON
assertThat(passed) + LangfuseScoringClient.score() 写入 Dashboard
评估维度
工具选择正确性
评什么:给定用户 query,Agent 是否调用了正确的 tool 组合。
面试价值:证明 ReAct 范式的工具调度可靠性。
| Query | 期望工具 | 验证点 |
|---|---|---|
| "今天北京天气怎么样?" | weatherTool | 天气查询 → 天气工具 |
| "帮我算 (15*23)+47" | calculatorTool | 数学计算 → 计算器 |
| "公司2024年营收增长率?" | knowledgeSearchTool | 知识查询 → RAG |
| "上海多少度?超30度算电费" | weather + calc | 多工具编排 |
RAG 召回相关性
评什么:检索到的文档是否与 query 语义相关,是否召回了正确的文档。
Answer 完整性
评什么:最终回答是否覆盖了 query 要求的所有关键信息点。
Prompt 拼装正确性
评什么:AgentOrchestrator.buildSystemPrompt() 是否正确拼装了所有必要的 prompt 段落。
验证方式:通过反射调用 private 方法,将实际输出与期望段落对比。
System Prompt 拼装顺序(8 段)
基础角色定义
UserProfileService.formatForSystemPrompt()
话题约束(如有 topicId)
formatSkills() — 技能目录
formatSubAgents() — 子 Agent 目录
TaskPlanner 输出
计划强制指令
最大步数限制
子 Agent 上下文隔离
评什么:子 Agent 的执行是否与主 Agent 完全隔离。
多轮对话连贯性
评什么:Agent 是否正确利用对话历史(memory snapshot)提供连贯的回答。
数据模型
统一 JSON Schema
各维度字段使用矩阵
| 字段 | 工具选择 | RAG | Answer | Prompt | 子Agent | 多轮 |
|---|---|---|---|---|---|---|
| query | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| availableTools | ✓ | ○ | ○ | – | ✓ | – |
| memorySnapshot | – | – | – | – | – | ✓ |
| ragDocuments | – | ✓ | ✓ | – | – | – |
| promptSegments | – | – | – | ✓ | – | – |
| subAgentBehavior | – | – | – | – | ✓ | – |
| expected.tools | ✓ | ○ | ○ | – | ✓ | – |
| answerCriteria | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| docIds | – | ✓ | ✓ | – | – | – |
✓ 必填 ○ 可选 – 不适用
数据集规模
Judge 系统
为什么需要独立 Judge 模型
Judge Prompt 设计原则
要求返回 {"score": N, "reasoning": "..."} JSON
每个 Prompt 内嵌评分 rubric,消除歧义
JudgeService.extractJson() 自动剥离 markdown 代码围栏
{{variable}} 占位符,运行时填充
评分阈值
Langfuse 集成
双写策略
- git 版本控制
- CI 原生加载
- 离线可用
- UI 可视化
- Experiment 对比
- 评分趋势
REST API 端点
| 端点 | 用途 | 调用时机 |
|---|---|---|
POST /api/public/scores | 写入评分 | 每个 case 评估完成后 |
POST /api/public/datasets | 创建/更新 Dataset | 评估开始前 |
POST /api/public/dataset-items | 添加 Dataset Item | 同步数据集时 |
POST /api/public/dataset-run-items | 关联 trace 到 Dataset | 评估完成后 |
认证方式
测试执行
前置条件
运行命令
输出
| 输出 | 位置 | 格式 |
|---|---|---|
| 控制台报告 | stdout | score + reasoning + 总结 |
| 本地 JSON | target/evaluation-reports/ | 结构化 JSON |
| Langfuse 评分 | Dashboard → Scores | 评分趋势图 |
| Langfuse Dataset | Dashboard → Datasets | Experiment 对比 |
文件结构
测试体系对比
面试叙事线
开场(30 秒)
"我搭了一套 6 维度的 Agent 评估体系,用 LLM-as-Judge 做自动化评分。数据集 git 版本控制,评分自动写入 Langfuse Dashboard。mvn test -Dgroups=evaluation 一键跑完。"
技术深度(2-3 分钟)
逐维度展示:工具选择准确率 → RAG 召回 MRR → Answer 完整性 → Prompt 拼装 snapshot 回归 → 子 Agent 隔离证明 → 多轮对话记忆利用。每个维度用 30 秒,展示评分结果和 Judge reasoning。
工程化能力(1 分钟)
"评估结果双写:本地 JSON 做 git 版本控制,Langfuse Dashboard 做可视化。Judge 模型独立于业务模型,避免自评偏见。整个评估体系零 Langfuse SDK 依赖,通过 REST API 实现。"
迭代能力(30 秒)
"每次 prompt 变更后跑一次评估,Langfuse Experiment 对比不同版本的评分趋势。数据驱动迭代,不是凭感觉调 prompt。"
后续扩展
| 项目 | 优先级 | 说明 |
|---|---|---|
| 扩充数据集 | 高 | 每个维度扩充到 20+ 用例 |
| CI 集成 | 中 | GitHub Actions 运行评估,PR 评论评分 |
| Langfuse Experiment | 中 | 不同版本的评分趋势对比 |
| 人工标注校准 | 低 | 人工标注用例,校准 Judge 准确率 |
| 成本监控 | 低 | 统计评估运行的 LLM API 费用 |