17 KiB
17 KiB
---
name: eval-driven-dev
description: >
使用评估驱动开发改进 AI 应用。定义评估标准、对应用进行插桩、构建黄金数据集、观察和评估应用运行情况、分析结果,并生成具体的改进行动计划。
当用户要求为任何调用 LLM 模型的 Python 项目搭建 QA、添加测试、添加评估、做评测、做基准测试、修复错误行为、改进质量或做质量保障时,始终使用此技能。
license: MIT
compatibility: Python 3.10+
metadata:
version: 0.8.4
pixie-qa-version: ">=0.8.4,<0.9.0"
pixie-qa-source: https://github.com/yiouli/pixie-qa/
---
# Python LLM 应用的评估驱动开发
你正在构建一个**自动化评估流水线**,用于端到端测试基于 Python 的 AI 应用——就像真实用户那样运行它,使用真实输入——然后通过评估器对输出进行评分,并通过 `pixie test` 产生通过/失败结果。
**你测试的是应用本身**——它的请求处理、上下文组装(如何收集数据、构建提示词、管理对话状态)、路由和响应格式化。应用使用了 LLM,这使得输出具有非确定性——这就是为什么你使用评估器(LLM 作为评判者、相似度评分)而不是 `assertEqual`——但被测对象是应用的代码,而不是 LLM。
在评估过程中,应用自身的代码会真实运行——路由、提示词组装、LLM 调用、响应格式化——没有任何内容被 mock 或 stub。但应用从外部来源(数据库、缓存、第三方 API、语音流)读取的数据,会通过插桩(instrumentations)替换为测试指定的值。这意味着每个测试用例精确控制应用看到的数据,同时仍然执行完整的应用代码路径。
**规则:应用的 LLM 调用必须使用真实的 LLM。** 不得用虚假实现替换、mock、stub 或拦截 LLM。LLM 是核心价值生成组件——替换它会使得评估变成同义反复(你同时控制输入和输出,因此评分毫无意义)。如果项目的测试套件中包含 LLM mock 模式,那是项目自身单元测试使用的——切勿将其用于评估 Runnable。
**交付物是一个能运行的 `pixie test` 并产生真实评分**——不是计划,不光是插桩,不光是数据集。
此技能是关于执行工作,而非描述工作。阅读代码、编辑文件、运行命令,产出可运行的流水线。
---
## 开始之前
**首先,激活虚拟环境**。找到项目正确的虚拟环境并激活它。虚拟环境激活后,运行技能资源中包含的 setup.sh 脚本。
该脚本会将 `eval-driven-dev` 技能和 `pixie-qa` Python 包更新到最新版本,初始化 pixie 工作目录(如果尚未初始化),并在后台启动一个 Web 服务器以向用户展示更新。
**安装错误处理——哪些可以跳过,哪些必须成功:**
- **技能更新失败** → 可以继续。现有技能版本足以使用。
- **pixie-qa 升级失败但已安装** → 可以继续使用现有版本。
- **pixie-qa 未安装且安装失败** → **停止。** 请用户帮助。工作流无法在没有 `pixie` 包的情况下进行。
- **`pixie init` 失败** → **停止。** 请用户帮助。
- **`pixie start`(Web 服务器)失败** → **停止。** 请用户帮助。检查 pixie 根目录下的 `server.log` 以获取诊断信息。常见原因:端口冲突、缺少依赖、环境运行缓慢。**没有 Web 服务器就不能继续**——用户需要它来查看评估结果。
---
## 工作流程
按顺序执行步骤 1-6,中间不要停顿。不要在中间步骤询问用户确认——自行验证每个步骤并继续。
**如何工作——在执行任何操作之前先阅读以下内容:**
- **一次只做一个步骤。** 只阅读当前步骤的说明。在处理步骤 1 时,不要阅读步骤 2-6。
- **仅在步骤要求时阅读参考资料。** 每个步骤会指定一个特定的参考文件。到达该步骤时再阅读——不要提前阅读。
- **立即创建产物。** 为某个子步骤阅读代码后,立即写入该子步骤的输出文件,再继续下一步。不要在多个子步骤间积累理解之后再写任何东西。
- **验证,然后继续。** 每个步骤都有一个检查点。验证通过后,再进入下一步。不要在验证当前步骤的同时规划后续步骤。
**何时停止并请求帮助:**
有些阻碍是无法也不应该绕过的。当你遇到以下任何情况时,**立即停止并请用户帮助**——不要尝试变通方案:
- **应用因缺少环境变量或配置而无法运行**:应用需要未设置且无法推断的环境变量或配置。**不要**通过 mock、伪造或替换应用组件来绕过——评估必须执行真实的生产代码。请用户修复环境设置。
- **应用导入失败表明项目已损坏**:如果应用的核心模块因缺少系统依赖或不兼容的 Python 版本而无法导入(而不仅仅是你可以安装的 pip 包),请用户修复项目设置。
- **入口点不明确**:如果应用有多个同样合理的入口点,且项目分析无法明确哪个最重要,请询问用户应该以哪个为目标。
你应该自行解决的阻碍(不要询问):缺少 Python 包(安装它们)、缺少 `pixie` 包(安装它)、端口冲突(选择不同端口)、文件权限问题(修复它们)。
**按顺序执行步骤 1-6。** 如果用户的提示明确表明前面的步骤已经完成(例如"运行现有测试"、"重新运行评估"),则跳到相应步骤。如有疑问,从步骤 1 开始。
---
### 步骤 1:理解应用并定义评估标准
**首先,检查用户提示中的具体要求。** 在阅读应用代码之前,先审视用户的要求:
- **引用的文档或规格说明**:提示中是否提到要遵循的文件(例如"按照 EVAL_SPEC.md 中的规格说明"、"使用 REQUIREMENTS.md 中的方法")?如果是,**先阅读该文件**——它可能指定了数据集、评估维度、通过标准或方法论,这些会覆盖你的默认值。
- **指定的数据集或数据来源**:提示是否引用了特定的数据文件(例如"使用 eval_inputs/research_questions.json 中的问题"、"使用 call_scenarios.json 中的场景")?如果是,**阅读这些文件**——你必须以它们为基础构建评估数据集,而不是编造泛化的替代品。
- **指定的评估维度**:提示是否命名了要评估的具体质量方面(例如"评估事实准确性、完整性和偏见"、"测试身份验证和工具调用正确性")?如果是,**每个命名的维度都必须在你的测试文件中有一个对应的评估器**。
如果提示指定了上述任何内容,则它们具有优先权。在继续之前先阅读并整合它们。
步骤 1 有三个子步骤。每个子步骤阅读自己的参考文件并生成自己的输出文件。**在开始下一个子步骤之前,完整完成当前子步骤。**
#### 子步骤 1a:项目分析
> **参考文件**:立即阅读 `references/1-a-project-analysis.md`。
在查看代码结构或入口点之前,先理解这个软件在真实世界中的功能——它的目的、它的用户、真实输入的复杂性,以及它在哪里失败。这种理解驱动所有下游决策:哪些入口点最重要、定义哪些评估标准、使用哪些追踪输入、以及创建哪些数据集条目。在继续之前,先写详细的上下文文件。**注意**:项目可能包含 `tests/`、`fixtures/`、`examples/`、mock 服务器和文档——这些是项目自身的开发基础设施,**不是**你评估流水线的数据来源。在获取追踪输入和数据集内容时忽略它们。
> **检查点**:`pixie_qa/00-project-analysis.md` 已写入——涵盖该软件的功能、目标用户、能力清单(如果项目有,至少 3 个能力)、真实输入特征,以及困难问题/故障模式(至少 2 个)。
#### 子步骤 1b:入口点与执行流程
> **参考文件**:立即阅读 `references/1-b-entry-point.md`。
阅读源代码以了解应用如何启动以及真实用户如何调用它。使用 `pixie_qa/00-project-analysis.md` 中的**能力清单**来确定入口点的优先级——专注于能运行最有价值能力的入口点,而不是只找第一个找到的。在继续之前,先写详细的上下文文件。
> **检查点**:`pixie_qa/01-entry-point.md` 已写入——涵盖入口点、执行流程、面向用户的接口和环境要求。
#### 子步骤 1c:评估标准
> **参考文件**:立即阅读 `references/1-c-eval-criteria.md`。
定义应用的用例和评估标准。从 `pixie_qa/00-project-analysis.md` 中的**能力清单**推导出用例。从**困难问题/故障模式**推导出评估标准——而不是泛化的质量维度。用例驱动数据集创建(步骤 4);评估标准驱动评估器选择(步骤 3)。在继续之前,先写详细的上下文文件。
> **检查点**:`pixie_qa/02-eval-criteria.md` 已写入——涵盖用例、评估标准及其适用范围。现在还不要阅读步骤 2 的说明。
---
### 步骤 2:插桩、运行应用并捕获参考追踪
步骤 2 有三个子步骤。每个子步骤阅读自己的参考文件。**在开始下一个子步骤之前,完整完成当前子步骤。**
#### 子步骤 2a:使用 `wrap` 进行插桩
> **参考文件**:立即阅读 `references/2a-instrumentation.md`。
在应用的数据边界处添加 `wrap()` 调用,以便评估框架可以注入受控输入并捕获输出。这使得应用无需改变其逻辑即可被测试。
> **检查点**:所有数据边界均已添加 `wrap()` 调用。`pixie_qa/02-eval-criteria.md` 中的每个评估标准都有对应的数据点。
#### 子步骤 2b:实现 Runnable
> **参考文件**:立即阅读 `references/2b-implement-runnable.md`。
编写一个 Runnable 类,让评估框架能够像真实用户一样调用应用。Runnable 应该很简单——它只是将应用的真正入口点连接到评估框架接口。如果它变得复杂,说明有问题。
> **检查点**:`pixie_qa/run_app.py` 已写入。Runnable 使用真实的 LLM 配置调用应用的真正入口点——没有 mock,没有伪造,没有组件替换。
#### 子步骤 2c:捕获并验证参考追踪
> **参考文件**:立即阅读 `references/2c-capture-and-verify-trace.md`。
通过 Runnable 运行应用并捕获追踪。该追踪证明插桩和 Runnable 工作正常,并为步骤 4 的数据集创建提供所需的数据结构。
> **检查点**:`pixie_qa/reference-trace.jsonl` 存在。所有预期的 `wrap` 条目和 `llm_span` 条目均已出现。`pixie format` 显示所有评估所需的数据点。现在还不要阅读步骤 3 的说明。
---
### 步骤 3:定义评估器
> **参考文件**:立即阅读 `references/3-define-evaluators.md` 以获取详细的子步骤。
**目标**:将步骤 1c 中的定性评估标准转化为具体的、可运行的评分函数。每个标准映射到一个内置评估器、一个**智能体评估器**(任何语义或定性标准的默认选择),或一个手动自定义函数(仅用于机械性/确定性检查,如正则表达式或字段存在性)。评估器映射产物在标准和数据集之间架起桥梁,确保每个质量维度都有一个评分器。选择能够衡量 `pixie_qa/00-project-analysis.md` 中识别的**困难问题**的评估器——而不仅仅是泛化的质量维度。
> **检查点**:所有评估器已实现。`pixie_qa/03-evaluator-mapping.md` 已写入,包含标准到评估器的映射及决策理由。现在还不要阅读步骤 4 的说明。
---
### 步骤 4:构建数据集
> **参考文件**:立即阅读 `references/4-build-dataset.md` 以获取详细的子步骤。
**目标**:创建将所有内容联系在一起的测试场景——Runnable(步骤 2)、评估器(步骤 3)和用例(步骤 1c)。每个数据集条目定义要向应用发送什么、应用应从外部服务看到什么数据,以及如何对结果进行评分。使用步骤 2 中的参考追踪作为数据结构和字段名的真相来源。覆盖 `pixie_qa/00-project-analysis.md` 中**能力清单**的条目,并包括针对其中识别的**故障模式**的条目。**不要使用项目自身的测试夹具、mock 服务器或示例数据作为数据集的 `eval_input` 内容**——应使用真实世界的数据。**应用中每个 `wrap(purpose="input")` 必须在每个条目的 `eval_input` 中有预先捕获的内容**——当应用有输入 wrap 时,不要将 `eval_input` 留空。
> **检查点**:数据集 JSON 已创建于 `pixie_qa/datasets/<name>.json`,包含覆盖所有用例的多样化条目。**数据集真实性审核已通过**——条目使用真实世界的数据且规模具有代表性,没有项目测试夹具污染,至少有一个条目针对故障模式且结果不确定,并且每个 `eval_input` 对所有输入 wrap 都有捕获的内容。现在还不要阅读步骤 5 的说明。
---
### 步骤 5:运行 `pixie test` 并修复机械性问题
> **参考文件**:立即阅读 `references/5-run-tests.md` 以获取详细的子步骤。
**目标**:端到端执行完整流水线,使其在没有机械错误的情况下运行。此步骤严格限于修复 pixie QA 组件(数据集、Runnable、自定义评估器)中的设置和数据问题——**不是**修复应用本身或评估结果质量。一旦 `pixie test` 无错误完成,并为每个条目产生真实的评估器评分,此步骤即完成。
> **检查点**:`pixie test` 运行完成。每个数据集条目都有评估器评分(真实的 `EvaluationResult` 或 `PendingEvaluation`)。没有设置错误,没有导入失败,没有数据验证错误。
>
> 如果测试报错,那是你的 QA 组件中的机械性 bug——修复并重新运行。但一旦测试产生了评分,就继续前进。不要在这里评估结果质量——那是步骤 6 的事。
**在测试产生评分后,始终进行到步骤 6。** 分析是必不可少的关键步骤——没有它,待定评估永远无法完成,用户只能得到未经解读的原始评分,没有任何可操作的见解。不要停在这里问用户是否要继续。
**迭代运行的循环规则**:每次成功的 `pixie test` 调用都会创建一个具体的 `pixie_qa/results/<test_id>` 目录并启动一个新的分析周期。在你编辑应用代码、提示词、数据集、评估器或重新运行 `pixie test` 之前,先对该确切的结果目录完成步骤 6。不要跳过早期周期而只分析最后一次运行。
---
### 步骤 6:分析结果
> **参考文件**:立即阅读 `references/6-analyze-outcomes.md`——其中包含完整的三阶段分析流程、编写指南和输出格式要求。
**目标**:通过结构化的数据驱动流程分析 `pixie test` 结果,生成关于测试用例质量、评估器质量和应用质量的可操作见解。此步骤完成待定评估,写入每个条目和每个数据集的分析,并生成一个按优先级排序的行动计划。每项陈述必须有评估运行中的具体数据支持——不得推测,不得含糊。
**持久化的分析产物**:在此简化的工作流中,仅在数据集级别和测试运行级别持久化分析。这些产物仍然包含**详细版本**(供智能体消费:数据点、证据线索、推理链)和**摘要版本**(供人类审查:可在 2 分钟内阅读的简洁 TLDR)。不要创建每个条目的分析文件。
**硬性完成门禁**:步骤 6 **未完成**,直到以下所有条件均满足:
- 每个 `pixie_qa/results/<test_id>/dataset-*/entry-*/evaluations.jsonl` 中 `"status": "pending"` 的条目,都已替换为包含 `score` 和 `reasoning` 的评分结果。
- 每个数据集目录都有 `analysis.md` 和 `analysis-summary.md`。
- 测试运行根目录下有 `action-plan.md` 和 `action-plan-summary.md`。
- 你已经针对 `pixie_qa/results/<test_id>` 运行了此技能 `resources/` 目录中的步骤 6 验证脚本,并且它报告成功。
**明确不足够的:**
- 只写一个顶层文件如 `pixie_qa/06-analysis.md`
- 说待定评估留给用户在 Web UI 中查看
- 说某个条目"可能通过"而没有更新 `evaluations.jsonl`
---
## Web 服务器管理
pixie-qa 在后台运行一个 Web 服务器,用于向用户展示上下文、追踪和评估结果。它由设置脚本自动启动(通过 `pixie start` 命令,该命令启动一个分离的后台进程并立即返回)。
当用户完成 eval-driven-dev 工作流后,告知他们 Web 服务器仍在运行,你可以通过以下命令清理它:
```bash
pixie stop
重要提示:Web 服务器停止后,Web UI 将无法访问。因此,只有在用户确认他们已完成所有 Web UI 功能后才停止服务器。如果他们想继续使用 Web UI,不要停止服务器。
每当你重新启动工作流时,始终再次运行 resources 中的 setup.sh 脚本,以确保 Web 服务器正在运行: