eval-driven-dev 技能 Step 5 实战:运行 pixie test 并修复机制性问题
2026/9/13 8:20:37 网站建设 项目流程

eval-driven-dev 技能 Step 5 实战:运行 pixie test 并修复机制性问题

【免费下载链接】awesome-copilotCommunity-contributed instructions, agents, skills, and configurations to help you make the most of GitHub Copilot.项目地址: https://gitcode.com/GitHub_Trending/aw/awesome-copilot

本指南聚焦于 eval-driven-dev 技能工作流中的Step 5(Run pixie test and Fix Mechanical Issues),讲解如何使用 pixie-qa 评测框架端到端执行评估流水线:从命令行启动测试、理解评估 harness 的内部执行顺序,到系统性地分类并修复"机制性问题"(mechanical issues),最终让每个数据集条目都产出真实可用的评估分数。读完本文,你将掌握pixie test的完整运行原理、并发安全陷阱的排查方法,以及如何区分"该在 Step 5 修的问题"与"必须留给 Step 6 分析的问题"。


一、Step 5 在整个工作流中的位置与目标

eval-driven-dev 是一条完整的评估驱动开发流水线,共 6 个步骤:

  1. Step 1:分析应用、确定入口点、定义评估标准(产出pixie_qa/00-project-analysis.md01-entry-point.md02-eval-criteria.md
  2. Step 2:用wrap()对应用打点(2a-instrumentation)、实现 Runnable(2b-implement-runnable)、捕获参考 trace(2c-capture-and-verify-trace)
  3. Step 3:定义评估器(3-define-evaluators)
  4. Step 4:构建数据集(4-build-dataset)
  5. Step 5:运行pixie test并修复机制性问题 ——本文主题
  6. Step 6:分析评估结果、生成行动方案(6-analyze-outcomes)

Step 5 的目标非常明确:让整个流水线"跑起来",而不是评估结果好坏。它只修复你在前几步构建的东西——数据集(dataset)、Runnable、自定义评估器(custom evaluators)——中的机制性问题,比如数据集格式错误、Runnable 无法运行、评估器报错等。这一步评估应用输出质量,也修复应用本身的 bug。

按 SKILL.md 的定义,最终交付物是一个能产生真实分数的pixie test运行——不是方案、不是打点、不是数据集。Step 5 就是这个交付物的"临门一脚"。

注意:Step 5 的检查点(Checkpoint)要求pixie test完整跑通,每个数据集条目都有评估器分数(真实的EvaluationResultPendingEvaluation),且没有 setup 错误、导入失败、数据校验错误。一旦产出分数就立即进入 Step 6——不要在 Step 5 停下询问用户,因为 pending 评估只有经过 Step 6 分析才会完成,否则用户只能看到一堆未解释的原始分数。


二、5a:运行测试

2.1 基本命令

在项目根目录(虚拟环境已激活的前提下)执行:

uv run pixie test

pixie test会自动加载.env文件后再运行测试,因此你的环境变量(如 LLM API Key)会按预期注入。

如果需要查看每个测试用例的分数和评估器推理过程,使用详细输出模式:

uv run pixie test -v

2.2 相关 CLI 命令速览

根据 testing-api.md 的 CLI 命令表,与测试流程相关的命令还包括:

命令说明
pixie test [path] [-v] [--no-open]对数据集文件运行评估测试
pixie dataset create <name>创建新的空数据集
pixie dataset list列出所有数据集
pixie dataset save <name> [--select MODE]将一个 span 保存到数据集
pixie dataset validate [path]校验数据集 JSON 文件
pixie analyze <test_run_id>生成分析与建议(对应 Step 6)

在 Step 5 之前或排查阶段,pixie dataset validate可以提前发现数据集 JSON 的格式问题,减少进入测试环节后的返工。


三、评估 harness 的执行流程(运行原理)

pixie test运行时,评估 harness 按以下顺序处理(对应 5-run-tests.md 中描述的 8 个环节):

  1. 解析 Runnable:从数据集的runnable字段解析出目标类(格式为filepath:ClassName,例如"pixie_qa/run_app.py:AppRunnable")。
  2. 构建实例并初始化:调用Runnable.create()构造实例,然后调用一次setup()(用于初始化共享资源,如 HTTP 客户端、数据库连接、测试服务器)。
  3. 并发运行所有数据集条目(最多 4 个并行): a. 从条目读取input_dataeval_inputb. 用eval_input数据填充 wrap 输入注册表(wrap input registry) c. 初始化捕获注册表(capture registry) d. 将input_data校验为 Pydantic 模型,并调用Runnable.run(args)e. 应用中wrap(purpose="input")调用返回注册表中的值,而不是调用真实外部服务f.wrap(purpose="output"/"state")调用捕获数据供评估使用 g. 由捕获数据构建Evaluableh. 运行评估器(evaluators)
  4. 收尾:最后调用一次Runnable.teardown()(释放setup()中获取的资源)。

3.1 Runnable 生命周期与并发模型

根据 wrap-api.md 中的pixie.Runnable协议定义:

class pixie.Runnable(Protocol[T]): @classmethod def create(cls) -> Runnable[Any]: ... async def setup(self) -> None: ... async def run(self, args: T) -> None: ... async def teardown(self) -> None: ...

生命周期要点:

  • create()—— 类方法,构造并返回一个 runnable 实例;
  • setup()——async,在第一次run()之前调用一次,用于初始化共享资源;可选,默认是 no-op;
  • run(args)——async为每个数据集条目并发调用(最多 4 个并行),args是由input_data构建并校验过的 Pydantic 模型;在此调用应用的真实入口点;
  • teardown()——async,在最后一次run()之后调用一次;可选,默认是 no-op。

因为run()通过asyncio.gather并发调用,你的实现必须并发安全

3.2 wrap 注册表在测试时的行为

Step 5 的执行之所以能"用测试数据替换外部依赖",依赖的是wrap()在 eval 模式下的行为(详见 wrap-api.md):

  • purpose="input":在 eval 模式下,返回注册表中的注入值。若data是 callable,返回的包装器会忽略原函数、每次调用都返回注入值——从而阻止真实外部调用执行
  • purpose="output"/purpose="state":在 eval 模式下捕获输出/状态,供构建Evaluable使用。

这也是为什么在 2a-instrumentation 中强调:对purpose="input"的外部调用必须使用函数形式wrap(fetch_page, purpose="input", name="fetched_page")(url)),否则真实调用仍会执行,导致测试变慢、不稳定、依赖外部服务可用性。

