niceeval 0.4.4 → 0.4.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (177) hide show
  1. package/README.md +21 -12
  2. package/README.zh.md +8 -9
  3. package/docs-site/.mintignore +13 -0
  4. package/docs-site/AGENTS.md +46 -0
  5. package/docs-site/concepts/adapter.mdx +287 -0
  6. package/docs-site/concepts/assert.mdx +243 -0
  7. package/docs-site/concepts/drive.mdx +118 -0
  8. package/docs-site/concepts/evals.mdx +108 -0
  9. package/docs-site/concepts/experiment.mdx +37 -0
  10. package/docs-site/concepts/hitl.mdx +83 -0
  11. package/docs-site/concepts/judge.mdx +129 -0
  12. package/docs-site/concepts/overview.mdx +98 -0
  13. package/docs-site/concepts/tier.mdx +42 -0
  14. package/docs-site/docs-ref/00-index.md +23 -0
  15. package/docs-site/docs-ref/01-page-types.md +43 -0
  16. package/docs-site/docs-ref/03-style-rules.md +45 -0
  17. package/docs-site/docs-ref/04-code-examples.md +37 -0
  18. package/docs-site/docs-ref/05-dx-failure-paths.md +45 -0
  19. package/docs-site/docs-ref/06-checklists.md +53 -0
  20. package/docs-site/docs.json +256 -0
  21. package/docs-site/example/ai-agent-application.mdx +148 -0
  22. package/docs-site/example/claude-code-codex-plugin.mdx +162 -0
  23. package/docs-site/example/claude-code-codex-skill.mdx +147 -0
  24. package/docs-site/example/showcase.mdx +39 -0
  25. package/docs-site/example/tier1-ai-sdk-v7.mdx +136 -0
  26. package/docs-site/example/tier1-claude-sdk.mdx +119 -0
  27. package/docs-site/example/tier1-codex-sdk.mdx +111 -0
  28. package/docs-site/example/tier1-langgraph.mdx +119 -0
  29. package/docs-site/example/tier1-pi-sdk.mdx +119 -0
  30. package/docs-site/favicon.svg +5 -0
  31. package/docs-site/github-diff.css +135 -0
  32. package/docs-site/github-diff.js +11 -0
  33. package/docs-site/guides/authoring.mdx +129 -0
  34. package/docs-site/guides/ci-integration.mdx +97 -0
  35. package/docs-site/guides/connect-otel.mdx +209 -0
  36. package/docs-site/guides/connect-your-agent.mdx +221 -0
  37. package/docs-site/guides/dataset-fanout.mdx +98 -0
  38. package/docs-site/guides/experiments.mdx +71 -0
  39. package/docs-site/guides/fixtures.mdx +147 -0
  40. package/docs-site/guides/reporters.mdx +113 -0
  41. package/docs-site/guides/runner.mdx +79 -0
  42. package/docs-site/guides/sandbox-agent.mdx +138 -0
  43. package/docs-site/guides/sandbox-backends.mdx +64 -0
  44. package/docs-site/guides/scoring-guide.mdx +92 -0
  45. package/docs-site/guides/viewing-results.mdx +195 -0
  46. package/docs-site/guides/write-experiment.mdx +81 -0
  47. package/docs-site/guides/write-send.mdx +347 -0
  48. package/docs-site/images/adapter-tiers-zh.svg +60 -0
  49. package/docs-site/images/agent-turn-roundtrip-en.svg +62 -0
  50. package/docs-site/images/agent-turn-roundtrip-zh.svg +77 -0
  51. package/docs-site/images/hitl-handshake-zh.svg +89 -0
  52. package/docs-site/images/logo.svg +6 -0
  53. package/docs-site/index.mdx +181 -0
  54. package/docs-site/introduction.mdx +141 -0
  55. package/docs-site/quickstart.mdx +136 -0
  56. package/docs-site/reference/builtin-agents.mdx +161 -0
  57. package/docs-site/reference/capabilities.mdx +76 -0
  58. package/docs-site/reference/cli.mdx +120 -0
  59. package/docs-site/reference/define-agent.mdx +168 -0
  60. package/docs-site/reference/define-config.mdx +41 -0
  61. package/docs-site/reference/define-eval.mdx +160 -0
  62. package/docs-site/reference/events.mdx +131 -0
  63. package/docs-site/reference/expect.mdx +112 -0
  64. package/docs-site/tracker.js +8 -0
  65. package/docs-site/zh/concepts/adapter.mdx +286 -0
  66. package/docs-site/zh/concepts/assert.mdx +243 -0
  67. package/docs-site/zh/concepts/drive.mdx +118 -0
  68. package/docs-site/zh/concepts/evals.mdx +124 -0
  69. package/docs-site/zh/concepts/experiment.mdx +37 -0
  70. package/docs-site/zh/concepts/hitl.mdx +83 -0
  71. package/docs-site/zh/concepts/judge.mdx +130 -0
  72. package/docs-site/zh/concepts/overview.mdx +109 -0
  73. package/docs-site/zh/concepts/tier.mdx +44 -0
  74. package/docs-site/zh/example/ai-agent-application.mdx +152 -0
  75. package/docs-site/zh/example/claude-code-codex-plugin.mdx +163 -0
  76. package/docs-site/zh/example/claude-code-codex-skill.mdx +147 -0
  77. package/docs-site/zh/example/showcase.mdx +39 -0
  78. package/docs-site/zh/example/tier1-ai-sdk-v7.mdx +140 -0
  79. package/docs-site/zh/example/tier1-claude-sdk.mdx +122 -0
  80. package/docs-site/zh/example/tier1-codex-sdk.mdx +117 -0
  81. package/docs-site/zh/example/tier1-langgraph.mdx +123 -0
  82. package/docs-site/zh/example/tier1-pi-sdk.mdx +122 -0
  83. package/docs-site/zh/guides/agent-feedback-loop.mdx +79 -0
  84. package/docs-site/zh/guides/authoring.mdx +129 -0
  85. package/docs-site/zh/guides/ci-integration.mdx +97 -0
  86. package/docs-site/zh/guides/connect-otel.mdx +208 -0
  87. package/docs-site/zh/guides/connect-your-agent.mdx +226 -0
  88. package/docs-site/zh/guides/dataset-fanout.mdx +83 -0
  89. package/docs-site/zh/guides/experiments.mdx +72 -0
  90. package/docs-site/zh/guides/fixtures.mdx +147 -0
  91. package/docs-site/zh/guides/official-adapters.mdx +132 -0
  92. package/docs-site/zh/guides/reporters.mdx +113 -0
  93. package/docs-site/zh/guides/runner.mdx +82 -0
  94. package/docs-site/zh/guides/sandbox-agent.mdx +139 -0
  95. package/docs-site/zh/guides/sandbox-backends.mdx +75 -0
  96. package/docs-site/zh/guides/scoring-guide.mdx +92 -0
  97. package/docs-site/zh/guides/viewing-results.mdx +195 -0
  98. package/docs-site/zh/guides/write-experiment.mdx +101 -0
  99. package/docs-site/zh/guides/write-send.mdx +353 -0
  100. package/docs-site/zh/index.mdx +180 -0
  101. package/docs-site/zh/introduction.mdx +140 -0
  102. package/docs-site/zh/quickstart.mdx +137 -0
  103. package/docs-site/zh/reference/builtin-agents.mdx +364 -0
  104. package/docs-site/zh/reference/capabilities.mdx +76 -0
  105. package/docs-site/zh/reference/cli.mdx +140 -0
  106. package/docs-site/zh/reference/define-agent.mdx +461 -0
  107. package/docs-site/zh/reference/define-config.mdx +107 -0
  108. package/docs-site/zh/reference/define-eval.mdx +674 -0
  109. package/docs-site/zh/reference/events.mdx +252 -0
  110. package/docs-site/zh/reference/expect.mdx +208 -0
  111. package/package.json +3 -2
  112. package/src/agents/bub.ts +15 -5
  113. package/src/agents/claude-code.ts +8 -5
  114. package/src/agents/codex.ts +9 -5
  115. package/src/agents/sdk-streams.test.ts +4 -4
  116. package/src/agents/sdk-streams.ts +14 -9
  117. package/src/agents/types.ts +40 -1
  118. package/src/agents/ui-message-stream.ts +1 -0
  119. package/src/cli.ts +36 -7
  120. package/src/context/types.ts +140 -0
  121. package/src/expect/index.ts +15 -8
  122. package/src/i18n/en.ts +19 -6
  123. package/src/i18n/zh-CN.ts +19 -6
  124. package/src/o11y/parsers/bub.test.ts +71 -0
  125. package/src/o11y/parsers/bub.ts +5 -0
  126. package/src/o11y/types.ts +27 -2
  127. package/src/runner/reporters/artifacts.ts +11 -3
  128. package/src/runner/reporters/live.ts +45 -8
  129. package/src/runner/run.ts +71 -21
  130. package/src/runner/types.ts +45 -2
  131. package/src/sandbox/types.ts +18 -0
  132. package/src/scoring/types.ts +5 -0
  133. package/src/shared/types.ts +3 -0
  134. package/src/util.test.ts +26 -1
  135. package/src/util.ts +16 -0
  136. package/src/view/app/App.tsx +2 -2
  137. package/src/view/app/components/AttemptModal.tsx +2 -0
  138. package/src/view/app/components/CopyControls.tsx +87 -28
  139. package/src/view/app/i18n.ts +3 -3
  140. package/src/view/client-dist/app.css +1 -1
  141. package/src/view/client-dist/app.js +18 -18
  142. package/docs/README.md +0 -120
  143. package/docs/adapters/README.md +0 -60
  144. package/docs/adapters/authoring.md +0 -179
  145. package/docs/adapters/coding-agent-skills-plugins.md +0 -324
  146. package/docs/adapters/collection.md +0 -128
  147. package/docs/adapters/contract.md +0 -264
  148. package/docs/adapters/reference/agent-eval.md +0 -215
  149. package/docs/adapters/reference/agent-loop-apis.md +0 -69
  150. package/docs/adapters/reference/claude-code-otel-telemetry.md +0 -100
  151. package/docs/adapters/reference/eve-protocol.md +0 -127
  152. package/docs/adapters/reference/otel-genai.md +0 -107
  153. package/docs/adapters/reference/otel-instrumentation.md +0 -65
  154. package/docs/adapters/targets.md +0 -99
  155. package/docs/architecture.md +0 -140
  156. package/docs/assertions.md +0 -387
  157. package/docs/capabilities-by-construction.md +0 -48
  158. package/docs/cli.md +0 -173
  159. package/docs/concepts.md +0 -106
  160. package/docs/e2e-ci.md +0 -332
  161. package/docs/eval-authoring.md +0 -319
  162. package/docs/experiments.md +0 -157
  163. package/docs/getting-started.md +0 -224
  164. package/docs/multi-agent.md +0 -145
  165. package/docs/observability.md +0 -337
  166. package/docs/origin-integration.md +0 -195
  167. package/docs/references.md +0 -35
  168. package/docs/reports.md +0 -551
  169. package/docs/results-format.md +0 -228
  170. package/docs/results-lib.md +0 -191
  171. package/docs/runner.md +0 -104
  172. package/docs/sandbox.md +0 -276
  173. package/docs/scoring.md +0 -119
  174. package/docs/source-map.md +0 -126
  175. package/docs/tier-sync.md +0 -193
  176. package/docs/view.md +0 -194
  177. package/docs/vision.md +0 -88
