关于 agent-evaluation
使用 MLflow 运行 GenAI Agent 评估的技能,涵盖追踪前置条件、数据集发现与准备、评分器注册、执行和结果分析。它要求使用 MLflow 原生 API,并在开始前确认 Agent 的用途和评估重点。
主要功能
- 01使用 MLflow 原生评估 API
- 02优先检查现有数据集
- 03评估前注册评分器
- 04先运行小规模试测
- 05分析评估结果
适用场景
- 01使用现有数据集评估 Agent
- 02创建并运行评估数据集
- 03完整评估前验证评分器
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ mlflow/ skills --skill agent-evaluation安装后在 Claude Code 中输入/agent-evaluation确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
assets/evaluation_report_template.mdreferences/advanced-evaluation.mddatabricks-online-monitoring.mddataset-preparation.mdprompt-optimization.mdscorers-constraints.mdscorers.mdsetup-guide.mdthroughput-guide.mdtroubleshooting.mdscripts/analyze_results.pycreate_dataset_template.pylist_datasets.pyrun_evaluation_template.pysetup_mlflow.pyvalidate_auth.pyvalidate_environment.pyvalidate_tracing_runtime.pyscripts/utils/__init__.pyenv_validation.py详细介绍
使用 MLflow 评估 Agent
使用 MLflow 评估 GenAI Agent 的完整指南。可将此技能用于完整评估工作流或单个组件,例如跟踪设置、环境配置、数据集创建、评分器定义或评估执行。可根据需要独立使用各个部分。
⛔ 严重警告:必须使用 MLflow API
不要创建自定义评估框架。 必须使用 MLflow 原生 API:
- 数据集:使用
mlflow.genai.datasets.create_dataset()——不要使用自定义测试用例文件 - 评分器:使用 MLflow 内置评分器、
@scorer或mlflow.genai.judges.make_judge()——不要使用自定义评估框架 - 评估:使用
mlflow.genai.evaluate()——不要使用自定义评估循环 - 脚本:使用提供的
scripts/目录模板——不要创建自定义evaluation/目录
为什么? MLflow 会在实验中跟踪所有内容(数据集、评分器、跟踪记录、结果)。自定义框架会绕过这些功能,导致失去所有可观测性。
如果你打算创建 evaluation/eval_dataset.py 或类似的自定义文件,请立即停止。改用 scripts/create_dataset_template.py。
目录
快速开始
⚠️ 提醒:使用此技能中的 MLflow API。不要创建自定义评估框架。
设置(前置条件):安装 MLflow 3.8+,配置环境并集成跟踪功能
分 5 步完成评估工作流(每一步都使用 MLflow API):
- 了解:运行 Agent,检查跟踪记录,了解其用途
- 评分器:注册已商定的评分器套件(如果尚不存在,请先使用
build-a-scorer) - 数据集:始终先查找现有数据集,仅在需要时创建新数据集 3.5. 试运行:先运行 3 个问题——在完整评估前发现损坏的工具和配置错误的评分器
- 评估:在数据集上运行 Agent,应用评分器并分析结果
**职责范围:**此技能负责运行评估,包括注册、数据集、执行和分析。评分器套件的设计(采用哪些标准,以及使用代码检查、内置评分器还是 LLM 评审器)属于 build-a-scorer 技能的职责。两者的交接点是:确认标准套件,并为每项标准选定实现方式。
命令约定
始终使用 uv run 运行 MLflow 和 Python 命令:
uv run mlflow --version # MLflow CLI commands
uv run python scripts/xxx.py # Python script execution
uv run python -c "..." # Python one-liners
这可确保命令在正确的环境中运行,并具备适当的依赖项。
严重警告:捕获 CLI 输出时,将 stderr 与 stdout 分开:
将 CLI 命令的输出保存到文件以供解析(JSON、CSV 等)时,始终单独重定向 stderr,以避免日志与结构化数据混杂:
# Save both separately for debugging
uv run mlflow traces evaluate ... --output json > results.json 2> evaluation.log
文档访问协议
所有 MLflow 文档都必须通过 llms.txt 访问:
- 从以下地址开始:
https://mlflow.org/docs/latest/llms.txt - 使用具体提示词,在 llms.txt 中查询相关主题
- 如果 llms.txt 引用了其他文档,请使用 WebFetch 访问该 URL
- 不要使用 WebSearch——先通过 WebFetch 访问 llms.txt
此要求适用于所有步骤,尤其是:
- 创建数据集(从 llms.txt 阅读 GenAI 数据集文档)
- 注册评分器(查阅 MLflow 文档中的评分器 API)
- 执行评估(了解 mlflow.genai.evaluate API)
探索 Agent 结构
每个项目都有独特的结构。 应动态探索,而不是依赖假设:
查找 Agent 入口点
# Search for main agent functions
grep -r "def.*agent" . --include="*.py"
grep -r "def (run|stream|handle|process)" . --include="*.py"
# Check common locations
ls main.py app.py src/*/agent.py 2>/dev/null
# Look for API routes
grep -r "@app\.(get|post)" . --include="*.py" # FastAPI/Flask
grep -r "def.*route" . --include="*.py"
了解项目结构
# Check entry points in package config
cat pyproject.toml setup.py 2>/dev/null | grep -A 5 "scripts\|entry_points"
# Read project documentation
cat README.md docs/*.md 2>/dev/null | head -100
# Explore main directories
ls -la src/ app/ agent/ 2>/dev/null
设置概览
预检查:使用现有环境
执行任何设置之前,请检查是否已设置 MLFLOW_TRACKING_URI 和 MLFLOW_EXPERIMENT_ID:
echo "MLFLOW_TRACKING_URI=$MLFLOW_TRACKING_URI"
echo "MLFLOW_EXPERIMENT_ID=$MLFLOW_EXPERIMENT_ID"
如果两者都已设置,则完全跳过步骤 1–2。 环境已经完成预配置。不要运行 setup_mlflow.py,不要创建 .env 文件,也不要覆盖这些值。直接进入步骤 3(跟踪集成)和评估工作流。
设置步骤(仅当环境未预配置时)
- 安装 MLflow(版本 >=3.8.0)
- 配置环境(跟踪 URI 和实验)
- 指南:按照
references/setup-guide.md中的步骤 1-2 操作
- 指南:按照
- 集成跟踪(autolog 和 @mlflow.trace 装饰器)
- ⚠️ 必须:使用
instrumenting-with-mlflow-tracingskill 设置跟踪 - ✓ 验证:完成实现后运行
scripts/validate_tracing_runtime.py
- ⚠️ 必须:使用
⚠️ **必须先确保跟踪正常工作,才能进行评估。**如果跟踪失败,请停止并排查问题。
检查点——继续之前请验证:
- 已安装 MLflow >=3.8.0
- 已设置 MLFLOW_TRACKING_URI 和 MLFLOW_EXPERIMENT_ID
- 已启用 Autolog 并添加 @mlflow.trace 装饰器
- 测试运行已创建跟踪(验证跟踪 ID 不为 None)
验证脚本:
uv run python scripts/validate_environment.py # Check MLflow install, env vars, connectivity
uv run python scripts/validate_auth.py # Test authentication before expensive operations
评估工作流
步骤 1:访谈 Agent(必需——不得跳过)
在进行其他操作之前,先向用户提出以下问题。获得答复之前,不得继续。
必答问题:
- “你的 Agent 是做什么的?请用 1-2 句话描述其用途。”
- “它最需要做好哪 2-3 件事?”
- “你已经注意到哪些常见的失败模式?”
使用答复来:
- 为
generate_evals_df编写agent_description参数 - 设定评估优先级
- 判断质量标准是否已经明确(继续步骤 2),还是仍需与用户共同制定(使用
build-a-scorerskill——见步骤 2)
**如果在自动化模式下运行:**从代码库中读取 Agent 的用途(SKILL.md、README 或主入口点的文档字符串)。仍需说明你的发现并在继续之前确认。
**范围说明:**这三个问题用于确定 Agent 是什么。仅凭这些信息不足以设计评分器套件。如果第 (2) 和 (3) 题的答复含糊不清,例如“给出好的回答”“应该准确”,请勿据此臆造评分器名称;这正是 build-a-scorer 的用途。
步骤 2:注册质量评分器
此步骤用于注册并运行评分器。评分器的设计——哪些标准重要,以及每项标准用代码检查、内置评分器还是 LLM 评审来实现最划算——属于 build-a-scorer 技能的范畴。
💡 如果用户还没有评分器套件,请先使用
build-a-scorer技能。 它会提供一组已确认的 3-5 项原子标准,并为每项标准选择一种实现方式 (代码检查、内置评分器或make_judge),以及一种可在聚合过程中保留的输出类型。然后回到这里 注册并运行评分器。如果实验中已注册评分器,或用户提供了明确的标准和实现方式列表,请直接跳到下方的注册步骤。
- 检查实验中已注册的评分器:
uv run mlflow scorers list -x $MLFLOW_EXPERIMENT_ID
重要:如果实验中已注册评分器,则必须使用这些评分器进行评估。
- 添加已商定套件中的内置评分器
内置评分器见 references/scorers.md。添加套件要求的、尚未注册的评分器。
- 添加已商定套件中的自定义评分器
使用 make_judge()(LLM 评审)或 @scorer(确定性代码检查)实现其余标准。API 见 references/scorers.md,可能导致结果悄然出错的约束见 references/scorers-constraints.md。
如果你此时是在自行设定标准,而不是实现已商定的标准,请停止并使用 build-a-scorer——用户尚未确认其标准的评分器无法通过验证。
⚠️ 关键——评分器返回值:评分器必须指示 LLM 评审返回
"yes"或"no"(或布尔值/数值)。"pass"或"fail"返回值会被_cast_assessment_value_to_float静默转换为None,并且不会纳入results.metrics,既不会报错,也不会发出警告——结果只会消失。安全与有问题的返回值完整列表见references/scorers-constraints.md中的约束 2。
-
必须:在评估前使用 Python API 注册新评分器:
from mlflow.genai.judges import make_judge from mlflow.genai.scorers import BuiltinScorerName import os scorer = make_judge(...) # Or, scorer = BuiltinScorerName() scorer.register()
重要:注册前,请参阅 references/scorers.md →“评分器的模型选择”,配置评分器的 model 参数。
⚠️ **必须在评估前注册评分器。**未注册的内联评分器不会出现在 mlflow scorers list 中,也无法重复使用。
- 验证注册情况:
uv run mlflow scorers list -x $MLFLOW_EXPERIMENT_ID # Should show your scorers
步骤 3:准备评估数据集
务必先查找现有数据集,以避免重复劳动:
-
运行数据集发现(必需):
uv run python scripts/list_datasets.py # Lists, compares, recommends datasets uv run python scripts/list_datasets.py --format json # Machine-readable output uv run python scripts/list_datasets.py --help # All options -
向用户展示发现结果:
- 展示所有发现的数据集及其特征(规模、涵盖的主题)
- 如果发现了数据集,根据 Agent 类型突出显示最相关的选项
-
询问用户是否使用现有数据集:
- “我找到了 [N] 个现有评估数据集。你想使用其中一个吗?(y/n)”
- 如果是:询问要使用哪个数据集并记录数据集名称,然后跳到步骤 3.5
- 如果否:继续下方的阶段 A
如果要创建新数据集,请采用下方的两阶段方法。
阶段 A:合理性检查(5 个问题——始终先运行)
根据步骤 1 访谈的回答,手动创建一个最小的 5 题数据集。目标是在投入大规模生成之前,确认整个流程端到端运行正常。
import mlflow
from mlflow.genai.datasets import create_dataset
# Derive 5 representative questions directly from the agent's stated purpose
# and known failure modes identified in Step 1
sanity_records = [
{"inputs": {"query": "<question 1 from interview>"}, "expected_response": "<expected answer>"},
{"inputs": {"query": "<question 2 from interview>"}, "expected_response": "<expected answer>"},
# ... 5 total
]
sanity_dataset = create_dataset(
records=sanity_records,
name="sanity-check-5q",
)
在此数据集上运行评估(见步骤 4),然后按以下方式向用户展示结果:
“这是一次合理性检查——5 个问题可以确认整个流程能正常运行,但在统计上并不具备意义。接下来将进入阶段 B,生成正式的评估集。”
只有阶段 A 成功完成且没有错误后,才能进入阶段 B。
阶段 B:正式评估数据集(100+ 个问题——阶段 A 通过后运行)
根据 Agent 的实际语料生成问题,而不是从头编造。具体方法取决于项目使用的是 Databricks 还是 OSS MLflow。
在 Databricks 上——使用 generate_evals_df 从 Agent 的文档语料合成问题:
from databricks.agents.evals import generate_evals_df, estimate_synthetic_num_evals
import mlflow
# agent_description comes from Step 1 interview answers
agent_description = "<agent purpose from interview>"
# docs_df: a Spark or pandas DataFrame with a "content" column containing
# the documents/chunks the agent retrieves from (e.g., your Vector Search index)
evals = generate_evals_df(
docs=docs_df,
num_evals=100,
agent_description=agent_description,
)
# Merge into MLflow dataset — don't create a separate dataset
dataset = mlflow.genai.datasets.create_dataset(name="generated-evals-100q")
dataset.merge_records(evals)
生成前,估算合适的 num_evals:
recommended = estimate_synthetic_num_evals(docs_df)
print(f"Recommended num_evals: {recommended}")
数据集规模建议:
- 少于 30 个问题:统计意义不足——避免据此得出结论
- 50–100 个问题:足以发现回归问题,适用于大多数 Agent
- 200+ 个问题:比较模型变体或对多个维度评分时建议采用
在 OSS MLflow 上——使用 RAGAS TestsetGenerator 根据文档语料生成问题:
from ragas.testset import TestsetGenerator
from ragas.llms import LangchainLLMWrapper
from ragas.embeddings import LangchainEmbeddingsWrapper
generator = TestsetGenerator(
llm=LangchainLLMWrapper(your_llm),
embedding_model=LangchainEmbeddingsWrapper(your_embeddings),
)
testset = generator.generate_with_langchain_docs(docs, testset_size=100)
evals_df = testset.to_pandas()
# Convert to MLflow dataset schema and merge
import mlflow
records = [
{"inputs": {"query": row["user_input"]}, "expected_response": row["reference"]}
for _, row in evals_df.iterrows()
]
dataset = mlflow.genai.datasets.create_dataset(name="generated-evals-100q")
dataset.merge_records(records)
如果没有可用的文档语料——请用户提供 50–100 个来自生产日志或使用记录的典型查询。这些查询比合成问题更贴近实际,有条件时应优先使用。
重要:不要跳过数据集发现步骤。始终先运行 list_datasets.py,即使计划创建新数据集也不例外。这样可以避免重复工作,并确保用户了解现有的评估数据集。
完整的数据集指南: 请参阅 references/dataset-preparation.md
检查点——继续前请确认:
- 已注册评分器
- 阶段 A 健全性检查已通过(流水线端到端运行)
- 阶段 B 数据集已创建,包含 50+ 个问题(或已选择现有数据集)
步骤 3.5:试运行(完整评估前必须执行)
在执行完整评估前,先使用数据集中的 3 个问题运行评估。这样可以及早发现工具故障、评分器配置错误和身份验证失败,避免它们悄然影响 100 个问题的结果。
如果已完成上述阶段 A,流水线就已通过验证——试运行时只需关注评分器输出。
import mlflow
dataset = mlflow.genai.datasets.get_dataset(name="<your-dataset-name>")
dry_run_records = dataset.df.head(3)
使用与完整评估相同的封装函数和评分器,对这 3 条记录运行 mlflow.genai.evaluate()。
检查每条响应:
- 工具调用——Agent 是否调用了任何工具?对于需要检索的问题,如果 Agent 一个工具都没调用,说明工具可能已损坏(403 错误、速率限制、缺少凭据)。
- 响应质量——响应是否为空或内容笼统(“我不知道”“我无法帮助你处理此问题”)?空响应会被评为不相关,并影响完整评估的结果。
- 评分器输出——3 个评分是否全部为
0或None?如果是,则说明评分器配置错误(检查返回值——"pass"/"fail"会被静默转换为None;请改用"yes"/"no")。
决策门槛:
- **如果试运行发现工具故障或空响应:**停止。继续前先修复根本问题(身份验证、工具配置、检索)。不要在基础设施故障时运行完整评估。
- **如果 3 个评分器输出全部为 0 或 None:**停止。排查评分器返回值,并在继续前重新注册评分器。
- **如果试运行通过:**向用户报告:*“试运行通过(3/3 条响应非空、已调用工具、评分非零)。正在继续完整评估。”*然后继续步骤 4。
**重要原因:**工具故障(文档抓取返回 403、GitHub API 速率限制)会导致 Agent 返回空响应,并被评为 0。运行 100 个问题的评估后才发现所有工具都已失效,不仅浪费时间,还会产生误导性结果。试运行可在不到一分钟内发现这些问题。
步骤 4:运行评估
**大型数据集(50+ 个问题)?**请参阅
references/throughput-guide.md,了解吞吐量优化方法——包括并行度环境变量、异步预测函数,以及针对 200+ 个问题的评估进行数据集拆分。
4a. 启动前估算运行时间
开始评估前,先告知用户预计耗时:
-
统计数据集中的问题数量:
import mlflow dataset = mlflow.genai.datasets.get_dataset(name="<your-dataset-name>") print(f"Dataset size: {len(dataset.df)} questions") -
计算预估时间 — 每个问题都会运行一次 Agent 和一次评分器裁判:
- Opus 级裁判模型(例如
claude-opus-4):每个问题约 45–90 秒 - Sonnet 级裁判模型(例如
claude-sonnet-4):每个问题约 20–45 秒 - 每个问题使用多个评分器会按比例增加耗时
Estimated time = N questions × 30–60s per question ÷ parallelism factor (typically 4–8x) - Opus 级裁判模型(例如
-
开始前告知用户:
“此数据集有 N 个问题。按典型并行度估算,每个问题约需 30–60 秒,评估大约需要 X–Y 分钟。我会将其作为后台任务运行,这样你可以继续工作;完成后我会总结结果。”
4b. 生成评估脚本
# Generate evaluation script (specify module and entry point)
uv run python scripts/run_evaluation_template.py \
--module mlflow_agent.agent \
--entry-point run_agent
生成的脚本会创建一个包装函数,该函数:
- 接受与数据集输入键匹配的关键字参数
- 提供 Agent 所需的任何其他参数(例如
llm_provider) - 运行
mlflow.genai.evaluate(data=df, predict_fn=wrapper, scorers=registered_scorers) - 将结果保存到
evaluation_results.csv
⚠️ 重要:wrapper 的签名必须与数据集输入键匹配
MLflow 会调用 predict_fn(**inputs)——它会将 inputs 字典解包为关键字参数。
| 数据集记录 | MLflow 调用 | predict_fn 必须为 |
|---|---|---|
{"inputs": {"query": "..."}} | predict_fn(query="...") | def wrapper(query): |
{"inputs": {"question": "...", "context": "..."}} | predict_fn(question="...", context="...") | def wrapper(question, context): |
常见错误(错误示例):
def wrapper(inputs): # ❌ WRONG - inputs is NOT a dict
return agent(inputs["query"])
4c. 作为后台子 Agent 启动
将评估作为后台子 Agent 运行,以便主会话保持可用。使用 run_in_background: true 的 Agent 工具:
子 Agent 指令(请原样传递):
Run the agent evaluation and write results to scratchpad.
Steps:
1. cd <project-directory>
2. Run: uv run python run_agent_evaluation.py
3. When complete, write a summary to scratchpad/eval-results.md with:
- Exit status (success or error message)
- Path to results file (evaluation_results.csv)
- Wall-clock time taken
4. Return only: "Evaluation complete. Results written to scratchpad/eval-results.md"
在主会话中,通过检查暂存文件来轮询完成状态,而不是阻塞等待:
# Poll every 30s using Glob
# Glob("scratchpad/eval-results.md")
# When the file appears, read it and proceed to analysis
不要使用 TaskOutput 等待后台 Agent——这会将完整记录(约 10–20k 个令牌)全部载入主上下文。
4d. 分析结果(评估完成后)
scratchpad/eval-results.md 出现后,运行分析:
# Pattern detection, failure analysis, recommendations
# Reads the CSV produced by mlflow.genai.evaluate() above
uv run python scripts/analyze_results.py evaluation_results.csv
生成 evaluation_report.md,其中包含各评分器的通过率和改进建议。
该脚本会读取 CSV 中的 {scorer_name}/value 和 {scorer_name}/rationale 列。
为保持向后兼容,它也接受来自 mlflow traces evaluate 的旧版 JSON 格式:
uv run python scripts/analyze_results.py evaluation_results.json # legacy format
uv run python scripts/analyze_results.py evaluation_results.csv --output my_report.md # custom output
参考资料
references/ 中的详细指南(按需加载):
- setup-guide.md — 环境设置(安装 MLflow、配置跟踪 URI)
- Tracing:使用
instrumenting-with-mlflow-tracing技能(有关 autolog、装饰器、会话跟踪和验证的权威指南) - dataset-preparation.md — 数据集架构、API、创建、Unity Catalog
- scorers.md — 内置与自定义评分器、注册、测试
- scorers-constraints.md — 自定义评分器的 CLI 要求(是/否格式、模板)
- troubleshooting.md — 按阶段分类的常见错误及解决方案
- throughput-guide.md — 并行度环境变量、异步 predict_fn、针对 200 个以上问题评估的数据集拆分
- advanced-evaluation.md — 筛选生产跟踪记录、比较版本或提示词,以及运行持续评估
- databricks-online-monitoring.md — 在 Databricks 上注册、启动、验证、采样和管理生产评分器
- prompt-optimization.md — 使用 GEPA 优化已注册的提示词,在保留集上评估,并按条件进行推广
脚本具有自文档说明功能——运行时使用 --help 查看用法详情。