3.3 并发安全:必读的 Semaphore 模式

由于条目并发运行,Runnable 的run()方法必须并发安全。如果你看到sqlite3.OperationalError"database is locked"或类似错误,说明你的 Runnable 中共享了 SQLite 连接等可变状态,需要在 Runnable 中加Semaphore(1)(详见 Step 2 参考文档的并发安全章节)。

wrap-api.md 给出的标准做法:

class AppRunnable(pixie.Runnable[AppArgs]): _sem: asyncio.Semaphore @classmethod def create(cls) -> "AppRunnable": inst = cls() inst._sem = asyncio.Semaphore(1) # serialise DB access return inst async def run(self, args: AppArgs) -> None: async with self._sem: await call_app(args.message)

常见并发陷阱(来自 wrap-api.md):

  • SQLite:并发写入不安全——使用Semaphore(1)aiosqlite并开启 WAL 模式;
  • 全局可变状态:在run()中修改的模块级 dict/list 需要保护;
  • 限流 API:加信号量以避免 429 错误。

但注意:只有当应用确实存在共享可变状态时才需要加信号量。如果应用使用按请求隔离的状态(按唯一 ID 隔离)或天然无状态,并发调用自然是隔离的(2b-implement-runnable)。另外,2b-implement-runnable.md 提醒:不要在 runnable 文件中使用from __future__ import annotations——它会破坏 Pydantic 对嵌套模型的解析,应改用带引号的返回类型(-> "AppRunnable")。


四、5b:只修复机制性问题

这一阶段严格限定为修复你在前几步构建的东西——数据集、Runnable、自定义评估器。你修复的是阻止流水线运行的机制问题不是评估或改进应用的输出质量。

4.1 属于机制性问题(需要修复)

错误原因修复方式
WrapRegistryMissError: name='<key>'数据集条目缺少应用wrap(purpose="input", name="<key>")所期望的name对应的eval_input在每个受影响的条目中,向eval_input添加缺失的{"name": "<key>", "value": ...}
WrapTypeMismatchError反序列化后的类型与应用期望的类型不匹配修正数据集中的 value
Runnable 解析失败runnable路径或类名错误,或类未实现Runnable协议修正数据集中的filepath:ClassName;确保类有create()run()方法
导入错误runnable/evaluator 的模块路径或语法错误修正被引用的文件
ModuleNotFoundError: pixie_qapixie_qa/目录缺少__init__.py运行pixie init重建
TypeError: ... is not callable评估器名称指向不可调用的属性评估器必须是函数、类或可调用实例
sqlite3.OperationalError并发的run()调用共享 SQLite 连接在 Runnable 中添加asyncio.Semaphore(1)(见上文)
自定义评估器崩溃自定义评估器实现中的 bug修复评估器代码

4.2 不属于机制性问题(不要在此处修复)

  • 应用产出错误/低质量输出→ 这是应用行为,留待 Step 6 分析
  • 评估器分数偏低→ 这是质量信号,留待 Step 6 分析
  • 应用内部的 LLM 调用失败→ 在 Step 6 中报告,不要 mock 或绕过
  • 评估器分数在不同运行间波动→ LLM 非确定性的正常现象,不是 bug

这一"修复边界"的设计意图很关键:Step 5 只保证"管道通了",至于分数高低、应用好坏,必须在完整分析后才有意义。尤其要注意最后一点——LLM 评估天然带有非确定性,分数波动不是你需要修的问题。

4.3 迭代策略

修复是循环过程:修错误 → 重新运行 → 修下一个错误,直到pixie test完整跑通、所有条目都产出真实评估分数。