@@ -0,0 +1,113 @@
1
+ ---
2
+ title: "把结果上报到 Braintrust 与其它目的地"
3
+ sidebarTitle: "Reporter 上报"
4
+ description: "用内置 reporters 把 eval 结果送到 Braintrust 实验、JUnit XML 或自定义目的地。"
5
+ ---
6
+
7
+ [NiceEval](https://niceeval.com/) 自己跑、自己判分;reporter 负责把结果送出去。控制台输出和 `.niceeval/` artifacts 本身就是内置 reporter,始终开启。其余 reporter 从 `niceeval/reporters` 导入,按需挂载。
8
+
9
+ 挂载位置有两个:
10
+
11
+ - `niceeval.config.ts` 的 `reporters`:观测整次运行的每个 eval。共享目的地(比如一个 Braintrust 实验)通常写在这里。
12
+ - 单个 eval 的 `reporters`:实例只观测引用它的 eval。多个 eval 引用同一个实例时合并观测,结果落进同一个目的地;已经写在 config 里的实例在 eval 上再列一遍也不会重复上报。
13
+
14
+ ## Braintrust
15
+
16
+ `Braintrust(...)` 把一次运行作为一个 Braintrust experiment 上传,每个 attempt 一行。放在 config 里覆盖整次运行:
17
+
18
+ ```ts niceeval.config.ts
19
+ import { defineConfig } from "niceeval";
20
+ import { Braintrust } from "niceeval/reporters";
21
+
22
+ export default defineConfig({
23
+ reporters: [Braintrust({ project: "weather-agent" })],
24
+ });
25
+ ```
26
+
27
+ 只想上报部分 eval 时,挂在 eval 上:
28
+
29
+ ```ts evals/forecast.eval.ts
30
+ import { defineEval } from "niceeval";
31
+ import { Braintrust } from "niceeval/reporters";
32
+
33
+ export default defineEval({
34
+ reporters: [Braintrust({ project: "weather-agent" })],
35
+ async test(t) {
36
+ await t.send("北京今天适合骑车吗?");
37
+ t.succeeded();
38
+ },
39
+ });
40
+ ```
41
+
42
+ 前置条件:安装 `braintrust` 包(`npm install braintrust`,它是可选依赖,不装不影响其它功能),并设置 `BRAINTRUST_API_KEY`;需要在代码里显式传 key 时用 `apiKey` 参数。运行结束后终端会打印 experiment URL。
43
+
44
+ ### 上报口径
45
+
46
+ - 每个 attempt 是 Braintrust 里的一行;`runs: 3` 会产生三行,靠 metadata 里的 `attempt` 区分。
47
+ - soft 断言按名字记为 score;gate 断言记在 `gate:` 前缀下。这样在 Braintrust 的实验对比里,gate 回归和 soft 分数回归用同一套 diff 看。
48
+ - metrics 带开始/结束时间、token 用量和估算成本;缺的数据不写,不补零。
49
+ - metadata 带 `agent`、`model`、`experiment`、`flags`、`outcome` 和失败断言明细,方便在 Braintrust 里按维度过滤。
50
+
51
+ ### 配置项
52
+
53
+ <ParamField body="project" type="string">
54
+ Braintrust 项目名。省略时用 `niceeval`。
55
+ </ParamField>
56
+
57
+ <ParamField body="projectId" type="string">
58
+ Braintrust 项目 id。与 `project` 给一个即可。
59
+ </ParamField>
60
+
61
+ <ParamField body="experiment" type="string">
62
+ 实验名。省略时由 Braintrust 自动命名。
63
+ </ParamField>
64
+
65
+ <ParamField body="baseExperiment" type="string">
66
+ 作为对比基线(diff base)的既有实验名。
67
+ </ParamField>
68
+
69
+ <ParamField body="baseExperimentId" type="string">
70
+ 作为对比基线的既有实验 id。
71
+ </ParamField>
72
+
73
+ <ParamField body="update" type="boolean">
74
+ 为 `true` 时更新同名既有实验,而不是新建一个。
75
+ </ParamField>
76
+
77
+ <ParamField body="metadata" type="Record<string, unknown>">
78
+ 实验级附加 metadata,与 NiceEval 自动写入的字段合并,同名以这里为准。
79
+ </ParamField>
80
+
81
+ <ParamField body="apiKey" type="string">
82
+ Braintrust API key。省略时 SDK 读 `BRAINTRUST_API_KEY`。
83
+ </ParamField>
84
+
85
+ ## JUnit 与 Json
86
+
87
+ `JUnit(path)` 输出 JUnit XML,让失败出现在 CI 的测试报告 UI 里;临时生成可以直接用 CLI 的 `--junit <path>`,不用改配置。`Json(path)` 把完整 `RunSummary` 落成一个 JSON 文件,喂下游脚本或 dashboard。CI 场景的完整接法见[CI 集成](./ci-integration)。
88
+
89
+ ## 自定义 reporter
90
+
91
+ reporter 是实现若干可选回调的对象,拿到的是和内置 reporter 相同的结构化结果:
92
+
93
+ ```ts
94
+ import type { Reporter } from "niceeval";
95
+
96
+ const notify: Reporter = {
97
+ async onEvalComplete(result) {
98
+ if (result.outcome === "failed") {
99
+ await fetch("http://localhost:3000/notify", {
100
+ method: "POST",
101
+ body: JSON.stringify({ eval: result.id, agent: result.agent }),
102
+ });
103
+ }
104
+ },
105
+ };
106
+ ```
107
+
108
+ - `onRunStart(evals, agent, shape)`:运行开始,收到本次实际要跑的 eval 列表和运行规模。
109
+ - `onEvalComplete(result)`:每个 attempt 完成即时触发,回调串行化,不会交错。
110
+ - `onRunComplete(summary)`:运行结束,收到聚合汇总。
111
+ - `onEvent(event)`:更细粒度的事件流(`eval:start`、`run:budgetExceeded` 等)。
112
+
113
+ reporter 抛错只会打一条诊断信息,不会让运行中断。只有目的地没被内置覆盖时才需要自定义——`.niceeval/` 的 artifacts 已经记录了全部结果,事后分析直接读它(见[查看结果](./viewing-results))。
@@ -0,0 +1,82 @@
1
+ ---
2
+ title: "NiceEval runner 如何调度和执行 eval"
3
+ sidebarTitle: "运行器"
4
+ description: "NiceEval runner 发现 eval,用有界并发调度,缓存结果,重试脆弱基础设施,并执行预算保护。"
5
+ ---
6
+
7
+ Runner 是把 eval 文件变成一次实际运行的执行引擎。它负责发现、过滤、调度、缓存、attempt、reporters 和 artifact 输出。
8
+
9
+ ## 发现
10
+
11
+ runner 会读取 `evals/` 下的:
12
+
13
+ - `*.eval.ts` 文件
14
+ - 导出 eval 数组的数据集文件
15
+
16
+ ```bash
17
+ npx niceeval list
18
+ ```
19
+
20
+ `list` 只发现和打印 ID,不执行 eval。
21
+
22
+ ## 过滤
23
+
24
+ `exp` 命令中,实验名之后的位置参数是 eval ID 前缀:
25
+
26
+ ```bash
27
+ npx niceeval exp local
28
+ npx niceeval exp local weather
29
+ npx niceeval exp local fixtures/button
30
+ ```
31
+
32
+ 不要把 agent 名放进位置参数。agent/model/flags 写进 experiment。
33
+
34
+ ## 并发
35
+
36
+ ```bash
37
+ npx niceeval exp local --max-concurrency 8
38
+ ```
39
+
40
+ 远程 HTTP agent 可以用更高并发;本地 Docker sandbox 通常需要更低并发,避免 CPU、内存和磁盘竞争。
41
+
42
+ ## runs 与 early-exit
43
+
44
+ ```bash
45
+ npx niceeval exp local fixtures/button --runs 5 --early-exit
46
+ ```
47
+
48
+ `runs` 用于测 pass rate。`early-exit` 会在某个 attempt 通过后停止同一 eval 的剩余尝试。
49
+
50
+ ## 缓存
51
+
52
+ [NiceEval](https://niceeval.com/) 可以根据输入、配置和相关文件 fingerprint 跳过已通过结果。缓存适合加速迭代,但如果你在调试非确定性行为,应该明确关闭或清理相关缓存。
53
+
54
+ ## 超时和预算
55
+
56
+ ```bash
57
+ npx niceeval exp local --timeout 300000 --budget 5
58
+ ```
59
+
60
+ 超时保护单个 eval,预算保护整次运行成本。
61
+
62
+ ## Reporter
63
+
64
+ runner 在 eval 完成后把结果交给 reporters:
65
+
66
+ - console reporter 提供实时反馈。
67
+ - JSON artifacts 用于后续分析。
68
+ - JUnit reporter 适合 CI。
69
+ - Braintrust reporter 把一次运行作为实验上报,跨提交比较。
70
+
71
+ 挂载方式和 Braintrust 配置见 [Reporter 上报](./reporters)。
72
+
73
+ ## 输出目录
74
+
75
+ 每次运行会写入 `.niceeval/<timestamp>/`,包括 `summary.json`,以及每个 attempt 的 `events.json`、`sources.json`、`trace.json`、`o11y.json` 和 `diff.json` 等拆分工件。
76
+
77
+ ## 推荐调试流程
78
+
79
+ 1. 先跑 `npx niceeval list` 确认发现结果。
80
+ 2. 用 `npx niceeval exp <实验> <ID 前缀>` 缩小到一个 eval。
81
+ 3. 失败后运行 `npx niceeval view` 查看 transcript 和 diff。
82
+ 4. 再扩大到完整 suite 或 experiment。
@@ -0,0 +1,139 @@
1
+ ---
2
+ title: "沙箱 Agent:评估 Claude Code、Codex 和 bub"
3
+ sidebarTitle: "沙箱 Agent"
4
+ description: "使用 NiceEval 内置 agents 或自定义 adapter,在 Docker 或云端 sandbox 中运行 coding-agent CLI。"
5
+ ---
6
+
7
+ Sandbox agent 会在隔离环境中启动 coding-agent CLI,给它 workspace 和任务,让它自由修改文件、运行命令,然后收集 transcript、diff 和测试结果。
8
+
9
+ ## 内置 sandbox agents
10
+
11
+ <CardGroup cols={3}>
12
+ <Card title="claude-code" icon="code">
13
+ 运行 Anthropic Claude Code CLI,需要 `ANTHROPIC_API_KEY`。
14
+ </Card>
15
+ <Card title="codex" icon="terminal">
16
+ 运行 OpenAI Codex CLI,需要 `CODEX_API_KEY`。
17
+ </Card>
18
+ <Card title="bub" icon="robot">
19
+ 运行 bub coding agent,鉴权遵循 bub CLI 自身约定。
20
+ </Card>
21
+ </CardGroup>
22
+
23
+ ## 运行内置 agent
24
+
25
+ 在 experiment 里设置 `sandbox`(或者作为项目级兜底写进 `niceeval.config.ts`),选择 [NiceEval](https://niceeval.com/) 在哪里创建隔离环境:
26
+
27
+ ```ts
28
+ // experiments/local.ts
29
+ import { defineExperiment } from "niceeval";
30
+ import { claudeCodeAgent } from "niceeval/adapter";
31
+ import { dockerSandbox } from "niceeval/sandbox";
32
+
33
+ export default defineExperiment({
34
+ agent: claudeCodeAgent(),
35
+ model: "claude-sonnet-4-6",
36
+ sandbox: dockerSandbox(),
37
+ });
38
+ ```
39
+
40
+ ```shell
41
+ export ANTHROPIC_API_KEY=sk-ant-...
42
+ npx niceeval exp local fixtures/button
43
+
44
+ npx niceeval exp local fixtures/button --runs 10 --early-exit
45
+ ```
46
+
47
+ <Note>
48
+ 没有对应的 CLI flag——后端选择完全写在代码里。如果 experiment 和 `niceeval.config.ts` 都没设置 `sandbox`,[NiceEval](https://niceeval.com/) 在创建 sandbox 时会直接报错,不会自动探测。
49
+ </Note>
50
+
51
+ 内置 agent 从 `niceeval/adapter` 导出的是工厂函数。需要配置鉴权、代理、MCP 或 GitHub skill 时,把这些写进工厂参数;模型仍然写在 experiment 的 `model` 字段,sandbox 后端仍然写在 `sandbox` 字段:
52
+
53
+ ```ts
54
+ import { defineExperiment } from "niceeval";
55
+ import { claudeCodeAgent } from "niceeval/adapter";
56
+ import { dockerSandbox } from "niceeval/sandbox";
57
+
58
+ export default defineExperiment({
59
+ agent: claudeCodeAgent({
60
+ apiKey: process.env.ANTHROPIC_API_KEY,
61
+ baseUrl: process.env.ANTHROPIC_BASE_URL,
62
+ maxTurns: 8,
63
+ mcpServers: [
64
+ {
65
+ name: "browser",
66
+ command: "npx",
67
+ args: ["-y", "@anthropic/mcp-browser"],
68
+ },
69
+ ],
70
+ skills: ["Effect-TS/skills"],
71
+ }),
72
+ model: "claude-sonnet-4-6",
73
+ sandbox: dockerSandbox(),
74
+ });
75
+ ```
76
+
77
+ ## agent 环境变量
78
+
79
+ | Agent | 必需变量 |
80
+ |---|---|
81
+ | `claude-code` | `ANTHROPIC_API_KEY` |
82
+ | `codex` | `CODEX_API_KEY` |
83
+ | `bub` | 遵循 bub CLI 鉴权 |
84
+
85
+ ## 工作流程
86
+
87
+ ```text
88
+ createSandbox
89
+ → git init && git commit
90
+ → adapter.setup? # 装 CLI / 写 agent 配置
91
+ → test(t): uploadDirectory(...) # 写入这条 eval 的起始文件
92
+ → adapter.send(input, ctx)
93
+ → test(t): runCommand(...) # 手工运行验证命令
94
+ → collectGeneratedFiles() # git diff HEAD
95
+ → sandbox.stop()
96
+ ```
97
+
98
+ 起始文件和验证命令都写在 `test(t)` 中。agent 执行阶段只能看到你已经写进 sandbox 的文件。
99
+
100
+ ## 自定义 sandbox agent
101
+
102
+ ```ts
103
+ import { defineSandboxAgent } from "niceeval/adapter";
104
+
105
+ export default defineSandboxAgent({
106
+ name: "my-agent",
107
+ async send(input, ctx) {
108
+ await ctx.sandbox.runCommand("my-agent", ["run", input.text, "--json-out", "agent-events.json"]);
109
+ const transcript = await ctx.sandbox.readFile("agent-events.json");
110
+ return {
111
+ status: "completed",
112
+ events: parseTranscript(transcript),
113
+ };
114
+ },
115
+ });
116
+ ```
117
+
118
+ ## `ctx.model` 与 `ctx.flags`
119
+
120
+ CLI 传入的模型和自定义 flags 会出现在 adapter context 中。adapter 可以决定如何把它们转成 CLI 参数或 HTTP payload。
121
+
122
+ ## 在 experiment 中使用自定义 agent
123
+
124
+ ```ts
125
+ import { defineExperiment } from "niceeval";
126
+ import { dockerSandbox } from "niceeval/sandbox";
127
+ import myAgent from "./agents/my-agent";
128
+
129
+ export default defineExperiment({
130
+ agent: myAgent,
131
+ model: "claude-sonnet-4-6",
132
+ sandbox: dockerSandbox(),
133
+ runs: 3,
134
+ });
135
+ ```
136
+
137
+ <Warning>
138
+ 不要在 runner 里写 agent-specific 分支。差异行为应该放进 adapter。
139
+ </Warning>
@@ -0,0 +1,75 @@
1
+ ---
2
+ title: "Sandbox 后端:Docker、Vercel 与第三方"
3
+ sidebarTitle: "沙箱后端"
4
+ description: "NiceEval 在 Docker 或 Vercel sandbox 中运行 coding agents。了解如何选择后端、配置权限,并通过 warm pools 改善性能。"
5
+ ---
6
+
7
+ Sandbox backend 是创建和管理隔离运行环境的基础设施。[NiceEval](https://niceeval.com/) 把它们包装成同一个 `Sandbox` 接口,所以 adapter 不需要知道当前用的是本地 Docker、Vercel micro-VM 还是第三方云服务。
8
+
9
+ ## `Sandbox` 接口
10
+
11
+ Adapter 常用操作包括:
12
+
13
+ | 方法 | 用途 |
14
+ |---|---|
15
+ | `runCommand(cmd, args)` | 运行命令 |
16
+ | `runShell(script)` | 运行 shell 脚本 |
17
+ | `readFile(path)` | 读取文件 |
18
+ | `writeFiles(files)` | 写入一组文件 |
19
+ | `uploadFiles(files)` | 上传 workspace 或测试文件 |
20
+ | `workdir` | 后端真实工作目录;省略的 `cwd` / `targetDir` 都解析到这里 |
21
+ | `runCommand(..., { cwd })` | 单条命令临时切换工作目录;相对路径按 `workdir` 解析 |
22
+ | `stop()` | 销毁环境 |
23
+
24
+ ## 选择后端
25
+
26
+ 选择后端只能写在代码里——没有对应的 CLI flag,[NiceEval](https://niceeval.com/) 也不会自动探测后端。在 experiment 里设置 `sandbox` 字段(或者在 `niceeval.config.ts` 里设置作为项目级兜底),三选一:
27
+
28
+ ```ts
29
+ // experiments/local.ts
30
+ import { defineExperiment } from "niceeval";
31
+ import { dockerSandbox } from "niceeval/sandbox";
32
+
33
+ export default defineExperiment({
34
+ agent: myCodingAgent,
35
+ model: "claude-sonnet-4-6",
36
+ sandbox: dockerSandbox(), // 或 vercelSandbox() / e2bSandbox()
37
+ });
38
+ ```
39
+
40
+ 如果 experiment 和 `niceeval.config.ts` 都没有设置 `sandbox`,[NiceEval](https://niceeval.com/) 在创建 sandbox 时会直接报错,而不会猜一个后端。
41
+
42
+ 三个内置后端的 SDK 不随 NiceEval 一起安装——用哪个就装哪个,避免把用不到的依赖(以及它们的原生构建脚本)带进你的项目:
43
+
44
+ | 后端 | 安装命令 |
45
+ |---|---|
46
+ | `dockerSandbox()` | `pnpm add dockerode @types/dockerode` |
47
+ | `vercelSandbox()` | `pnpm add @vercel/sandbox` |
48
+ | `e2bSandbox()` | `pnpm add e2b` |
49
+
50
+ 漏装时不会静默失败:NiceEval 在创建 sandbox 的那一刻报错并直接给出上面的安装命令,例如 `Docker sandbox requires 'dockerode'. Install it with: pnpm add dockerode @types/dockerode`。
51
+
52
+ ## Docker
53
+
54
+ Docker 适合本地开发和标准 CI。优点是简单、可控、无云端依赖;缺点是机器资源有限,冷启动和安装依赖可能较慢。
55
+
56
+ ## Vercel Sandbox
57
+
58
+ Vercel Sandbox 适合需要云端隔离、更多资源或更稳定环境的任务。需要相应 token 或 OIDC 配置。
59
+
60
+ ## 第三方后端
61
+
62
+ 只要实现 `Sandbox` 接口,就可以接入其他 sandbox provider。adapter 仍然只依赖接口,不依赖 provider 私有 API。
63
+
64
+ ## 权限和 root
65
+
66
+ 不同后端对 root 权限、网络、文件系统和进程生命周期的约束不同。编写 fixture 时尽量避免依赖宿主机环境,把依赖写进 `package.json` 或 fixture setup。
67
+
68
+ ## 性能建议
69
+
70
+ - 减少 fixture 依赖体积。
71
+ - 使用缓存或预热机制。
72
+ - 控制 `sandboxConcurrency`,避免本地 Docker 资源耗尽。
73
+ - 把慢测试拆成必要的 gate 和可选的 soft 检查。
74
+
75
+ Warm pools 和复用属于 runner / scheduler 层面的能力,详见 [Runner](/zh/guides/runner)。
@@ -0,0 +1,92 @@
1
+ ---
2
+ title: "评分指南: 断言、judge 和成本限制"
3
+ sidebarTitle: "评分指南"
4
+ description: "用 NiceEval 的五种评分机制评估任意 eval:值断言、作用域断言、LLM-as-judge、test-as-scoring 和效率检查。"
5
+ ---
6
+
7
+ 好的 eval 应该尽量把“是否成功”拆成可解释的信号。[NiceEval](https://niceeval.com/) 允许你混合精确断言、语义 judge、事件流检查和真实测试。
8
+
9
+ ## 选择断言类型
10
+
11
+ | 目标 | 推荐机制 |
12
+ |---|---|
13
+ | 回复包含固定字段 | `includes` / `matches` |
14
+ | 结构化 JSON 完全匹配 | `equals` |
15
+ | 工具调用是否发生 | `t.calledTool` / `t.notCalledTool` |
16
+ | 输出是否语义正确 | `t.judge.*` |
17
+ | 代码是否工作 | `t.check(await t.sandbox.runCommand("npm", ["test"]), commandSucceeded())` |
18
+ | 成本是否可控 | `t.maxTokens` / `t.maxCost` |
19
+
20
+ ## 值断言
21
+
22
+ ```ts
23
+ import { includes, equals, matches } from "niceeval/expect";
24
+
25
+ t.check(t.reply, includes("refund"));
26
+ t.check(turn.data, equals({ intent: "refund" }));
27
+ t.check(t.reply, matches(/order #\d+/));
28
+ ```
29
+
30
+ 值断言适合精确、稳定、低歧义的结果。
31
+
32
+ ## 作用域断言
33
+
34
+ ```ts
35
+ t.succeeded();
36
+ t.calledTool("search");
37
+ t.usedNoTools();
38
+ t.sandbox.fileChanged("src/app.ts");
39
+ t.check(await t.sandbox.runCommand("npm", ["test"]), commandSucceeded());
40
+ ```
41
+
42
+ 它们检查整次运行的事实,通常来自标准事件流或 sandbox artifacts。
43
+
44
+ ## LLM-as-judge
45
+
46
+ ```ts
47
+ t.judge.autoevals.factuality("Refunds are available within 30 days.", { on: t.reply }).atLeast(0.8);
48
+ t.judge.autoevals.closedQA("The answer is specific, polite, and does not invent policy.", { on: t.reply }).atLeast(0.75);
49
+ ```
50
+
51
+ Judge 适合语义质量,但不适合替代所有确定性断言。能精确检查的地方优先精确检查。
52
+
53
+ ## Gate 和 soft 的取舍
54
+
55
+ ```ts
56
+ t.check(t.reply, includes("refund").gate());
57
+ t.check(t.reply, includes("friendly tone").atLeast(0.7));
58
+ ```
59
+
60
+ - `gate`:失败就是失败。
61
+ - `soft`:保留分数,用于比较质量。
62
+
63
+ ## 代码任务用测试评分
64
+
65
+ 在 `.eval.ts` 里运行项目测试或临时探针:
66
+
67
+ ```ts
68
+ import { commandSucceeded, includes } from "niceeval/expect";
69
+
70
+ const testResult = await t.sandbox.runCommand("npm", ["test"]);
71
+ t.check(testResult, commandSucceeded());
72
+
73
+ const src = await t.sandbox.readSourceFiles({ extensions: ["ts"] });
74
+ t.check(src.text(), includes(/z\.object\s*\(/));
75
+ ```
76
+
77
+ ## 成本和效率
78
+
79
+ ```ts
80
+ t.maxTokens(25_000);
81
+ t.maxCost(0.1);
82
+ ```
83
+
84
+ 对 coding agent 和长链路 agent 尤其有用,可以防止通过大量重试或工具调用掩盖质量问题。
85
+
86
+ ## 实用建议
87
+
88
+ - 先写 1-2 个 gate,保证任务底线。
89
+ - 再加 soft 分数比较质量。
90
+ - 复杂语义用 judge,但让 judge 有明确 rubric。
91
+ - coding-agent 结果尽量用真实测试验证。
92
+ - 把失败消息写清楚,方便从报告直接定位问题。