expo-skill-eval

expo-skill-eval

热门

端到端评估本仓库中的 Expo Skill —— 覆盖触发准确率、生成代码质量,以及通过 Expo Go 在 iOS 模拟器和 Android 模拟器上的运行截图(Web 端可选)。当用户想要评估某个 Expo Skill、测试 Skill 能否生成可运行的代码、用设备截图跑基准测试,或校验 Skill 的输出渲染是否正确时使用。

2229Star
116Fork
更新于 2026/7/19
SKILL.md
只读
名称
expo-skill-eval
描述

端到端评估本仓库中的 Expo Skill —— 覆盖触发准确率、生成代码质量,以及通过 Expo Go 在 iOS 模拟器和 Android 模拟器上的运行截图(Web 端可选)。当用户想要评估某个 Expo Skill、测试 Skill 能否生成可运行的代码、用设备截图跑基准测试,或校验 Skill 的输出渲染是否正确时使用。

版本
1.0.0

Expo Skill Eval

评估 plugins/expo/skills/ 路径下的 Skill,测量其触发准确率、生成代码质量以及在 Expo Go 中的运行时渲染效果。

前置要求:装有 Xcode(含 iOS 模拟器)的 macOS、配置了至少一个 AVD 的 Android SDK,以及 bun。无需其它设备工具链。

工作区根目录:/private/tmp/expo-skill-eval-<skill-name>/iteration-N/(例如 /private/tmp/expo-skill-eval-expo-ui/iteration-4/)。

开始之前 —— 明确评估范围

在启动流水线之前,务必跟用户确认以下所有事项 —— 切勿遗漏任何一项(仅当用户请求中已明确说明某项选择时方可跳过该项)。请使用 AskUserQuestion 工具按顺序分批提问,每次提问不超过 4 个问题:

  1. 评估哪一个 Skill(如果请求中未写明)。
  2. Prompts(提示词) —— 决定由哪些提示词来驱动评估。内置提示词(来自 Skill 的评估用例)默认全选;用户可取消勾选某些项、添加自定义文本提示词,或者基于上传的截图生成(即 Skill 需要复刻的目标 UI 界面)。详见下方的 Prompts 章节。
  3. 校验哪些内容(What to verify) —— 多选题,包含三个维度:运行时 + 截图 / 触发准确率 / 代码检查(无需真实设备)。详见下方的 校验哪些内容 章节。
  4. Expo SDK —— 最新版本(默认,自动检测)或锁定为指定版本。
  5. Runner(运行器) —— Expo Go(默认)或开发构建(development build)。
  6. 目标平台 —— iOS / Android / Web(始终提供这三个选项)。
  7. claude -p 的权限标识 —— skip-permissions(默认)或 accept-edits。
  8. 结果查看器交付方式 —— 仅本地(默认)或发布为可分享的 Artifact。
  9. 如果勾选了触发准确率 —— 确认已发布/已安装的 expo 插件已被禁用(或未安装)。

每一项的详细说明见下文。第 4–6 项(SDK、Runner、目标平台)适合整合进同一个 AskUserQuestion 调用中提问。

如果请求中未明确要评估的 Skill,列出 plugins/expo/skills/ 下所有可用的 Skill,并询问用户需要评估哪一个。

被测 Skill 的两种加载机制(因阶段而异)(切勿全局混用):Executor(执行器)运行阶段通过文件路径直接引用(SKILL_PATH = plugins/expo/skills/<skill>/SKILL.md,显式读取);而触发率评估阶段则将其作为插件加载(--plugin-dir plugins/expo,以便模型能根据其描述自动匹配触发)。这两种方式都指向仓库本地的版本 —— 也就是你当前评估的对象。启动测试 Harness 所在的会话本身并不需要任何特殊标识(Harness 会通过仓库路径找到该 Skill);这些机制仅作用于 Harness 派生的 claude -p 子进程。各阶段为何有所不同,详见步骤 1 和步骤 3。包含触发率评估时的一项必需前置检查: 如果系统中已安装或启用了已发布版本expo 插件,请在启动 Harness 之前通过 /plugin 命令将其禁用,测试结束后再重新启用。禁用插件属于全局配置修改,当前会话以及派生的 claude -p 子进程都会继承该配置。触发率评估必须禁用它的原因是:该阶段会通过 --plugin-dir 加载本地 Skill,如果此时已经安装了另一个 expo 插件,两者就会产生冲突 —— 模型可能会误触发已发布expo:expo-ui,而检测逻辑只看工具调用名称,这会导致系统静默给已发布的描述打分而非你本地修改的版本(冲突甚至还可能引发报错)。而 Executor / 运行时 / 静态检查阶段不受此影响 —— 它们是直接读取本地 SKILL_PATH 文件的,没有使用 --plugin-dir —— 因此不包含触发率评估的运行可以跳过禁用操作。禁用 expo 插件不会影响 expo-skill-eval(因为它是一个独立的项目级 Skill,不属于 expo 插件的一部分),所以 Harness 依然能正常使用。

