TensorZero 评估实战:从俳句生成到数据集构建与 LLM Judge 对比评估
【免费下载链接】tensorzeroTensorZero is an open-source LLMOps platform that unifies an LLM gateway, observability, evaluation, optimization, and experimentation.项目地址: https://gitcode.com/GitHub_Trending/te/tensorzero
TensorZero 是一个开源的 LLMOps 平台,将 LLM 网关(Gateway)、可观测性、评估(Evaluation)、优化与实验统一到一个工作流中。本文以仓库中的 examples/evaluations/tutorial 教程为骨架,完整演示一条"定义函数与变体 → 配置多种评估器 → 批量生成样本 → 构建数据集 → 用 CLI 与 UI 运行评估 → 对比不同变体效果"的评估闭环。读完本文,你将掌握 TensorZero 评估体系的核心配置语法(exact_match 与 llm_judge)、Evaluations CLI 的完整用法,以及如何在 TensorZero UI 中直观对比不同模型变体的质量差异,可直接迁移到自己的 LLM 应用评测流程中。
教程概览与目录结构
本教程位于仓库的 examples/evaluations/tutorial 目录,其核心是一个"俳句(Haiku)生成与评估"示例:定义一个write_haiku函数,提供gpt_4o与gpt_4o_mini两个变体,并为它配置精确匹配(exact match)与多种 LLM 裁判(LLM judge)评估器。整个目录结构如下:
examples/evaluations/tutorial/ ├── config/ │ ├── tensorzero.toml # 函数、变体与评估器的核心配置 │ └── functions/write_haiku/ │ ├── user_schema.json # 用户输入 JSON Schema │ ├── user_template.minijinja # 提示词模板 │ └── evaluators/ │ ├── valid_haiku/system_instructions.txt │ ├── metaphor_count/system_instructions.txt │ └── compare_haikus/system_instructions.txt ├── data/nounlist.txt # 100 个俳句主题词来源 ├── docker-compose.yml # Gateway / UI / ClickHouse / Evaluations 编排 ├── main.py # 批量生成 100 首俳句的脚本 ├── pyproject.toml # Python 依赖(tensorzero 客户端) └── uv.lock需要说明的是:README 中提到的.env.example示例文件并未包含在当前仓库快照中,稍后我们按 docker-compose.yml 中实际引用的环境变量手动创建.env即可。
环境准备:Docker、Python 与 OpenAI API Key
开始之前需要满足以下前置条件(与 README 一致):
- 安装 Docker(用于启动 Gateway、UI、ClickHouse 与 Evaluations 服务);
- 安装 Python 3.10+(教程脚本与客户端运行环境,见 pyproject.toml 中的
requires-python = ">=3.10"); - 安装 Python 依赖,推荐使用
uv包管理器,在 examples/evaluations/tutorial 目录下执行uv sync,核心依赖只有一个:tensorzeroPython 客户端; - 生成 OpenAI API Key(
OPENAI_API_KEY),因为两个俳句变体与所有 LLM judge 变体都指向openai::gpt-4o/openai::gpt-4o-mini模型。
然后创建.env文件,写入 OpenAI 凭据:
OPENAI_API_KEY=sk-...这一步之所以必须,是因为 docker-compose.yml 中 gateway 与 evaluations 两个服务都对OPENAI_API_KEY做了强校验:${OPENAI_API_KEY:?Environment variable OPENAI_API_KEY must be set.},未设置时容器启动会直接失败。如果还使用了其他模型提供方(如 GCP Vertex),同样在此追加对应凭据。
一键启动基础设施:docker compose up
在 examples/evaluations/tutorial 目录下执行:
docker compose up它会拉起三个默认服务(该 compose 文件为学习用途做了刻意简化,生产部署请参考官方部署指南):
| 服务 | 镜像 | 端口 | 作用 |
|---|---|---|---|
clickhouse | clickhouse:lts | 8123(HTTP)/ 9000(Native) | 开发用 ClickHouse,存储推理记录、数据集与评估结果,数据卷clickhouse-data持久化 |
gateway | tensorzero/gateway | 3000 | TensorZero 网关,以--config-file /app/config/tensorzero.toml加载配置,通过TENSORZERO_CLICKHOUSE_URL连接 ClickHouse |
ui | tensorzero/ui | 4000 | TensorZero 管理界面,通过TENSORZERO_GATEWAY_URL: http://gateway:3000连接网关 |
编排上依赖关系已自动处理:gateway 等待 ClickHouse 健康(wget ... :8123/ping探活),ui 等待 gateway 健康(/health探活)。另外还有一个evaluations服务(镜像tensorzero/evaluations)默认不会启动——它带有profiles: [evaluations]标记,只在显式运行时被拉起,这正是后续"用 CLI 跑评估"的入口。
网关健康检查地址为http://localhost:3000/health,UI 地址为http://localhost:4000,启动完成后即可打开 UI 浏览。
理解评估对象:write_haiku函数与两个变体
评估的第一步是定义被评估的函数。config/tensorzero.toml 中定义了write_haiku:
[functions.write_haiku] type = "chat" user_schema = "functions/write_haiku/user_schema.json" [functions.write_haiku.variants.gpt_4o_mini] type = "chat_completion" model = "openai::gpt-4o-mini" user_template = "functions/write_haiku/user_template.minijinja" [functions.write_haiku.variants.gpt_4o] type = "chat_completion" model = "openai::gpt-4o" user_template = "functions/write_haiku/user_template.minijinja"type = "chat"声明这是一个聊天型函数;user_schema指向 user_schema.json,规定用户输入必须是一个包含topic字符串字段的对象(required: ["topic"],且additionalProperties: false),网关据此对输入做结构校验;- 两个变体
gpt_4o与gpt_4o_mini都声明为chat_completion,分别路由到 OpenAI 的gpt-4o与gpt-4o-mini,共享同一个提示词模板 user_template.minijinja,内容只有一行:
Write a haiku about: {{ topic }}模板采用 MiniJinja 语法,{{ topic }}会在推理时被用户输入中的topic字段填充。两个变体共享函数与模板、仅模型不同,这为后面的"同配置、不同模型"对比评估创造了条件——评估结论可以直接归因于模型本身的差异。
定义评估器:精确匹配与 LLM 裁判
tensorzero.toml 的 EVALUATORS 段落在write_haiku函数下挂载了四个评估器,覆盖了 TensorZero 两类核心评估器类型。
1.exact_match:零成本精确匹配
[functions.write_haiku.evaluators.exact_match] type = "exact_match"exact_match无需模型调用,直接比对输出与参考答案是否完全一致,常作为快速、确定性的基线指标。从源码结构看(crates/tensorzero-core/src/config/rehydrate.rs),TensorZero 的评估器类型体系还包括Regex、ToolUse、Typescript(TypeScript 裁判)与LLMJudge等,exact_match只是其中最简单的一种。
2.valid_haiku:布尔型 LLM 裁判
[functions.write_haiku.evaluators.valid_haiku] type = "llm_judge" output_type = "boolean" optimize = "max" [functions.write_haiku.evaluators.valid_haiku.variants.gpt_4o_mini_judge] type = "chat_completion" model = "openai::gpt-4o-mini" system_instructions = "functions/write_haiku/evaluators/valid_haiku/system_instructions.txt" json_mode = "strict" active = true [functions.write_haiku.evaluators.valid_haiku.variants.gpt_4o_judge] type = "chat_completion" model = "openai::gpt-4o" system_instructions = "functions/write_haiku/evaluators/valid_haiku/system_instructions.txt" json_mode = "strict"关键点:
type = "llm_judge"表示由另一个 LLM 充当裁判;output_type = "boolean"声明裁判输出为布尔值(是否合格);optimize = "max"声明该指标越大越好,后续优化功能(如 GEPA)会以它为优化目标;- 裁判本身也是
chat_completion变体,可以配置多个裁判变体并指定active = true来选定默认裁判(这里gpt_4o_mini_judge为激活态,gpt_4o_judge未标active); json_mode = "strict"强制裁判以严格 JSON 模式输出结构化结果。
裁判的系统指令见 valid_haiku/system_instructions.txt:
Evaluate if the text follows the haiku structure of exactly three lines with a 5-7-5 syllable pattern, totaling 17 syllables. Verify only this specific syllable structure of a haiku without making content assumptions.
即:只校验"三行、5-7-5 音节、共 17 音节"的形式结构,不做内容层面的假设——这保证了判定标准的客观性。
3.metaphor_count:浮点型 LLM 裁判
[functions.write_haiku.evaluators.metaphor_count] type = "llm_judge" output_type = "float" optimize = "max" [functions.write_haiku.evaluators.metaphor_count.variants.gpt_4o_mini_judge] type = "chat_completion" model = "openai::gpt-4o-mini" system_instructions = "functions/write_haiku/evaluators/metaphor_count/system_instructions.txt" json_mode = "strict"output_type = "float"表示裁判输出一个浮点数。其指令 metaphor_count/system_instructions.txt 非常简短:
How many metaphors does the generated haiku have?
即让裁判统计生成的俳句中包含多少隐喻,用于评估创意维度。
4.compare_haikus:带参考输出的 LLM 裁判
[functions.write_haiku.evaluators.compare_haikus] type = "llm_judge" include = { reference_output = true } output_type = "boolean" optimize = "max" [functions.write_haiku.evaluators.compare_haikus.variants.gpt_4o_mini_judge] type = "chat_completion" model = "openai::gpt-4o-mini" system_instructions = "functions/write_haiku/evaluators/compare_haikus/system_instructions.txt" json_mode = "strict"与前面不同,这里多了include = { reference_output = true }:评估时会把数据集中预先保存的参考输出(reference output)一并注入裁判上下文,让裁判进行"生成结果 vs 参考结果"的对照评判。其指令 compare_haikus/system_instructions.txt:
Does the generated haiku include the same figures of speech as the reference haiku?
即判断生成的俳句是否使用了与参考俳句相同的修辞手法——这是典型的"有参考对比型"评估器,适用于需要与标注数据对齐的质检场景。
生成样本数据:运行main.py批量产出 100 首俳句
评估需要数据集,而数据集来自真实推理。执行:
python main.pymain.py 会通过 TensorZero Python 客户端向网关发起 100 次推理,流程如下:
- 固定随机种子
random.seed(0),保证每次运行结果可复现; - 用
AsyncTensorZeroGateway.build_http(gateway_url="http://localhost:3000")建立指向网关的异步 HTTP 客户端; - 从 data/nounlist.txt 读取主题词列表,随机打乱后取前 100 个作为俳句主题;
- 以
asyncio.Semaphore(10)将并发限制在 10,创建 100 个任务并发调用t0.inference(function_name="write_haiku", variant_name="gpt_4o", input={"messages": [{"role": "user", "content": [{"type": "text", "arguments": {"topic": topic}}]}]})生成俳句,最后asyncio.gather(*tasks)汇聚结果。
注意请求体的结构:content列表中的元素是带arguments的文本块,topic会被模板引擎填入user_template。这些推理会被网关自动写入 ClickHouse,成为后续构建数据集的素材。这些推理数据本身就是评估的数据池——评估数据集就是从这些已产生的推理记录中筛选出来的。
在 UI 中构建数据集
推理完成后,打开 UI(http://localhost:4000),按以下步骤构建评估数据集:
- 导航到Datasets页面,选择Build Dataset(直达地址
http://localhost:4000/datasets/builder); - 新建数据集,命名为
haiku_dataset; - 选择
write_haiku函数,metric 选择None(不需要显式指标),数据集输出(dataset output)选择Inference(直接使用推理输出作为数据集内容)。
构建完成后,haiku_dataset就包含刚才生成的 100 首俳句及其输入主题,可供评估运行使用。选择 "Inference" 作为输出意味着评估对象是真实线上推理的产出,而非人工构造的标注数据。
运行评估(一):Evaluations CLI 评估gpt_4o变体
TensorZero 提供独立的 Evaluations CLI 工具(对应 crates/evaluations 与 Docker 镜像tensorzero/evaluations),一条命令即可对指定函数、指定变体、指定评估器组合发起批量评估:
docker compose run --rm evaluations \ --function-name write_haiku \ --evaluator-names valid_haiku,metaphor_count,exact_match,compare_haikus \ --dataset-name haiku_dataset \ --variant-name gpt_4o \ --concurrency 5逐项解读参数:
| 参数 | 取值 | 含义 |
|---|---|---|
--function-name | write_haiku | 被评估的函数 |
--evaluator-names | valid_haiku,metaphor_count,exact_match,compare_haikus | 逗号分隔的评估器名列表,本次同时跑 1 个精确匹配 + 3 个 LLM 裁判 |
--dataset-name | haiku_dataset | 评估所用的数据集 |
--variant-name | gpt_4o | 被评估的模型变体 |
--concurrency | 5 | 并发度,控制同时执行的评估请求数 |
docker compose run --rm evaluations会临时拉起带evaluationsprofile 的服务容器(--rm表示任务结束后自动清理),容器内部加载 config/tensorzero.toml 与 ClickHouse 连接配置(TENSORZERO_CLICKHOUSE_URL),对haiku_dataset中的每条数据运行gpt_4o变体并逐项套用四个评估器,结果写回 ClickHouse。exact_match直接比对输出,valid_haiku、metaphor_count、compare_haikus则由配置中active = true的gpt_4o_mini_judge裁判变体以严格 JSON 模式给出结构化判定。
运行评估(二):UI 评估gpt_4o_mini变体并对比结果
CLI 评估完gpt_4o后,再用 UI 评估gpt_4o_mini,从而横向比较两个变体在相同数据集、相同评估器下的质量差异:
- 导航到Evaluations页面(
http://localhost:4000/evaluations),选择New Run; - 发起一次针对
gpt_4o_mini变体的评估运行(数据集与评估器沿用haiku_dataset及同一组评估器,保证变量可控); - 评估完成后,在下拉框中选中之前那次
gpt_4o的评估运行,UI 会将两次运行的结果并排对比。
对比视角可以落在:valid_haiku的合格率(布尔型、越大越好)、metaphor_count的平均隐喻数量(浮点型、越大越好)、exact_match的精确命中率,以及compare_haikus的修辞一致性通过率。由于两个变体共享同一函数、模板与评估器,任何差异都可归因于gpt-4o与gpt-4o-mini本身的能力差距——这正是"变体对比评估"的核心价值:用数据而非主观印象决定哪个模型方案上线。
小结与延伸
本教程走完了 TensorZero 评估的完整闭环:定义函数与变体 → 配置exact_match与llm_judge(布尔/浮点/带参考输出三种形态)→ 批量推理生成样本 → UI 构建数据集 → CLI 与 UI 双通道运行评估 → 变体间结果对比。四个评估器分别对应了"确定性基线、形式合规、创意量化、参考对照"四类常见评测诉求,而其output_type/optimize字段同时为 TensorZero 的优化与实验能力(如 GEPA、DICL 等)提供了可直接消费的指标目标。
如果希望继续深入,可以阅读 crates/evaluations 了解 CLI 的完整实现与更多参数(如数据集筛选、指标聚合),查看 crates/tensorzero-core/src/config 中评估器配置的解析与校验逻辑(UninitializedEvaluatorConfig/StoredEvaluatorConfig的各类评估器分支),或参考 docs/evaluations 下的推理评估与工作流评估文档,将同一套评估机制扩展到更复杂的多步骤工作流上。
【免费下载链接】tensorzeroTensorZero is an open-source LLMOps platform that unifies an LLM gateway, observability, evaluation, optimization, and experimentation.项目地址: https://gitcode.com/GitHub_Trending/te/tensorzero
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考