想知道你的 RAG 智能体是否准备好上线?只需使用 Elasticsearch Workflows 和两个 Claude 模型,就能在正确性、忠实度和检索质量三个维度上给它打分。
1. 引言:自动化评估
在构建检索增强生成(RAG)系统时,我们总会面临一个核心问题:怎么知道智能体给出的答案到底好不好?
手动抽查几个问题------可行。但如果要调整检索策略、修改提示词、更换模型,每次改动都需要重新验证全部答案,手动评估就变得既不现实又不可靠。人的评分标准也常常摇摆不定,难以复现。
"LLM 即评判者"(LLM-as-a-Judge) 应运而生:用一个较强的语言模型来自动评判较弱模型输出的质量,从而取代人工审核。这个思路并不复杂------如果语言模型能够稳定地判断一个答案是否正确,那我们就能在几分钟内自动化完成数百个测试用例的质量检查。
而本文更进一步:将整套评估流程完全内置于 Elasticsearch Workflows 中。无需外部评估框架,无需额外基础设施。一个小模型(Claude Haiku 4.5)负责回答问题,一个大模型(Claude Sonnet 4.6)负责从三个维度打分。知识库、评判列表、工作流执行、评分结果------全部数据都存储在同一个 Elasticsearch 系统中。
在 35 个 HotpotQA 测试案例上,Haiku 4.5 的正确性得分为 0.74,忠实度得分为 0.90。这些数字足以帮我们精准定位:问题出在检索环节,还是推理环节?
2. 前置条件
开始之前,请确保你已具备:
- 一个 Elastic Cloud 集群 或自管理的 Elasticsearch/Kibana 9.4+ 环境(若没有,可申请免费试用)。
- Python 3.13(用于运行配套的示例 Notebook)。
- 你的
ELASTICSEARCH_URL和ELASTICSEARCH_API_KEY(参照连接指南获取),以及KIBANA_URL(从 Kibana 访问页面获取)。
3. 理解 LLM-as-a-Judge 评估模式
3.1 核心理念
- 传统方式:人工逐条检查答案 → 费时、费力、标准不一。
- LLM-as-a-Judge:用强模型当"评委",给弱模型的答案自动打分 → 快速、一致、可重复。
3.2 本文的两阶段流程
#mermaid-svg-RBgf7FjvQSVyfmFy{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-RBgf7FjvQSVyfmFy .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-RBgf7FjvQSVyfmFy .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-RBgf7FjvQSVyfmFy .error-icon{fill:#552222;}#mermaid-svg-RBgf7FjvQSVyfmFy .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-RBgf7FjvQSVyfmFy .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-RBgf7FjvQSVyfmFy .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-RBgf7FjvQSVyfmFy .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-RBgf7FjvQSVyfmFy .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-RBgf7FjvQSVyfmFy .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-RBgf7FjvQSVyfmFy .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-RBgf7FjvQSVyfmFy .marker{fill:#333333;stroke:#333333;}#mermaid-svg-RBgf7FjvQSVyfmFy .marker.cross{stroke:#333333;}#mermaid-svg-RBgf7FjvQSVyfmFy svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-RBgf7FjvQSVyfmFy p{margin:0;}#mermaid-svg-RBgf7FjvQSVyfmFy .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-RBgf7FjvQSVyfmFy .cluster-label text{fill:#333;}#mermaid-svg-RBgf7FjvQSVyfmFy .cluster-label span{color:#333;}#mermaid-svg-RBgf7FjvQSVyfmFy .cluster-label span p{background-color:transparent;}#mermaid-svg-RBgf7FjvQSVyfmFy .label text,#mermaid-svg-RBgf7FjvQSVyfmFy span{fill:#333;color:#333;}#mermaid-svg-RBgf7FjvQSVyfmFy .node rect,#mermaid-svg-RBgf7FjvQSVyfmFy .node circle,#mermaid-svg-RBgf7FjvQSVyfmFy .node ellipse,#mermaid-svg-RBgf7FjvQSVyfmFy .node polygon,#mermaid-svg-RBgf7FjvQSVyfmFy .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-RBgf7FjvQSVyfmFy .rough-node .label text,#mermaid-svg-RBgf7FjvQSVyfmFy .node .label text,#mermaid-svg-RBgf7FjvQSVyfmFy .image-shape .label,#mermaid-svg-RBgf7FjvQSVyfmFy .icon-shape .label{text-anchor:middle;}#mermaid-svg-RBgf7FjvQSVyfmFy .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-RBgf7FjvQSVyfmFy .rough-node .label,#mermaid-svg-RBgf7FjvQSVyfmFy .node .label,#mermaid-svg-RBgf7FjvQSVyfmFy .image-shape .label,#mermaid-svg-RBgf7FjvQSVyfmFy .icon-shape .label{text-align:center;}#mermaid-svg-RBgf7FjvQSVyfmFy .node.clickable{cursor:pointer;}#mermaid-svg-RBgf7FjvQSVyfmFy .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-RBgf7FjvQSVyfmFy .arrowheadPath{fill:#333333;}#mermaid-svg-RBgf7FjvQSVyfmFy .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-RBgf7FjvQSVyfmFy .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-RBgf7FjvQSVyfmFy .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-RBgf7FjvQSVyfmFy .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-RBgf7FjvQSVyfmFy .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-RBgf7FjvQSVyfmFy .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-RBgf7FjvQSVyfmFy .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-RBgf7FjvQSVyfmFy .cluster text{fill:#333;}#mermaid-svg-RBgf7FjvQSVyfmFy .cluster span{color:#333;}#mermaid-svg-RBgf7FjvQSVyfmFy div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-RBgf7FjvQSVyfmFy .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-RBgf7FjvQSVyfmFy rect.text{fill:none;stroke-width:0;}#mermaid-svg-RBgf7FjvQSVyfmFy .icon-shape,#mermaid-svg-RBgf7FjvQSVyfmFy .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-RBgf7FjvQSVyfmFy .icon-shape p,#mermaid-svg-RBgf7FjvQSVyfmFy .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-RBgf7FjvQSVyfmFy .icon-shape .label rect,#mermaid-svg-RBgf7FjvQSVyfmFy .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-RBgf7FjvQSVyfmFy .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-RBgf7FjvQSVyfmFy .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-RBgf7FjvQSVyfmFy :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 知识库
HotpotQA 段落
阶段1:回答模型
Claude Haiku 4.5
评判列表
问题 + 标准答案
候选答案
阶段2:评判模型
Claude Sonnet 4.6
三个评分
正确性 / 忠实度 / 上下文相关性
4. 三大 RAG 评估指标
| 指标 | 衡量什么? | 低分意味着什么? |
|---|---|---|
| 正确性(correctness) | 候选答案是否与标准答案一致? | 智能体答非所问,或给出错误结论。 |
| 忠实度(faithfulness) | 答案是否基于检索到的段落? | 智能体产生了幻觉(编造事实)。 |
| 上下文相关性(context_relevance) | 检索到的段落与问题相关吗? | 检索环节带回了无关文档。 |
三者结合的价值 :
假设正确性高但上下文相关性低,那说明模型在检索质量不佳的情况下仍然答对了------很可能依赖了自身训练记忆。这在公开知识(如维基百科)上可能奏效,但在私有数据上就会失效。
5. 加载并索引 HotpotQA 数据集
我们使用 HotpotQA 的 distractor 配置:每个问题附带 10 个段落,其中 2 个包含答案(支撑段落),8 个为干扰项。问题多为多跳(multi-hop)类型,需要结合两个段落才能答对。
数据最终存入两个 Elasticsearch 索引:
5.1 知识库索引:hotpot-knowledge-base
存储所有上下文段落,每个文档包含标题和段落内容。段落字段被复制到 semantic_content(映射为 semantic_text),以便用自然语言进行语义检索,无需手动管理嵌入向量。
python
INDEX_NAME = "hotpot-knowledge-base"
if es_client.indices.exists(index=INDEX_NAME):
es_client.indices.delete(index=INDEX_NAME)
es_client.indices.create(
index=INDEX_NAME,
mappings={
"properties": {
"title": {"type": "keyword"},
"passage": {
"type": "text",
"copy_to": "semantic_content",
},
"semantic_content": {
"type": "semantic_text",
"inference_id": ".jina-embeddings-v5-text-small",
},
}
},
)
5.2 评判列表索引:hotpot-judgement-list
存储评测用例,每个文档包含问题和标准答案(ground truth)。
json
{"question": "Were Scott Derrickson and Ed Wood of the same nationality?", "answer": "yes"}
6. Elasticsearch Workflow 如何运行评估?
6.1 整体流程图
#mermaid-svg-yuSQuA3ehhqhrHQt{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-yuSQuA3ehhqhrHQt .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-yuSQuA3ehhqhrHQt .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-yuSQuA3ehhqhrHQt .error-icon{fill:#552222;}#mermaid-svg-yuSQuA3ehhqhrHQt .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-yuSQuA3ehhqhrHQt .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-yuSQuA3ehhqhrHQt .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-yuSQuA3ehhqhrHQt .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-yuSQuA3ehhqhrHQt .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-yuSQuA3ehhqhrHQt .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-yuSQuA3ehhqhrHQt .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-yuSQuA3ehhqhrHQt .marker{fill:#333333;stroke:#333333;}#mermaid-svg-yuSQuA3ehhqhrHQt .marker.cross{stroke:#333333;}#mermaid-svg-yuSQuA3ehhqhrHQt svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-yuSQuA3ehhqhrHQt p{margin:0;}#mermaid-svg-yuSQuA3ehhqhrHQt .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-yuSQuA3ehhqhrHQt .cluster-label text{fill:#333;}#mermaid-svg-yuSQuA3ehhqhrHQt .cluster-label span{color:#333;}#mermaid-svg-yuSQuA3ehhqhrHQt .cluster-label span p{background-color:transparent;}#mermaid-svg-yuSQuA3ehhqhrHQt .label text,#mermaid-svg-yuSQuA3ehhqhrHQt span{fill:#333;color:#333;}#mermaid-svg-yuSQuA3ehhqhrHQt .node rect,#mermaid-svg-yuSQuA3ehhqhrHQt .node circle,#mermaid-svg-yuSQuA3ehhqhrHQt .node ellipse,#mermaid-svg-yuSQuA3ehhqhrHQt .node polygon,#mermaid-svg-yuSQuA3ehhqhrHQt .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-yuSQuA3ehhqhrHQt .rough-node .label text,#mermaid-svg-yuSQuA3ehhqhrHQt .node .label text,#mermaid-svg-yuSQuA3ehhqhrHQt .image-shape .label,#mermaid-svg-yuSQuA3ehhqhrHQt .icon-shape .label{text-anchor:middle;}#mermaid-svg-yuSQuA3ehhqhrHQt .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-yuSQuA3ehhqhrHQt .rough-node .label,#mermaid-svg-yuSQuA3ehhqhrHQt .node .label,#mermaid-svg-yuSQuA3ehhqhrHQt .image-shape .label,#mermaid-svg-yuSQuA3ehhqhrHQt .icon-shape .label{text-align:center;}#mermaid-svg-yuSQuA3ehhqhrHQt .node.clickable{cursor:pointer;}#mermaid-svg-yuSQuA3ehhqhrHQt .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-yuSQuA3ehhqhrHQt .arrowheadPath{fill:#333333;}#mermaid-svg-yuSQuA3ehhqhrHQt .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-yuSQuA3ehhqhrHQt .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-yuSQuA3ehhqhrHQt .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-yuSQuA3ehhqhrHQt .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-yuSQuA3ehhqhrHQt .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-yuSQuA3ehhqhrHQt .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-yuSQuA3ehhqhrHQt .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-yuSQuA3ehhqhrHQt .cluster text{fill:#333;}#mermaid-svg-yuSQuA3ehhqhrHQt .cluster span{color:#333;}#mermaid-svg-yuSQuA3ehhqhrHQt div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-yuSQuA3ehhqhrHQt .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-yuSQuA3ehhqhrHQt rect.text{fill:none;stroke-width:0;}#mermaid-svg-yuSQuA3ehhqhrHQt .icon-shape,#mermaid-svg-yuSQuA3ehhqhrHQt .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-yuSQuA3ehhqhrHQt .icon-shape p,#mermaid-svg-yuSQuA3ehhqhrHQt .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-yuSQuA3ehhqhrHQt .icon-shape .label rect,#mermaid-svg-yuSQuA3ehhqhrHQt .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-yuSQuA3ehhqhrHQt .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-yuSQuA3ehhqhrHQt .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-yuSQuA3ehhqhrHQt :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 手动触发工作流
步骤1: load_cases
从评判列表加载全部35个问题
步骤2: eval_loop
foreach 遍历每个案例
子步骤: retrieve
对知识库做语义检索,取前4个段落
子步骤: agent_answer
Haiku 根据段落生成答案
子步骤: judge
Sonnet 对答案打分
子步骤: save
将评分结果写入 eval-results 索引
全部完成,结果可查询
6.2 工作流定义(YAML)
工作流采用 YAML 定义,通过 Workflows API(Elastic 9.4+)上传。下面逐段解析关键部分。
常量与触发器
yaml
consts:
kbIndex: hotpot-knowledge-base
judgeIndex: hotpot-judgement-list
resultsIndex: eval-results
triggers:
- type: manual # 手动触发,便于调试和重放
步骤 1:加载所有评测案例
yaml
- name: load_cases
type: elasticsearch.search
with:
index: "{{ consts.judgeIndex }}"
query:
match_all: {}
size: 35
步骤 2:循环处理每个案例(foreach)
yaml
- name: eval_loop
type: foreach
foreach: "{{ steps.load_cases.output.hits.hits }}"
steps:
# 子步骤 2.1:语义检索
- name: retrieve
type: elasticsearch.search
with:
index: "{{ consts.kbIndex }}"
query:
semantic:
field: semantic_content
query: "{{ foreach.item._source.question }}"
size: 4
步骤 3:回答模型(Haiku)
使用 ai.prompt 类型,引用 Kibana 中配置的 AI 连接器 Anthropic-Claude-Haiku-4-5。提示词强制模型仅依据提供的段落作答,若找不到答案则回复"unknown"。
yaml
- name: agent_answer
type: ai.prompt
with:
connector-id: Anthropic-Claude-Haiku-4-5
prompt: >
You are a Wikipedia QA assistant. Answer the question
using ONLY the passages provided. Keep the answer short
(one line). If the passages do not contain the answer,
reply "unknown".
Question: {{ foreach.item._source.question }}
Passages:
1. {{ steps.retrieve.output.hits.hits[0]._source.passage }}
2. {{ steps.retrieve.output.hits.hits[1]._source.passage }}
3. {{ steps.retrieve.output.hits.hits[2]._source.passage }}
4. {{ steps.retrieve.output.hits.hits[3]._source.passage }}
步骤 4:评判模型(Sonnet)
评判模型接收问题、标准答案、候选答案、检索段落,并输出结构化的 JSON 评分。关键在于 schema 块------它强制模型返回符合规范的 JSON 对象,无需再解析文本或处理 Markdown 代码块。
yaml
- name: judge
type: ai.prompt
with:
connector-id: Anthropic-Claude-Sonnet-4-6
prompt: >
You are a STRICT evaluator. Score the candidate answer
against the ground truth on three axes. Each score MUST
be exactly one of these three values: 0.0, 0.5, or 1.0.
Do not return any other number.
correctness:
1.0 = candidate contains the ground truth answer exactly
or an unambiguous synonym, and nothing factually wrong.
0.5 = partially correct (one side of a multi-hop right,
or mostly right with minor noise).
0.0 = wrong, missing, or contradicts the ground truth.
faithfulness:
1.0 = every factual claim is supported by the passages.
0.5 = mostly supported, one minor unsupported claim.
0.0 = contains at least one unsupported claim.
context_relevance:
1.0 = the passages contain enough to answer the question.
0.5 = partial coverage (one hop covered, the other missing).
0.0 = passages do not cover the answer.
Be harsh. If in doubt between two scores, pick the lower one.
Question: {{ foreach.item._source.question }}
Ground truth: {{ foreach.item._source.answer }}
Candidate: {{ steps.agent_answer.output.content }}
Passages:
1. {{ steps.retrieve.output.hits.hits[0]._source.passage }}
2. {{ steps.retrieve.output.hits.hits[1]._source.passage }}
3. {{ steps.retrieve.output.hits.hits[2]._source.passage }}
4. {{ steps.retrieve.output.hits.hits[3]._source.passage }}
schema:
type: object
properties:
correctness:
type: number
minimum: 0
maximum: 1
faithfulness:
type: number
minimum: 0
maximum: 1
context_relevance:
type: number
minimum: 0
maximum: 1
required:
- correctness
- faithfulness
- context_relevance
步骤 5:保存结果
将每个案例的评分写入 eval-results 索引。由于 schema 保证了输出是结构化 JSON,我们可以直接用 {``{ steps.judge.output.content.correctness }} 等引用具体字段。
yaml
- name: save
type: elasticsearch.index
with:
index: "{{ consts.resultsIndex }}"
document:
qid: "{{ foreach.item._source.qid }}"
question: "{{ foreach.item._source.question }}"
ground_truth: "{{ foreach.item._source.answer }}"
candidate: "{{ steps.agent_answer.output.content }}"
correctness: "{{ steps.judge.output.content.correctness }}"
faithfulness: "{{ steps.judge.output.content.faithfulness }}"
context_relevance: "{{ steps.judge.output.content.context_relevance }}"
6.3 上传并运行工作流
使用 Elastic 9.4 提供的 REST API:
POST /api/workflows--- 创建/更新工作流POST /api/workflows/{id}/run--- 启动执行GET /api/workflows/executions/{id}--- 轮询执行状态
35 个测试案例,整个流程大约几分钟完成(包含 35 次语义检索 + 35 次 Haiku 调用 + 35 次 Sonnet 调用 + 35 次索引写入)。
7. 解读评估结果
7.1 聚合统计
直接从 eval-results 索引查询并计算各指标均值,无需额外解析。
| 指标 | 平均分 | 解读 |
|---|---|---|
| 正确性 | 0.74 | 约 7/10 的问题答对。对于多跳维基百科问题,算是不错的成绩,但仍有提升空间。 |
| 忠实度 | 0.90 | 当 Haiku 给出答案时,绝大多数内容都基于检索段落。幻觉问题不严重。 |
| 上下文相关性 | 0.86 | 语义检索大多数时候能带回相关段落;但部分多跳问题需要的信息不在前 4 个段落中。 |
7.2 分数分布图示
#mermaid-svg-T4iBu5VXBirCTekK{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-T4iBu5VXBirCTekK .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-T4iBu5VXBirCTekK .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-T4iBu5VXBirCTekK .error-icon{fill:#552222;}#mermaid-svg-T4iBu5VXBirCTekK .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-T4iBu5VXBirCTekK .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-T4iBu5VXBirCTekK .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-T4iBu5VXBirCTekK .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-T4iBu5VXBirCTekK .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-T4iBu5VXBirCTekK .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-T4iBu5VXBirCTekK .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-T4iBu5VXBirCTekK .marker{fill:#333333;stroke:#333333;}#mermaid-svg-T4iBu5VXBirCTekK .marker.cross{stroke:#333333;}#mermaid-svg-T4iBu5VXBirCTekK svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-T4iBu5VXBirCTekK p{margin:0;}#mermaid-svg-T4iBu5VXBirCTekK :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 各指标平均分(Haiku 4.5 作为回答模型) 正确性忠实度上下文相关性 10.90.80.70.60.50.40.30.20.10 平均分 (0-1)
7.3 洞察:问题出在哪儿?
忠实度(0.90)远高于正确性(0.74) ------这说明模型没有编造事实,而是在较难的问题上直接答错了 。因此,问题核心在于检索覆盖不足 或推理能力不够,而非幻觉。后续优化方向可以是:
- 增加检索段落数量(如从 4 个增至 8 个);
- 对最难的案例切换到更强的模型。
8. 对生产环境的启示
我们构建了一套完全运行在 Elasticsearch 内部的评估流水线。知识库、评判列表、工作流执行、评分结果------所有组件都统一在同一系统内,无需额外基础设施。
- 版本可控:工作流 YAML 可以纳入 Git,方便追踪变更。
- 可重放:当知识库或回答模型更新时,一键重新运行同一管道,对比新旧分数。
- API 可触发:可集成到 CI/CD,实现自动化回归测试。
对于本次测试,Haiku 在忠实度上表现可靠,但在多跳问题上的正确性还有不足。是否满足生产要求,取决于你的具体场景 。而评估管道的意义,正是给你数据支撑,让你能自信决策,而非凭感觉猜测。
9. 总结
- LLM-as-a-Judge 是一种高效、可扩展的自动化评估方法,用强模型评判弱模型。
- 在 Elasticsearch Workflows 中,我们用 Claude Haiku 4.5 回答,用 Claude Sonnet 4.6 从正确性、忠实度、上下文相关性三个维度打分。
- 整个流程通过 YAML 工作流 定义,所有数据与索引共存于 Elasticsearch。
- 实测结果揭示了 Haiku 的强项(忠实度高)和弱项(多跳正确率一般),为后续优化指明了方向。
立即行动:开始 Elastic Cloud 试用,用你自己的数据和模型跑一遍评估管道,看清你的 RAG 智能体到底表现如何。