在准备阶段将此作为明确的前置确认向用户提示 —— 就像确认评估哪个 Skill 一样。只要包含触发率评估,在开始步骤 1 之前,就要求用户确认已发布的 expo 插件已被禁用(或未安装);如果依然处于启用状态,请暂停并提示用户通过 /plugin 禁用它。在用户确认之前,不要运行触发率评估 —— Harness 无法可靠地自动检测已安装的插件(读取全局插件配置或运行 claude plugin list 会触发交互提示),因此这是一项手动确认操作,而非自动校验。

选择提示词(Prompts)—— 内置提示词、自定义提示词或目标截图。 提示词是驱动 Executor(分别在挂载 Skill 和不挂载 Skill 模式下)运行的输入源;它们与后文的校验维度是分离开的。请通过 AskUserQuestion 与用户确认提示词(若用户请求中已明确提示词则可跳过):

  • 内置提示词 —— 通过读取被测 Skill(其 SKILL.mdreferences/)以及 references/runtime-matrix.md 自动生成的代表性提示词,覆盖该 Skill 的标准使用场景。(如果该 Skill 已经在 evals/evals.json 中内置了评估用例,则将其中的 prompt 字段一并纳入 —— 但大多数 Skill 并没有,因此通常需要自行推导)。默认全选这些提示词,以便默认运行即可测试 Skill 的标准场景;允许用户手动取消勾选。
  • 自定义文本提示词 —— 用户手动输入的即兴提示词。无需为其单独占用一个选项槽位:AskUserQuestion 会自动附带一个 "Type something"(输入其它内容)/ Other 选项,用户在其中输入的任何文本都会自动成为自定义文本测试用例。
  • 基于上传的截图生成 —— 用户提供一张目标截图的路径(即要求复刻的 UI 界面)。Executor 会被指令打开该截图 —— claude -p 可以通过其 Read 工具读取 PNG 图片 —— 并构建出一个与之匹配的 App;该用例会将路径记录为 reference_image,评分阶段会将生成的 App 与该目标图进行对比(步骤 6)。对于 UI 类型的 Skill 来说,这是最强有力的视觉测试方式:“把这个界面做出来”。

严格遵守 AskUserQuestion 每题最多 4 个选项的限制,并按以下优先级排布(必须避免的 Bug:选项填满 4 个后,上传截图选项被静默丢弃):

  1. 始终为“基于上传的截图生成”保留一个选项槽位。 这是视觉评估的核心亮点,绝对不能被挤掉。
  2. 不要添加显式的“自定义文本提示词”选项 —— 自动生成的 "Type something" / Other 选项已经涵盖了此功能。
  3. 用预选的内置/代表性提示词填满剩余不超过 3 个的槽位。如果内置提示词超过 3 个,请将它们合并为一个预选的 "所有内置提示词 (默认)" 选项,并在后续提问中提供细分挑选,从而保证上传截图选项始终能放得下。

请将其展示为一个多选列表。当用户勾选了“基于上传的截图生成”时,在随后的提问中要求用户提供目标图片的路径。每一个被选中的提示词(无论是内置、输入的还是图片的)都会生成一个评测用例(分别在挂载 Skill 和不挂载 Skill 模式下各运行一次)。

除非用户请求中已经非常明确,否则务必向用户确认要校验的内容。 展示以下选项并允许用户选择一项或多项(粗体代表根据 Skill 的 references/runtime-matrix.md 记录所推荐的默认项):

