> ## Documentation Index
> Fetch the complete documentation index at: https://niceeval.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Sandbox Fixture：用任务评估 coding agents

> 用 .eval.ts 给 coding agent 准备隔离 workspace、发送真实任务，并用 Sandbox 文件、命令、diff 和 judge 验证结果。

评估 coding agent 时，单纯检查一段回复不够。你通常要给它一个真实项目，让它读写文件、运行命令、提交改动，然后检查产物是否正确。[NiceEval](https://niceeval.com/) 的当前推荐写法是：用普通 `.eval.ts` 文件显式准备 sandbox workspace、发送任务并断言结果。

可运行参考见 [coding-agent-skill](https://github.com/CorrectRoadH/coding-agent-skill)（独立仓库）。

## 推荐目录结构

```text theme={null}
evals/
├─ api-validation.eval.ts
├─ config-schema.eval.ts
└─ ponytail-safe-path.eval.ts

workspaces/
└─ ts-starter/
   ├─ package.json
   ├─ tsconfig.json
   └─ src/

skills/
└─ zod.md

experiments/
├─ baseline.ts
└─ with-skill.ts
```

`workspaces/` 存放 Agent 可见的初始项目。`.eval.ts` 控制 Workspace 上传时机、任务 prompt 和结果检查。`experiments/` 选择 Agent、模型，以及是否注入 Skill 或插件。

## 准备 workspace

在评估用例里把初始项目上传到 sandbox：

```ts theme={null}
import { defineEval } from "niceeval";

export default defineEval({
  description: "给 Express 路由添加请求体验证",
  async test(t) {
    await t.sandbox.uploadDirectory("../workspaces/ts-starter");

    await t.send("在 src/routes/users.ts 里实现 POST /users 路由。").then((turn) => turn.succeeded());

    t.sandbox.fileChanged("src/routes/users.ts");
  },
});
```

也可以用 `t.sandbox.writeFiles()` 在单个评估用例里补充种子文件，适合小任务或安全探针。

## 写任务 prompt

Prompt 应该像真实工单，描述目标和约束，但不要泄露验证答案。

```ts theme={null}
await t
  .send(
    `在 src/config/env.ts 里实现环境变量校验。
要求：
- 用 Zod 定义 EnvSchema
- PORT 转成 number
- DATABASE_URL 必须是合法 URL
- JWT_SECRET 最少 32 个字符
- 导出 env 对象和 Env 类型`,
  )
  .then((turn) => turn.succeeded());
```

把“是否防路径穿越”“是否复用现有工具”这类隐式质量要求留给验证阶段，才能测出 Skill 或插件是否真的帮助 agent 主动补齐上下文。

## 验证文件和代码

```ts theme={null}
import { includes, excludes } from "niceeval/expect";

const src = await t.sandbox.readSourceFiles({ extensions: ["ts"] });
const config = src.fileMatching(/env/);
const code = config?.content ?? "";

t.check(code, includes(/z\.object\s*\(/));
t.check(code, includes(/EnvSchema\.parse\s*\(\s*process\.env/));
t.check(code, excludes(/process\.env\.\w+\s*\?\?/));
t.sandbox.fileChanged("src/config/env.ts");
```

`t.sandbox.fileChanged()` 是作用域断言：它在运行结束后用 Sandbox diff 判断目标文件是否真的被修改。

## 运行项目测试或探针脚本

对 coding-agent 任务，真实命令通常比文本匹配更可靠：

```ts theme={null}
await t.sandbox.writeFiles({
  "_test_traversal.py": [
    "import sys, os",
    "sys.path.insert(0, '.')",
    "from uploads import safe_upload_path",
    "base = '/var/uploads'",
    "try:",
    "    p = safe_upload_path(base, '../../etc/passwd')",
    "    assert os.path.commonpath([base, os.path.abspath(p)]) == base",
    "except (ValueError, PermissionError, AssertionError):",
    "    pass",
    "print('ok')",
  ].join("\n"),
});

const result = await t.sandbox.runCommand("python3", ["_test_traversal.py"]);
t.check(result.stdout.trim(), includes(/ok/));
```

也可以运行项目自己的 test/lint/build 脚本：

```ts theme={null}
import { commandSucceeded } from "niceeval/expect";

const result = await t.sandbox.runCommand("npm", ["test"]);
t.check(result, commandSucceeded());
```

## 用 experiment 做对照组

不要把 Agent 名、插件名或 URL 放进位置参数。Experiment 选择 Agent 并固定运行配置；CLI 的评估用例位置参数只过滤评估用例 ID。

```bash theme={null}
pnpm exec niceeval exp compare
pnpm exec niceeval exp compare api-validation
```

典型 A/B：

* `experiments/baseline.ts`：裸 agent。
* `experiments/with-skill.ts`：同一 agent + setup hook 注入 `CLAUDE.md`。
* 两组使用同一批评估用例、同一模型、同一 runs 和预算。

## Sandbox Fixture 的适用场景

* 需要 agent 修改真实文件。
* 需要运行项目测试、构建或 lint。
* 需要比较 diff。
* 需要评估 Claude Code、Codex 这类 coding agent。
* 需要比较 Skill / 插件 / Hook 是否改善真实任务。

如果只是评 direct agent 应用，用普通 direct adapter 会更轻。
