
Phoenix TypeScript 合成测试数据生成基于维度组合构建评估实验集【免费下载链接】phoenixAI Observability Evaluation项目地址: https://gitcode.com/gh_mirrors/phoenix13/phoenix合成测试数据是 LLM 应用评估体系中的关键一环当真实生产数据有限、涉及敏感信息或难以采集时你可以通过引导模型生成结构化样本快速覆盖常见场景、复杂多步骤用例以及错别字、越界查询等边界情况。本文基于 Phoenix 开源仓库中 TypeScript 侧的评估实践文档系统讲解维度驱动的合成数据生成方法——先定义变化轴dimensions再生成组合元组最后逐条转换为自然语言查询——并展示如何与arizeai/phoenix-client的数据集Dataset与实验Experiment能力衔接把合成数据变成可复现、可量化的评估流程。读完本文你将掌握维度设计、两步生成管线、面向失败模式的定向生成、质量控制与样本量规划以及将合成数据上传 Phoenix 并运行实验的完整 TypeScript 代码路径。何时使用合成数据与真实数据的取舍合成数据并非万能替代品它与真实数据各有适用场景。评估文档给出了清晰的取舍标准使用合成数据使用真实数据生产数据有限已有充足 traces测试边界与边缘情况验证实际行为上线前pre-launch评估上线后post-launch监控核心判断依据是目的合成数据服务于系统性覆盖适合在发布前对评估器Evaluator进行压力测试确保它能覆盖正常、边界、噪声等不同行为角度而真实数据服务于真实性验证用于确认系统在实际流量下的表现。实践中两者是互补的——先用合成数据跑通评估管线、校准评估器再切换到真实 traces 做持续监控。维度驱动方法定义变化轴合成数据生成的第一步是为你的领域定义变化轴dimensions。每个轴代表输入空间中的一个变化维度轴上的取值枚举了该维度的代表性状态const dimensions { issueType: [billing, technical, shipping], customerMood: [frustrated, neutral, happy], complexity: [simple, moderate, complex], };以上例而言issueType刻画问题类型customerMood刻画用户情绪complexity刻画问题复杂程度。三个轴形成 3×3×3 27 种组合空间每一组取值对应一种可预期的输入形态。这种设计的价值在于可枚举、可追溯每个合成样本都能回溯到它覆盖了哪些维度组合评估结果出现偏差时可以精确定位是哪个维度组合暴露了问题。这正是 Phoenix 评估方法论中错误分析优先Error analysis first的延伸——你无法自动化评估从未观察到的行为而维度组合让未观察到的行为变成一张显式的清单。面向已知失败模式的维度设计维度不应凭空设计而应来源于错误分析。将线上错误分析可参考仓库中 axial-coding.md 描述的把开放笔记聚合成结构化失败分类法的流程发现的失败类型直接映射为维度取值// 来自错误分析的发现 const dimensions { timezone: [EST, PST, UTC, ambiguous], // 已知失败模糊时区 dateFormat: [ISO, US, EU, relative], // 已知失败日期格式混用 };例如若线上数据显示模型在解析相对日期如last Tuesday或模糊时区时频繁出错就把ambiguous、relative显式列为维度取值。这样合成数据集就变成了对已知缺陷的回归测试集——每次修改 Prompt 或 Agent 逻辑后重跑即可验证缺陷是否被修复、是否复发。两步生成管线从元组到自然语言维度组合只是抽象的取值元组真正用于评估的是贴近真实用户习惯的自然语言输入。因此生成过程分两步生成元组组合维度取值得到结构化的Tuple转换为自然查询对每个元组发起一次独立的 LLM 调用将其翻译成真实、多样、非公式化的用户消息。import { generateText } from ai; import { openai } from ai-sdk/openai; // Step 1: 创建元组 type Tuple [string, string, string]; const tuples: Tuple[] [ [billing, frustrated, complex], [shipping, neutral, simple], ]; // Step 2: 将元组转换为自然语言查询 async function tupleToQuery(t: Tuple): Promisestring { const { text } await generateText({ model: openai(gpt-4o), prompt: Generate a realistic customer message: Issue: ${t[0]}, Mood: ${t[1]}, Complexity: ${t[2]} Write naturally, include typos if appropriate. Dont be formulaic., }); return text; }该代码使用 Vercel AI SDK 的generateText与ai-sdk/openai提供方。仓库中 setup-typescript.md 明确了 TypeScript 侧的环境要求arizeai/phoenix-evals2.x 需要Node.js 22.12与 AI SDKv7ai^7且使用的模型提供方必须与 AI SDK v7 兼容如ai-sdk/openaiv4。安装命令如下# 使用 npm npm install arizeai/phoenix-client arizeai/phoenix-evals arizeai/phoenix-otel npm install ai-sdk/openai # LLM-as-judge 评估器所需的提供方 # 使用 pnpm pnpm add arizeai/phoenix-client arizeai/phoenix-evals arizeai/phoenix-otel两点关键设计值得注意独立 LLM 调用每个元组单独生成避免一次生成多个样本时模型模式化地套用同一句式提示词中明确要求Write naturally, include typos if appropriate. Dont be formulaic主动注入错别字等噪声提升样本真实性。结构保留元组中的维度信息可作为样本的 metadata 一并存储评估时可按维度维度切片分析实现Per-dimension的细粒度归因。质量控制验证、去重、平衡批量生成后必须经过质量控制否则合成数据的覆盖性会被低质量样本稀释。文档给出三项核心检查Validate验证检查是否存在占位符文本、是否满足最小长度Deduplicate去重使用 embedding 相似度移除近似重复的查询Balance平衡确保各维度取值在数据集中覆盖均衡避免某类组合过量、某类缺失。其中验证可以通过确定性代码实现无需额外 LLM 调用function validateQuery(query: string): boolean { const minLength 20; const hasPlaceholder /\[.*?\]|.*?/.test(query); return query.length minLength !hasPlaceholder; }该函数用正则\[.*?\]|.*?捕获常见的占位符残留如[insert text]、name并强制 20 字符的最小长度阈值剔除过短或无意义的生成结果。去重与平衡则需要结合 embedding 相似度计算与维度统计可在生成循环之后作为批量校验步骤执行。质量控制应与上文的确定性优先原则呼应——能用代码完成的校验长度、占位符、格式就不要交给 LLM确定性逻辑先行LLM 只负责需要语义理解的环节。样本量规划合成数据集的规模取决于用途文档给出了三档经验值用途规模初步探索Initial exploration50–100全面评估Comprehensive eval100–500每维度组合Per-dimension每个组合 10–20规模选择要结合评估目标权衡初步探索阶段用小样本快速验证评估管线和 Prompt 方向全面评估需要更大样本以获得统计稳定的分数。这里需要特别强调稳定性问题——仓库中 experiments-running-typescript.md 明确指出当任务或评估器是非确定性的LLM 调用、工具使用、流式输出、LLM-as-judge单次运行的分数是带噪声的在小数据集上这种逐次噪声会淹没 Prompt 变更带来的真实信号。因此运行实验时可以配合repetitions参数对每个样本重复执行多次并对分数取均值const experiment await runExperiment({ client, experimentName: synthetic-eval-v1, dataset: { datasetName: customer_support_queries }, task, evaluators, repetitions: 3, // 每个样本运行 3 次平滑 LLM 采样噪声 maxConcurrency: 5, // 限制并发执行数 });判断原则是当任务或评估器涉及 LLM 且数据集较小时优先使用 repetitions当任务与评估器均为确定性逻辑如与 ground truth 做字符串比对时单次运行即为答案。不要轻信基于单个 10 样本运行做出的调优决策——repetitions: 1默认值只是静默依赖单次运行而已。将合成数据落地 Phoenix数据集与实验生成并质检后的合成样本需要通过arizeai/phoenix-client的数据集 API 上传到 Phoenix再通过实验 API 驱动评估。仓库 experiments-datasets-typescript.md 与 createDataset.ts 源码 详细说明了这一链路。创建数据集upsert 语义import { createClient } from arizeai/phoenix-client; import { createDataset } from arizeai/phoenix-client/datasets; const client createClient(); const { datasetId } await createDataset({ client, name: customer_support_synthetic, examples: [ { input: { query: ughh my order never arrived can you check it }, output: { intent: order_status, classification: correct }, metadata: { issueType: shipping, complexity: simple }, }, // ... 其余合成样本 ], });源码层面的关键语义是upsert不存在则创建存在则更新createDataset会先按名称匹配已有数据集若同名数据集已存在则更新为与本次传入的 examples 一致用相同输入重复调用是无操作no-op。从 createDataset.ts 的实现可以看到函数会将 examples 拆分为inputs、outputs、metadata、splits四组并行上传。此外每个 example 支持携带稳定 IDid——服务器会更新匹配行而非新增行也可以携带spanId将样本关联回源 trace这在用真实 traces 采样建数据集时尤为有用。Example类型的完整结构如下interface Example { input: Recordstring, unknown; // 任务输入 output?: Recordstring, unknown | null; // 期望输出 metadata?: Recordstring, unknown | null; // 附加上下文如来源、类别 splits?: string | string[] | null; // 划分train、[train, easy] 等 spanId?: string | null; // 关联源 trace 的 OTEL span ID id?: string | null; // 稳定 ID服务器更新匹配行 }将合成样本的维度取值写入metadata即可在评估结果中按维度切片归因——这正是维度驱动方法论在 Phoenix 数据模型中的落点。运行实验把数据集变成评估证据数据集创建完成后用runExperiment定义任务函数与评估器即可执行评估。任务函数接收每个 example 的 input返回模型输出评估器通过asExperimentEvaluator包装为代码评估器接收{ output, expected }并返回{ score, label }import { runExperiment, asExperimentEvaluator, } from arizeai/phoenix-client/experiments; const task async (example: { input: Recordstring, unknown }) { return await callLLM(example.input.query as string); }; const intentMatch asExperimentEvaluator({ name: intent_match, kind: CODE, evaluate: async ({ output, expected }) ({ score: output expected?.intent ? 1.0 : 0.0, label: output expected?.intent ? match : no_match, }), }); const experiment await runExperiment({ client, experimentName: synthetic-customer-support-v1, dataset: { datasetId }, task, evaluators: [intentMatch], });若任务内部调用 AI SDK 的generateText/streamText需注意一个与仓库版本相关的细节arizeai/phoenix-client7.x 要求 AI SDK v7而 AI SDK v7不会自行通过全局 tracer provider 发出 OpenTelemetry spans。正确做法是在任务函数内部构造ai-sdk/otel的OpenTelemetry集成并逐调用传入telemetry选项因为该集成在构造时绑定当前激活的 tracer provider而runExperiment只在任务运行期间挂载实验专属的 provider——若在启动时一次性registerTelemetry绑定发生在 provider 存在之前任务 spans 会丢失。这与普通应用 tracing 的启动时注册习惯正好相反是实验场景特有的注意事项。来自arizeai/phoenix-evals的评估器会被自动追踪无需额外 telemetry 配置。合成数据生成的通用最佳实践综合仓库中 cookbook 合成数据教程 与评估技能文档 phoenix-evals/SKILL.md 的要点合成数据生成应遵循以下实践设定明确目标先定义要覆盖的场景、边界情况和失败模式再动手生成。维度的来源是错误分析而不是拍脑袋结构化提示词使用 JSON schema、校验规则和显式输出格式约束生成结果要求模型只输出合法 JSON、无代码围栏、无多余文本降低解析失败率确保覆盖均衡混合正/反例正确与错误分类、边界条件与多样输入让评估器接受全面压力测试验证数据质量检查 schema 合规性、逻辑一致性与真实感——Placeholder 残留、重复样本、维度失衡都会污染评估结论迭代优化先跑一轮实验发现覆盖缺口再针对性补充维度或调整生成提示词形成生成→评估→补缺→再生成的闭环。对于 Agent 类系统合成数据集还应显式划分类别以保证均衡覆盖happy-path简单常见请求、complex/multi-step多步推理、edge cases歧义或不完整输入、adversarial/refusal越界或不安全请求、noise错别字、俚语、多语言。这与 axial-coding.md 中 Agent 失败分类法的思想一脉相承——先定义行为边界in-scope 与 out-of-scope再为每个边界组织覆盖样本才能系统验证 Agent 的可靠性、安全性与鲁棒性。小结维度驱动的合成数据生成为 Phoenix 评估实验提供了一条可枚举、可追溯、可回归的数据供给路径以错误分析为依据设计维度轴用元组 → 自然语言两步管线批量产出贴近真实的样本以验证、去重、平衡三道质量控制把关最后按用途规模规划样本量通过createDatasetupsert 语义与runExperiment含 repetitions 与并发控制无缝接入 Phoenix 的实验评估闭环。对尚无充足生产数据的项目而言这是在上线前建立评估基线、校准 LLM-as-a-Judge 最经济且最可控的方式。【免费下载链接】phoenixAI Observability Evaluation项目地址: https://gitcode.com/gh_mirrors/phoenix13/phoenix创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考