架构 · 24

Evaluation Runtime 与指标语义

Evaluation Package、Dataset、Run、Sample、启发式指标、SQLite 持久化与客户端报告的当前边界。

文档范围#

本页说明当前 Evaluation 的状态持有者、运行链和指标算法。

Evaluation Package
→ Parsed Dataset
→ Evaluation Run
→ Sample Attempts
→ Metric Summary
→ Client-side Markdown Report

这些对象不是同一层:

Package
!= Frozen Corpus

Run Persisted
!= Durable Job

Metric Name
!= Standard Algorithm

Markdown Report
!= Server Artifact

产品入口与 Runtime#

桌面端有两个入口:

入口 当前职责
新建评测 包生成、ZIP 上传、Dataset 校验、Run 启动、日志和结果
评测中心 Run 列表、搜索、详情、Markdown 导出和删除

后端主要对象:

对象 状态持有者
Parsed Dataset Evaluation Service 内存 + SQLite
Complete Samples Evaluation Service 内存 + SQLite JSON
Evaluation Run Evaluation Service 内存 + SQLite JSON
执行调度 当前 Backend 进程
Markdown Report 当前桌面客户端

HTTP 接口#

当前公开路由:

POST   /evaluation/packages/generate
POST   /evaluation/datasets/parse
GET    /evaluation/runs
GET    /evaluation/runs/:runId
POST   /evaluation/runs
DELETE /evaluation/runs/:runId
POST   /evaluation/runs/batch-delete

当前没有 Dataset 管理、Run Cancel、Retry、Resume、Compare 或服务端 Report API。

Evaluation Package#

推荐结构:

manifest.json
evalset.json
documents/*

Manifest 主要保存:

datasetName
knowledgeBaseId
mode
topK
topN
repeat
concurrency
timeoutSeconds

Sample 主要保存:

id
question
expectedAnswer / referenceAnswer
goldSources
tags

Gold Source 匹配#

当前只做:

trim(lowercase(retrieved documentName))
===
trim(lowercase(goldSource))

不支持 Document ID、Chunk ID、模糊名称或语义匹配。

Documents 条目的真实用途#

Parser 只记录 documents 名称和大小。它不会读取正文用于评测,也不会把文件导入 Knowledge Base。

自动生成 ZIP 中 documents 内容是固定占位文本。因此当前 ZIP 不能在另一实例中独立重建相同语料和索引。

Package Generator#

自动生成器:

ready + enabled documents
→ 随机选择 documents / chunks
→ evaluation role 生成 JSON Sample
→ 校验字段和重复 question
→ 写 ZIP

evaluation role 当前只用于 Sample Generation,不在 Run 中做 Judge。

当前没有固定随机 seed、单条重试、自动事实校验或人工审批步骤。

Dataset Parser#

上传条件:

  • 单个 .zip
  • 最大 100 MB;
  • 完整读入内存。

Parser 查找:

manifest.json

evalset.json
或 evalset/evalset.json
或 dataset/evalset.json

documents/*

校验结果分为:

  • pass;
  • warning;
  • error。

任一 error 阻止 Run。Reference Answer 或 Gold Source 缺失通常只产生 warning。

Dataset 会立即写入 SQLite。当前没有 Dataset list / delete 入口,因此重复解析和删除 Run 后可能留下孤立 Dataset。

Run 生命周期#

POST /evaluation/runs
→ status=queued
→ persist
→ queueMicrotask(executeRun)
→ status=running
→ Sample workers
→ completed / failed

queued 是当前进程内事件循环调度,不是持久队列。

Run 支持:

  • Sample concurrency;
  • Repeat;
  • Attempt timeout;
  • 持续 Sample / Metric / Log 持久化;
  • 最多 200 条日志。

Run 不支持:

  • Cancel;
  • Pause;
  • Resume;
  • Checkpoint;
  • 独立 Worker;
  • 全局资源预算。

两种执行模式#

Retrieve#

Evaluation 调用名义上的 retrieveOnly 路径。

但当前 ragGraph.retrieve() 仍运行完整图:

rewrite
→ embed
→ retrieve
→ rerank / fallback
→ generate

最后只返回 Sources,丢弃 Answer。

因此当前 Retrieve 模式仍可能依赖 llm 并产生 Generate 延迟和成本。生成指标在该模式中固定为 0,表示当前不评估,而不是质量为零。

Retrieve + Generate#

执行完整 RAG,并保存最终 Answer 和 Sources。

Run 不保存完整 RAG Node breakdown、Vector / Lexical 分路、RRF 明细、Rerank degraded 状态、Provider Observation、Token 或 Cost。

模型依赖#

模型角色 当前用途
evaluation 自动生成 question、expectedAnswer、tags
embedding 查询向量化
rerank 可选重排
llm Answer Generate;当前 Retrieve 模式也会因实现漂移调用
task 只有需要根据对话历史改写 Query 时才使用;当前评测通常不带历史

当前没有 Judge Model。

Sample 与 Attempt#

同一 Sample 的 Repeat 顺序执行。

成功 Attempt 记录:

  • Hit / Recall;
  • Sources;
  • Answer;
  • 三个生成启发式分数;
  • Latency。

失败 Attempt 记录错误和实际耗时。

Sample 聚合:

  • 成功 Attempt 的数值取平均;
  • 任一成功 Attempt 命中,Sample Hit 为 true;
  • 最佳 Attempt 按 Recall、Hit、Latency 选择;
  • 任一 Attempt 失败,Sample status 仍为 failed。

Run 聚合:

任一 Sample failed
→ Run failed

因此 failed Run 仍可能包含大量成功结果。

Timeout#

当前 Timeout 使用:

Promise.race(ragCall, timeoutRejection)

没有把 AbortSignal 传递给底层 Provider。

Attempt 已超时
!= 底层请求已取消

全部 Attempt 失败时,Sample latency 使用配置 Timeout,而不是实际失败耗时平均。

SQLite 持久化#

表:

evaluation_datasets
evaluation_runs

Dataset、Samples 和 Run 以 JSON 快照保存。

当前没有 userId 字段。它适用于当前本地单实例,不构成未来服务器多用户隔离合同。

Backend 重启#

启动时会 hydrate Dataset 和 Run JSON,但不会恢复执行。

running / queued Run
→ Backend restart
→ 状态仍为 running / queued
→ 不重新排队
→ 当前 API 又拒绝删除

这会产生永久卡住的 Run,是当前最高优先级的生命周期缺口之一。

指标基础#

当前 Gold Source 匹配只基于 documentName。

Hit@K#

至少命中一个 Gold documentName 的 Sample 数
/
全部 Sample 数

不检查首次命中排名,也不检查命中 Chunk 是否足以回答问题。

Recall@K#

命中的唯一 Gold documentName 数
/
Gold documentName 总数

Sample 多 Repeat 时先平均成功 Attempt,再对全部 Sample 聚合。

MRR#

当前不是标准 Mean Reciprocal Rank。

每条 Sample 当前贡献:

hit ? max(recall, 1/3) : 0

代码没有读取首个正确来源的实际排名。该字段应理解为历史近似值,不能与外部 MRR 直接比较。

Source Hit Rate#

当前:

sourceHit = hit

所以 Source Hit Rate 在聚合结果中实质与 Hit@K 同义,不是返回来源中 Gold 来源所占比例。

生成启发式指标#

当前没有 LLM Judge。Tokenization 主要是:

lowercase
→ 按非英文数字和非中文字符切分
→ unique token set

Faithfulness#

Answer tokens 中出现在 Retrieved Sources 的比例

Answer 为空时,当前代码会使用 expectedAnswer 作为计算 basis。

它只能反映词项重合,不能检查逻辑、数字、否定关系、证据支持或幻觉。

Answer Relevance#

Question / Answer token overlap * 0.6
+
Expected Answer / Answer token overlap * 0.4

没有 expectedAnswer 时,第二项回退为 Question overlap。

Answer Completeness#

Expected Answer tokens 被 Answer 覆盖的比例

它不惩罚错误或多余内容,也不能识别同义表达。

Average Latency 与 Failed Count#

Average Latency 是 Sample 总耗时平均,不是纯 Retrieval 延迟。

当前 Retrieve 模式中的额外 Generate 也计入其中。

Failed Count 统计最终 Sample status=failed。由于任一 Repeat 失败都会让 Sample failed,它同时包含部分成功和完全失败的样本。

Aggregate 边界#

检索指标对全部 Sample 聚合,失败 Sample 以 0 进入分母。

生成指标只对最终 status=success 的 Sample 聚合。因此有一个 Repeat 失败但其余成功的 Sample,会被排除在生成指标平均之外。

Markdown Report#

报告由桌面端即时生成,不是服务器 Artifact。

客户端还计算一套硬编码权重的加权平均,并对 Latency 与 Failed Count 做前端归一化。

该分数:

  • 不保存到 Run;
  • 没有 algorithm version;
  • 不是 Runtime 成功标准;
  • 可能在未来导出同一旧 Run 时改变。

报告中的 Mermaid、风险建议和指标解释也属于当前客户端代码。

当前偏差与影响#

严重度 当前偏差 影响
queued / running 重启后不恢复且不能删除 Run 可永久卡住
指标名称强于算法 容易误当标准 RAG 评测
Retrieve 仍执行 Generate 额外模型依赖、延迟和成本
ZIP 不冻结语料 跨时间和跨实例不可严格复现
Timeout 不取消底层调用 超时后资源可能继续占用
Dataset 无管理入口 数据可能持续积累
任一 Repeat 失败令 Run failed 总状态掩盖部分成功
Strict 600 秒被 clamp 为 300 秒 UI 与 manifest 不一致
Report weighted score 未版本化 旧 Run 解释可能变化

当前非目标#

Evaluation 当前不是:

  • RAGAS;
  • LLM-as-a-Judge;
  • 研究型标准基准;
  • 模型排行榜;
  • Release Gate;
  • Experiment Tracking 平台;
  • Durable Worker 系统;
  • 跨实例自包含评测包;
  • 专业正确性证明。

相关文档#