选项 作用 何时推荐为默认
运行时 + 截图 完整流水线:Fixture → Executor → 静态门禁 → 在 iOS/Android 上运行 App 并截屏。Runner(Expo Go 或开发构建)属于独立的问题 —— 不要在这里混为一谈。 默认推荐用于任何会渲染 App 屏幕的 Skill(即 references/runtime-matrix.md 中对应 expo-go/dev-build 行的 Skill)。需要提前启动模拟器/仿真器。
触发准确率 通过 claude -p 运行真实的提示词,检查 Skill 是否被成功读取。测量召回率(仅针对应当触发的查询)。 作为独立检查项时始终很有用。
代码检查(无需真实设备) tsc --noEmit + 差异感知 Lint + expo export,加上打分器会根据你提供的自定义预期校验生成的代码。无需连接任何设备。 默认推荐用于 static-onlyn/a 类型的 Skill,以及当你只想校验代码规范(例如正确的 import 路径、Host 包裹层等)而无需实际运行 App 的场景。

将这些选项作为同一个多选题提问 —— “你想校验哪些维度?” 这些是打分维度(如何评判构建出来的成果)—— 与 Prompts 阶段(要构建什么)是截然不同的。用户可以自由组合勾选。当提示词包含上传的截图时(见 Prompts),务必勾选 “运行时 + 截图”,这样 Harness 才能捕获生成的 App 截图,打分器也才能将其与目标截图进行比对。

在给出建议之前,请先查阅 references/runtime-matrix.md 获取该 Skill 的默认模式。如果请求中已经指定了模式(如“只需检查是否触发”、“在设备上运行”),则跳过此提问直接继续。

选择 Expo SDK 版本 —— 在准备阶段一次性确认。 运行 bash /abs/path/expo-skill-eval/scripts/latest-sdk.sh 来检测最新版本(该脚本会输出主版本号,例如 56;其内部使用 bun 运行 npm view expo dist-tags --json 并通过 JSON.parse/semver 读取主版本,这符合 bash 脚本规则 —— 因此不要自行内联运行 npm 注册表查询,否则会触发交互提示)。然后通过 AskUserQuestion 与用户确认:默认使用最新的 SDK,或者允许用户指定较旧的版本(例如为了复现特定版本的 Bug)。在构建 Fixture 的所有环节中一律使用选定的版本 —— 将其作为 <sdk> 参数传递给 make-fixture.sh,并写入每个评估用例的 runtime.sdk 字段中。如果用户请求中已经写明了版本号(如“在 SDK 54 上评估”),则跳过检测直接使用该版本。

默认使用最新版本 —— 这能确保与 expo start 自动在设备上安装的 Expo Go 保持兼容。如果选择的 SDK 版本低于设备上已安装的 Expo Go 版本,expo start 会尝试弹窗提示“是否安装推荐的 Expo Go 版本?”;而在无 TTY 环境下(快照脚本将 stdin 重定向自 /dev/null),进程会直接崩溃报错 Input is required, but 'npx expo' is in non-interactive mode,导致所有快照截图全部失败。因此,只有当你已经在模拟器/仿真器上预装了匹配版本的 Expo Go 时才可以指定旧版 SDK —— 否则请一律保持最新版。

选择 Runner —— Expo Go(默认)或开发构建(development build)。 通过 AskUserQuestion 询问用户(若请求中已明确则跳过):

  • Expo Go(默认) —— 快照脚本直接通过 expo start --ios / expo start --android 运行 App。速度快(无需原生编译),且能运行 Expo Go 内置的所有内容(包括 SDK 56+ 中的 @expo/ui)。无法运行自定义原生代码(如 expo-modules、config plugins,以及未内置在 Expo Go 中的原生依赖)。
  • 开发构建(development build) —— 快照脚本改为运行 expo run:ios / expo run:android,为每个 Fixture 编译原生开发客户端。适用于输出代码需要自定义原生代码的 Skill(否则这些 Skill 只能跑 static-only 检查)。速度慢得多 —— expo run 需要对每个 Fixture 进行预构建和原生编译(每次需数分钟,首次尤甚),并且需要完整的 iOS/Android 构建工具链 —— 因此只有在 Skill 确实依赖原生代码时才选择此项。极度消耗磁盘: 每个 Fixture 的原生构建产物都高达数 GB。虽然快照阶段会在每个 Fixture 处理完后运行 clean-fixture.sh 以将磁盘峰值控制在约一次构建的大小,但对于开发构建模式,依然建议减少评测用例数量并仅使用单一平台,同时预留几 GB 的可用空间。clean-fixture.sh 会清理每个 Fixture 的构建产物node_modulesiosandroid.expodist 以及 Fixture 的 iOS DerivedData),但会保留 App 源码和 Git 记录。控制开发构建磁盘占用的关键在于减少评估用例 + 使用单平台 —— 因为它只能回收每个 Fixture 自身的构建产物,无法清除...