niceeval 0.6.2 → 0.7.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/INDEX.md +23 -23
- package/README.zh.md +6 -6
- package/dist/agents/types.d.ts +2 -2
- package/dist/i18n/zh-CN.d.ts +3 -3
- package/dist/report/aggregate.d.ts +32 -26
- package/dist/report/aggregate.js +157 -76
- package/dist/report/built-in/index.d.ts +2 -0
- package/dist/report/built-in/index.js +8 -0
- package/dist/report/components.d.ts +91 -164
- package/dist/report/components.js +377 -114
- package/dist/report/compute.d.ts +86 -73
- package/dist/report/compute.js +592 -432
- package/dist/report/flag.d.ts +28 -17
- package/dist/report/flag.js +86 -16
- package/dist/report/format.d.ts +11 -11
- package/dist/report/format.js +17 -15
- package/dist/report/index.d.ts +16 -17
- package/dist/report/index.js +20 -22
- package/dist/report/load.js +3 -2
- package/dist/report/locale.d.ts +49 -34
- package/dist/report/locale.js +106 -58
- package/dist/report/metrics.d.ts +10 -3
- package/dist/report/metrics.js +46 -12
- package/dist/report/primitives.d.ts +42 -15
- package/dist/report/primitives.js +135 -26
- package/dist/report/react/AttemptList.d.ts +10 -8
- package/dist/report/react/AttemptList.js +18 -10
- package/dist/report/react/DeltaTable.js +19 -18
- package/dist/report/react/EvalList.d.ts +3 -3
- package/dist/report/react/EvalList.js +0 -0
- package/dist/report/react/ExperimentComparison.d.ts +4 -2
- package/dist/report/react/ExperimentComparison.js +5 -4
- package/dist/report/react/ExperimentList.d.ts +3 -3
- package/dist/report/react/ExperimentList.js +16 -15
- package/dist/report/react/MetricBars.js +5 -4
- package/dist/report/react/MetricLine.js +12 -5
- package/dist/report/react/MetricMatrix.js +1 -1
- package/dist/report/react/MetricScatter.js +54 -17
- package/dist/report/react/MetricTable.js +2 -12
- package/dist/report/react/ScopeSummary.d.ts +10 -0
- package/dist/report/react/ScopeSummary.js +17 -0
- package/dist/report/react/Scoreboard.js +6 -6
- package/dist/report/react/cell.js +2 -2
- package/dist/report/react/fixtures.d.ts +5 -9
- package/dist/report/react/fixtures.js +105 -149
- package/dist/report/react/index.d.ts +15 -5
- package/dist/report/react/index.js +18 -7
- package/dist/report/report.d.ts +137 -20
- package/dist/report/report.js +261 -34
- package/dist/report/text/faces.d.ts +17 -19
- package/dist/report/text/faces.js +225 -157
- package/dist/report/text/plot.js +1 -1
- package/dist/report/text/table.js +2 -2
- package/dist/report/tree.d.ts +90 -40
- package/dist/report/tree.js +252 -94
- package/dist/report/types.d.ts +245 -300
- package/dist/report/types.js +4 -3
- package/dist/report/web.d.ts +21 -5
- package/dist/report/web.js +42 -16
- package/dist/results/select.d.ts +38 -16
- package/dist/results/select.js +73 -25
- package/dist/results/types.d.ts +38 -14
- package/dist/shared/aggregate.d.ts +3 -2
- package/dist/shared/aggregate.js +5 -4
- package/docs-site/zh/README.md +44 -0
- package/docs-site/zh/examples/ai-agent-application.mdx +63 -0
- package/docs-site/zh/examples/coding-agent-extensions.mdx +57 -0
- package/docs-site/zh/examples/index.mdx +50 -0
- package/docs-site/zh/{concepts → explanation}/adapter.mdx +11 -11
- package/docs-site/zh/{concepts → explanation}/assert.mdx +7 -7
- package/docs-site/zh/{concepts → explanation}/drive.mdx +8 -8
- package/docs-site/zh/{concepts → explanation}/evals.mdx +4 -4
- package/docs-site/zh/{concepts → explanation}/experiment.mdx +8 -8
- package/docs-site/zh/{concepts → explanation}/hitl.mdx +8 -8
- package/docs-site/zh/{concepts → explanation}/judge.mdx +5 -5
- package/docs-site/zh/{concepts → explanation}/overview.mdx +5 -5
- package/docs-site/zh/{guides → explanation}/runner.mdx +1 -1
- package/docs-site/zh/{concepts → explanation}/tier.mdx +6 -6
- package/docs-site/zh/{guides → how-to}/agent-feedback-loop.mdx +7 -7
- package/docs-site/zh/{guides → how-to}/authoring.mdx +2 -2
- package/docs-site/zh/{guides → how-to}/connect-otel.mdx +6 -6
- package/docs-site/zh/{guides → how-to}/connect-your-agent.mdx +18 -18
- package/docs-site/zh/{guides → how-to}/custom-reports.mdx +6 -6
- package/docs-site/zh/{guides → how-to}/experiments.mdx +3 -3
- package/docs-site/zh/{guides → how-to}/publish-report.mdx +2 -2
- package/docs-site/zh/{guides → how-to}/sandbox-agent.mdx +2 -2
- package/docs-site/zh/{guides → how-to}/sandbox-providers.mdx +1 -1
- package/docs-site/zh/{guides → how-to}/viewing-results.mdx +6 -6
- package/docs-site/zh/{guides → how-to}/write-experiment.mdx +3 -3
- package/docs-site/zh/{guides → how-to}/write-send.mdx +13 -13
- package/docs-site/zh/index.mdx +23 -25
- package/docs-site/zh/introduction.mdx +8 -8
- package/docs-site/zh/reference/builtin-agents.mdx +5 -5
- package/docs-site/zh/reference/capabilities.mdx +6 -6
- package/docs-site/zh/reference/cli.mdx +9 -7
- package/docs-site/zh/reference/define-agent.mdx +1 -1
- package/docs-site/zh/reference/events.mdx +3 -3
- package/docs-site/zh/{guides → reference}/official-adapters.mdx +7 -7
- package/docs-site/zh/{guides → reference}/report-components.mdx +5 -5
- package/docs-site/zh/{guides → reference}/results-data.mdx +5 -5
- package/docs-site/zh/{guides → troubleshooting}/debug-sandbox.mdx +2 -2
- package/docs-site/zh/{guides → troubleshooting}/debugging.mdx +4 -2
- package/docs-site/zh/{quickstart.mdx → tutorials/quickstart.mdx} +5 -17
- package/package.json +6 -2
- package/src/agents/index.ts +2 -2
- package/src/agents/openai-compat.ts +1 -1
- package/src/agents/streaming.ts +2 -2
- package/src/agents/types.ts +3 -3
- package/src/cli.ts +42 -23
- package/src/context/context.ts +1 -1
- package/src/context/session.test.ts +1 -1
- package/src/context/session.ts +1 -1
- package/src/i18n/en.ts +18 -16
- package/src/i18n/zh-CN.ts +16 -15
- package/src/report/aggregate.ts +175 -87
- package/src/report/built-in/index.tsx +9 -0
- package/src/report/components.tsx +625 -285
- package/src/report/compute.ts +717 -515
- package/src/report/dual-render.test.tsx +738 -1148
- package/src/report/flag.ts +97 -33
- package/src/report/format.ts +18 -22
- package/src/report/index.ts +113 -58
- package/src/report/load.ts +3 -2
- package/src/report/locale.ts +120 -69
- package/src/report/metrics.ts +42 -12
- package/src/report/primitives.tsx +190 -45
- package/src/report/react/AttemptList.tsx +32 -20
- package/src/report/react/DeltaTable.tsx +63 -45
- package/src/report/react/EvalList.tsx +0 -0
- package/src/report/react/ExperimentComparison.tsx +12 -7
- package/src/report/react/ExperimentList.tsx +38 -26
- package/src/report/react/MetricBars.tsx +5 -4
- package/src/report/react/MetricLine.tsx +13 -8
- package/src/report/react/MetricMatrix.tsx +2 -2
- package/src/report/react/MetricScatter.tsx +74 -20
- package/src/report/react/MetricTable.tsx +4 -76
- package/src/report/react/ScopeSummary.tsx +86 -0
- package/src/report/react/Scoreboard.tsx +28 -10
- package/src/report/react/cell.tsx +2 -2
- package/src/report/react/enhance.js +57 -5
- package/src/report/react/fixtures.ts +109 -156
- package/src/report/react/index.tsx +24 -39
- package/src/report/react/render.test.tsx +139 -104
- package/src/report/react/styles.css +181 -91
- package/src/report/report.test.ts +761 -1031
- package/src/report/report.ts +425 -47
- package/src/report/text/faces.ts +257 -164
- package/src/report/text/plot.ts +1 -1
- package/src/report/text/table.ts +2 -2
- package/src/report/tree.ts +362 -104
- package/src/report/types.ts +257 -287
- package/src/report/web.ts +63 -20
- package/src/results/attempt-evidence.test.ts +4 -4
- package/src/results/attempt-evidence.ts +5 -5
- package/src/results/copy.ts +6 -6
- package/src/results/host-equivalence.test.ts +26 -14
- package/src/results/index.ts +10 -4
- package/src/results/open.ts +8 -4
- package/src/results/results.test.ts +4 -3
- package/src/results/select.ts +104 -34
- package/src/results/types.ts +36 -14
- package/src/runner/feedback/human.test.ts +1 -1
- package/src/runner/run.ts +1 -1
- package/src/sandbox/cli-commands.ts +2 -2
- package/src/scoring/judge.test.ts +1 -1
- package/src/shared/aggregate.ts +5 -4
- package/src/show/compose.ts +50 -67
- package/src/show/index.ts +107 -56
- package/src/show/render.ts +43 -27
- package/src/show/report-host.test.ts +188 -0
- package/src/show/report-host.ts +375 -0
- package/src/show/show.test.ts +86 -36
- package/src/view/app/App.test.tsx +69 -0
- package/src/view/app/App.tsx +144 -48
- package/src/view/app/components/AttemptModal.tsx +324 -63
- package/src/view/app/components/CodeView.tsx +10 -4
- package/src/view/app/i18n.ts +31 -17
- package/src/view/app/lib/artifact-url.ts +14 -3
- package/src/view/app/main.tsx +13 -8
- package/src/view/app/pages/{RunsPage.tsx → AttemptsPage.tsx} +6 -6
- package/src/view/app/types.ts +4 -1
- package/src/view/artifact-serving.test.ts +21 -1
- package/src/view/client-dist/app.css +1 -1
- package/src/view/client-dist/app.js +6 -6
- package/src/view/data.test.ts +9 -3
- package/src/view/data.ts +145 -49
- package/src/view/index.ts +48 -44
- package/src/view/server.ts +35 -15
- package/src/view/shared/types.ts +34 -5
- package/src/view/styles.css +224 -0
- package/src/view/view-report.test.ts +161 -57
- package/dist/report/built-ins/experiment-comparison.d.ts +0 -39
- package/dist/report/built-ins/experiment-comparison.js +0 -119
- package/dist/report/built-ins/index.d.ts +0 -2
- package/dist/report/built-ins/index.js +0 -2
- package/dist/report/react/GroupSummary.d.ts +0 -8
- package/dist/report/react/GroupSummary.js +0 -8
- package/dist/report/react/RunOverview.d.ts +0 -8
- package/dist/report/react/RunOverview.js +0 -12
- package/docs-site/zh/example/ai-agent-application.mdx +0 -152
- package/docs-site/zh/example/claude-code-codex-plugin.mdx +0 -167
- package/docs-site/zh/example/claude-code-codex-skill.mdx +0 -152
- package/docs-site/zh/example/showcase.mdx +0 -39
- package/src/report/built-in-user-parity.test.tsx +0 -597
- package/src/report/built-ins/experiment-comparison.tsx +0 -179
- package/src/report/built-ins/index.ts +0 -7
- package/src/report/react/GroupSummary.tsx +0 -66
- package/src/report/react/RunOverview.tsx +0 -109
- /package/docs-site/zh/{example/tier1-ai-sdk-v7.mdx → examples/integrations/ai-sdk-v7.mdx} +0 -0
- /package/docs-site/zh/{example/tier1-claude-sdk.mdx → examples/integrations/claude-sdk.mdx} +0 -0
- /package/docs-site/zh/{example/tier1-codex-sdk.mdx → examples/integrations/codex-sdk.mdx} +0 -0
- /package/docs-site/zh/{example/tier1-langgraph.mdx → examples/integrations/langgraph.mdx} +0 -0
- /package/docs-site/zh/{example/tier1-pi-sdk.mdx → examples/integrations/pi-sdk.mdx} +0 -0
- /package/docs-site/zh/{guides → how-to}/ci-integration.mdx +0 -0
- /package/docs-site/zh/{guides → how-to}/dataset-fanout.mdx +0 -0
- /package/docs-site/zh/{guides → how-to}/fixtures.mdx +0 -0
- /package/docs-site/zh/{guides → how-to}/reporters.mdx +0 -0
- /package/docs-site/zh/{guides → how-to}/scoring-guide.mdx +0 -0
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "自写 Adapter 评估 AI Agent 应用"
|
|
3
|
+
sidebarTitle: "AI Agent 应用"
|
|
4
|
+
description: "一个可运行的 AI SDK v6 Web Agent 评测项目,覆盖自写 Adapter、工具调用、图片理解、多轮会话、模型对比和双路可观测。"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
这个项目演示如何用 `defineAgent` 把已有 HTTP Agent 接入 NiceEval。它适合需要控制自有协议和事件映射的应用。
|
|
8
|
+
|
|
9
|
+
- [查看完整源码](https://github.com/CorrectRoadH/niceeval/tree/main/examples/zh/ai-sdk)
|
|
10
|
+
- 本地目录:`examples/zh/ai-sdk/`
|
|
11
|
+
|
|
12
|
+
<Note>
|
|
13
|
+
如果应用使用 AI SDK v7 的 UI Message Stream,优先使用内置 `uiMessageStreamAgent`。对应的无侵入示例见 [AI SDK v7](/zh/examples/integrations/ai-sdk-v7)。
|
|
14
|
+
</Note>
|
|
15
|
+
|
|
16
|
+
## 这个项目证明什么
|
|
17
|
+
|
|
18
|
+
| 部分 | 实现 |
|
|
19
|
+
| --- | --- |
|
|
20
|
+
| 被测应用 | AI SDK v6 Web Agent,HTTP `POST /api/turn` |
|
|
21
|
+
| Adapter | `defineAgent` + 自定义 `AgentEvent` → `StreamEvent` 映射 |
|
|
22
|
+
| Eval | 天气工具、图片理解、多轮文本、多轮图片上下文 |
|
|
23
|
+
| Experiment | 每个文件固定一个模型,同组比较 DeepSeek 与 GPT |
|
|
24
|
+
| 可观测 | 应用继续上报 Langfuse,同时把本轮 OTLP 数据发给 NiceEval |
|
|
25
|
+
|
|
26
|
+
Adapter 只负责连接和翻译。URL 与模型属于 Experiment;Eval 只描述交互与好结果。这个分层让同一批 Eval 可以复用到不同模型和部署实例。
|
|
27
|
+
|
|
28
|
+
## 目录
|
|
29
|
+
|
|
30
|
+
```text
|
|
31
|
+
examples/zh/ai-sdk/
|
|
32
|
+
├── src/ # 被测 Web Agent
|
|
33
|
+
├── adapter/adapter.ts # 自写 NiceEval Adapter
|
|
34
|
+
├── evals/ # 工具、图片和多轮 Eval
|
|
35
|
+
├── experiments/ # 模型对比
|
|
36
|
+
└── niceeval.config.ts
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## 跑起来
|
|
40
|
+
|
|
41
|
+
这个示例调用真实模型,没有 Mock 模式。先复制环境变量并填入 OpenAI 兼容服务的凭据:
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
cd examples/zh/ai-sdk
|
|
45
|
+
pnpm install
|
|
46
|
+
cp .env.example .env
|
|
47
|
+
pnpm dev
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
另开一个终端运行:
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
cd examples/zh/ai-sdk
|
|
54
|
+
pnpm exec niceeval list
|
|
55
|
+
pnpm exec niceeval exp compare-models weather-tool
|
|
56
|
+
pnpm exec niceeval view
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## 继续阅读
|
|
60
|
+
|
|
61
|
+
- [接入你的 Agent](/zh/how-to/connect-your-agent):从最小 Adapter 开始接入自己的协议。
|
|
62
|
+
- [如何写好 Send](/zh/how-to/write-send):逐步补齐会话、工具、HITL 和 OTel。
|
|
63
|
+
- [实验矩阵](/zh/how-to/experiments):组织模型和配置对比。
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "评估 Coding Agent 扩展"
|
|
3
|
+
sidebarTitle: "Coding Agent 扩展"
|
|
4
|
+
description: "用真实 Workspace、基线实验和自定义报告,评估 Skill、提示词与 Plugin Benchmark 是否改善 Coding Agent 的任务结果。"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
这个案例把扩展内容作为 Experiment 变量,让同一个 Coding Agent 在同一批真实开发任务上运行,再比较任务成功率、成本、耗时和行为差异。
|
|
8
|
+
|
|
9
|
+
- [查看完整源码](https://github.com/CorrectRoadH/coding-agent-skill)
|
|
10
|
+
- [查看 Fixtures 指南](/zh/how-to/fixtures)
|
|
11
|
+
|
|
12
|
+
## 两组实验
|
|
13
|
+
|
|
14
|
+
| 实验 | 对照 | 测什么 |
|
|
15
|
+
| --- | --- | --- |
|
|
16
|
+
| Zod Skill | `with-skill` vs `baseline` | Skill 是否让 Agent 稳定使用 `z.object().safeParse()`,而不是退回手写校验 |
|
|
17
|
+
| Ponytail Benchmark | Baseline / Caveman / Ponytail / YAGNI One-liner | 完整决策 Skill 是否比裸 Agent、简短风格 Skill 或一句提示更有效 |
|
|
18
|
+
|
|
19
|
+
Ponytail 这一组迁移自第三方 Plugin 的 Agentic Benchmark,但这个仓库实际比较的是注入给 Agent 的内容与提示。它不用于证明某个原生 Plugin 包装或安装协议是否正确。原生 Skill / Plugin 的安装配置见 [官方适配器](/zh/reference/official-adapters)。
|
|
20
|
+
|
|
21
|
+
## 实验设计
|
|
22
|
+
|
|
23
|
+
每个 Arm 固定相同的模型、Sandbox、任务集、Runs 和预算,只改变注入内容。Eval 不读取“当前是哪个 Arm”,也不为实验组降低验收标准。
|
|
24
|
+
|
|
25
|
+
```text
|
|
26
|
+
coding-agent-skill/
|
|
27
|
+
├── skills/ # 各 Arm 注入的内容
|
|
28
|
+
├── workspaces/ts-starter/ # 每个 Eval 的初始项目
|
|
29
|
+
├── evals/ # 真实开发任务与验证
|
|
30
|
+
├── experiments/ # Baseline 和实验 Arm
|
|
31
|
+
└── reports/benchmark.tsx # Arm × Metric 自定义报告
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
验证优先看最终产物:项目测试、隐藏探针、源码和 Diff。只有事件稳定且完整时,才把 Skill Load 或工具调用作为 Gate。
|
|
35
|
+
|
|
36
|
+
## 跑起来
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
git clone https://github.com/CorrectRoadH/coding-agent-skill.git
|
|
40
|
+
cd coding-agent-skill
|
|
41
|
+
pnpm install
|
|
42
|
+
cp .env.example .env
|
|
43
|
+
docker info
|
|
44
|
+
|
|
45
|
+
pnpm exec niceeval exp ponytail-baseline
|
|
46
|
+
pnpm exec niceeval exp caveman
|
|
47
|
+
pnpm exec niceeval exp ponytail
|
|
48
|
+
pnpm exec niceeval exp yagni-oneliner
|
|
49
|
+
pnpm exec niceeval view --report reports/benchmark.tsx
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## 从这个案例复用什么
|
|
53
|
+
|
|
54
|
+
- 用 Experiment 表达有扩展和无扩展的对照,不让 Eval 知道实验条件。
|
|
55
|
+
- Prompt 不泄露答案;验证阶段再检查测试、源码、Diff 和行为证据。
|
|
56
|
+
- 把任务成功率作为主指标,把 Token、成本、耗时和行为作为解释指标。
|
|
57
|
+
- [评分指南](/zh/how-to/scoring-guide) 负责选择 Gate、Soft 和 Judge;本页不复制评分 API。
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "NiceEval Examples"
|
|
3
|
+
sidebarTitle: "选择示例"
|
|
4
|
+
description: "按被测对象选择可运行的 NiceEval 示例:Agent Framework 接入、完整 AI Agent 评测、Coding Agent 扩展 benchmark 和真实项目。"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
这里的每个示例都有真实可运行源码。先按被测对象选择,不必从头依次阅读。
|
|
8
|
+
|
|
9
|
+
如果你还没有跑通过第一条 Eval,先读 [Quickstart](/zh/tutorials/quickstart)。如果你已经知道要完成什么,直接进入对应的 [How-to Guides](/zh/how-to/connect-your-agent)。
|
|
10
|
+
|
|
11
|
+
## 接入已有 Agent Framework
|
|
12
|
+
|
|
13
|
+
下面五组示例都保留接入前的普通应用和接入 NiceEval 后的完整项目。页面中的代码 diff 从这两份源码生成。
|
|
14
|
+
|
|
15
|
+
| 被测对象 | 接入方式 | 示例覆盖 |
|
|
16
|
+
| --- | --- | --- |
|
|
17
|
+
| [AI SDK v7](/zh/examples/integrations/ai-sdk-v7) | 内置 `uiMessageStreamAgent` | UI Message Stream、多轮、工具、HITL |
|
|
18
|
+
| [Claude Agent SDK](/zh/examples/integrations/claude-sdk) | `fromClaudeSdkMessages` | 原生事件流、多轮、工具、HITL |
|
|
19
|
+
| [Codex SDK](/zh/examples/integrations/codex-sdk) | `fromCodexThreadEvents` | 编码任务、文件和命令、usage;SDK 不支持 HITL |
|
|
20
|
+
| [pi-agent-core](/zh/examples/integrations/pi-sdk) | `fromPiAgentEvents` | 原生事件流、多轮、工具、HITL;SDK 没有 OTel |
|
|
21
|
+
| [LangGraph](/zh/examples/integrations/langgraph) | 手写自定义 SSE 帧映射 | Python 应用、多轮、工具、HITL |
|
|
22
|
+
|
|
23
|
+
每组源码都位于 [`examples/zh/origin/`](https://github.com/CorrectRoadH/niceeval/tree/main/examples/zh/origin) 和 [`examples/zh/tier1/`](https://github.com/CorrectRoadH/niceeval/tree/main/examples/zh/tier1)。需要 OTel 或 Experiment Flags 时,再沿相同项目进入 `tier2/` 和 `tier3/`。
|
|
24
|
+
|
|
25
|
+
## 完整评测项目
|
|
26
|
+
|
|
27
|
+
<CardGroup cols={2}>
|
|
28
|
+
<Card title="自写 Adapter 评估 AI Agent 应用" icon="robot" href="/zh/examples/ai-agent-application">
|
|
29
|
+
一个 AI SDK v6 Web Agent,覆盖工具调用、图片理解、多轮会话、模型对比和双路可观测。
|
|
30
|
+
</Card>
|
|
31
|
+
<Card title="评估 Coding Agent 扩展" icon="wand-magic-sparkles" href="/zh/examples/coding-agent-extensions">
|
|
32
|
+
用真实 Workspace 和对照实验衡量 Skill、提示词与 Plugin Benchmark 对任务结果的影响。
|
|
33
|
+
</Card>
|
|
34
|
+
</CardGroup>
|
|
35
|
+
|
|
36
|
+
## 真实项目
|
|
37
|
+
|
|
38
|
+
### Coding Agent Memory Evals
|
|
39
|
+
|
|
40
|
+
[coding-agent-memory-evals](https://github.com/CorrectRoadH/coding-agent-memory-evals) 用同一批开发任务和同一个模型,对比 Coding Agent 是否带持久记忆时的任务成功率、成本、耗时和行为差异。
|
|
41
|
+
|
|
42
|
+
- [查看在线报告](https://niceeval.com/showcase/memory)
|
|
43
|
+
- [查看项目源码](https://github.com/CorrectRoadH/coding-agent-memory-evals)
|
|
44
|
+
|
|
45
|
+
## 什么不放在 Examples
|
|
46
|
+
|
|
47
|
+
- 单段 API 用法放进 How-to 或 Reference。
|
|
48
|
+
- 没有可运行源码的伪项目不收录。
|
|
49
|
+
- Roadmap 和尚未实现的接入不收录。
|
|
50
|
+
- 同一个项目不为 Skill、Plugin、Hook 等相邻叫法复制多张案例页。
|
|
@@ -6,7 +6,7 @@ description: "Adapter 是你写的适配器。本文讲清楚 send 函数传入
|
|
|
6
6
|
|
|
7
7
|
在 [NiceEval](https://niceeval.com/) 里,`Adapter` 是连接运行器和被测系统的适配层。Adapter 需要实现 `send` 函数:把 `t.send()` 等 eval 侧动作发给你的应用,再把应用返回翻译成 [NiceEval](https://niceeval.com/) 的标准 `Turn`。
|
|
8
8
|
|
|
9
|
-
后续阅读[写 send](/zh/
|
|
9
|
+
后续阅读[写 send](/zh/how-to/write-send)
|
|
10
10
|
|
|
11
11
|
## 适配器
|
|
12
12
|
如果被测系统使用标准的 OpenAI Chat Completions 或 Responses 协议,可以直接用官方适配器。自己实现的前后端协议(HTTP、gRPC、WebSocket 都行)则写一个 Adapter:它知道怎么鉴权、怎么调用你的应用、怎么把返回翻译成标准事件流。
|
|
@@ -94,12 +94,12 @@ export default defineExperiment({
|
|
|
94
94
|
|
|
95
95
|
## 接入等级
|
|
96
96
|
|
|
97
|
-
按「Adapter 接到哪里、额外拿到什么观测数据」,接入分三级:**Tier 1 只接 send**(应用代码一行不改,全套断言在这一级就齐了)、**Tier 2 send + OTel**(应用把 span 发给 [NiceEval](https://niceeval.com/),换 `niceeval view` 的调用瀑布图)、**Tier 3 侵入改造 + experiment flags**(feature A/B)。每档投入什么、买到什么、什么时候升级,见 [Tier](/zh/
|
|
97
|
+
按「Adapter 接到哪里、额外拿到什么观测数据」,接入分三级:**Tier 1 只接 send**(应用代码一行不改,全套断言在这一级就齐了)、**Tier 2 send + OTel**(应用把 span 发给 [NiceEval](https://niceeval.com/),换 `niceeval view` 的调用瀑布图)、**Tier 3 侵入改造 + experiment flags**(feature A/B)。每档投入什么、买到什么、什么时候升级,见 [Tier](/zh/explanation/tier)。
|
|
98
98
|
|
|
99
99
|
eval 侧的驱动 API——`t.send()`、`t.sendFile()`、`t.newSession()`、HITL 的 `t.respond()` / `t.respondAll()`
|
|
100
100
|
统一都是调用 Adapter 的 `send`。
|
|
101
101
|
|
|
102
|
-
怎么收敛、send 里怎么接,见[写 send](/zh/
|
|
102
|
+
怎么收敛、send 里怎么接,见[写 send](/zh/how-to/write-send)。
|
|
103
103
|
|
|
104
104
|
## send 函数
|
|
105
105
|
|
|
@@ -119,7 +119,7 @@ interface Agent {
|
|
|
119
119
|
`send` 是唯一要实现的函数。它的签名里只有三个类型,分开看。
|
|
120
120
|
|
|
121
121
|
<Note>
|
|
122
|
-
这里的 `setup` / `teardown` 是 Agent 自己"怎么连自己"的私事(装 CLI、写鉴权配置)。按实验变化的环境准备(装某个实验专属的二进制、预热、跨 attempt 保存状态)不写在 Agent 上,挂在 `sandbox` 字段那个 Sandbox spec 自己的 `.setup()` / `.teardown()` 链式方法上,见 [沙箱 provider · 环境钩子](/zh/
|
|
122
|
+
这里的 `setup` / `teardown` 是 Agent 自己"怎么连自己"的私事(装 CLI、写鉴权配置)。按实验变化的环境准备(装某个实验专属的二进制、预热、跨 attempt 保存状态)不写在 Agent 上,挂在 `sandbox` 字段那个 Sandbox spec 自己的 `.setup()` / `.teardown()` 链式方法上,见 [沙箱 provider · 环境钩子](/zh/how-to/sandbox-providers#环境钩子)。
|
|
123
123
|
</Note>
|
|
124
124
|
|
|
125
125
|
### 传入:`TurnInput`
|
|
@@ -232,7 +232,7 @@ interface AgentSession {
|
|
|
232
232
|
|
|
233
233
|
Runner 为 Agent 的 `setup`、每次 `send` 和 `teardown` 分别绑定 lifecycle scope。Adapter 只报告当前回调内部的 progress/diagnostic,不能传 phase、颜色或输出流。`progress` 不落盘;diagnostic 会进入 Attempt 的 `result.json`。无法继续时抛错,由 runner 保存结构化 error 并把 Attempt 标为 `errored`。
|
|
234
234
|
|
|
235
|
-
`ctx` 里没有要你检查的标志位。三个档位字段都是"透传"语义:`model`、`flags` 由 experiment 声明、运行器原样递过来,Adapter 只负责随请求转发给应用,不解释它们的含义;`telemetry` 仅在配置了 OTel 接入时出现,`send` 里只需要把 `headers` spread 进请求头——接收端点在 `defineConfig` 里固定、由应用启动时指向,不从这里传,见[OTel 接入](/zh/
|
|
235
|
+
`ctx` 里没有要你检查的标志位。三个档位字段都是"透传"语义:`model`、`flags` 由 experiment 声明、运行器原样递过来,Adapter 只负责随请求转发给应用,不解释它们的含义;`telemetry` 仅在配置了 OTel 接入时出现,`send` 里只需要把 `headers` spread 进请求头——接收端点在 `defineConfig` 里固定、由应用启动时指向,不从这里传,见[OTel 接入](/zh/how-to/connect-otel)。`experimentId` 是路径推导出的稳定标识,典型用途是在 Sandbox 的环境钩子里按实验隔离跨 attempt 的状态(缓存目录名、沙箱快照 tag 按它分区),见 [沙箱 provider · 环境钩子](/zh/how-to/sandbox-providers#环境钩子)。
|
|
236
236
|
|
|
237
237
|
`session` 是本条会话线的自有状态,[NiceEval](https://niceeval.com/) 对它只承诺一件事:**同一条会话线的每次 `send` 拿到同一个 `ctx.session`,新会话线(eval 的第一轮,或 `t.newSession()` 之后)拿到一个全新的。** 会话续接(`id`/`capture`、`history`)和 HITL 停轮现场(`hold`/`take`)的存取器都在它上面,"第一轮"就是新会话线的自然形态——`id` 是 `undefined`、`history.get()` 是空数组,没有要判断的分支;`state` 是这些存取器之外的逃生舱,框架从不往里写数据。
|
|
238
238
|
|
|
@@ -257,7 +257,7 @@ interface Turn {
|
|
|
257
257
|
]
|
|
258
258
|
```
|
|
259
259
|
|
|
260
|
-
对象统共十种类型(`message`、`action.*`、`input.requested`……完整清单见[事件流参考](/zh/reference/events))。断言读的就是这个数组:`t.calledTool("get_weather")` 数 `action.called`,`t.reply` 取最后一条 assistant `message`。注意 `send` 每次只返回**本轮**的数组——跨轮拼成整条会话线是运行器的事,见下一节。多数情况下你也不手写这些对象:官方转换器的返回值就是一个填好 `events`、`usage`、`status` 的完整 `Turn`,怎么选转换器见[写 send](/zh/
|
|
260
|
+
对象统共十种类型(`message`、`action.*`、`input.requested`……完整清单见[事件流参考](/zh/reference/events))。断言读的就是这个数组:`t.calledTool("get_weather")` 数 `action.called`,`t.reply` 取最后一条 assistant `message`。注意 `send` 每次只返回**本轮**的数组——跨轮拼成整条会话线是运行器的事,见下一节。多数情况下你也不手写这些对象:官方转换器的返回值就是一个填好 `events`、`usage`、`status` 的完整 `Turn`,怎么选转换器见[写 send](/zh/how-to/write-send)。
|
|
261
261
|
|
|
262
262
|
`data` 不是"随便放点什么"的口袋,它只有一条规则:**要什么,由 eval 在 send 上用 schema 声明;声明了才有 data,拿到手就是声明的类型。**
|
|
263
263
|
|
|
@@ -302,8 +302,8 @@ turn.data.amount; // 类型是 number——不是 unknown,不用手动收窄
|
|
|
302
302
|
|
|
303
303
|
## 相关阅读
|
|
304
304
|
|
|
305
|
-
- [写 send](/zh/
|
|
306
|
-
- [接入你的 Agent](/zh/
|
|
307
|
-
- [Drive](/zh/
|
|
308
|
-
- [Assert](/zh/
|
|
309
|
-
- [架构概览](/zh/
|
|
305
|
+
- [写 send](/zh/how-to/write-send) — 实操教程:从发一条消息到完整接入,七步递进,每步解锁一组断言。
|
|
306
|
+
- [接入你的 Agent](/zh/how-to/connect-your-agent) — 接入全景:最小接入、参数通道与增量地图。
|
|
307
|
+
- [Drive](/zh/explanation/drive) — eval 侧视角:`t.send()`、`t.newSession()` 与 HITL 怎么用。
|
|
308
|
+
- [Assert](/zh/explanation/assert) — 标准事件流驱动的完整断言词汇。
|
|
309
|
+
- [架构概览](/zh/explanation/overview) — 四层架构和边界。
|
|
@@ -4,7 +4,7 @@ sidebarTitle: "断言"
|
|
|
4
4
|
description: "NiceEval 的断言词汇——值断言、作用域断言、test-as-scoring 和效率断言——以及 gate / soft 严重度和判定 verdict 的规则。"
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
断言把 agent 在一次 eval 里做的一切——每条消息、每次工具调用、每处文件改动、每一分 token——折叠成一个可解释的结果。[NiceEval](https://niceeval.com/) 提供四种互补的断言机制:有的立即检查一个值,有的在整轮跑完后评估整次运行,有的在沙箱里跑测试,有的衡量效率。四种都产出同一种 `Assertion` 类型,都进同一套判定规则。第五种机制——让语言模型评判开放式质量——见 [Judge](/zh/
|
|
7
|
+
断言把 agent 在一次 eval 里做的一切——每条消息、每次工具调用、每处文件改动、每一分 token——折叠成一个可解释的结果。[NiceEval](https://niceeval.com/) 提供四种互补的断言机制:有的立即检查一个值,有的在整轮跑完后评估整次运行,有的在沙箱里跑测试,有的衡量效率。四种都产出同一种 `Assertion` 类型,都进同一套判定规则。第五种机制——让语言模型评判开放式质量——见 [Judge](/zh/explanation/judge)。
|
|
8
8
|
|
|
9
9
|
## 四种断言机制
|
|
10
10
|
|
|
@@ -119,7 +119,7 @@ t.check(turn.data, satisfies((d) => d.total > 0, "total is positive"));
|
|
|
119
119
|
|
|
120
120
|
## 2. 作用域断言
|
|
121
121
|
|
|
122
|
-
作用域断言在 `test(t)` 里注册,但在函数返回**之后**才对累积完的完整轮次数据评估。它们读的是 `t.send()` 产出的标准事件流(见 [Drive](/zh/
|
|
122
|
+
作用域断言在 `test(t)` 里注册,但在函数返回**之后**才对累积完的完整轮次数据评估。它们读的是 `t.send()` 产出的标准事件流(见 [Drive](/zh/explanation/drive))及其派生事实——所以只要你的 adapter 产出正确的事件,这些断言对任何 agent 都一样好用。
|
|
123
123
|
|
|
124
124
|
<Warning>
|
|
125
125
|
作用域断言只有在 agent 声明了对应能力时才出现在 `t` 上。agent 没声明 `toolObservability: true` 时调用 `t.calledTool()` 是编译期报错。
|
|
@@ -181,7 +181,7 @@ t.sandbox.noFailedShellCommands();
|
|
|
181
181
|
|
|
182
182
|
`t.sandbox.diff` 是可查询对象:`t.sandbox.diff.get("src/Button.tsx")` 返回文件改动后的内容;`t.sandbox.diff.isEmpty()` 检查有没有文件变化;`t.sandbox.diff.matches(re)` 和 `t.sandbox.notInDiff(re)` 对完整 diff 文本跑正则。
|
|
183
183
|
|
|
184
|
-
作用域断言到处遵守同一条规则:**接收者决定作用域,不是断言名字决定作用域。** `t.*` 聚合这次 eval run 的全部轮次(含 `t.newSession()` 开的额外 session);`session.*`(`t.newSession()` 的返回值)只看这一条 session;`turn.*`(`t.send()` 的返回值)只看这一轮自己。同一套词汇,不同接收者——各接收者是什么见 [Drive](/zh/
|
|
184
|
+
作用域断言到处遵守同一条规则:**接收者决定作用域,不是断言名字决定作用域。** `t.*` 聚合这次 eval run 的全部轮次(含 `t.newSession()` 开的额外 session);`session.*`(`t.newSession()` 的返回值)只看这一条 session;`turn.*`(`t.send()` 的返回值)只看这一轮自己。同一套词汇,不同接收者——各接收者是什么见 [Drive](/zh/explanation/drive)。
|
|
185
185
|
|
|
186
186
|
## 3. Test-as-scoring(沙箱型 eval)
|
|
187
187
|
|
|
@@ -238,7 +238,7 @@ t.check(t.reply, jsonValid());
|
|
|
238
238
|
|
|
239
239
|
## 相关阅读
|
|
240
240
|
|
|
241
|
-
- [Drive](/zh/
|
|
242
|
-
- [Judge](/zh/
|
|
243
|
-
- [写 send](/zh/
|
|
244
|
-
- [Evals](/zh/
|
|
241
|
+
- [Drive](/zh/explanation/drive) — `t.send()`、`t.newSession()` 和 HITL:这些断言读的 Turn 数据是怎么产出的。
|
|
242
|
+
- [Judge](/zh/explanation/judge) — 第五种评分机制,评无法写成固定规则的开放式质量。
|
|
243
|
+
- [写 send](/zh/how-to/write-send) — 标准事件流如何产出,作用域断言依赖它什么。
|
|
244
|
+
- [Evals](/zh/explanation/evals) — 断言如何折进 eval 生命周期和 verdict 类型。
|
|
@@ -4,7 +4,7 @@ sidebarTitle: "驱动"
|
|
|
4
4
|
description: "t.send() 和它返回的 Turn、t.sendFile()、多轮对话、t.newSession(),以及 respond() 处理的人工介入(HITL)。"
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
在断言或 judge 之前,先要让 agent 动起来。**Drive** 是 `test(t)` 里发送输入、拿到结果的那部分——`t.send()`、`t.sendFile()`、`t.newSession()`,以及 HITL 的 `t.respond()` / `t.respondAll()`。驱动产出的都是一个 **Turn**,[NiceEval](https://niceeval.com/) 里的所有断言和 judge 都从 Turn 的数据上读,具体看 [Assert](/zh/
|
|
7
|
+
在断言或 judge 之前,先要让 agent 动起来。**Drive** 是 `test(t)` 里发送输入、拿到结果的那部分——`t.send()`、`t.sendFile()`、`t.newSession()`,以及 HITL 的 `t.respond()` / `t.respondAll()`。驱动产出的都是一个 **Turn**,[NiceEval](https://niceeval.com/) 里的所有断言和 judge 都从 Turn 的数据上读,具体看 [Assert](/zh/explanation/assert) 和 [Judge](/zh/explanation/judge)。
|
|
8
8
|
|
|
9
9
|
## `t.send()` 和它返回的 `Turn`
|
|
10
10
|
|
|
@@ -61,7 +61,7 @@ await t.send("好,发出去。");
|
|
|
61
61
|
t.calledTool("send_email");
|
|
62
62
|
```
|
|
63
63
|
|
|
64
|
-
多轮 `t.send()` 能不能真的续上上文,取决于 Adapter 的 `send` 是否接了 `ctx.session` 的会话续接存取器(`history()` 或 `id` + `capture()`)——没接时每轮各是一场新对话。怎么接见 [Adapter](/zh/
|
|
64
|
+
多轮 `t.send()` 能不能真的续上上文,取决于 Adapter 的 `send` 是否接了 `ctx.session` 的会话续接存取器(`history()` 或 `id` + `capture()`)——没接时每轮各是一场新对话。怎么接见 [Adapter](/zh/explanation/adapter) 与[写 send](/zh/how-to/write-send)。
|
|
65
65
|
|
|
66
66
|
## 独立会话 —— `t.newSession()`
|
|
67
67
|
|
|
@@ -83,7 +83,7 @@ t.check(fresh.reply, satisfies((r) => !r.includes("小明"), "没有记忆泄漏
|
|
|
83
83
|
|
|
84
84
|
## 人工介入(HITL)
|
|
85
85
|
|
|
86
|
-
有些 agent 会在一轮执行中间停下来,等审批或缺失信息,而不是直接跑完。这时这一轮以 `status: "waiting"` 结束,并带一条或多条 `input.requested` 事件说明在等什么。完整的心智模型(握手时序、Adapter 侧义务、rejected 语义)见 [HITL](/zh/
|
|
86
|
+
有些 agent 会在一轮执行中间停下来,等审批或缺失信息,而不是直接跑完。这时这一轮以 `status: "waiting"` 结束,并带一条或多条 `input.requested` 事件说明在等什么。完整的心智模型(握手时序、Adapter 侧义务、rejected 语义)见 [HITL](/zh/explanation/hitl),这里讲 eval 侧怎么用。
|
|
87
87
|
|
|
88
88
|
```ts
|
|
89
89
|
const draft = await t.send("拟一封跟进邮件,但先别发,等我确认。");
|
|
@@ -98,7 +98,7 @@ await t.respond({ request, optionId: "approve" });
|
|
|
98
98
|
t.calledTool("send_email");
|
|
99
99
|
```
|
|
100
100
|
|
|
101
|
-
`t.requireInputRequest(filter)` 把一个待处理的 HITL 请求变成可检查、可回应的具体值——如果匹配到 0 个或超过 1 个待处理请求就会抛出,所以尽量把能填的 filter 字段都填上(`id` / `prompt` / `display` / `action` / `optionIds` / `input`)来消歧。`t.respond(...)` 回答它并发出下一轮;每个参数是一条回答:字符串按待处理请求的顺序对位,`{ request, optionId }` 对象形式显式指名(多个请求并停时用它)。在底层它只是又一次普通的 `send`:回答文本进 `input.text`,同时以结构化形式逐条进 `input.responses`——命中请求选项的回答带 `{ requestId, optionId }`,自由文本回答带 `{ requestId, text }`,adapter 不用解析文本,按 `requestId` 就能对上"哪个回答给哪个请求"。每种回答到 adapter 长什么样,见[不同回答的入参](/zh/
|
|
101
|
+
`t.requireInputRequest(filter)` 把一个待处理的 HITL 请求变成可检查、可回应的具体值——如果匹配到 0 个或超过 1 个待处理请求就会抛出,所以尽量把能填的 filter 字段都填上(`id` / `prompt` / `display` / `action` / `optionIds` / `input`)来消歧。`t.respond(...)` 回答它并发出下一轮;每个参数是一条回答:字符串按待处理请求的顺序对位,`{ request, optionId }` 对象形式显式指名(多个请求并停时用它)。在底层它只是又一次普通的 `send`:回答文本进 `input.text`,同时以结构化形式逐条进 `input.responses`——命中请求选项的回答带 `{ requestId, optionId }`,自由文本回答带 `{ requestId, text }`,adapter 不用解析文本,按 `requestId` 就能对上"哪个回答给哪个请求"。每种回答到 adapter 长什么样,见[不同回答的入参](/zh/explanation/adapter#不同回答的入参)。
|
|
102
102
|
|
|
103
103
|
如果当前轮有多个同类待处理请求、都该给同一个答案(比如逐个批准一批文件改动),用 `t.respondAll(optionId)` 一次性处理,不用挨个解。`optionId` 会先对每条待处理请求校验——不在请求的 `options` 里就直接抛错,打错的字不会被静默当成别的答案发出去:
|
|
104
104
|
|
|
@@ -112,7 +112,7 @@ t.succeeded();
|
|
|
112
112
|
|
|
113
113
|
## 相关阅读
|
|
114
114
|
|
|
115
|
-
- [HITL](/zh/
|
|
116
|
-
- [Assert](/zh/
|
|
117
|
-
- [Judge](/zh/
|
|
118
|
-
- [Adapter](/zh/
|
|
115
|
+
- [HITL](/zh/explanation/hitl) — 停轮等人的完整概念:握手时序与两侧义务。
|
|
116
|
+
- [Assert](/zh/explanation/assert) — 从 `Turn.events` 和 `Turn.data` 上读的断言词汇。
|
|
117
|
+
- [Judge](/zh/explanation/judge) — `t.judge` / `session.judge` / `turn.judge` 各自默认评什么材料。
|
|
118
|
+
- [Adapter](/zh/explanation/adapter) — 能力从哪来:什么解锁 `t.newSession()`、HITL 和工具相关断言。
|
|
@@ -89,7 +89,7 @@ npx niceeval exp local weather/brooklyn
|
|
|
89
89
|
|
|
90
90
|
## gate 与 soft
|
|
91
91
|
|
|
92
|
-
`gate` 是硬门槛,失败会让 eval 失败;`soft` 参与打分,但不一定让 eval 失败。完整规则见 [Assert](/zh/
|
|
92
|
+
`gate` 是硬门槛,失败会让 eval 失败;`soft` 参与打分,但不一定让 eval 失败。完整规则见 [Assert](/zh/explanation/assert)。
|
|
93
93
|
|
|
94
94
|
## `*.eval.ts` 约定
|
|
95
95
|
|
|
@@ -117,9 +117,9 @@ export default rows.map((row) =>
|
|
|
117
117
|
);
|
|
118
118
|
```
|
|
119
119
|
|
|
120
|
-
生成 ID 类似 `sql/0000`、`sql/0001`。详见 [数据驱动测试](/zh/
|
|
120
|
+
生成 ID 类似 `sql/0000`、`sql/0001`。详见 [数据驱动测试](/zh/how-to/dataset-fanout)。
|
|
121
121
|
|
|
122
122
|
## 相关阅读
|
|
123
123
|
|
|
124
|
-
- [实验](/zh/
|
|
125
|
-
- [Assert](/zh/
|
|
124
|
+
- [实验](/zh/explanation/experiment) — 另一半:评谁、怎么跑;为什么和 eval 分开(晚绑定)。
|
|
125
|
+
- [Assert](/zh/explanation/assert) — gate 与 soft 的完整判定规则。
|
|
@@ -22,18 +22,18 @@ export default defineExperiment({
|
|
|
22
22
|
```
|
|
23
23
|
|
|
24
24
|
- `agent`:评谁。放的是已经配置好的实例——被测系统的 URL、鉴权传给 Adapter 工厂,不进 experiment 的其它字段。
|
|
25
|
-
- `model` / `flags`:透传语义。[NiceEval](https://niceeval.com/) 不解释它们的含义,原样经 `ctx` 递给 Adapter,由 Adapter 随请求转发、应用按需切换——这正是 [Tier](/zh/
|
|
26
|
-
- `runs`、`budget`、并发、`sandbox` 等运行参数:怎么跑、跑多少。完整字段见[写实验](/zh/
|
|
25
|
+
- `model` / `flags`:透传语义。[NiceEval](https://niceeval.com/) 不解释它们的含义,原样经 `ctx` 递给 Adapter,由 Adapter 随请求转发、应用按需切换——这正是 [Tier](/zh/explanation/tier) 里模型对比(Tier 1)和 feature A/B(Tier 3)的通道。
|
|
26
|
+
- `runs`、`budget`、并发、`sandbox` 等运行参数:怎么跑、跑多少。完整字段见[写实验](/zh/how-to/write-experiment)。
|
|
27
27
|
|
|
28
|
-
Experiment 是纯配置数据,没有 `setup` / `teardown` 这类生命周期字段。要按实验准备环境(装二进制、预热、跨 attempt 存取状态),挂在 `sandbox` 字段的 spec 上——`dockerSandbox()` 等工厂返回的对象可以链 `.setup()` / `.teardown()`,见 [沙箱 provider · 环境钩子](/zh/
|
|
28
|
+
Experiment 是纯配置数据,没有 `setup` / `teardown` 这类生命周期字段。要按实验准备环境(装二进制、预热、跨 attempt 存取状态),挂在 `sandbox` 字段的 spec 上——`dockerSandbox()` 等工厂返回的对象可以链 `.setup()` / `.teardown()`,见 [沙箱 provider · 环境钩子](/zh/how-to/sandbox-providers#环境钩子)。
|
|
29
29
|
|
|
30
30
|
## 矩阵对比
|
|
31
31
|
|
|
32
|
-
要比较的每个变体写一个 experiment 文件:两个模型就是两个文件,只差 `model` 一行;prompt A/B 就是只差一个参数。同一批 eval 在多个 experiment 下各跑一遍,pass rate、成本、延迟就有了可比的横截面——`niceeval view` 里叠着看。适合比什么、结果怎么读,见[实验矩阵](/zh/
|
|
32
|
+
要比较的每个变体写一个 experiment 文件:两个模型就是两个文件,只差 `model` 一行;prompt A/B 就是只差一个参数。同一批 eval 在多个 experiment 下各跑一遍,pass rate、成本、延迟就有了可比的横截面——`niceeval view` 里叠着看。适合比什么、结果怎么读,见[实验矩阵](/zh/how-to/experiments)。
|
|
33
33
|
|
|
34
34
|
## 相关阅读
|
|
35
35
|
|
|
36
|
-
- [写实验](/zh/
|
|
37
|
-
- [实验矩阵](/zh/
|
|
38
|
-
- [评估](/zh/
|
|
39
|
-
- [Tier](/zh/
|
|
36
|
+
- [写实验](/zh/how-to/write-experiment) — `defineExperiment` 的完整字段:runs、预算、并发与 sandbox。
|
|
37
|
+
- [实验矩阵](/zh/how-to/experiments) — 跨 agent / model / flags 的对比怎么组织、怎么读结果。
|
|
38
|
+
- [评估](/zh/explanation/evals) — 另一半:eval 是什么、生命周期与 verdict。
|
|
39
|
+
- [Tier](/zh/explanation/tier) — `model` / `flags` 各在哪一档生效。
|
|
@@ -29,7 +29,7 @@ HITL(human-in-the-loop,人工介入)指 agent 在执行中间停下来,
|
|
|
29
29
|
两个容易想歪的地方:
|
|
30
30
|
|
|
31
31
|
- **回答轮不是新对话。** 它发生在同一条会话线上,`ctx.session` 还是同一个——Adapter 靠它找回上一轮挂起的现场。
|
|
32
|
-
- **回答不用从文本里猜。** `input.responses` 逐请求带着 `{ requestId, optionId }`(自由文本回答则是 `{ requestId, text }`),命中选项的 `optionId` 在 eval 侧已校验过存在,打错的字直接抛错而不是静默传给应用。每种回答到 Adapter 长什么样,见[不同回答的入参](/zh/
|
|
32
|
+
- **回答不用从文本里猜。** `input.responses` 逐请求带着 `{ requestId, optionId }`(自由文本回答则是 `{ requestId, text }`),命中选项的 `optionId` 在 eval 侧已校验过存在,打错的字直接抛错而不是静默传给应用。每种回答到 Adapter 长什么样,见[不同回答的入参](/zh/explanation/adapter#不同回答的入参)。
|
|
33
33
|
|
|
34
34
|
## eval 侧:三个动作
|
|
35
35
|
|
|
@@ -47,7 +47,7 @@ t.calledTool("send_email", { status: "completed" });
|
|
|
47
47
|
- `t.requireInputRequest(filter)` 从待处理请求里精确取一个(按 `id` / `prompt` / `action` / `optionIds` 等字段匹配),匹配到 0 个或超过 1 个都会抛,多个请求并停时靠它消歧。
|
|
48
48
|
- `t.respond(...)` 回答并发出下一轮;同类请求要给同一个答案时(比如逐个批准一批改动),`t.respondAll(optionId)` 一次处理完。
|
|
49
49
|
|
|
50
|
-
批准和拒绝是同一扇门的两个分支,各写一条 eval 才算评完:批准后该发生的发生了,拒绝后该发生的没发生。逐个 API 的完整用法见 [Drive](/zh/
|
|
50
|
+
批准和拒绝是同一扇门的两个分支,各写一条 eval 才算评完:批准后该发生的发生了,拒绝后该发生的没发生。逐个 API 的完整用法见 [Drive](/zh/explanation/drive#人工介入-hitl)。
|
|
51
51
|
|
|
52
52
|
## Adapter 侧:两条义务,一次续跑
|
|
53
53
|
|
|
@@ -57,9 +57,9 @@ HITL 对 Adapter 的全部要求就三件事——前两件发生在停下的那
|
|
|
57
57
|
2. **每个待回答的问题吐一条 `input.requested`**,`id` 稳定、字段尽量填全——eval 侧的检查和对位全靠它们;
|
|
58
58
|
3. **下一次 `send` 先交裁决、再续跑**:从 `input.responses` 按 `requestId` 把裁决交回应用(不要按顺序猜),然后接着上一轮挂起的地方继续,而不是重发请求。
|
|
59
59
|
|
|
60
|
-
"挂起的现场"(比如读了一半的 SSE 流)存在本会话线的 `ctx.session` 上——停轮时 `ctx.session.hold(现场)`,回答轮 `ctx.session.take()` 取回,取到即清除。怎么和流式驱动拼起来,见[写 send](/zh/
|
|
60
|
+
"挂起的现场"(比如读了一半的 SSE 流)存在本会话线的 `ctx.session` 上——停轮时 `ctx.session.hold(现场)`,回答轮 `ctx.session.take()` 取回,取到即清除。怎么和流式驱动拼起来,见[写 send](/zh/how-to/write-send#第五步:hitl) 第五步的完整骨架。
|
|
61
61
|
|
|
62
|
-
和 [NiceEval](https://niceeval.com/) 的其它能力一样,HITL 没有布尔声明:**做到了就是有**。send 返回过 `"waiting"` 并吐了 `input.requested`,`t.respond` 就能工作;没做到,eval 会在第一个 `parked()` 或 `requireInputRequest()` 上明确失败,而不是静默假通过。能力如何从构造中来,见 [Adapter](/zh/
|
|
62
|
+
和 [NiceEval](https://niceeval.com/) 的其它能力一样,HITL 没有布尔声明:**做到了就是有**。send 返回过 `"waiting"` 并吐了 `input.requested`,`t.respond` 就能工作;没做到,eval 会在第一个 `parked()` 或 `requireInputRequest()` 上明确失败,而不是静默假通过。能力如何从构造中来,见 [Adapter](/zh/explanation/adapter#能力从哪来:构造证明,不是问卷)。
|
|
63
63
|
|
|
64
64
|
## 拒绝不是故障
|
|
65
65
|
|
|
@@ -77,7 +77,7 @@ HITL 对 Adapter 的全部要求就三件事——前两件发生在停下的那
|
|
|
77
77
|
|
|
78
78
|
## 相关阅读
|
|
79
79
|
|
|
80
|
-
- [Drive](/zh/
|
|
81
|
-
- [Adapter](/zh/
|
|
82
|
-
- [写 send](/zh/
|
|
83
|
-
- [接入你的 Agent](/zh/
|
|
80
|
+
- [Drive](/zh/explanation/drive#人工介入-hitl) — eval 侧的完整用法:`t.parked()`、`t.requireInputRequest()`、`t.respond()` / `t.respondAll()`。
|
|
81
|
+
- [Adapter](/zh/explanation/adapter#不同回答的入参) — 回答到 Adapter 的结构化入参,四种典型形态。
|
|
82
|
+
- [写 send](/zh/how-to/write-send) — Adapter 侧实操:`ctx.session.hold` / `take` 与流式 + HITL 的完整骨架。
|
|
83
|
+
- [接入你的 Agent](/zh/how-to/connect-your-agent) — 接入全景:最小接入、参数通道与增量地图。
|
|
@@ -4,7 +4,7 @@ sidebarTitle: "评判"
|
|
|
4
4
|
description: "t.judge / session.judge / turn.judge 如何用独立裁判模型评估事实性、闭合式质量和摘要忠实度,以及模型解析优先级和严重度。"
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
judge 断言是第五种评分机制,和 [Assert](/zh/
|
|
7
|
+
judge 断言是第五种评分机制,和 [Assert](/zh/explanation/assert) 里的四种并列。用在“对不对靠规则说不清”的地方——开放式行文、语气、事实一致性、摘要质量。裁判模型和被测 agent **完全分离**,避免自评:同一个模型给自己的输出打分,天然会打得偏高。
|
|
8
8
|
|
|
9
9
|
```ts
|
|
10
10
|
t.judge.autoevals.factuality(reference).atLeast(0.8); // 与参考文本的事实一致性
|
|
@@ -113,7 +113,7 @@ defineConfig({
|
|
|
113
113
|
|
|
114
114
|
## 严重度:judge 默认 soft
|
|
115
115
|
|
|
116
|
-
judge 调用和其它断言一样是评分函数,遵守 [Assert · gate 与 soft 严重度](/zh/
|
|
116
|
+
judge 调用和其它断言一样是评分函数,遵守 [Assert · gate 与 soft 严重度](/zh/explanation/assert#gate-与-soft-严重度) 同一套机制——只是**默认值**和大多数值匹配器不同:
|
|
117
117
|
|
|
118
118
|
```ts
|
|
119
119
|
t.judge.autoevals.closedQA("语气是否礼貌?"); // 不带阈值 → soft,纯记分,永不让 eval 失败
|
|
@@ -125,6 +125,6 @@ t.judge.autoevals.closedQA("语气是否礼貌?").gate(); // 提升为 gat
|
|
|
125
125
|
|
|
126
126
|
## 相关阅读
|
|
127
127
|
|
|
128
|
-
- [Assert](/zh/
|
|
129
|
-
- [Drive](/zh/
|
|
130
|
-
- [Evals](/zh/
|
|
128
|
+
- [Assert](/zh/explanation/assert) — gate / soft 严重度的完整规则,以及 judge 分数最终折进的判定规则。
|
|
129
|
+
- [Drive](/zh/explanation/drive) — `t.send()`、`t.newSession()`,以及 `t.judge` / `session.judge` / `turn.judge` 各自挂在哪个 handle 上。
|
|
130
|
+
- [Evals](/zh/explanation/evals) — judge 分数如何折进 eval 生命周期和 verdict 类型。
|
|
@@ -102,8 +102,8 @@ Subject under test / Sandbox Provider
|
|
|
102
102
|
|
|
103
103
|
## 相关阅读
|
|
104
104
|
|
|
105
|
-
- [Evals](/zh/
|
|
106
|
-
- [Adapter](/zh/
|
|
107
|
-
- [Drive](/zh/
|
|
108
|
-
- [Assert](/zh/
|
|
109
|
-
- [Judge](/zh/
|
|
105
|
+
- [Evals](/zh/explanation/evals) — eval 是什么,以及生命周期细节。
|
|
106
|
+
- [Adapter](/zh/explanation/adapter) — 如何写 adapter,并在 experiment 中引用它。
|
|
107
|
+
- [Drive](/zh/explanation/drive) — `t.send()`、session 与 HITL:如何产出断言要读的 `Turn` 数据。
|
|
108
|
+
- [Assert](/zh/explanation/assert) — 断言词汇和判定规则。
|
|
109
|
+
- [Judge](/zh/explanation/judge) — LLM-as-judge,评开放式质量。
|
|
@@ -20,7 +20,7 @@ description: "按「Adapter 接到哪里、额外拿到什么观测数据」接
|
|
|
20
20
|
|
|
21
21
|
还是同一个 `send`、同一套事件映射,只是让应用把 OTel span 也发给 [NiceEval](https://niceeval.com/) 一份。应用已埋点(AI SDK telemetry、LangGraph、OpenLLMetry / OpenInference、自埋 gen_ai)就零改动;没埋点补的是一段通用 OTel 初始化——这属于可观测性建设,不是为 eval 定制的改造。
|
|
22
22
|
|
|
23
|
-
这一档买到的是**观测**:`niceeval view` 的调用瀑布图——应用内部每次模型调用、每次工具执行、各自的耗时与 token,按轮铺成时间线。断言不受影响:span 只进瀑布图,不进事件流、不喂断言。走法见[OTel 接入](/zh/
|
|
23
|
+
这一档买到的是**观测**:`niceeval view` 的调用瀑布图——应用内部每次模型调用、每次工具执行、各自的耗时与 token,按轮铺成时间线。断言不受影响:span 只进瀑布图,不进事件流、不喂断言。走法见[OTel 接入](/zh/how-to/connect-otel)。
|
|
24
24
|
|
|
25
25
|
## Tier 3:侵入改造 + experiment flags
|
|
26
26
|
|
|
@@ -34,11 +34,11 @@ description: "按「Adapter 接到哪里、额外拿到什么观测数据」接
|
|
|
34
34
|
|
|
35
35
|
## 怎么升级
|
|
36
36
|
|
|
37
|
-
三级递进不互斥:先用 Tier 1 跑通基线和模型对比;要调用瀑布图,升 Tier 2;要对照应用内部变体,再升 Tier 3。每次升级都只是给 Adapter 或应用加东西,experiment 侧怎么组织对比见[实验](/zh/
|
|
37
|
+
三级递进不互斥:先用 Tier 1 跑通基线和模型对比;要调用瀑布图,升 Tier 2;要对照应用内部变体,再升 Tier 3。每次升级都只是给 Adapter 或应用加东西,experiment 侧怎么组织对比见[实验](/zh/explanation/experiment)。
|
|
38
38
|
|
|
39
39
|
## 相关阅读
|
|
40
40
|
|
|
41
|
-
- [接入你的 Agent](/zh/
|
|
42
|
-
- [Adapter](/zh/
|
|
43
|
-
- [OTel 接入](/zh/
|
|
44
|
-
- [实验](/zh/
|
|
41
|
+
- [接入你的 Agent](/zh/how-to/connect-your-agent) — 接入全景:最小接入与参数通道。
|
|
42
|
+
- [Adapter](/zh/explanation/adapter) — 契约本身:`send` 传入什么返回什么,`ctx.model` / `ctx.telemetry` / `ctx.flags` 按档位出现。
|
|
43
|
+
- [OTel 接入](/zh/how-to/connect-otel) — Tier 2 的完整走法。
|
|
44
|
+
- [实验](/zh/explanation/experiment) — model / flags 对比在 experiment 侧怎么声明。
|
|
@@ -24,12 +24,12 @@ AI 通常按任务选择这些入口:
|
|
|
24
24
|
|
|
25
25
|
| 任务 | 随包文档 |
|
|
26
26
|
| --- | --- |
|
|
27
|
-
| 初始化项目 | `docs-site/zh/quickstart.mdx` |
|
|
28
|
-
| 编写 Eval | `docs-site/zh/
|
|
29
|
-
| 定义实验 | `docs-site/zh/
|
|
30
|
-
| 连接被测 Agent | `docs-site/zh/
|
|
31
|
-
| 配置 Sandbox | `docs-site/zh/
|
|
32
|
-
| 解释运行结果 | `docs-site/zh/
|
|
27
|
+
| 初始化项目 | `docs-site/zh/tutorials/quickstart.mdx` |
|
|
28
|
+
| 编写 Eval | `docs-site/zh/explanation/evals.mdx` |
|
|
29
|
+
| 定义实验 | `docs-site/zh/how-to/write-experiment.mdx` |
|
|
30
|
+
| 连接被测 Agent | `docs-site/zh/explanation/adapter.mdx` |
|
|
31
|
+
| 配置 Sandbox | `docs-site/zh/how-to/sandbox-agent.mdx` |
|
|
32
|
+
| 解释运行结果 | `docs-site/zh/how-to/viewing-results.mdx` |
|
|
33
33
|
|
|
34
34
|
## 用 bash 完成一次反馈闭环
|
|
35
35
|
|
|
@@ -280,4 +280,4 @@ Eval,还是实验环境。修改后用 --force 重跑对应 Eval,比较新
|
|
|
280
280
|
|
|
281
281
|
真实 Agent 的运行可能产生费用。实验阶段可以加 `--budget <美元>` 限制本轮累计成本;预算只能限制单次命令,不能替代上面的停止条件。
|
|
282
282
|
|
|
283
|
-
人与 AI 随时可以接手同一轮工作。AI 用 `niceeval show` 读取的结果,也能由人运行 `npx niceeval view` 在网页中查看。两者读取同一批 artifact;完整的输出格式、历史选择和网页操作见[查看结果](/zh/
|
|
283
|
+
人与 AI 随时可以接手同一轮工作。AI 用 `niceeval show` 读取的结果,也能由人运行 `npx niceeval view` 在网页中查看。两者读取同一批 artifact;完整的输出格式、历史选择和网页操作见[查看结果](/zh/how-to/viewing-results)。
|
|
@@ -91,7 +91,7 @@ export default rows.map((row) =>
|
|
|
91
91
|
);
|
|
92
92
|
```
|
|
93
93
|
|
|
94
|
-
生成 ID 为 `sql/0000`、`sql/0001` 等。详见 [数据驱动测试](/zh/
|
|
94
|
+
生成 ID 为 `sql/0000`、`sql/0001` 等。详见 [数据驱动测试](/zh/how-to/dataset-fanout)。
|
|
95
95
|
|
|
96
96
|
## Sandbox workspace
|
|
97
97
|
|
|
@@ -110,7 +110,7 @@ export default defineEval({
|
|
|
110
110
|
});
|
|
111
111
|
```
|
|
112
112
|
|
|
113
|
-
详见 [Fixtures](/zh/
|
|
113
|
+
详见 [Fixtures](/zh/how-to/fixtures)。
|
|
114
114
|
|
|
115
115
|
## 从 Eval 报告长步骤和诊断
|
|
116
116
|
|
|
@@ -4,11 +4,11 @@ sidebarTitle: "OTel 接入"
|
|
|
4
4
|
description: "把应用已经在发的 OTel span 也发给 NiceEval 一份,niceeval view 里就有每轮的调用瀑布图。断言不从这里来——接好 send 那一刻断言就齐了。"
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
先说清这条接入**不**改变什么:断言。`t.calledTool`、`t.maxTokens`、耗时这些判定的依据,全部来自你的 adapter 在 `send` 里返回的 `Turn`(`events` + `usage`)——接好 send 的那一刻,全套断言就齐了,和 OTel 没有关系(见[接入你的 agent](/zh/
|
|
7
|
+
先说清这条接入**不**改变什么:断言。`t.calledTool`、`t.maxTokens`、耗时这些判定的依据,全部来自你的 adapter 在 `send` 里返回的 `Turn`(`events` + `usage`)——接好 send 的那一刻,全套断言就齐了,和 OTel 没有关系(见[接入你的 agent](/zh/how-to/connect-your-agent))。
|
|
8
8
|
|
|
9
9
|
OTel 接入买到的是另一样东西:**`niceeval view` 里的调用瀑布图**。应用内部每次模型调用、每次工具执行、各自的耗时和 token,按轮铺开成一条时间线——失败的 eval 为什么失败、慢的轮次慢在哪一步,经常一眼就在瀑布图里。
|
|
10
10
|
|
|
11
|
-
如果你的应用已经在发 OTel trace——AI SDK 的 telemetry、LangGraph 的 LangSmith 导出、OpenLLMetry / OpenInference 自动埋点,或自己按 GenAI 语义埋的点——那瀑布图的数据你已经在生产了:让应用把 span 也发给 [NiceEval](https://niceeval.com/) 一份即可,应用代码一行不改,仍是无侵入(见 [Tier](/zh/
|
|
11
|
+
如果你的应用已经在发 OTel trace——AI SDK 的 telemetry、LangGraph 的 LangSmith 导出、OpenLLMetry / OpenInference 自动埋点,或自己按 GenAI 语义埋的点——那瀑布图的数据你已经在生产了:让应用把 span 也发给 [NiceEval](https://niceeval.com/) 一份即可,应用代码一行不改,仍是无侵入(见 [Tier](/zh/explanation/tier))。
|
|
12
12
|
|
|
13
13
|
## 原理(一段话)
|
|
14
14
|
|
|
@@ -197,12 +197,12 @@ export default defineAgent({
|
|
|
197
197
|
|
|
198
198
|
## 边界
|
|
199
199
|
|
|
200
|
-
- **断言相关的一切都在 send**。想断工具调用,把它映射进 `events`(官方转换器或手写映射,见[写 send](/zh/
|
|
201
|
-
- **多轮会话、HITL 不归 span 管**。span 没有"等人输入"语义,会话续接也是应用协议的事——这两样照常在 `send` 里做(会话续接见[写 send](/zh/
|
|
200
|
+
- **断言相关的一切都在 send**。想断工具调用,把它映射进 `events`(官方转换器或手写映射,见[写 send](/zh/how-to/write-send));想断 usage,`send` 返回里带上。不存在"span 里有、events 里没有,于是断言看 span"的路径。
|
|
201
|
+
- **多轮会话、HITL 不归 span 管**。span 没有"等人输入"语义,会话续接也是应用协议的事——这两样照常在 `send` 里做(会话续接见[写 send](/zh/how-to/write-send),HITL 概念见 [HITL](/zh/explanation/hitl))。
|
|
202
202
|
- **收不到 span 会有提示**。整个 run 0 span 通常是端点没接上(env 没注入、服务没重启),[NiceEval](https://niceeval.com/) 会在日志里提示;瀑布图为空,断言照常判。
|
|
203
203
|
|
|
204
204
|
## 相关阅读
|
|
205
205
|
|
|
206
|
-
- [接入你的 agent](/zh/
|
|
207
|
-
- [写 send](/zh/
|
|
206
|
+
- [接入你的 agent](/zh/how-to/connect-your-agent) —— 断言从哪来:send 的事件映射。
|
|
207
|
+
- [写 send](/zh/how-to/write-send) —— 手写 adapter 的完整教程,第六步就是本页的 adapter 侧接法。
|
|
208
208
|
- [事件流参考](/zh/reference/events) —— 断言消费的事件长什么样。
|