supabase/evals
GitHub: supabase/evals
Supabase 官方的 AI 智能体评估框架,用于测试和比较不同模型在 Supabase 平台各类开发任务中的掌握程度和实战表现。
Stars: 16 | Forks: 1
# Supabase Evals
本仓库旨在解答智能体在各类任务中对 Supabase 的掌握程度。
## 快速开始
使用子模块克隆:
```
git clone --recurse-submodules git@github.com:supabase/evals.git
```
如果你已经克隆了但没有包含子模块:
```
git submodule update --init
```
在仓库根目录下执行:
```
pnpm install
cp .env.example .env
```
由智能体驱动的运行需要 `.env` 中包含相关的服务商密钥(例如 `OPENAI_API_KEY`、`ANTHROPIC_API_KEY`)
## 核心概念
- 一个 **eval** 是 `evals//` 下的一个场景。它包含 prompt、scorer 以及两个环境的可选起始状态:`remote/`(托管项目)和 `local/`(智能体的工作文件)。
- 一个 **experiment** 是 `experiments/.ts` 下的一种智能体/runtime/model 设置。
- 一个 **eval suite** 是一组命名后放在一起运行的 eval 集合。
- 一个 **experiment suite** 是一组具有相关配置的命名 experiment 集合,用于进行正面交锋对比。
- 一个 **agent** 是接收 eval prompt 并调用已配置工具的模型驱动程序。
- 一个 **runtime** 是 experiment 提供给智能体的、类似于 Supabase 的本地环境和工具交互面。
- `platform-lite` 暴露了一个与 Supabase Management API 兼容的 HTTP 交互面,该交互面由 [`@supabase/lite`](https://github.com/supabase/supabase-lite) 提供支持,因此像 `@supabase/mcp-server-supabase` 这样的真实工具可以针对轻量级项目运行。
## 运行 eval
运行 eval 会执行 experiment x eval 组合,并将本地结果文件写入 `results/`。
使用单个 experiment 运行单个 eval:
```
pnpm eval -- --eval resolve-dataapi-001-empty-results --experiment claude-code-sonnet-5
```
跨多个 experiment 运行选定的 eval:
```
pnpm eval -- \
--experiment claude-code-sonnet-5 \
--experiment claude-code-opus-5 \
--eval resolve-dataapi-001-empty-results \
--eval investigate-auth-001-deleted-user-access
```
`--suite`、`--experiment-suite`、`--experiment` 和 `--eval` 接受通过重复标志或逗号分隔的值输入的多个参数。
在所有 benchmark eval 中运行所有 benchmark 和 no-skills experiment:
```
pnpm eval -- --suite benchmark --experiment-suite benchmark,no-skills
```
### 在 Web 应用中查看结果
在本地运行 eval 后,将其结果导出到 `eval-results.json` 以供 Web 应用使用:
```
pnpm export-results
```
启动 Web 应用开发服务器:
```
pnpm web
```
## Eval 结构
每个 eval 包含:
1. `PROMPT.md` - frontmatter 元数据以及智能体看到的任务描述。
2. `EVAL.ts` - 一个默认导出的 scorer。
3. 可选的 `remote/` - 托管项目的起始状态,植入到 platform-lite 中:`project.sql`(数据库)、`logs.jsonl`(可观测性日志)、`functions/`(已部署的 edge functions)。
4. 可选的 `local/` - 智能体的起始文件,被复制到智能体工作的沙盒工作区中(如果缺失则表示为空工作区,或者对于 tools eval 完全没有沙盒)。
这两个目录映射了 Supabase 的两个环境:`remote/` 描述了客户的托管项目已经具有的外观,`local/` 描述了开发者的工作目录已经具有的外观。
`PROMPT.md` frontmatter 驱动 eval 发现和站点过滤:
```
---
stage: build
suite: benchmark
product:
- database
- auth
topic:
- rls
- security
motivation: AI-123
---
```
允许的元数据值定义在 `packages/core/src/eval-metadata.ts` 中。
每个 eval 都必须包含 `suite`(`benchmark`、`regression` 或 `other`)。使用 `--suite regression` / `--suite other` 运行 eval suite。使用 `--experiment-suite benchmark` 或 `--experiment-suite no-skills` 分别选择 experiment suite。
## Eval 模式
有两种 runtime,会根据每个 eval 自动选择:
- **Tools eval** 针对实验的 MCP/工具交互面(无 `local/` 目录,无 `interface: cli`)运行智能体,然后对生成的项目状态或报告进行评分。
- **Local-stack eval** 在 Docker 沙盒内运行智能体——包含一个 `bash` 工具以及文件工具,并安装了真实的 Supabase CLI——以便它可以针对真实的本地堆栈运行 `supabase init/start/db/test`。当一个 eval 提供了 `local/` 工作区**或者**声明了 `interface: cli` 时,就会使用此 runtime(后者涵盖了从空工作区开始的引导场景)。
`interface`(`mcp` | `cli`)在其他情况下是一个 benchmark 维度(一个跨团队 KPI 标签),而不是 runtime 开关——`local/` 目录和 `interface: cli` 才是决定沙盒是否启动的关键。
### Local-stack eval
Supabase CLI 是智能体的工具;**local stack**(`supabase start` 在开发机器上运行的 Docker 服务)是其作用的环境——这与 platform-lite 模拟的远程/托管平台不同。Experiment 像声明 MCP server 和 skills 一样声明环境:添加 `localStack: localStackRuntime()`(来自 [`@supabase-evals/sandbox`](packages/sandbox/src/local-stack-runtime.ts));没有包含此项的 experiment 将跳过这些 eval。Skills 像往常一样与 CLI 工具组合,并且工具交互面会合并,因此 experiment 原则上可以同时暴露 MCP 和 CLI。
**评分使用宿主机工具链针对导出的工作区进行。** 在智能体完成后,测试框架(harness)会将其工作区从沙盒复制到宿主机(`docker cp`),因此 scorer 可以针对生成的文件在仓库根目录下运行 `vite`/`vitest`,而不需要沙盒中存在该工具链——这与以前用于“项目” eval 的构建/测试评分相同。Scorer 也可以通过评分上下文在沙盒**内部**(针对活动堆栈)运行命令和 SQL。
Local-stack eval 需要运行中的 Docker daemon。每次尝试都会启动一个挂载了宿主机 Docker socket 的新沙盒容器,因此 `supabase start` 会将本地堆栈作为同级容器生成;沙盒使用宿主机网络运行,因此它们发布的端口直接映射到沙盒的 `127.0.0.1` 默认端口上。Supabase 的默认宿主机端口(54321-54329)必须空闲——在运行前停止任何本地的 `supabase start` 堆栈。
在智能体启动之前,eval 的可选 `local/` 目录将被复制到沙盒工作区中。`services:` frontmatter 列表声明了场景需要的 local-stack 服务(例如 `gotrue`、`kong`、`postgrest`);所有其他服务都会从 `supabase start` 中排除——即使是由智能体自己运行时也是如此——以保持堆栈启动快速。空列表(`services: []`)仅启动数据库;完全省略该键则会启动完整的堆栈。
当 eval 需要特定的 Supabase CLI 版本时,在其 frontmatter 中设置 `cliVersion: 2.109.1`。这会覆盖 experiment 的 `localStackRuntime({ cliVersion })` 设置;否则将应用 runtime 设置或仓库范围的默认值。
Scorer 只检查智能体生成的内容,而不检查测试框架(harness)提供了什么状态:当设置 `projectRunning: true`(默认值)时,运行中的堆栈和植入的 `local/` 工作区已经准备好,因此只对智能体在其基础上做出的增量进行评分;当设置 `projectRunning: false` 时,智能体需要自行创建该状态,因此依赖该状态进行评分也是完全合理的。
在无需智能体运行的情况下测试沙盒管道流程(需要 Docker,不属于 `pnpm check` 的一部分):
```
pnpm --filter @supabase-evals/sandbox test:docker
```
## Skills
Skills 来自 [`supabase/agent-skills`](https://github.com/supabase/agent-skills),以 git submodule 的形式固定在 `submodules/agent-skills`。`skills/` 目录包含指向该子模块的符号链接。
要在 experiment 中使用某个 skill,请在 experiment 的 `skills` 数组中引用其目录名称。
两种 runtime 都会延迟加载 skills([渐进式披露](https://ai-sdk.dev/cookbook/guides/agent-skills)):只有每个 skill 的名称+描述包含在 system prompt 中,智能体按需提取 skill 的完整指令。它们的区别仅在于获取正文的方式,因为 tools 模式下的智能体没有文件系统:
- **Local-stack(沙盒)模式:** 使用 [Vercel 的 `skills` CLI](https://github.com/vercel-labs/skills) 将 skills 安装到工作区中(内置在沙盒镜像中,源自本地 `skills/` 目录——从不来自网络),位于 `.claude/skills/` 下。当任务匹配时,智能体使用其文件工具读取 `.claude/skills//SKILL.md`(及其引用的任何文件)。
- **Tools 模式:** 无文件系统,因此当智能体使用 skill 的名称调用 `load_skill` 工具时,该工具会返回 skill 的完整指令。
## 框架检查
```
pnpm check
```
运行类型检查和本地冒烟测试。
## 贡献
有关添加 eval 和 experiment 以及提交更改的指南,请参阅 [CONTRIBUTING.md](CONTRIBUTING.md)。
标签:AI智能体, LLM评估, Ollama, SOC Prime, Supabase, 开发工具, 自动化攻击, 请求拦截