文章

LLM-as-a-Judge 不是银弹:拆解 IBM CLEAR 如何给 AI Agent 做全身体检

LLM-as-a-Judge 不是银弹:拆解 IBM CLEAR 框架如何给 AI Agent 做全身体检。

LLM-as-a-Judge 不是银弹:拆解 IBM CLEAR 如何给 AI Agent 做全身体检

从”能跑就行”到”量化诊断”——一个开源的企业级 Agent 事后审计框架深度解读

⏱️ 阅读时间:约 10 分钟


📋 读完你将了解

  • 为什么传统评测手段无法诊断多步 AI Agent 的”暗病”
  • CLEAR 双管道架构的设计哲学:LLM Analysis 与 Agentic Analysis 的本质区别
  • 6 种 LLM-as-a-Judge 评判策略如何做到”一题一策”,以及背后的策略模式实现
  • Aggregation 三步走(提炼→去重→映射)如何从海量评语中自动提炼系统级缺陷
  • 一条完整的 Agent Trace 从 JSON 到诊断报告的全流程数据解剖
  • 5 分钟上手实操:安装、配置、跑通第一条评测管道

一、那个莫名其妙挂掉的 Agent

你花了两周搭建的 Code Agent,在本地 Demo 跑得风生水起。

推到测试环境 100 条真实任务,挂了 23 条。你翻着几千行的 Trace 日志,眼睛发酸,最终得出结论——”幻觉了”。

但”幻觉了”这三个字,够你写复盘报告吗?

你没法回答以下任何一个问题:是哪个步骤开始出错的?工具选对了吗?参数合理吗?分析了问题但写错了补丁?还是补丁正确但测试不通过?

更致命的是——这些问题之间有模式吗?还是纯属随机个例?

这就是当前 AI Agent 工程化的核心尴尬:我们有能力把 Agent 跑起来,却没有任何系统手段去诊断它怎么就挂了

IBM 开源的 CLEAR(Comprehensive LLM Evaluation & Analysis Resource)正是为这个尴尬而生。

核心铁律: CLEAR 不是一个”打分框架”,而是一个”事后审计系统”。它的目标不是告诉你 Agent 好不好,而是告诉你——哪里不好、为什么不好、有没有规律。


二、两条流水线,两种哲学

CLEAR 的设计有一个非常显性的特征:它把评测拆成了两条完全独立的管道。

这不是过度设计,而是对”单一 LLM 调用”和”多步 Agent 推理”这两种场景本质差异的诚实面对。

2.1 先看全貌:CLEAR 四层架构

在深入两条管道之前,先建立全局认知。CLEAR 采用清晰的分层设计:

image

2.2 双管道对比

%%{init: {
  'theme': 'base',
  'themeVariables': {
    'background': '#0f172a',
    'primaryColor': '#1e293b',
    'primaryTextColor': '#f8fafc',
    'primaryBorderColor': '#38bdf8',
    'lineColor': '#64748b',
    'secondaryColor': '#1e1b4b',
    'tertiaryColor': '#0f172a',
    'edgeLabelBackground': '#1e293b'
  }
}}%%
graph LR
    subgraph LLM["LLM Analysis Pipeline 单轮对话评测"]
        direction LR
        A1[DataLoader<br/>CSV 加载] --> A2[Generation<br/>可选生成]
        A2 --> A3[EvalUseCase<br/>LLM-as-a-Judge 打分]
        A3 --> A4[Summary<br/>评语摘要]
        A4 --> A5[Aggregation<br/>问题聚合诊断]
    end

    subgraph AGENTIC["Agentic Analysis Pipeline 多步 Agent 评测"]
        direction LR
        B1[PreprocessTraces<br/>Trace 标准化] --> B2[StepByStep<br/>逐步骤评分]
        B1 --> B3[FullTrajectory<br/>全轨迹多维评估]
        B3 --> B4[ClearAnalysis<br/>根因 + 问题诊断]
    end

    A3 -.->|复用 EvalUseCase| B2
    A5 -.->|复用 Aggregation| B4

    %% 审美细节优化微调
    style LLM fill:#1e293b,stroke:#334155,stroke-width:2px,color:#f8fafc
    style AGENTIC fill:#0f172a,stroke:#312e81,stroke-width:2px,color:#f8fafc
    
    style A1 fill:#0ea5e9,stroke:#38bdf8,stroke-width:1px,color:#ffffff
    style A2 fill:#1e293b,stroke:#38bdf8,stroke-width:1px,color:#f8fafc
    style A3 fill:#1e293b,stroke:#38bdf8,stroke-width:1px,color:#f8fafc
    style A4 fill:#1e293b,stroke:#38bdf8,stroke-width:1px,color:#f8fafc
    style A5 fill:#1e293b,stroke:#38bdf8,stroke-width:1px,color:#f8fafc

    style B1 fill:#6366f1,stroke:#818cf8,stroke-width:1px,color:#ffffff
    style B2 fill:#1e1b4b,stroke:#818cf8,stroke-width:1px,color:#f8fafc
    style B3 fill:#1e1b4b,stroke:#818cf8,stroke-width:1px,color:#f8fafc
    style B4 fill:#1e1b4b,stroke:#818cf8,stroke-width:1px,color:#f8fafc
    
    linkStyle 0,1,2,3 stroke:#38bdf8,stroke-width:2px;
    linkStyle 4,5,6 stroke:#818cf8,stroke-width:2px;
    linkStyle 7,8 stroke:#cbd5e1,stroke-width:2px,stroke-dasharray: 5 5;