遇到意外错误(参数名错误、导入失败、API 不匹配)时,不要靠猜——先阅读 wrap-api.md、evaluators.md 或 testing-api.md 获取权威 API 参考,再动手修复。

4.4 从源头减少机制性问题

很多 Step 5 的报错其实可以在前序步骤预防:

  • eval_input缺失问题:根据 4-build-dataset,如果应用存在任何wrap(purpose="input")调用,每个数据集条目都必须提供对应的eval_input(否则应用会在 eval 运行时发起真实外部调用)。其 4c″ 节的"数据集真实性审计"硬门槛中就有"eval_input完整性检查"一项,逐条核对每个 input wrap 是否都有对应条目。
  • WrapTypeMismatchErroreval_input的值必须与wrap()调用返回的精确类型和格式匹配(4-build-dataset 4b′ 节"内容格式")。以参考 trace 为模板复制数据形状,而不是凭空构造。
  • Runnable 解析失败:数据集的"runnable"字段格式为"pixie_qa/run_app.py:AppRunnable",路径相对项目根目录,且项目根目录会自动加入sys.path,可直接用普通import引用项目模块(wrap-api.md)。

五、输出:结果目录结构

pixie test成功运行后,结果按条目存储到如下目录结构中:

{PIXIE_ROOT}/results/<test_id>/ meta.json # 测试运行元数据 dataset-{idx}/ metadata.json # 数据集名称、路径、runnable entry-{idx}/ config.json # 评估器、描述、期望 eval-input.jsonl # 提供给评估器的输入数据 eval-output.jsonl # 从应用捕获的输出数据 evaluations.jsonl # 评估结果(已评分 + 待处理 pending) trace.jsonl # LLM 调用 trace(如已捕获)

各文件含义:

  • meta.json—— 本次测试运行的元数据(时间、参数等);
  • dataset-{idx}/metadata.json—— 数据集名称、路径、runnable 引用;
  • entry-{idx}/config.json—— 该条目的评估器列表、描述(description)、期望(expectation);
  • entry-{idx}/eval-input.jsonl—— 喂给评估器的输入数据;
  • entry-{idx}/eval-output.jsonl—— 运行应用时捕获的输出数据;
  • entry-{idx}/evaluations.jsonl——核心产物:每条评估结果,包含已评分的(scored)与待处理的(pending,例如 agent evaluator 产生的PendingEvaluation);
  • entry-{idx}/trace.jsonl—— LLM 调用 trace(若已捕获)。

<test_id>会打印在控制台输出中。在 Step 6 你会引用这个目录:按 SKILL.md 的硬性完成门槛,Step 6 必须把evaluations.jsonl中每个"status": "pending"条目替换为含scorereasoning的评分结果,并为每个数据集目录生成analysis.md/analysis-summary.md、为测试运行根目录生成action-plan.md/action-plan-summary.md


六、与前后步骤的衔接

  • 循环规则(来自 SKILL.md):每次成功的pixie test都会创建具体的pixie_qa/results/<test_id>目录并开启一个新的分析周期。在修改应用代码、提示词、数据集、评估器或重跑pixie test之前,必须先针对该结果目录完成 Step 6。不要跳过早期周期只分析最后一次运行。
  • pixie testpixie trace的关系:测试阶段使用 eval 模式(注册表注入输入、捕获输出),而 trace 阶段运行真实依赖以捕获参考数据(wrap-api.md 中wrap()在三种模式——no-op、tracing、eval——下的行为差异,是理解整条流水线的钥匙)。
  • 应用真实代码路径原则:整个评估过程中应用的 LLM 调用必须走真实 LLM,绝不 mock、stub 或拦截。如果项目自带测试套件中包含 LLM mock 模式,那是项目自身单元测试用的,不要移植到 eval Runnable 中(SKILL.md)。同理,Step 5 遇到"应用内部 LLM 调用失败"也不能用 mock 绕过,而应在 Step 6 报告。

七、小结

Step 5 是评估驱动开发流水线中"从构建到验证"的转换点。记住三条核心原则:

  1. 目标纯粹:只修"管道问题"(数据集格式、Runnable 可运行性、评估器可调用性),不评质量、不改应用;
  2. 理解执行模型:Runnable 生命周期(create → setup → 并发 run → teardown)、wrap 注册表注入、并发安全(Semaphore)是排查一切报错的基础;
  3. 产出明确pixie test完整跑通、所有条目有真实分数后,立即进入 Step 6 分析——结果目录{PIXIE_ROOT}/results/<test_id>/是后续所有分析工作的数据基础。

想深入 API 细节的读者,可直接查阅 testing-api.md(数据集 JSON 格式、评估器名称解析、Evaluable/Evaluation/ScoreThreshold类型)、wrap-api.md(Runnable 协议、wrap()三种模式、错误类型)与 evaluators.md(内置评估器选择指南、自定义评估器工厂函数)。

【免费下载链接】awesome-copilotCommunity-contributed instructions, agents, skills, and configurations to help you make the most of GitHub Copilot.项目地址: https://gitcode.com/GitHub_Trending/aw/awesome-copilot

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询