niceeval 0.4.6 → 0.5.1
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.
- package/docs-site/zh/concepts/adapter.mdx +6 -6
- package/docs-site/zh/concepts/experiment.mdx +7 -7
- package/docs-site/zh/concepts/overview.mdx +1 -1
- package/docs-site/zh/concepts/tier.mdx +6 -6
- package/docs-site/zh/guides/agent-feedback-loop.mdx +64 -21
- package/docs-site/zh/guides/connect-your-agent.mdx +7 -7
- package/docs-site/zh/guides/custom-reports.mdx +243 -0
- package/docs-site/zh/guides/experiments.mdx +3 -3
- package/docs-site/zh/guides/report-components.mdx +252 -0
- package/docs-site/zh/guides/reporters.mdx +1 -1
- package/docs-site/zh/guides/results-data.mdx +224 -0
- package/docs-site/zh/guides/runner.mdx +1 -1
- package/docs-site/zh/guides/sandbox-agent.mdx +2 -2
- package/docs-site/zh/guides/viewing-results.mdx +147 -77
- package/docs-site/zh/guides/write-experiment.mdx +9 -9
- package/docs-site/zh/guides/write-send.mdx +6 -6
- package/docs-site/zh/index.mdx +1 -1
- package/docs-site/zh/introduction.mdx +1 -1
- package/docs-site/zh/reference/cli.mdx +11 -3
- package/docs-site/zh/reference/define-agent.mdx +5 -5
- package/docs-site/zh/reference/define-config.mdx +1 -1
- package/docs-site/zh/reference/define-eval.mdx +3 -3
- package/package.json +3 -2
- package/src/agents/ai-sdk.test.ts +1 -1
- package/src/agents/ai-sdk.ts +2 -2
- package/src/agents/claude-code.ts +1 -1
- package/src/agents/codex.ts +2 -2
- package/src/agents/streaming.test.ts +1 -1
- package/src/agents/types.ts +4 -4
- package/src/agents/ui-message-stream.test.ts +1 -1
- package/src/cli.ts +120 -18
- package/src/context/context.test.ts +1 -1
- package/src/context/context.ts +3 -3
- package/src/context/session.ts +2 -2
- package/src/context/types.ts +2 -2
- package/src/i18n/en.ts +29 -7
- package/src/i18n/zh-CN.ts +24 -2
- package/src/report/aggregate.ts +79 -50
- package/src/report/components.tsx +190 -0
- package/src/report/compute.ts +149 -84
- package/src/report/default-report.tsx +222 -0
- package/src/report/dual-face.test.tsx +527 -0
- package/src/report/format.ts +29 -0
- package/src/report/index.ts +79 -24
- package/src/report/load.ts +67 -0
- package/src/report/metrics.ts +2 -1
- package/src/report/param.ts +18 -0
- package/src/report/primitives.tsx +117 -0
- package/src/report/react/CaseList.tsx +2 -2
- package/src/report/react/DeltaTable.tsx +2 -2
- package/src/report/react/MetricBars.tsx +109 -0
- package/src/report/react/MetricLine.tsx +200 -0
- package/src/report/react/MetricMatrix.tsx +1 -1
- package/src/report/react/MetricScatter.tsx +1 -1
- package/src/report/react/MetricTable.tsx +1 -1
- package/src/report/react/RunOverview.tsx +4 -4
- package/src/report/react/Scoreboard.tsx +3 -3
- package/src/report/react/cell.tsx +1 -1
- package/src/report/react/fixtures.ts +98 -36
- package/src/report/react/format.ts +3 -28
- package/src/report/react/index.tsx +41 -24
- package/src/report/react/render.test.tsx +8 -8
- package/src/report/react/styles.css +77 -0
- package/src/report/report.test.ts +248 -128
- package/src/report/report.ts +69 -0
- package/src/report/text/faces.ts +356 -0
- package/src/report/text/layout.ts +125 -0
- package/src/report/text/plot.ts +127 -0
- package/src/report/tree.ts +220 -0
- package/src/report/types.ts +75 -27
- package/src/report/web.ts +40 -0
- package/src/results/copy.ts +95 -41
- package/src/results/format.ts +12 -11
- package/src/results/index.ts +34 -17
- package/src/results/open.ts +201 -81
- package/src/results/results.test.ts +595 -191
- package/src/results/select.ts +107 -55
- package/src/results/types.ts +137 -45
- package/src/results/writer.ts +258 -0
- package/src/runner/attempt.ts +3 -3
- package/src/runner/fingerprint.ts +1 -1
- package/src/runner/reporters/artifacts.ts +38 -78
- package/src/runner/reporters/braintrust.test.ts +2 -2
- package/src/runner/reporters/braintrust.ts +3 -3
- package/src/runner/run.ts +1 -1
- package/src/runner/types.ts +18 -12
- package/src/show/compose.ts +215 -0
- package/src/show/index.ts +263 -0
- package/src/show/render.ts +456 -0
- package/src/show/show.test.ts +505 -0
- package/src/view/app/App.tsx +85 -24
- package/src/view/app/components/CostScoreChart.tsx +29 -10
- package/src/view/app/components/ExperimentTable.tsx +27 -9
- package/src/view/app/components/GroupSelector.tsx +1 -1
- package/src/view/app/i18n.ts +18 -3
- package/src/view/app/lib/attempt-route.test.ts +9 -9
- package/src/view/app/lib/attempt-route.ts +5 -5
- package/src/view/app/lib/outcome.ts +1 -3
- package/src/view/app/lib/rows.ts +95 -15
- package/src/view/app/main.tsx +18 -6
- package/src/view/app/pages/RunsPage.tsx +4 -7
- package/src/view/app/pages/TracesPage.tsx +3 -8
- package/src/view/app/types.ts +50 -6
- package/src/view/client-dist/app.css +1 -1
- package/src/view/client-dist/app.js +20 -20
- package/src/view/data.test.ts +254 -0
- package/src/view/data.ts +336 -0
- package/src/view/index.ts +64 -10
- package/src/view/server.ts +31 -9
- package/src/view/shared/types.ts +47 -41
- package/src/view/styles.css +5 -0
- package/src/view/template.html +1 -0
- package/src/view/view-report.test.ts +308 -0
- package/docs-site/.mintignore +0 -13
- package/docs-site/AGENTS.md +0 -46
- package/docs-site/concepts/adapter.mdx +0 -287
- package/docs-site/concepts/assert.mdx +0 -243
- package/docs-site/concepts/drive.mdx +0 -118
- package/docs-site/concepts/evals.mdx +0 -108
- package/docs-site/concepts/experiment.mdx +0 -37
- package/docs-site/concepts/hitl.mdx +0 -83
- package/docs-site/concepts/judge.mdx +0 -129
- package/docs-site/concepts/overview.mdx +0 -98
- package/docs-site/concepts/tier.mdx +0 -42
- package/docs-site/docs-ref/00-index.md +0 -23
- package/docs-site/docs-ref/01-page-types.md +0 -43
- package/docs-site/docs-ref/03-style-rules.md +0 -45
- package/docs-site/docs-ref/04-code-examples.md +0 -37
- package/docs-site/docs-ref/05-dx-failure-paths.md +0 -45
- package/docs-site/docs-ref/06-checklists.md +0 -53
- package/docs-site/docs.json +0 -256
- package/docs-site/example/ai-agent-application.mdx +0 -148
- package/docs-site/example/claude-code-codex-plugin.mdx +0 -162
- package/docs-site/example/claude-code-codex-skill.mdx +0 -147
- package/docs-site/example/showcase.mdx +0 -39
- package/docs-site/example/tier1-ai-sdk-v7.mdx +0 -136
- package/docs-site/example/tier1-claude-sdk.mdx +0 -119
- package/docs-site/example/tier1-codex-sdk.mdx +0 -111
- package/docs-site/example/tier1-langgraph.mdx +0 -119
- package/docs-site/example/tier1-pi-sdk.mdx +0 -119
- package/docs-site/favicon.svg +0 -5
- package/docs-site/github-diff.css +0 -135
- package/docs-site/github-diff.js +0 -11
- package/docs-site/guides/authoring.mdx +0 -129
- package/docs-site/guides/ci-integration.mdx +0 -97
- package/docs-site/guides/connect-otel.mdx +0 -209
- package/docs-site/guides/connect-your-agent.mdx +0 -221
- package/docs-site/guides/dataset-fanout.mdx +0 -98
- package/docs-site/guides/experiments.mdx +0 -71
- package/docs-site/guides/fixtures.mdx +0 -147
- package/docs-site/guides/reporters.mdx +0 -113
- package/docs-site/guides/runner.mdx +0 -79
- package/docs-site/guides/sandbox-agent.mdx +0 -138
- package/docs-site/guides/sandbox-backends.mdx +0 -64
- package/docs-site/guides/scoring-guide.mdx +0 -92
- package/docs-site/guides/viewing-results.mdx +0 -195
- package/docs-site/guides/write-experiment.mdx +0 -81
- package/docs-site/guides/write-send.mdx +0 -347
- package/docs-site/index.mdx +0 -181
- package/docs-site/introduction.mdx +0 -141
- package/docs-site/quickstart.mdx +0 -136
- package/docs-site/reference/builtin-agents.mdx +0 -161
- package/docs-site/reference/capabilities.mdx +0 -76
- package/docs-site/reference/cli.mdx +0 -120
- package/docs-site/reference/define-agent.mdx +0 -168
- package/docs-site/reference/define-config.mdx +0 -41
- package/docs-site/reference/define-eval.mdx +0 -160
- package/docs-site/reference/events.mdx +0 -131
- package/docs-site/reference/expect.mdx +0 -112
- package/docs-site/tracker.js +0 -8
- package/src/report/react/data.ts +0 -17
- package/src/view/aggregate.ts +0 -103
- package/src/view/loader.test.ts +0 -61
- package/src/view/loader.ts +0 -257
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: "查看 NiceEval 结果并调试 agent 行为"
|
|
3
3
|
sidebarTitle: "查看结果"
|
|
4
|
-
description: "
|
|
4
|
+
description: "每次运行写入 .niceeval/ 的结构化工件有两扇门:niceeval show 在终端逐级下钻榜单、断言、transcript、trace 与 diff;niceeval view 在网页看同一份证据。"
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
每次运行后,[NiceEval](https://niceeval.com/) 都会把结构化结果写入 `.niceeval/<timestamp
|
|
7
|
+
每次运行后,[NiceEval](https://niceeval.com/) 都会把结构化结果写入 `.niceeval/<timestamp>/`。看结果有两扇门,读的是同一批工件:`niceeval show` 是终端读法,人和 coding agent 都能用;`niceeval view` 是网页读法,适合人浏览证据。show 就是 view 的终端版,两处读到的判决口径不分叉。
|
|
8
8
|
|
|
9
9
|
## 控制台输出
|
|
10
10
|
|
|
@@ -16,10 +16,16 @@ Discovered 3 evals
|
|
|
16
16
|
✗ api-validation (38s)
|
|
17
17
|
- gate: expected src/routes/users.ts to include .safeParse() [FAILED]
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
Failing:
|
|
20
|
+
✗ api-validation
|
|
21
|
+
gate fileIncludes("src/routes/users.ts", ".safeParse()")
|
|
22
|
+
→ niceeval show api-validation
|
|
23
|
+
|
|
24
|
+
Results: 2 passed, 1 failed, 0 errored, 0 skipped
|
|
25
|
+
Structured results: .niceeval/2026-07-09T10-00-00-000Z/summary.json
|
|
20
26
|
```
|
|
21
27
|
|
|
22
|
-
|
|
28
|
+
运行中每个 eval 一条流式行,失败断言内联展开;运行结束的收尾块把失败集中重放一遍,每条自带下钻命令,末尾是结构化结果入口。这段输出怎么进「跑→读→修→再跑」的循环,见 [Agent 反馈闭环](/zh/guides/agent-feedback-loop)。
|
|
23
29
|
|
|
24
30
|
## `.niceeval/<timestamp>/`
|
|
25
31
|
|
|
@@ -38,7 +44,130 @@ Results: 2 passed, 1 failed, 0 errored, 0 skipped
|
|
|
38
44
|
└─ diff.json
|
|
39
45
|
```
|
|
40
46
|
|
|
41
|
-
## `niceeval
|
|
47
|
+
## `niceeval show`:终端下钻
|
|
48
|
+
|
|
49
|
+
`niceeval show` 的位置参数与 `exp` 同一语义——eval id 前缀选「看哪些 eval」;flag 选「看哪个切面」:
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
niceeval show # 榜单:每个 experiment 的通过率、成本、耗时与失败清单
|
|
53
|
+
niceeval show weather # 前缀过滤:weather/* 下每个 eval 的判决
|
|
54
|
+
niceeval show weather/brooklyn # 单个 eval:各 experiment 的 attempt、断言明细、错误与用量
|
|
55
|
+
niceeval show weather/brooklyn --transcript # agent 的完整对话与工具调用
|
|
56
|
+
niceeval show weather/brooklyn --trace # trace 瀑布的文本版
|
|
57
|
+
niceeval show fixtures/button --diff # sandbox 里的文件改动
|
|
58
|
+
niceeval show weather/brooklyn --history # 跨 run 时间轴:抖动与回归拐点
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
同一个实验多次跑会留下多份结果,默认视图只回答一个问题——「现在什么水位」:每个 experiment × eval 取时间上最新的那份判决,跨 run 合成。按前缀只重跑了部分 eval 时,其余 eval 的判决从更早的 run 补齐,榜单永远是全局水位,不会因为一次局部重跑变残缺。合成是有标注的:每行带判决产生的时间,榜单头写明合成自几个 run。合成状态可能混着不同版本的被测代码——所以收工判决以 `--force` 全量重跑为准,迭代途中的 `show` 负责快、收尾的全量跑负责真。
|
|
62
|
+
|
|
63
|
+
多 experiment、多 attempt 时,证据切面默认挑最新一次失败的 attempt;用 `--experiment` 与 `--attempt` 指定其它,用 `--run <目录>` 钉死看某一次历史 run,用 `--history` 看跨 run 趋势(见下文)。默认榜单只是报告槽的出厂填充:`--report <文件>` 可以把它整槽换成你自己的口径,同一个文件也能喂给 `view`,见[自定义报告](/zh/guides/custom-reports)。位置前缀、`--run`、`--experiment` 对 `--report` 同样生效(收窄报告拿到的选集);`--history` 与 `--report` 互斥,证据切面 flag 出现时走证据室、不渲染报告槽。
|
|
64
|
+
|
|
65
|
+
`niceeval view` 的每个视图都有 CLI 对应物:
|
|
66
|
+
|
|
67
|
+
| `niceeval view` 里的视图 | 终端对应 |
|
|
68
|
+
| --- | --- |
|
|
69
|
+
| Experiments 榜单 | `niceeval show` |
|
|
70
|
+
| attempt 详情(断言、错误、用量) | `niceeval show <eval id>` |
|
|
71
|
+
| transcript | `niceeval show <eval id> --transcript` |
|
|
72
|
+
| trace 瀑布图 | `niceeval show <eval id> --trace` |
|
|
73
|
+
| 文件改动 | `niceeval show <eval id> --diff` |
|
|
74
|
+
| 历史 run 列表 | `niceeval show <eval id> --history`;钉死某一次用 `--run <目录>` |
|
|
75
|
+
| 质量 × 成本散点图 | `niceeval show` 榜单的 pass / cost 列已含同一份数据;要图形化口径,用 `MetricScatter` 积木写[自定义报告](/zh/guides/custom-reports) |
|
|
76
|
+
|
|
77
|
+
### 榜单
|
|
78
|
+
|
|
79
|
+
```text
|
|
80
|
+
$ niceeval show
|
|
81
|
+
Current verdicts · 2 experiments · composed from 3 runs · latest 2026-07-09T10-00-00-000Z
|
|
82
|
+
|
|
83
|
+
experiment evals pass cost duration
|
|
84
|
+
compare/bub-gpt-5.4 13/15 87% $0.42 4m 12s
|
|
85
|
+
compare/codex-gpt-5.4 12/15 80% $0.51 5m 03s
|
|
86
|
+
|
|
87
|
+
Failing:
|
|
88
|
+
✗ weather/brooklyn compare/codex-gpt-5.4 gate calledTool("get_weather") 41s ago
|
|
89
|
+
✗ fixtures/button compare/bub-gpt-5.4 gate fileChanged("src/components/Button.tsx") 2h ago
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
跑多 experiment 的组时,`niceeval exp` 收尾块里的汇总表就是这个形状——同一份表格渲染,判决折叠口径也相同;区别只在数据范围:收尾块只汇总本次 run,`show` 榜单是跨 run 合成的现刻水位,各自在表头如实标注。
|
|
93
|
+
|
|
94
|
+
### 单个 eval
|
|
95
|
+
|
|
96
|
+
```text
|
|
97
|
+
$ niceeval show weather/brooklyn
|
|
98
|
+
weather/brooklyn — 布鲁克林天气查询
|
|
99
|
+
|
|
100
|
+
compare/bub-gpt-5.4 ✓ passed 1 attempt 38s $0.03 (2h ago)
|
|
101
|
+
compare/codex-gpt-5.4 ✗ failed 3 attempts 41s $0.04 (just now)
|
|
102
|
+
|
|
103
|
+
attempt 3 · compare/codex-gpt-5.4 · failed · 41s · 12.3k tokens · $0.04
|
|
104
|
+
✗ gate calledTool("get_weather") — tool was never called
|
|
105
|
+
✓ gate succeeded()
|
|
106
|
+
✗ soft judge("回答基于实时数据") — 0.2/1: reply invents a temperature without any tool call
|
|
107
|
+
|
|
108
|
+
artifacts: .niceeval/2026-07-09T10-00-00-000Z/artifacts/compare__codex-gpt-5.4__weather__brooklyn__2/
|
|
109
|
+
next: niceeval show weather/brooklyn --transcript | --trace | --diff
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### transcript、trace 与 diff
|
|
113
|
+
|
|
114
|
+
`--transcript` 把 `events.json` 渲染成逐轮对话,工具调用带出入参与耗时:
|
|
115
|
+
|
|
116
|
+
```text
|
|
117
|
+
$ niceeval show weather/brooklyn --transcript
|
|
118
|
+
attempt 3 · compare/codex-gpt-5.4 · failed
|
|
119
|
+
|
|
120
|
+
[user] 布鲁克林今天天气怎么样?
|
|
121
|
+
[assistant] 布鲁克林今天大约 24°C,晴。
|
|
122
|
+
|
|
123
|
+
(2 events · no tool calls · full stream: …/events.json)
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
`--trace` 把 `trace.json` 画成文本瀑布,span 类目与 web 版同一套标准化口径,不同 agent 的图天然可比:
|
|
127
|
+
|
|
128
|
+
```text
|
|
129
|
+
$ niceeval show weather/brooklyn --trace
|
|
130
|
+
agent run ▕████████████████████▏ 41.2s
|
|
131
|
+
├─ inference ▕█████░░░░░░░░░░░░░░░▏ 10.1s
|
|
132
|
+
├─ inference ▕░░░░░█████████░░░░░░▏ 18.3s
|
|
133
|
+
└─ inference ▕░░░░░░░░░░░░░░██████▏ 12.4s
|
|
134
|
+
|
|
135
|
+
(3 spans · no execute_tool spans · full trace: …/trace.json)
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
`--diff` 默认给文件级摘要;看单个文件的完整改动用 `--diff=<文件路径>`——路径必须用 `=` 连写,位置参数永远留给 eval id 前缀:
|
|
139
|
+
|
|
140
|
+
```text
|
|
141
|
+
$ niceeval show fixtures/button --diff
|
|
142
|
+
M src/components/Button.tsx +42 −3
|
|
143
|
+
A src/components/Button.css +18
|
|
144
|
+
|
|
145
|
+
(full diff: …/diff.json)
|
|
146
|
+
$ niceeval show fixtures/button --diff=src/components/Button.tsx
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
三个切面对长内容都会截断,但截断永远如实标注剩余数量和原始工件路径——输出对上下文窗口友好,事实源一字不少地留在盘上。
|
|
150
|
+
|
|
151
|
+
### 历史与抖动:`--history`
|
|
152
|
+
|
|
153
|
+
榜单和单个 eval 视图回答「现在」;「这个 eval 稳不稳」「什么时候开始坏的」问的是趋势。`--history` 给跨 run 时间轴,每次真实执行一行:
|
|
154
|
+
|
|
155
|
+
```text
|
|
156
|
+
$ niceeval show weather/brooklyn --history
|
|
157
|
+
compare/codex-gpt-5.4 · 5 runs · passed 2/5
|
|
158
|
+
|
|
159
|
+
2026-07-09T10-00 ✗ failed 3 attempts $0.04 gate calledTool("get_weather")
|
|
160
|
+
2026-07-09T08-12 ✓ passed 1 attempt $0.03
|
|
161
|
+
2026-07-08T18-22 ✗ failed 3 attempts $0.05 gate calledTool("get_weather")
|
|
162
|
+
2026-07-08T11-05 ✓ passed 1 attempt $0.03
|
|
163
|
+
2026-07-07T16-40 ✗ failed 3 attempts $0.05 gate calledTool("get_weather")
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
✓✗ 交替说明这个 eval 在抖,该修的是稳定性(被测程序或断言),反复重跑碰运气只会烧钱;连续绿转红的拐点就是回归引入的位置,用 `--run <目录>` 钉住拐点前后两次细看。时间轴只列真实执行——缓存携带的旧结果是判决的复印件,不占行,否则趋势会被复印件灌满假数据。不带 eval id 的 `niceeval show --history` 给每个 experiment 的 per-run 通过率序列,同一份趋势的榜单视角。
|
|
167
|
+
|
|
168
|
+
两次 run 的精确对比(这次修复具体翻转了哪些 eval)不做成 flag:用 `DeltaTable` 积木写一份报告递给 `--report`,几行就是一份自定义对比报告,终端和网页两扇门都认——内置命令只管固定摆法,自定义口径见[自定义报告](/zh/guides/custom-reports)。
|
|
169
|
+
|
|
170
|
+
## `niceeval view`:网页证据室
|
|
42
171
|
|
|
43
172
|
```bash
|
|
44
173
|
npx niceeval view
|
|
@@ -50,9 +179,11 @@ npx niceeval view
|
|
|
50
179
|
失败后立刻运行 `npx niceeval view`,可以直接打开刚刚那次运行的 artifacts。
|
|
51
180
|
</Tip>
|
|
52
181
|
|
|
182
|
+
view 的结构是「报告槽 + 证据室」:报告槽默认装官方榜单,`--report <文件>` 整槽换成你自己的报告(与 `show --report` 吃同一个文件),见[自定义报告](/zh/guides/custom-reports);证据室(attempt 弹窗、transcript、trace 瀑布)始终保留,报告里的数字点进去就是证据。
|
|
183
|
+
|
|
53
184
|
## 导出与静态托管
|
|
54
185
|
|
|
55
|
-
发布结果只有一种导出:`--out <目录>`
|
|
186
|
+
发布结果只有一种导出:`--out <目录>` 整站导出,完整带上能查看的一切。想要自己的页面形态,用报告积木自建(见[自定义报告](/zh/guides/custom-reports))。
|
|
56
187
|
|
|
57
188
|
### 内置查看器整站:静态托管
|
|
58
189
|
|
|
@@ -69,86 +200,25 @@ NiceEval 写入 `<dir>/index.html`,并把查看器要读取的工件(`source
|
|
|
69
200
|
- `diff.json` 和 `o11y.json` 不会被复制。查看器不读取它们,且 diff 可能达到上百 MB。
|
|
70
201
|
- 用 `file://` 直接打开 `index.html` 时浏览器不允许 fetch 工件,代码视图会提示源码不可用。本地预览用 http 服务打开。
|
|
71
202
|
|
|
72
|
-
最简单的流程是在跑过 eval 的机器上导出,把产物目录直接部署,不需要额外步骤。`.niceeval/` 通常不进版本库,如果构建发生在别的机器(CI、托管平台),先用 `
|
|
203
|
+
最简单的流程是在跑过 eval 的机器上导出,把产物目录直接部署,不需要额外步骤。`.niceeval/` 通常不进版本库,如果构建发生在别的机器(CI、托管平台),先用 `copySnapshots` 把要发布的快照瘦身复制进仓库,再对着快照目录导出:
|
|
73
204
|
|
|
74
205
|
```typescript
|
|
75
206
|
// scripts/snapshot.ts —— 跑完 eval 后执行,产物提交进仓库
|
|
76
|
-
import { openResults,
|
|
207
|
+
import { openResults, copySnapshots } from "niceeval/results";
|
|
77
208
|
|
|
78
209
|
const results = await openResults(".niceeval");
|
|
79
|
-
|
|
80
|
-
await copyRun(snapshots, "site-data/run", {
|
|
210
|
+
await copySnapshots(results.latest(), "site-data/run", {
|
|
81
211
|
artifacts: ["sources", "events", "trace"],
|
|
82
212
|
});
|
|
83
213
|
```
|
|
84
214
|
|
|
85
215
|
```bash
|
|
86
|
-
npx niceeval view --
|
|
216
|
+
npx niceeval view --run site-data/run --out site # CI 上对着快照构建
|
|
87
217
|
```
|
|
88
218
|
|
|
89
|
-
`
|
|
90
|
-
|
|
91
|
-
### 自建报告页:自己的看法
|
|
92
|
-
|
|
93
|
-
内置查看器的榜单形态是固定的。想要自己的看法——考试成绩单、benchmark 榜、质量 × 成本散点——用报告积木搭进你自己的应用:`niceeval/results` 读结果,`niceeval/report` 算数据,`niceeval/report/react` 渲染组件。
|
|
94
|
-
|
|
95
|
-
计算和渲染之间是一条可序列化边界:计算函数(`table()`、`scatter()`、`overview()` 等)读文件系统,只能跑在 Node(构建脚本、服务端、CI);组件只认算好的 JSON 数据,零 IO,在哪都能渲染。静态发布因此有两种姿势。
|
|
219
|
+
结果目录经 `--run` 递入,与 `show --run` 同一语义——位置参数永远留给 eval id 前缀。
|
|
96
220
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
```tsx
|
|
100
|
-
// app/evals/page.tsx
|
|
101
|
-
import { openResults, latestPerExperiment } from "niceeval/results";
|
|
102
|
-
import { table, passRate, costUSD } from "niceeval/report";
|
|
103
|
-
import { MetricTable } from "niceeval/report/react";
|
|
104
|
-
import "niceeval/report/react/styles.css";
|
|
105
|
-
|
|
106
|
-
export default async function EvalsPage() {
|
|
107
|
-
const results = await openResults(".niceeval");
|
|
108
|
-
const { snapshots } = latestPerExperiment(results.snapshots);
|
|
109
|
-
const data = await table(snapshots, {
|
|
110
|
-
rows: "agent",
|
|
111
|
-
columns: [passRate, costUSD],
|
|
112
|
-
sort: passRate,
|
|
113
|
-
});
|
|
114
|
-
return <MetricTable data={data} />;
|
|
115
|
-
}
|
|
116
|
-
```
|
|
117
|
-
|
|
118
|
-
**姿势二:CI 落 JSON,任意前端渲染。** 计算跑在出结果的地方,页面在哪都行(Vite SPA、已有的内部面板):
|
|
119
|
-
|
|
120
|
-
```typescript
|
|
121
|
-
// scripts/build-report-data.ts —— CI 里跑完 eval 后执行
|
|
122
|
-
import { writeFile } from "node:fs/promises";
|
|
123
|
-
import { openResults, latestPerExperiment } from "niceeval/results";
|
|
124
|
-
import { table, passRate, costUSD } from "niceeval/report";
|
|
125
|
-
|
|
126
|
-
const results = await openResults(".niceeval");
|
|
127
|
-
const { snapshots } = latestPerExperiment(results.snapshots);
|
|
128
|
-
await writeFile("public/report.json", JSON.stringify({
|
|
129
|
-
board: await table(snapshots, { rows: "agent", columns: [passRate, costUSD] }),
|
|
130
|
-
}));
|
|
131
|
-
```
|
|
132
|
-
|
|
133
|
-
```tsx
|
|
134
|
-
// 前端:任何 React 应用
|
|
135
|
-
import { MetricTable } from "niceeval/report/react";
|
|
136
|
-
|
|
137
|
-
const doc = await fetch("/report.json").then((r) => r.json());
|
|
138
|
-
|
|
139
|
-
<MetricTable data={doc.board} />;
|
|
140
|
-
```
|
|
141
|
-
|
|
142
|
-
组件不 hydrate 也完整:排序在数据侧预排、下钻是普通链接、展开折叠用 `<details>`,静态导出的产物不需要任何客户端 JS。样式随包发布(`niceeval/report/react/styles.css`),在其后加载自己的 CSS 即可覆盖。
|
|
143
|
-
|
|
144
|
-
自建页负责结论,逐条 attempt 的 transcript 和 trace 不必自己画:把内置查看器一起导出到子路径(`npx niceeval view --out <站点目录>/evidence`),再用组件的 `attemptHref` 生成深链跳过去:
|
|
145
|
-
|
|
146
|
-
```tsx
|
|
147
|
-
<MetricTable
|
|
148
|
-
data={data}
|
|
149
|
-
attemptHref={(ref) => `/evidence/#/attempt/${encodeURIComponent(ref.run)}/${ref.result}`}
|
|
150
|
-
/>
|
|
151
|
-
```
|
|
221
|
+
`results.latest()` 按实验挑最新快照,而不是挑最新的 run——某次运行只跑了部分实验时,其它实验仍保留上一轮的结果。
|
|
152
222
|
|
|
153
223
|
## Artifact 说明
|
|
154
224
|
|
|
@@ -189,7 +259,7 @@ Soft 断言的分数记录在 `assertions[].score` 里;非 `--strict` 模式
|
|
|
189
259
|
|
|
190
260
|
## 调试建议
|
|
191
261
|
|
|
192
|
-
-
|
|
193
|
-
-
|
|
194
|
-
- coding-agent 失败时看 `
|
|
195
|
-
-
|
|
262
|
+
- 收尾块的失败清单每条自带下钻命令:`niceeval show <eval id>` 先看断言明细。
|
|
263
|
+
- 想知道 agent 为什么这么做,看 `--transcript`(或 view 的 transcript 视图)了解决策过程。
|
|
264
|
+
- coding-agent 失败时看 `--diff` 和命令事件输出;工具调用问题看 `--trace` 与 `events.json`。
|
|
265
|
+
- 判断缺陷在被测程序还是 eval 本身、修完怎么重跑,流程见 [Agent 反馈闭环](/zh/guides/agent-feedback-loop)。
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: "写实验:用 defineExperiment 固定运行配置"
|
|
3
3
|
sidebarTitle: "写实验"
|
|
4
|
-
description: "学习如何在 experiments/ 里用 defineExperiment 选择 agent、传 model 和
|
|
4
|
+
description: "学习如何在 experiments/ 里用 defineExperiment 选择 agent、传 model 和 params、设置 runs、预算、并发与 sandbox。"
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
Experiment 是可签入的运行配置:同一批 eval 对着哪个 adapter
|
|
7
|
+
Experiment 是可签入的运行配置:同一批 eval 对着哪个 adapter、哪个模型、哪些参数、跑几次、预算多少,都写在 `experiments/` 里。CLI 的位置参数只负责筛 eval,不负责临时改 agent 或运行配置。
|
|
8
8
|
|
|
9
9
|
## 最小实验
|
|
10
10
|
|
|
@@ -20,7 +20,7 @@ export default defineExperiment({
|
|
|
20
20
|
|
|
21
21
|
`agent` 放的是已经配置好的 agent 实例。被测系统的 URL、鉴权、协议细节通常传给 adapter 工厂;运行器不会单独保存一个 `agentConfig` 字段。
|
|
22
22
|
|
|
23
|
-
## 传 model 和
|
|
23
|
+
## 传 model 和 params
|
|
24
24
|
|
|
25
25
|
```ts
|
|
26
26
|
// experiments/concise.ts
|
|
@@ -34,7 +34,7 @@ export default defineExperiment({
|
|
|
34
34
|
apiKey: process.env.STAGING_AGENT_API_KEY,
|
|
35
35
|
}),
|
|
36
36
|
model: "gpt-5.4",
|
|
37
|
-
|
|
37
|
+
params: {
|
|
38
38
|
promptVariant: "concise",
|
|
39
39
|
webResearch: false,
|
|
40
40
|
},
|
|
@@ -46,7 +46,7 @@ export default defineExperiment({
|
|
|
46
46
|
|
|
47
47
|
`model` 会作为 `ctx.model` 传给 adapter;应用接口支持模型选择时,adapter 把它放进请求体、header 或 CLI 参数即可。
|
|
48
48
|
|
|
49
|
-
`
|
|
49
|
+
`params` 会作为 `ctx.params` 传给 adapter,也会作为 `t.params` 出现在 eval 里。它适合表达 experiment 维度的 feature 开关,例如 prompt 版本、工具集、检索开关。真正按参数切换行为的是你的应用或 adapter,[NiceEval](https://niceeval.com/) 只负责原样透传。
|
|
50
50
|
|
|
51
51
|
```ts
|
|
52
52
|
// agents/web-agent.ts
|
|
@@ -57,7 +57,7 @@ async send(input, ctx) {
|
|
|
57
57
|
body: JSON.stringify({
|
|
58
58
|
message: input.text,
|
|
59
59
|
model: ctx.model,
|
|
60
|
-
|
|
60
|
+
params: ctx.params,
|
|
61
61
|
}),
|
|
62
62
|
signal: ctx.signal,
|
|
63
63
|
});
|
|
@@ -66,7 +66,7 @@ async send(input, ctx) {
|
|
|
66
66
|
|
|
67
67
|
## 一组实验怎么写
|
|
68
68
|
|
|
69
|
-
一个实验文件是一格配置。要比较多个模型、agent 或
|
|
69
|
+
一个实验文件是一格配置。要比较多个模型、agent 或 params,就把多个文件放进同一个文件夹:
|
|
70
70
|
|
|
71
71
|
```text
|
|
72
72
|
experiments/
|
|
@@ -89,7 +89,7 @@ npx niceeval exp prompt-variants
|
|
|
89
89
|
| `agent` | 选择并配置 adapter;必填 |
|
|
90
90
|
| `model` | 单个模型名,经 `ctx.model` 透传 |
|
|
91
91
|
| `reasoningEffort` | 单个推理努力程度(如 `"high"`),经 `ctx.reasoningEffort` / `t.reasoningEffort` 透传,归属与 `model` 一致 |
|
|
92
|
-
| `
|
|
92
|
+
| `params` | 任意 JSON 对象,经 `ctx.params` / `t.params` 透传 |
|
|
93
93
|
| `runs` | 每个 eval × 配置最多跑几次 |
|
|
94
94
|
| `earlyExit` | 多次运行里通过一次就提前停止 |
|
|
95
95
|
| `evals` | 限定这一格配置跑哪些 eval |
|
|
@@ -98,4 +98,4 @@ npx niceeval exp prompt-variants
|
|
|
98
98
|
| `maxConcurrency` | 这一格配置的并发上限 |
|
|
99
99
|
| `sandbox` | sandbox agent 使用的后端,如 `dockerSandbox()` / `e2bSandbox()` |
|
|
100
100
|
|
|
101
|
-
跨配置比较的设计建议见[实验矩阵](/zh/guides/experiments)。adapter 如何消费 `ctx.model` 和 `ctx.
|
|
101
|
+
跨配置比较的设计建议见[实验矩阵](/zh/guides/experiments)。adapter 如何消费 `ctx.model` 和 `ctx.params` 见[Adapter](/zh/concepts/adapter)。
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: "如何写好 Send"
|
|
3
3
|
sidebarTitle: "如何写好 Send"
|
|
4
|
-
description: "手写 Adapter 的 send 函数,一条主线七步走:发消息拿回复、接上之前的消息、记录消费、把工具解析成事件、人工介入(HITL)、接上 OTel trace、透传 experiment 的
|
|
4
|
+
description: "手写 Adapter 的 send 函数,一条主线七步走:发消息拿回复、接上之前的消息、记录消费、把工具解析成事件、人工介入(HITL)、接上 OTel trace、透传 experiment 的 params。每一步只在上一步的代码上多几行,每一步解锁一组断言。"
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
[Adapter](/zh/concepts/adapter) 讲了契约:`send` 传入 `TurnInput` 和 `AgentContext`,返回 `Turn`。这一页讲怎么写它——从"发一条消息拿到回复"的最小形态起步,一步一步加到完整接入。每一步只在上一步的代码上多几行,前面已有的部分在代码里用 `// ……省略` 标出;每一步末尾说明这几行解锁了哪些断言。改完任何一步都能立刻验证:把新解锁的断言写进一条 eval 重跑 `npx niceeval exp`,`niceeval view` 里能看到这一步新增的数据——多轮轨迹、用量、工具事件、待回答请求。
|
|
@@ -303,16 +303,16 @@ OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318/v1/traces node server.js
|
|
|
303
303
|
|
|
304
304
|
**这一步解锁**:`niceeval view` 里的调用瀑布图——应用内部每次模型调用、每次工具执行的耗时与 token,按轮铺成时间线。断言不变:判决依据在前几步的事件映射里已经齐了,span 只进瀑布图、不喂断言。接收器怎么起、span 怎么归属到轮,见 [OTel 接入](/zh/guides/connect-otel)。
|
|
305
305
|
|
|
306
|
-
## 第七步:透传 experiment 的
|
|
306
|
+
## 第七步:透传 experiment 的 params(A/B 对比)
|
|
307
307
|
|
|
308
|
-
应用把变体暴露成可切换的配置后,experiment 声明 `
|
|
308
|
+
应用把变体暴露成可切换的配置后,experiment 声明 `params`,运行器每轮经 `ctx.params` 原样递给 `send`;Adapter 不解释它们的含义,只随请求转发——应用按参数切换变体:
|
|
309
309
|
|
|
310
310
|
```ts
|
|
311
311
|
// ……send 其余部分同前,省略
|
|
312
312
|
body: JSON.stringify({
|
|
313
313
|
messages,
|
|
314
314
|
model: ctx.model, // ← 第一步就转发的 experiment.model;这里一起列出
|
|
315
|
-
|
|
315
|
+
params: ctx.params, // ← experiment.params 原样透传;没配时是 {}
|
|
316
316
|
}),
|
|
317
317
|
```
|
|
318
318
|
|
|
@@ -324,11 +324,11 @@ import chatApp from "../agents/chat-app.ts";
|
|
|
324
324
|
export default defineExperiment({
|
|
325
325
|
agent: chatApp,
|
|
326
326
|
model: "gpt-5.4", // ← 经 ctx.model 到 send
|
|
327
|
-
|
|
327
|
+
params: { promptVariant: "concise" }, // ← 每轮经 ctx.params 到 send
|
|
328
328
|
});
|
|
329
329
|
```
|
|
330
330
|
|
|
331
|
-
两个 experiment 文件各声明一份 `
|
|
331
|
+
两个 experiment 文件各声明一份 `params`,`npx niceeval exp` 分别跑同一批 eval,就是一组 A/B 对比。这是三档接入里的 Tier 3(要求应用配合暴露开关),投入与回报见 [Tier](/zh/concepts/tier);`params` 与 `model`、`runs` 等其余 experiment 字段见[写实验](/zh/guides/write-experiment)。
|
|
332
332
|
|
|
333
333
|
**这一步解锁**:同一批 eval 跨变体的成绩对比。
|
|
334
334
|
|
package/docs-site/zh/index.mdx
CHANGED
|
@@ -87,7 +87,7 @@ eval 运行完成后,[NiceEval](https://niceeval.com/) 会生成易读报告
|
|
|
87
87
|
| 概念 | 一句话 |
|
|
88
88
|
|---|---|
|
|
89
89
|
| [Eval](/zh/concepts/evals) | 一个测试用例:写在 `evals/*.eval.ts` 里,描述测什么。 |
|
|
90
|
-
| [Experiment](/zh/concepts/experiment) | 可签入的运行配置:决定连哪个 Adapter、什么 model、什么
|
|
90
|
+
| [Experiment](/zh/concepts/experiment) | 可签入的运行配置:决定连哪个 Adapter、什么 model、什么 params。 |
|
|
91
91
|
| [Adapter](/zh/concepts/adapter) | 连接被测系统的适配层:实现一个 `send`,把返回翻译成标准事件流。 |
|
|
92
92
|
| [Sandbox](/zh/guides/sandbox-backends) | 需要隔离工作区的 coding agent 才用得到;直连 Web Agent 不需要。 |
|
|
93
93
|
| [Tier](/zh/concepts/tier) | 接入 Adapter 的三档投入:Tier 1 只接 send,Tier 2 加 OTel 换调用瀑布图,Tier 3 侵入改造做 feature A/B。 |
|
|
@@ -114,7 +114,7 @@ NiceEval 是一个 Agent-Native 的评估工具。Dataset / golden 那一套「
|
|
|
114
114
|
| 概念 | 一句话 |
|
|
115
115
|
|---|---|
|
|
116
116
|
| Eval | 一个测试用例:写在 `evals/*.eval.ts` 里,描述测什么。 |
|
|
117
|
-
| Experiment | 可签入的运行配置:决定连哪个 Adapter、什么 model、什么
|
|
117
|
+
| Experiment | 可签入的运行配置:决定连哪个 Adapter、什么 model、什么 params。 |
|
|
118
118
|
| Adapter | 连接被测系统的适配层:实现一个 `send`,把返回翻译成标准事件流。 |
|
|
119
119
|
| Sandbox | 需要隔离工作区的 coding agent 才用得到;直连 Web Agent 不需要。 |
|
|
120
120
|
| Tier | 接入 Adapter 的三档投入:Tier 1 只接 send,Tier 2 加 OTel 换调用瀑布图,Tier 3 侵入改造做 feature A/B。 |
|
|
@@ -4,7 +4,7 @@ sidebarTitle: "命令行"
|
|
|
4
4
|
description: "NiceEval CLI 参考:exp、init、list、clean 和 view 命令,以及 experiment、eval 过滤、sandbox、并发、预算和 JUnit CI 输出。"
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
[NiceEval](https://niceeval.com/) CLI 是发现、运行和查看 eval 的入口。实际执行 eval 时采用 experiment-first 模型:**`exp` 选择可签入的运行配置**,experiment 后的位置参数才按 eval ID 前缀过滤。agent、model 和
|
|
7
|
+
[NiceEval](https://niceeval.com/) CLI 是发现、运行和查看 eval 的入口。实际执行 eval 时采用 experiment-first 模型:**`exp` 选择可签入的运行配置**,experiment 后的位置参数才按 eval ID 前缀过滤。agent、model 和 params 写在 `experiments/`,不靠临时 CLI 参数。
|
|
8
8
|
|
|
9
9
|
## 命令
|
|
10
10
|
|
|
@@ -13,7 +13,7 @@ description: "NiceEval CLI 参考:exp、init、list、clean 和 view 命令,
|
|
|
13
13
|
运行命名实验组或配置。可选尾随位置参数按 eval ID 前缀过滤。
|
|
14
14
|
</Card>
|
|
15
15
|
<Card title="npx niceeval init" icon="wand-magic-sparkles">
|
|
16
|
-
创建空的 `evals/` 目录和最小的 `niceeval.config.ts`;不生成示例 eval
|
|
16
|
+
创建空的 `evals/` 目录和最小的 `niceeval.config.ts`;不生成示例 eval 文件。同时写入/刷新 niceeval 指引区块——项目已有 `AGENTS.md` 就写那份,只有 `CLAUDE.md` 就写进 `CLAUDE.md`,都没有则新建 `AGENTS.md`(见[Agent 反馈闭环](/zh/guides/agent-feedback-loop))。
|
|
17
17
|
</Card>
|
|
18
18
|
<Card title="npx niceeval list" icon="list">
|
|
19
19
|
发现并打印所有 eval,不运行。
|
|
@@ -72,6 +72,14 @@ npx niceeval exp compare-models weather
|
|
|
72
72
|
| `--junit` | string | 额外写一份 JUnit XML 报告到指定路径,供 CI 消费。 |
|
|
73
73
|
| `--out` | string | `view` 命令专用:把结果查看器静态导出到指定目录。 |
|
|
74
74
|
| `--port` | number | `view` 命令专用:指定本地服务器监听端口。 |
|
|
75
|
+
| `--transcript` | boolean | `show` 命令专用:渲染单个 eval 的完整对话与工具调用(证据切面)。 |
|
|
76
|
+
| `--trace` | boolean | `show` 命令专用:渲染单个 eval 的 trace 瀑布文本版(证据切面)。 |
|
|
77
|
+
| `--diff` | boolean | `show` 命令专用:sandbox 里的文件改动摘要;`--diff=<文件路径>` 看单个文件的完整改动(路径必须 `=` 连写)。 |
|
|
78
|
+
| `--history` | boolean | `show` 命令专用:跨 run 时间轴,只列真实执行;与 `--report` 互斥。 |
|
|
79
|
+
| `--experiment` | string | `show` 命令专用:选集只留该实验。 |
|
|
80
|
+
| `--attempt` | number | `show` 命令专用:指定详情 / 证据切面看第几次 attempt(与展示一致的 1 计序号)。 |
|
|
81
|
+
| `--run` | string | `show` 命令专用:钉死看某一个结果目录(历史 run 或 `copySnapshots` 产物)。 |
|
|
82
|
+
| `--report` | string | `show` 命令专用:把默认榜单整槽换成你的报告文件(默认导出 `defineReport(...)`)。 |
|
|
75
83
|
| `--dry` | boolean | 只打印本次会匹配到的 eval × 运行配置,不实际执行。 |
|
|
76
84
|
| `--quiet` | boolean | 关闭控制台 / live 进度输出(reporter 仍会写 artifacts)。 |
|
|
77
85
|
| `--force` | boolean | 忽略上次运行结果,不跳过已通过的 (experiment, eval) 组合,强制全部重跑。 |
|
|
@@ -97,7 +105,7 @@ npx niceeval exp compare-models
|
|
|
97
105
|
npx niceeval exp compare-models weather-tool
|
|
98
106
|
```
|
|
99
107
|
|
|
100
|
-
运行命名 experiment,用矩阵比较 agents、models 或
|
|
108
|
+
运行命名 experiment,用矩阵比较 agents、models 或 params。第二个参数开始是 eval ID 前缀过滤。
|
|
101
109
|
|
|
102
110
|
## `view`
|
|
103
111
|
|
|
@@ -214,16 +214,16 @@ readonly reasoningEffort?: string;
|
|
|
214
214
|
|
|
215
215
|
模型推理努力程度;归属同 model——实验决定,省略时不覆盖 agent 原生默认。
|
|
216
216
|
|
|
217
|
-
#### `
|
|
217
|
+
#### `params`
|
|
218
218
|
|
|
219
219
|
```ts
|
|
220
|
-
readonly
|
|
220
|
+
readonly params: Readonly<Record<string, unknown>>;
|
|
221
221
|
```
|
|
222
222
|
|
|
223
|
-
experiment 的 `
|
|
223
|
+
experiment 的 `params` 字段原样透传,内容和结构完全由 experiment 作者自定义
|
|
224
224
|
(如 `{ webResearch: true }`、`{ systemPrompt: "..." }`)。adapter 按自己的约定
|
|
225
|
-
|
|
226
|
-
(跑法层面的 --timeout/--budget 等)
|
|
225
|
+
读取其中的字段;框架本身不解释、不校验它的内容。命名特意避开 CLI 解析出的
|
|
226
|
+
`flag`(跑法层面的 --timeout/--budget 等),两者是不相关的概念。
|
|
227
227
|
|
|
228
228
|
#### `sandbox`
|
|
229
229
|
|
|
@@ -4,7 +4,7 @@ sidebarTitle: "defineConfig"
|
|
|
4
4
|
description: "defineConfig 参考:judge、reporters、并发、超时和 sandbox 默认值。"
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
`defineConfig` 从根目录的 `niceeval.config.ts` 默认导出,只放项目级默认值。agent、model、
|
|
7
|
+
`defineConfig` 从根目录的 `niceeval.config.ts` 默认导出,只放项目级默认值。agent、model、params、runs 和实验预算写在 `experiments/` 下的 `defineExperiment` 文件里。
|
|
8
8
|
|
|
9
9
|
```ts
|
|
10
10
|
import { defineConfig } from "niceeval";
|
|
@@ -207,13 +207,13 @@ readonly reasoningEffort?: string;
|
|
|
207
207
|
|
|
208
208
|
本次 attempt 的推理努力程度(如 "low"/"medium"/"high",取值由 adapter/模型决定)。
|
|
209
209
|
|
|
210
|
-
#### `
|
|
210
|
+
#### `params`
|
|
211
211
|
|
|
212
212
|
```ts
|
|
213
|
-
readonly
|
|
213
|
+
readonly params: Readonly<Record<string, unknown>>;
|
|
214
214
|
```
|
|
215
215
|
|
|
216
|
-
本次 attempt 生效的
|
|
216
|
+
本次 attempt 生效的 params(experiment.params 与 CLI flag 合并后的只读视图)。
|
|
217
217
|
|
|
218
218
|
#### `log`
|
|
219
219
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "niceeval",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.1",
|
|
4
4
|
"description": "Agent-native eval tool — eval agents, services, functions, and coding-agent fixtures",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -61,7 +61,8 @@
|
|
|
61
61
|
"files": [
|
|
62
62
|
"src",
|
|
63
63
|
"bin",
|
|
64
|
-
"docs-site"
|
|
64
|
+
"docs-site/zh",
|
|
65
|
+
"docs-site/images"
|
|
65
66
|
],
|
|
66
67
|
"dependencies": {
|
|
67
68
|
"autoevals": "0.0.132",
|
|
@@ -454,7 +454,7 @@ function fakeCtx(opts: { id?: string } = {}): AgentContext {
|
|
|
454
454
|
return {
|
|
455
455
|
signal: new AbortController().signal,
|
|
456
456
|
model: undefined,
|
|
457
|
-
|
|
457
|
+
params: {},
|
|
458
458
|
sandbox: undefined as unknown as AgentContext["sandbox"],
|
|
459
459
|
session,
|
|
460
460
|
log: () => {},
|
package/src/agents/ai-sdk.ts
CHANGED
|
@@ -367,7 +367,7 @@ export interface AiSdkGenerateContext<M = unknown> {
|
|
|
367
367
|
/** 实验钉的推理努力程度(ctx.reasoningEffort);省略 → 用应用自己的默认。应用自己决定怎么塞进 providerOptions(如 OpenAI 的 reasoningEffort)。 */
|
|
368
368
|
readonly reasoningEffort?: string;
|
|
369
369
|
readonly signal: AbortSignal;
|
|
370
|
-
readonly
|
|
370
|
+
readonly params: Readonly<Record<string, unknown>>;
|
|
371
371
|
/**
|
|
372
372
|
* 配了 `tracing`(如 `aiSdkOtel()`)才有:直接放进 generateText / streamText 的
|
|
373
373
|
* `telemetry` 选项。OTel provider、per-attempt 端点绑定和轮末 flush 都由工厂做,
|
|
@@ -505,7 +505,7 @@ export function aiSdkAgent<M = unknown>(options: AiSdkAgentOptions<M>): Agent {
|
|
|
505
505
|
model: ctx.model,
|
|
506
506
|
reasoningEffort: ctx.reasoningEffort,
|
|
507
507
|
signal: ctx.signal,
|
|
508
|
-
|
|
508
|
+
params: ctx.params,
|
|
509
509
|
telemetry: otel?.settings,
|
|
510
510
|
});
|
|
511
511
|
} catch (error) {
|
|
@@ -94,7 +94,7 @@ export function claudeCodeAgent(config?: ClaudeCodeConfig): Agent {
|
|
|
94
94
|
const args = ["--print", "--dangerously-skip-permissions"];
|
|
95
95
|
if (ctx.model) args.push("--model", ctx.model);
|
|
96
96
|
if (config?.maxTurns != null) args.push("--max-turns", String(config.maxTurns));
|
|
97
|
-
if (ctx.
|
|
97
|
+
if (ctx.params.webResearch) args.push("--allowedTools", "WebSearch,WebFetch");
|
|
98
98
|
if (ctx.session.id) args.push("--resume", ctx.session.id);
|
|
99
99
|
args.push(input.text);
|
|
100
100
|
|
package/src/agents/codex.ts
CHANGED
|
@@ -9,7 +9,7 @@ import type { Agent, McpServer } from "../types.ts";
|
|
|
9
9
|
//
|
|
10
10
|
// 连接方式:在沙箱里 spawn `codex exec --json`,stdout JSONL → parseCodex → 标准事件流。
|
|
11
11
|
// 配置:鉴权本地(config / env),模型交给实验(ctx.model),推理努力程度经 ctx.reasoningEffort
|
|
12
|
-
// (兼容旧的 ctx.
|
|
12
|
+
// (兼容旧的 ctx.params.effort),其余参数经 ctx.params。
|
|
13
13
|
// ───────────────────────────────────────────────────────────────────────────
|
|
14
14
|
|
|
15
15
|
export interface CodexConfig {
|
|
@@ -44,7 +44,7 @@ export function codexAgent(config?: CodexConfig): Agent {
|
|
|
44
44
|
// model 归属:实验决定(ctx.model);省略时不写 model 行,交给 codex CLI 原生默认,
|
|
45
45
|
// 不在 adapter 里硬编码一个会过期的模型名。
|
|
46
46
|
const modelLine = ctx.model ? `model = "${ctx.model}"\n` : "";
|
|
47
|
-
const effort = ctx.reasoningEffort ?? (ctx.
|
|
47
|
+
const effort = ctx.reasoningEffort ?? (ctx.params.effort as string | undefined) ?? "medium";
|
|
48
48
|
const base = getBaseUrl();
|
|
49
49
|
|
|
50
50
|
if (base) {
|
package/src/agents/types.ts
CHANGED
|
@@ -155,12 +155,12 @@ export interface AgentContext {
|
|
|
155
155
|
/** 模型推理努力程度;归属同 model——实验决定,省略时不覆盖 agent 原生默认。 */
|
|
156
156
|
readonly reasoningEffort?: string;
|
|
157
157
|
/**
|
|
158
|
-
* experiment 的 `
|
|
158
|
+
* experiment 的 `params` 字段原样透传,内容和结构完全由 experiment 作者自定义
|
|
159
159
|
* (如 `{ webResearch: true }`、`{ systemPrompt: "..." }`)。adapter 按自己的约定
|
|
160
|
-
*
|
|
161
|
-
* (跑法层面的 --timeout/--budget 等)
|
|
160
|
+
* 读取其中的字段;框架本身不解释、不校验它的内容。命名特意避开 CLI 解析出的
|
|
161
|
+
* `flag`(跑法层面的 --timeout/--budget 等),两者是不相关的概念。
|
|
162
162
|
*/
|
|
163
|
-
readonly
|
|
163
|
+
readonly params: Readonly<Record<string, unknown>>;
|
|
164
164
|
/** 仅沙箱型 agent 有(运行器按 --sandbox 备好)。 */
|
|
165
165
|
readonly sandbox: Sandbox;
|
|
166
166
|
readonly session: AgentSession;
|
|
@@ -73,7 +73,7 @@ function ctx(overrides: Partial<{ model: string }> = {}): AgentContext {
|
|
|
73
73
|
return {
|
|
74
74
|
signal: new AbortController().signal,
|
|
75
75
|
model: overrides.model,
|
|
76
|
-
|
|
76
|
+
params: {},
|
|
77
77
|
sandbox: undefined as never,
|
|
78
78
|
// 同一个 ctx 重复用 = 同一条会话线(续接,同一个 ctx.session);新造 = 新线。
|
|
79
79
|
session: createAgentSession(),
|