下面这张表看得会更清楚:

维度LLM AnalysisAgentic Analysis
评测对象单一 LLM 调用的一问一答多步 Agent 的完整执行轨迹
输入数据CSV(问题 + 回答 + 参考答案)JSON Trace(来自 MLflow/Langfuse)
评测粒度逐条记录逐步骤 + 全轨迹
核心能力打分 + 问题聚合打分 + 步骤诊断 + 根因分析
评判维度3 维(Adherence/Accuracy/Coherence)4 维(Correctness/Completeness/Relevance/ToolSelection)
经典场景评测翻译质量、数学解题、RAG 问答评测 Code Agent、Tool-Use Agent、多智能体协作

一句话区分: LLM Analysis 回答的是”这句话翻译得对不对”,Agentic Analysis 回答的是”这个程序员从接需求到交代码,每一步做得怎么样”。

为什么要拆成两条管道?因为评测逻辑根本不一样

单一 LLM 调用,你只需要看输入和输出——它回答了什么、对不对。但 Agent 的一次任务涉及多轮 LLM 调用和多次工具操作。issue_analyzer 分析对了但 code_writer 写错了,整个任务就挂了——你只盯着最终结果打分,等于给一个团队打绩效只看交付物不看过程。

CLEAR 的设计答案很清晰:把过程还给评测。


管道是骨架,但骨架再漂亮也回答不了一个核心问题 —— 谁来做裁判,又该怎么判?


三、裁判的六副面孔:LLM-as-a-Judge 怎么做到一题一策

聊到评测,绕不开一个核心命题——谁来做裁判?

CLEAR 的回答是”大模型当裁判”(LLM-as-a-Judge)。但这四个字已经被说烂了,大部分人理解的 LLM-as-a-Judge 就是:

“你帮我看看这个人回答得好不好,打个分。”

CLEAR 的不同在于:它把”打分”这个动作拆成了六种完全不同的裁判逻辑。

3.1 六种 Use Case 一览

每种 Use Case 有自己的 Prompt 模板、自己的评分维度、自己的解析方式:

Use Case核心评判逻辑典型 Prompt 指令
MathEval最终答案错误 → 最高 0.5 分“If the final answer is wrong, score cannot exceed 0.5”
RAGEval答案必须有检索文档支撑“Does the response faithfully reflect the provided documents?”
GeneralEval完全灵活的自定义标准用户通过 evaluation_criteria 自定义任意维度
AgentEval区分”思考”和”工具调用”“Separately assess reasoning quality and tool selection appropriateness”
ToolCallEvalSPARC 二元判定“Was the correct tool selected? Were parameters correct?”
External完全自定义 Judge接入外部评分服务或自定义逻辑

这六种 Use Case 之间不是”换个 Prompt”的关系,而是彻底的策略模式实现。

CLEAR 的 get_task_data_obj() 工厂函数根据你的 --task math--task rag,返回完全不同的 EvalUseCase 子类对象。来看一眼它核心的实现骨架:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# CLEAR 的策略模式:一套接口,六种实现
def get_task_data_obj(use_case_name: str) -> EvalUseCase:
    """工厂函数:根据名称返回对应的评判策略"""
    task_map = {
        "math":      MathUseCase,        # 数学:答案错误 → 上限 0.5
        "rag":       RAGUseCase,         # RAG:基于文档自洽性
        "general":   GeneralEvalUseCase, # 通用:完全自定义维度
        "agent":     AgentEvalUseCase,   # Agent:区分推理与工具调用
        "tool_call": ToolCallEvalUseCase,# 工具调用:SPARC 二元判定
        "external":  ExternalJudgeUseCase# 外部:接入自定义裁判
    }
    if use_case_name not in task_map:
        raise ValueError(f"Unknown use case: {use_case_name}")
    return task_map[use_case_name]()

# 每个子类重写自己的 Prompt 构建逻辑
class MathUseCase(EvalUseCase):
    def generate_evaluation_model_prompt(self, row) -> str:
        # 数学专属 Prompt:强调最终答案校验 + 推理步骤检查
        return f"""Evaluate this math solution...
        Rule: If final answer is incorrect, score ≤ 0.5
        Question: {row['question']}
        Response: {row['response']}
        Reference: {row.get('reference', 'N/A')}"""

设计要点: 不是 pipeline 里塞一堆 if-else,也不是一个万能 Prompt 打天下。每种任务有独立的 Prompt 模板和评分解析器,新增一种评测类型只需写一个新子类——这就是策略模式在评测系统中的经典应用。

3.2 一个 MathEval 的完整判例

来看一个具体的案例:

1
2
3
输入问题: 一个水池,进水管 3 小时注满,出水管 5 小时放完,同时开几小时注满?
模型回答: 2 小时
标准答案: 15/2 小时(即 7.5 小时)

如果你用规则匹配——”2小时”不等于”15/2小时”——判错,但毫无诊断价值。

CLEAR 的 MathEval Judge 会输出:

1
2
3
4
5
6
7
8
9
10
Evaluation score: 0.2

模型回答"2小时"完全错误。正确解法:
净流速 = 1/3 - 1/5 = 2/15 池/小时
时间 = 15/2 = 7.5 小时

问题诊断:
1. 缺乏任何推理步骤展示
2. 计算结果错误(可能犯了 5-3=2 的直觉错误)
3. 未展示对"净流速"概念的理解

打分 + 诊断,一箭双雕。 分数 0.2 告诉你这条记录有问题,评语告诉你问题是什么——后续的 Aggregation 模块就能从成百上千条这样的评语中提炼出系统级的缺陷模式。

💬 你的 Agent 踩过类似的坑吗? 遇到过”推理过程全对但工具调用选错了”的情况吗?评论区聊聊。


四、从打分到诊断的最后一公里:Aggregation 三步走

打分不难,难的是——打了 1000 条记录的分,你得到了一堆数字和评语文档,然后呢?

这就是 CLEAR 的 Stage 4 要做的事。它的核心流程是三步:

%%{init: {
  'theme': 'base',
  'themeVariables': {
    'background': '#0f172a',
    'primaryColor': '#1e293b',
    'primaryTextColor': '#f8fafc',
    'primaryBorderColor': '#38bdf8',
    'lineColor': '#64748b',
    'secondaryColor': '#1e1b4b',
    'tertiaryColor': '#0f172a',
    'edgeLabelBackground': '#1e293b'
  }
}}%%
graph LR
    subgraph INPUT["输入"]
        C1[评测结果 DataFrame<br/>score + evaluation_text]
    end

    subgraph STEP1["Step 1: Synthesize 提炼"]
        S1[分批发送评语给 LLM<br/>提取共性缺陷]
    end

    subgraph STEP2["Step 2: Deduplicate 去重"]
        S2[LLM 合并重复问题<br/>保留不同主题]
    end

    subgraph STEP3["Step 3: Map 映射"]
        S3[逐条记录二分类<br/>命中 / 未命中每个缺陷]
    end

    subgraph OUTPUT["输出"]
        C2[系统级缺陷列表<br/>+ 每条记录的问题画像]
    end

    C1 --> S1 --> S2 --> S3 --> C2

    %% 审美细节优化微调
    style INPUT fill:#1e293b,stroke:#334155,stroke-width:2px,color:#f8fafc
    style STEP1 fill:#1e293b,stroke:#334155,stroke-width:2px,color:#f8fafc
    style STEP2 fill:#1e293b,stroke:#334155,stroke-width:2px,color:#f8fafc
    style STEP3 fill:#1e293b,stroke:#334155,stroke-width:2px,color:#f8fafc
    style OUTPUT fill:#0f172a,stroke:#312e81,stroke-width:2px,color:#f8fafc

    style C1 fill:#0ea5e9,stroke:#38bdf8,stroke-width:1px,color:#ffffff
    style S1 fill:#1e293b,stroke:#38bdf8,stroke-width:1px,color:#f8fafc
    style S2 fill:#1e293b,stroke:#38bdf8,stroke-width:1px,color:#f8fafc
    style S3 fill:#1e293b,stroke:#38bdf8,stroke-width:1px,color:#f8fafc
    style C2 fill:#6366f1,stroke:#818cf8,stroke-width:1px,color:#ffffff

    linkStyle 0,1,2,3 stroke:#38bdf8,stroke-width:2px;

Step 1 — Synthesize(提炼)

把成百上千条评测文本分批喂给 LLM,让它从海量评语中提炼共性缺陷。

这里有一个非常巧妙的设计——加权采样

1
weights = (1 - score) ** 4

高分记录不会被送进去提炼问题——已经答对了,不需要诊断。低分记录的权重呈四次方放大,确保真正的缺陷被充分暴露

设计的巧思: 四次方而不是线性加权,意味着一个 0.1 分的记录被采样概率是一个 0.5 分记录的约 30 倍。问题越严重的样本,越应该被”解剖”。

💬 你觉得四次方够激进吗? 如果换成六次方,会不会漏掉那些”勉强及格”的边界案例?

Step 2 — Deduplicate(去重)

提炼出的缺陷列表中,大量问题是同一主题的不同表述。比如说:

  • “缺乏推理步骤展示”
  • “没有展示计算过程”
  • “直接给答案无推理”

这三个本质上是在说同一件事。LLM 会做语义去重:几乎相同 → 合并,同一主题不同方面 → 保留,同一主题但相反观点 → 保留(如”过于冗长”和”不够详细”这对矛盾本身就值得深究)。

Step 3 — Map(映射)

去重后的缺陷列表,每条都回溯到原始记录上做二分类——这条记录命中这个缺陷吗?

最终的输出不再是一个孤零零的分数,而是一份完整的问题画像:

1
2
3
4
5
6
7
8
9
系统级缺陷:
  1. 缺乏推理步骤展示  → 命中了 47% 的记录
  2. 计算逻辑错误      → 命中了 23% 的记录
  3. 题意理解偏差      → 命中了 12% 的记录

单条记录画像(row_42):
  - score: 0.2
  - 命中缺陷: [1, 2, 3]  ← 全部 3 个缺陷都命中了
  - 建议:重点加强净流速概念教学和多步骤推理训练

这就是 CLEAR 的竞争力——你不再需要从几千条日志中人工归纳问题模式。

这套 Aggregation 逻辑同样复用于 Agentic Analysis 的 ClearAnalysis 阶段:root_cause_clear_runner 分析”为什么任务失败”,issues_clear_runner 提炼”系统层面有什么共性问题”,底层调用的仍然是 synthesize_shortcomings()remove_duplicates_shortcomings()map_shortcomings_to_records() 这一套。


五、一条 Trace 的全流程解剖:从 JSON 到诊断报告

前面讲的都是 LLM Analysis 的套路,但 CLEAR 真正的杀手锏在 Agentic Analysis。

让我们追踪一条真实的 Agent Trace,看它如何从一团 JSON 变成一份可操作的诊断报告。

5.1 输入:来自 Langfuse 的原始 Trace

假设你的 Code Agent 执行了一次”修复空指针异常”的任务,Langfuse 记录的 Trace 长这样:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
{
  "id": "tr-abc123",
  "name": "code_fix_agent",
  "userId": "dev-team",
  "observations": [
    {
      "id": "obs-001",
      "name": "issue_analyzer",
      "type": "GENERATION",
      "input": "修复这个空指针异常...",
      "output": "问题出在 utils.py 第42行,需要加空值检查",
      "startTime": "2024-01-15T10:00:00Z",
      "endTime": "2024-01-15T10:00:05Z"
    },
    {
      "id": "obs-002",
      "name": "file_reader",
      "type": "SPAN",
      "input": {"file_path": "utils.py"},
      "output": {"content": "def process(x):\n    return x.strip()"},
      "parentObservationId": "obs-001",
      "startTime": "2024-01-15T10:00:05Z",
      "endTime": "2024-01-15T10:00:06Z"
    },
    {
      "id": "obs-003",
      "name": "code_writer",
      "type": "GENERATION",
      "input": "根据分析写补丁...",
      "output": "将第42行改为 if x is not None: return x.strip()",
      "parentObservationId": "obs-001",
      "startTime": "2024-01-15T10:00:06Z",
      "endTime": "2024-01-15T10:00:10Z"
    }
  ]
}

一团嵌套的 JSON,根本无法直接评测。

5.2 阶段 1:PreprocessTraces — 适配器模式标准化

CLEAR 的 get_extractor() 根据你的 Agent 框架(LangGraph / CrewAI)和可观测性平台(MLflow / Langfuse)自动选择合适的解析器,将异构 Trace 转为统一 Schema:

Name,          intent,         task_id,   step_in_trace, model_input,              response,                        tool_or_agent
issue_analyzer,修复空指针异常,  tr-abc123, 分析问题,      修复这个空指针异常...,      问题出在 utils.py 第42行...,       issue_analyzer
code_writer,   修复空指针异常,  tr-abc123, 编写补丁,      根据分析写补丁...,          将第42行改为 if x is not None...,  code_writer

设计亮点: 无论你用 LangGraph + MLflow 还是 CrewAI + Langfuse,最终都收敛到同一张 CSV。这就是适配器模式在评测系统中的典型落地——上层评测逻辑完全不需要感知底层框架差异。

5.3 阶段 2:StepByStep — 逐步骤穿透评测

转换后的 CSV 按 Name(Agent 节点名)分组,每个节点独立跑一轮 LLM Analysis。

issue_analyzer 节点使用 AgentEval(4 维度:Correctness / Completeness / Relevance / Tool Selection),而 code_writer 同样使用 AgentEval 但评测上下文不同——它在评估”修复方案的正确性”而非”问题分析的准确性”。

每个节点产出独立的 results.parquet + issues.json

1
2
3
4
5
6
7
issue_analyzer 节点诊断结果:
  - 平均分: 0.85(分析质量较高)
  - 系统性问题: "偶尔遗漏边界条件分析"

code_writer 节点诊断结果:
  - 平均分: 0.62(修复质量有待提升)
  - 系统性问题: "在 73% 的案例中跳过了必要的空值检查"

5.4 阶段 3:FullTrajectory + ClearAnalysis — 全局视角诊断

逐步骤评测只能告诉你”各环节表现如何”,但回答不了”这个任务整体算成功吗”。

FullTrajectory 用 14 个维度(9 个步骤级 + 5 个轨迹级)对整条轨迹做全局打分,ClearAnalysis 再基于失败案例跑一轮 Aggregation 三步走:

1
2
3
4
5
系统级根因(Root Cause):
  1. code_writer 空值检查遗漏 → 命中 73% 的失败轨迹
     → 建议:在 system prompt 中增加强制空值检查指令
  2. issue_analyzer 边界条件遗漏 → 命中 28% 的失败轨迹
     → 建议:增加边界条件分析的 few-shot 示例

从一团 JSON 到”哪个节点、什么问题、怎么修”,CLEAR 给出了完整的诊断闭环。


六、不止是评测,更是工程体系的一环

聊到这里,CLEAR 的设计哲学已经非常清晰了。

它跟传统评测工具最大的区别在于:传统工具追求的是”给一个分数”,CLEAR 追求的是”给一份体检报告”。

分数 → 诊断 → 归因 → 改进,这四个环节缺一不可。

6.1 工程底座的扎实铺垫

为了支撑大规模评测,CLEAR 在工程上做了大量扎实的铺垫。

推理后端通过工厂模式统一管理三种实现——LangChain 适配自建 WatsonX 服务,LiteLLM 对接 100+ 第三方 API,Endpoint 连接内部 HTTP 推理节点。

并发执行层用 ThreadPoolExecutor 处理同步调用,asyncio 处理异步调用,统一收敛到 run_parallel() 接口——调用方不需要感知底层是线程池还是事件循环。

配置管理采用三层合并策略——默认 YAML 提供基础值,用户 YAML 按需覆盖,CLI 参数作为最高优先级。多级 CSV Checkpoint 缓存则保障了数小时的评测任务中断后可从断点恢复。

结果存储选用 Parquet 格式配合 Brotli 压缩,比传统 CSV 效率高 5-10 倍。

6.2 竞品生态中的定位

但工程细节终究是”器”,真正让 CLEAR 有价值的是它的”道”——可操作性的诊断结果。放在整个 Agent 评测生态中看:

能力维度CLEARDeepEvalRagasLangSmith Eval
单轮 LLM 评测✅ 6 种 Use Case✅ 通用指标✅ RAG 专项✅ 自定义评估器
多步 Agent 评测✅ StepByStep + FullTrajectory❌ 不原生支持❌ 仅 RAG 管道✅ Trace 级评估
根因分析✅ Aggregation 三步走⚠️ 需手动配置
异构 Trace 兼容✅ LangGraph/CrewAI + MLflow/Langfuse✅ LangSmith 生态内
断点续评✅ 多级 CSV Checkpoint
开源自部署✅ Apache 2.0✅ MIT✅ Apache 2.0❌ SaaS 为主

CLEAR 的核心不可替代性: 它是目前唯一一个把”逐步骤诊断 → 问题聚合 → 根因映射”做成完整自动化闭环的开源工具。


🚀 5 分钟快速体验

下面是 CLEAR 的最小可运行路径:

环境准备

1
2
3
4
5
# 完整安装(含 Dashboard 和 Agentic Analysis)
pip install "clear-eval[all]"

# 配置 LLM Provider(以 OpenAI 为例)
export OPENAI_API_KEY="sk-xxx"

场景一:评测已有的模型回答

准备一个 CSV 文件 data/my_eval.csv

model_input,response
"What is the capital of France?","Paris"
"Solve 2x + 5 = 15","x = 5"

一行命令跑通 LLM Analysis 全管道:

1
2
3
4
5
6
run-clear-eval-analysis \
    --data-path data/my_eval.csv \
    --results-dir results \
    --task general \
    --eval-model-name gpt-4o \
    --provider openai

输出:results/analysis_results_my_eval_gpt_4o.zip — 包含完整评测结果和诊断报告。

场景二:Agentic Analysis 评测

1
2
3
4
5
6
7
run-clear-agentic-eval \
    --traces-dir ./mlflow_traces \
    --results-dir ./results \
    --agent-framework langgraph \
    --observability langfuse \
    --run-step-by-step true \
    --run-full-trajectory true

场景三:仅运行聚合分析(已有评测结果)

1
2
3
4
5
6
7
run-clear-eval-analysis \
    --aggregation-only true \
    --data-path results/checkpoint_my_eval_gpt_4o.csv \
    --results-dir results \
    --task general \
    --eval-model-name gpt-4o \
    --provider openai

📦 完整配置参考与更多使用场景,见 CLEAR GitHub 仓库


🏁 总结

CLEAR 代表了 AI Agent 评测领域的一个趋势:从”能不能用”走向”怎么才能更好用”。

它不是一个 Demo 级别的玩具框架,而是一个有清晰分层架构、有策略模式驱动的 Use Case 体系、有工程化断点续评和并行执行底座的生产级工具。

但一个值得思考的问题是:当 AI Agent 的行为复杂到一定程度,LLM-as-a-Judge 的裁判本身会不会也出现系统性的偏见?我们是否需要一个”评价裁判的裁判”?

欢迎各位在评论区聊聊你的看法——你的 Agent 评测踩过什么坑?你觉得”裁判偏见”该怎么解决?

本文由作者按照 CC BY 4.0 进行授权