niceeval 0.6.1 → 0.7.0

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 (378) hide show
  1. package/INDEX.md +23 -23
  2. package/README.zh.md +6 -6
  3. package/dist/agents/types.d.ts +69 -7
  4. package/dist/context/types.d.ts +32 -12
  5. package/dist/i18n/en.d.ts +54 -0
  6. package/dist/i18n/zh-CN.d.ts +57 -3
  7. package/dist/o11y/types.d.ts +16 -2
  8. package/dist/report/aggregate.d.ts +32 -24
  9. package/dist/report/aggregate.js +158 -50
  10. package/dist/report/built-in/index.d.ts +2 -0
  11. package/dist/report/built-in/index.js +8 -0
  12. package/dist/report/components.d.ts +93 -160
  13. package/dist/report/components.js +377 -114
  14. package/dist/report/compute.d.ts +87 -81
  15. package/dist/report/compute.js +597 -417
  16. package/dist/report/flag.d.ts +32 -6
  17. package/dist/report/flag.js +92 -4
  18. package/dist/report/format.d.ts +19 -11
  19. package/dist/report/format.js +30 -13
  20. package/dist/report/index.d.ts +16 -16
  21. package/dist/report/index.js +20 -21
  22. package/dist/report/load.js +3 -2
  23. package/dist/report/locale.d.ts +57 -33
  24. package/dist/report/locale.js +122 -56
  25. package/dist/report/metrics.d.ts +23 -4
  26. package/dist/report/metrics.js +110 -25
  27. package/dist/report/primitives.d.ts +48 -15
  28. package/dist/report/primitives.js +135 -26
  29. package/dist/report/react/AttemptList.d.ts +9 -7
  30. package/dist/report/react/AttemptList.js +17 -10
  31. package/dist/report/react/DeltaTable.js +19 -18
  32. package/dist/report/react/EvalList.d.ts +4 -4
  33. package/dist/report/react/EvalList.js +0 -0
  34. package/dist/report/react/ExperimentComparison.d.ts +10 -0
  35. package/dist/report/react/ExperimentComparison.js +12 -0
  36. package/dist/report/react/ExperimentList.d.ts +4 -3
  37. package/dist/report/react/ExperimentList.js +17 -18
  38. package/dist/report/react/MetricBars.js +5 -4
  39. package/dist/report/react/MetricLine.js +12 -5
  40. package/dist/report/react/MetricMatrix.js +1 -1
  41. package/dist/report/react/MetricScatter.js +59 -28
  42. package/dist/report/react/MetricTable.js +2 -12
  43. package/dist/report/react/ScopeSummary.d.ts +10 -0
  44. package/dist/report/react/ScopeSummary.js +17 -0
  45. package/dist/report/react/Scoreboard.js +6 -6
  46. package/dist/report/react/cell.js +2 -2
  47. package/dist/report/react/chart-math.d.ts +23 -6
  48. package/dist/report/react/chart-math.js +71 -19
  49. package/dist/report/react/fixtures.d.ts +5 -9
  50. package/dist/report/react/fixtures.js +110 -147
  51. package/dist/report/react/index.d.ts +15 -5
  52. package/dist/report/react/index.js +18 -7
  53. package/dist/report/report.d.ts +137 -16
  54. package/dist/report/report.js +259 -28
  55. package/dist/report/text/faces.d.ts +17 -19
  56. package/dist/report/text/faces.js +253 -184
  57. package/dist/report/text/plot.js +1 -1
  58. package/dist/report/text/table.js +38 -7
  59. package/dist/report/tree.d.ts +90 -40
  60. package/dist/report/tree.js +252 -94
  61. package/dist/report/types.d.ts +247 -284
  62. package/dist/report/types.js +4 -3
  63. package/dist/report/web.d.ts +21 -5
  64. package/dist/report/web.js +42 -16
  65. package/dist/results/select.d.ts +38 -16
  66. package/dist/results/select.js +73 -25
  67. package/dist/results/types.d.ts +49 -14
  68. package/dist/runner/feedback/sink.d.ts +110 -0
  69. package/dist/runner/types.d.ts +513 -22
  70. package/dist/sandbox/docker.d.ts +23 -2
  71. package/dist/sandbox/e2b.d.ts +15 -1
  72. package/dist/sandbox/errors.d.ts +30 -3
  73. package/dist/sandbox/io-retry.d.ts +17 -0
  74. package/dist/sandbox/registry.d.ts +2 -0
  75. package/dist/sandbox/resolve.d.ts +18 -5
  76. package/dist/sandbox/retry.d.ts +11 -1
  77. package/dist/sandbox/types.d.ts +39 -5
  78. package/dist/sandbox/vercel.d.ts +7 -1
  79. package/dist/scoring/coverage.d.ts +30 -0
  80. package/dist/scoring/display.d.ts +21 -0
  81. package/dist/scoring/display.js +120 -0
  82. package/dist/scoring/types.d.ts +103 -20
  83. package/dist/shared/aggregate.d.ts +4 -2
  84. package/dist/shared/aggregate.js +8 -7
  85. package/dist/shared/types.d.ts +28 -0
  86. package/dist/tty-line.d.ts +0 -4
  87. package/dist/util.d.ts +23 -0
  88. package/docs-site/zh/README.md +44 -0
  89. package/docs-site/zh/examples/ai-agent-application.mdx +63 -0
  90. package/docs-site/zh/examples/coding-agent-extensions.mdx +57 -0
  91. package/docs-site/zh/examples/index.mdx +50 -0
  92. package/docs-site/zh/{concepts → explanation}/adapter.mdx +31 -13
  93. package/docs-site/zh/{concepts → explanation}/assert.mdx +7 -7
  94. package/docs-site/zh/{concepts → explanation}/drive.mdx +8 -8
  95. package/docs-site/zh/{concepts → explanation}/evals.mdx +4 -4
  96. package/docs-site/zh/{concepts → explanation}/experiment.mdx +8 -8
  97. package/docs-site/zh/{concepts → explanation}/hitl.mdx +8 -8
  98. package/docs-site/zh/{concepts → explanation}/judge.mdx +5 -5
  99. package/docs-site/zh/{concepts → explanation}/overview.mdx +11 -11
  100. package/docs-site/zh/{guides → explanation}/runner.mdx +18 -8
  101. package/docs-site/zh/{concepts → explanation}/tier.mdx +6 -6
  102. package/docs-site/zh/{guides → how-to}/agent-feedback-loop.mdx +35 -33
  103. package/docs-site/zh/{guides → how-to}/authoring.mdx +35 -2
  104. package/docs-site/zh/{guides → how-to}/ci-integration.mdx +23 -12
  105. package/docs-site/zh/{guides → how-to}/connect-otel.mdx +6 -6
  106. package/docs-site/zh/{guides → how-to}/connect-your-agent.mdx +47 -21
  107. package/docs-site/zh/{guides → how-to}/custom-reports.mdx +34 -39
  108. package/docs-site/zh/{guides → how-to}/dataset-fanout.mdx +25 -3
  109. package/docs-site/zh/{guides → how-to}/experiments.mdx +12 -5
  110. package/docs-site/zh/how-to/publish-report.mdx +105 -0
  111. package/docs-site/zh/{guides → how-to}/reporters.mdx +2 -2
  112. package/docs-site/zh/{guides → how-to}/sandbox-agent.mdx +56 -7
  113. package/docs-site/zh/how-to/sandbox-providers.mdx +350 -0
  114. package/docs-site/zh/{guides → how-to}/scoring-guide.mdx +4 -4
  115. package/docs-site/zh/{guides → how-to}/viewing-results.mdx +82 -39
  116. package/docs-site/zh/{guides → how-to}/write-experiment.mdx +6 -4
  117. package/docs-site/zh/{guides → how-to}/write-send.mdx +30 -14
  118. package/docs-site/zh/index.mdx +24 -26
  119. package/docs-site/zh/introduction.mdx +8 -8
  120. package/docs-site/zh/reference/builtin-agents.mdx +32 -5
  121. package/docs-site/zh/reference/capabilities.mdx +8 -8
  122. package/docs-site/zh/reference/cli.mdx +40 -12
  123. package/docs-site/zh/reference/define-agent.mdx +58 -5
  124. package/docs-site/zh/reference/define-config.mdx +1 -1
  125. package/docs-site/zh/reference/define-eval.mdx +42 -9
  126. package/docs-site/zh/reference/events.mdx +3 -3
  127. package/docs-site/zh/reference/expect.mdx +26 -1
  128. package/docs-site/zh/{guides → reference}/official-adapters.mdx +32 -8
  129. package/docs-site/zh/{guides → reference}/report-components.mdx +45 -33
  130. package/docs-site/zh/{guides → reference}/results-data.mdx +21 -13
  131. package/docs-site/zh/troubleshooting/debug-sandbox.mdx +57 -0
  132. package/docs-site/zh/troubleshooting/debugging.mdx +212 -0
  133. package/docs-site/zh/{quickstart.mdx → tutorials/quickstart.mdx} +5 -17
  134. package/package.json +10 -2
  135. package/src/agents/ai-sdk-otel.test.ts +1 -0
  136. package/src/agents/ai-sdk.test.ts +3 -0
  137. package/src/agents/ai-sdk.ts +3 -0
  138. package/src/agents/bub-install-spec.test.ts +34 -0
  139. package/src/agents/bub-install-spec.ts +32 -0
  140. package/src/agents/bub.ts +31 -32
  141. package/src/agents/claude-code.test.ts +130 -9
  142. package/src/agents/claude-code.ts +76 -4
  143. package/src/agents/codex.test.ts +189 -40
  144. package/src/agents/codex.ts +155 -14
  145. package/src/agents/coding-cli-versions.test.ts +15 -0
  146. package/src/agents/coding-cli-versions.ts +3 -0
  147. package/src/agents/index.ts +13 -2
  148. package/src/agents/langgraph.test.ts +204 -0
  149. package/src/agents/langgraph.ts +495 -0
  150. package/src/agents/marketplace.ts +85 -0
  151. package/src/agents/native-config.test.ts +179 -0
  152. package/src/agents/native-config.ts +267 -0
  153. package/src/agents/openai-compat.test.ts +1 -0
  154. package/src/agents/openai-compat.ts +1 -1
  155. package/src/agents/openclaw.test.ts +31 -0
  156. package/src/agents/openclaw.ts +171 -0
  157. package/src/agents/plugin-config.test.ts +1 -0
  158. package/src/agents/sdk-streams.test.ts +79 -0
  159. package/src/agents/sdk-streams.ts +55 -10
  160. package/src/agents/skills.test.ts +1 -0
  161. package/src/agents/streaming.test.ts +3 -9
  162. package/src/agents/streaming.ts +2 -2
  163. package/src/agents/types.ts +71 -8
  164. package/src/agents/ui-message-stream.test.ts +3 -0
  165. package/src/cli.ts +446 -124
  166. package/src/context/context.test.ts +51 -12
  167. package/src/context/context.ts +162 -30
  168. package/src/context/session.test.ts +2 -1
  169. package/src/context/session.ts +115 -7
  170. package/src/context/types.ts +30 -12
  171. package/src/define.test.ts +13 -8
  172. package/src/define.ts +25 -4
  173. package/src/expect/index.ts +53 -23
  174. package/src/i18n/en.ts +81 -17
  175. package/src/i18n/zh-CN.ts +80 -17
  176. package/src/o11y/cost.test.ts +1 -0
  177. package/src/o11y/execution-tree.test.ts +1 -20
  178. package/src/o11y/otlp/mappers/claude-code.test.ts +1 -0
  179. package/src/o11y/otlp/parse.test.ts +1 -0
  180. package/src/o11y/otlp/turn-otel.test.ts +1 -0
  181. package/src/o11y/parsers/bub.test.ts +1 -0
  182. package/src/o11y/parsers/claude-code.test.ts +1 -34
  183. package/src/o11y/parsers/openclaw.test.ts +154 -0
  184. package/src/o11y/parsers/openclaw.ts +310 -0
  185. package/src/o11y/prices.json +746 -311
  186. package/src/o11y/tool-names.test.ts +1 -0
  187. package/src/o11y/types.ts +16 -2
  188. package/src/report/aggregate.ts +178 -61
  189. package/src/report/built-in/index.tsx +9 -0
  190. package/src/report/components.tsx +625 -279
  191. package/src/report/compute.ts +723 -491
  192. package/src/report/dual-render.test.tsx +741 -1024
  193. package/src/report/flag.ts +104 -12
  194. package/src/report/format.ts +32 -12
  195. package/src/report/index.ts +119 -46
  196. package/src/report/load.ts +3 -2
  197. package/src/report/locale.ts +136 -65
  198. package/src/report/metrics.ts +108 -25
  199. package/src/report/primitives.tsx +196 -45
  200. package/src/report/react/AttemptList.tsx +30 -43
  201. package/src/report/react/DeltaTable.tsx +63 -45
  202. package/src/report/react/EvalList.tsx +0 -0
  203. package/src/report/react/ExperimentComparison.tsx +73 -0
  204. package/src/report/react/ExperimentList.tsx +50 -32
  205. package/src/report/react/MetricBars.tsx +5 -4
  206. package/src/report/react/MetricLine.tsx +13 -8
  207. package/src/report/react/MetricMatrix.tsx +2 -2
  208. package/src/report/react/MetricScatter.tsx +86 -34
  209. package/src/report/react/MetricTable.tsx +4 -76
  210. package/src/report/react/ScopeSummary.tsx +86 -0
  211. package/src/report/react/Scoreboard.tsx +28 -10
  212. package/src/report/react/cell.tsx +2 -2
  213. package/src/report/react/chart-math.test.ts +85 -0
  214. package/src/report/react/chart-math.ts +101 -22
  215. package/src/report/react/enhance.js +89 -5
  216. package/src/report/react/fixtures.ts +114 -154
  217. package/src/report/react/index.tsx +24 -39
  218. package/src/report/react/render.test.tsx +138 -158
  219. package/src/report/react/styles.css +243 -82
  220. package/src/report/report.test.ts +779 -841
  221. package/src/report/report.ts +423 -41
  222. package/src/report/text/faces.ts +290 -193
  223. package/src/report/text/plot.ts +1 -1
  224. package/src/report/text/table.ts +44 -7
  225. package/src/report/tree.ts +362 -104
  226. package/src/report/types.ts +261 -271
  227. package/src/report/web.ts +63 -20
  228. package/src/results/annotated-source.test.ts +62 -9
  229. package/src/results/annotated-source.ts +64 -6
  230. package/src/results/attempt-evidence.test.ts +13 -11
  231. package/src/results/attempt-evidence.ts +20 -13
  232. package/src/results/attempt-source.ts +6 -3
  233. package/src/results/copy.ts +150 -60
  234. package/src/results/host-equivalence.test.ts +34 -20
  235. package/src/results/index.ts +12 -4
  236. package/src/results/locator.test.ts +1 -22
  237. package/src/results/open.ts +15 -5
  238. package/src/results/publish.ts +149 -0
  239. package/src/results/results.test.ts +89 -54
  240. package/src/results/select.ts +104 -34
  241. package/src/results/truncate.ts +90 -0
  242. package/src/results/types.ts +43 -14
  243. package/src/results/writer.ts +31 -13
  244. package/src/runner/attempt.test.ts +138 -7
  245. package/src/runner/attempt.ts +603 -104
  246. package/src/runner/discover.test.ts +47 -0
  247. package/src/runner/discover.ts +36 -2
  248. package/src/runner/eval-source.test.ts +1 -27
  249. package/src/runner/feedback/agent.test.ts +504 -0
  250. package/src/runner/feedback/agent.ts +409 -0
  251. package/src/runner/feedback/ci.test.ts +562 -0
  252. package/src/runner/feedback/ci.ts +401 -0
  253. package/src/runner/feedback/coordinator.test.ts +317 -0
  254. package/src/runner/feedback/coordinator.ts +397 -0
  255. package/src/runner/feedback/failure.ts +40 -0
  256. package/src/runner/feedback/human.test.ts +616 -0
  257. package/src/runner/feedback/human.ts +535 -0
  258. package/src/runner/feedback/index.ts +66 -0
  259. package/src/runner/feedback/io.ts +78 -0
  260. package/src/runner/feedback/profile.test.ts +50 -0
  261. package/src/runner/feedback/profile.ts +58 -0
  262. package/src/runner/feedback/reducer.test.ts +395 -0
  263. package/src/runner/feedback/reducer.ts +260 -0
  264. package/src/runner/feedback/renderer.ts +82 -0
  265. package/src/runner/feedback/sink.ts +203 -0
  266. package/src/runner/feedback/testing.ts +106 -0
  267. package/src/runner/ledger.test.ts +230 -0
  268. package/src/runner/ledger.ts +329 -0
  269. package/src/runner/report.test.ts +128 -3
  270. package/src/runner/report.ts +33 -9
  271. package/src/runner/reporters/artifacts.ts +8 -2
  272. package/src/runner/reporters/braintrust.test.ts +8 -7
  273. package/src/runner/reporters/braintrust.ts +9 -2
  274. package/src/runner/reporters/index.ts +2 -2
  275. package/src/runner/reporters/json.test.ts +162 -0
  276. package/src/runner/reporters/json.ts +35 -8
  277. package/src/runner/reporters/shared.ts +1 -5
  278. package/src/runner/run.test.ts +760 -3
  279. package/src/runner/run.ts +243 -37
  280. package/src/runner/sandbox-prep.ts +3 -42
  281. package/src/runner/timing.ts +158 -0
  282. package/src/runner/types.ts +518 -22
  283. package/src/sandbox/checkpoint.test.ts +55 -0
  284. package/src/sandbox/checkpoint.ts +29 -8
  285. package/src/sandbox/cli-commands.ts +407 -0
  286. package/src/sandbox/docker.ts +115 -16
  287. package/src/sandbox/e2b-agent-template.test.ts +56 -0
  288. package/src/sandbox/e2b-agent-template.ts +94 -0
  289. package/src/sandbox/e2b.ts +74 -9
  290. package/src/sandbox/errors.ts +111 -4
  291. package/src/sandbox/index.ts +2 -0
  292. package/src/sandbox/io-retry.test.ts +58 -0
  293. package/src/sandbox/io-retry.ts +45 -0
  294. package/src/sandbox/keep-registry.test.ts +86 -0
  295. package/src/sandbox/keep-registry.ts +142 -0
  296. package/src/sandbox/keep.ts +178 -0
  297. package/src/sandbox/paths.test.ts +1 -0
  298. package/src/sandbox/paths.ts +19 -8
  299. package/src/sandbox/registry.ts +20 -3
  300. package/src/sandbox/resolve.ts +76 -11
  301. package/src/sandbox/retry.test.ts +70 -0
  302. package/src/sandbox/retry.ts +46 -4
  303. package/src/sandbox/types.ts +44 -6
  304. package/src/sandbox/vercel.ts +43 -20
  305. package/src/scoring/collector.ts +60 -17
  306. package/src/scoring/coverage.ts +95 -0
  307. package/src/scoring/diff.ts +81 -0
  308. package/src/scoring/display.test.ts +121 -0
  309. package/src/scoring/display.ts +133 -0
  310. package/src/scoring/evidence.test.ts +189 -0
  311. package/src/scoring/judge.test.ts +142 -0
  312. package/src/scoring/judge.ts +15 -18
  313. package/src/scoring/scoped.ts +217 -50
  314. package/src/scoring/types.ts +117 -20
  315. package/src/scoring/verdict.ts +16 -4
  316. package/src/shared/aggregate.ts +8 -6
  317. package/src/shared/types.ts +31 -0
  318. package/src/show/compose.ts +50 -67
  319. package/src/show/index.ts +127 -56
  320. package/src/show/render.ts +662 -131
  321. package/src/show/report-host.test.ts +188 -0
  322. package/src/show/report-host.ts +375 -0
  323. package/src/show/show.test.ts +320 -54
  324. package/src/tty-line.ts +8 -26
  325. package/src/util.test.ts +1 -0
  326. package/src/util.ts +41 -0
  327. package/src/view/app/App.test.tsx +69 -0
  328. package/src/view/app/App.tsx +144 -48
  329. package/src/view/app/components/AttemptModal.tsx +423 -11
  330. package/src/view/app/components/CodeView.tsx +41 -14
  331. package/src/view/app/components/CopyControls.tsx +2 -2
  332. package/src/view/app/i18n.ts +37 -17
  333. package/src/view/app/lib/attempt-route.test.ts +1 -0
  334. package/src/view/app/lib/verdict.ts +7 -9
  335. package/src/view/app/main.tsx +13 -8
  336. package/src/view/app/pages/{RunsPage.tsx → AttemptsPage.tsx} +6 -6
  337. package/src/view/app/types.ts +4 -1
  338. package/src/view/artifact-serving.test.ts +2 -1
  339. package/src/view/client-dist/app.css +1 -1
  340. package/src/view/client-dist/app.js +17 -17
  341. package/src/view/data.test.ts +10 -3
  342. package/src/view/data.ts +155 -49
  343. package/src/view/index.ts +56 -41
  344. package/src/view/server.ts +37 -15
  345. package/src/view/shared/types.ts +34 -5
  346. package/src/view/styles.css +227 -0
  347. package/src/view/view-report.test.ts +167 -62
  348. package/dist/report/built-ins/experiment-comparison.d.ts +0 -1
  349. package/dist/report/built-ins/experiment-comparison.js +0 -13
  350. package/dist/report/built-ins/index.d.ts +0 -1
  351. package/dist/report/built-ins/index.js +0 -2
  352. package/dist/report/react/GroupSummary.d.ts +0 -8
  353. package/dist/report/react/GroupSummary.js +0 -8
  354. package/dist/report/react/RunOverview.d.ts +0 -8
  355. package/dist/report/react/RunOverview.js +0 -12
  356. package/docs-site/zh/example/ai-agent-application.mdx +0 -152
  357. package/docs-site/zh/example/claude-code-codex-plugin.mdx +0 -167
  358. package/docs-site/zh/example/claude-code-codex-skill.mdx +0 -152
  359. package/docs-site/zh/example/showcase.mdx +0 -39
  360. package/docs-site/zh/guides/publish-report.mdx +0 -91
  361. package/docs-site/zh/guides/sandbox-providers.mdx +0 -102
  362. package/src/report/built-in-user-parity.test.tsx +0 -640
  363. package/src/report/built-ins/experiment-comparison.tsx +0 -19
  364. package/src/report/built-ins/index.ts +0 -2
  365. package/src/report/react/GroupSummary.tsx +0 -66
  366. package/src/report/react/RunOverview.tsx +0 -109
  367. package/src/runner/reporters/console.ts +0 -70
  368. package/src/runner/reporters/live.test.ts +0 -56
  369. package/src/runner/reporters/live.ts +0 -247
  370. package/src/runner/reporters/quiet.test.ts +0 -66
  371. package/src/runner/reporters/quiet.ts +0 -49
  372. package/src/runner/reporters/table.ts +0 -277
  373. /package/docs-site/zh/{example/tier1-ai-sdk-v7.mdx → examples/integrations/ai-sdk-v7.mdx} +0 -0
  374. /package/docs-site/zh/{example/tier1-claude-sdk.mdx → examples/integrations/claude-sdk.mdx} +0 -0
  375. /package/docs-site/zh/{example/tier1-codex-sdk.mdx → examples/integrations/codex-sdk.mdx} +0 -0
  376. /package/docs-site/zh/{example/tier1-langgraph.mdx → examples/integrations/langgraph.mdx} +0 -0
  377. /package/docs-site/zh/{example/tier1-pi-sdk.mdx → examples/integrations/pi-sdk.mdx} +0 -0
  378. /package/docs-site/zh/{guides → how-to}/fixtures.mdx +0 -0
@@ -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/concepts/judge)。
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/concepts/drive))及其派生事实——所以只要你的 adapter 产出正确的事件,这些断言对任何 agent 都一样好用。
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/concepts/drive)。
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/concepts/drive) — `t.send()`、`t.newSession()` 和 HITL:这些断言读的 Turn 数据是怎么产出的。
242
- - [Judge](/zh/concepts/judge) — 第五种评分机制,评无法写成固定规则的开放式质量。
243
- - [写 send](/zh/guides/write-send) — 标准事件流如何产出,作用域断言依赖它什么。
244
- - [Evals](/zh/concepts/evals) — 断言如何折进 eval 生命周期和 verdict 类型。
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/concepts/assert) 和 [Judge](/zh/concepts/judge)。
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/concepts/adapter) 与[写 send](/zh/guides/write-send)。
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/concepts/hitl),这里讲 eval 侧怎么用。
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/concepts/adapter#不同回答的入参)。
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/concepts/hitl) — 停轮等人的完整概念:握手时序与两侧义务。
116
- - [Assert](/zh/concepts/assert) — 从 `Turn.events` 和 `Turn.data` 上读的断言词汇。
117
- - [Judge](/zh/concepts/judge) — `t.judge` / `session.judge` / `turn.judge` 各自默认评什么材料。
118
- - [Adapter](/zh/concepts/adapter) — 能力从哪来:什么解锁 `t.newSession()`、HITL 和工具相关断言。
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/concepts/assert)。
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/guides/dataset-fanout)。
120
+ 生成 ID 类似 `sql/0000`、`sql/0001`。详见 [数据驱动测试](/zh/how-to/dataset-fanout)。
121
121
 
122
122
  ## 相关阅读
123
123
 
124
- - [实验](/zh/concepts/experiment) — 另一半:评谁、怎么跑;为什么和 eval 分开(晚绑定)。
125
- - [Assert](/zh/concepts/assert) — gate 与 soft 的完整判定规则。
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/concepts/tier) 里模型对比(Tier 1)和 feature A/B(Tier 3)的通道。
26
- - `runs`、`budget`、并发、`sandbox` 等运行参数:怎么跑、跑多少。完整字段见[写实验](/zh/guides/write-experiment)。
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()`,见 [Sandbox 后端 · 环境钩子](/zh/guides/sandbox-providers#环境钩子)。
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/guides/experiments)。
32
+ 要比较的每个变体写一个 experiment 文件:两个模型就是两个文件,只差 `model` 一行;prompt A/B 就是只差一个参数。同一批 eval 在多个 experiment 下各跑一遍,pass rate、成本、延迟就有了可比的横截面——`niceeval view` 里叠着看。适合比什么、结果怎么读,见[实验矩阵](/zh/how-to/experiments)。
33
33
 
34
34
  ## 相关阅读
35
35
 
36
- - [写实验](/zh/guides/write-experiment) — `defineExperiment` 的完整字段:runs、预算、并发与 sandbox。
37
- - [实验矩阵](/zh/guides/experiments) — 跨 agent / model / flags 的对比怎么组织、怎么读结果。
38
- - [评估](/zh/concepts/evals) — 另一半:eval 是什么、生命周期与 verdict。
39
- - [Tier](/zh/concepts/tier) — `model` / `flags` 各在哪一档生效。
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/concepts/adapter#不同回答的入参)。
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/concepts/drive#人工介入-hitl)。
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/guides/write-send#第五步:hitl) 第五步的完整骨架。
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/concepts/adapter#能力从哪来:构造证明,不是问卷)。
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/concepts/drive#人工介入-hitl) — eval 侧的完整用法:`t.parked()`、`t.requireInputRequest()`、`t.respond()` / `t.respondAll()`。
81
- - [Adapter](/zh/concepts/adapter#不同回答的入参) — 回答到 Adapter 的结构化入参,四种典型形态。
82
- - [写 send](/zh/guides/write-send) — Adapter 侧实操:`ctx.session.hold` / `take` 与流式 + HITL 的完整骨架。
83
- - [接入你的 Agent](/zh/guides/connect-your-agent) — 接入全景:最小接入、参数通道与增量地图。
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/concepts/assert) 里的四种并列。用在“对不对靠规则说不清”的地方——开放式行文、语气、事实一致性、摘要质量。裁判模型和被测 agent **完全分离**,避免自评:同一个模型给自己的输出打分,天然会打得偏高。
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/concepts/assert#gate-与-soft-严重度) 同一套机制——只是**默认值**和大多数值匹配器不同:
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/concepts/assert) — gate / soft 严重度的完整规则,以及 judge 分数最终折进的判定规则。
129
- - [Drive](/zh/concepts/drive) — `t.send()`、`t.newSession()`,以及 `t.judge` / `session.judge` / `turn.judge` 各自挂在哪个 handle 上。
130
- - [Evals](/zh/concepts/evals) — judge 分数如何折进 eval 生命周期和 verdict 类型。
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 类型。
@@ -1,10 +1,10 @@
1
1
  ---
2
2
  title: "NiceEval 架构:evals、agents 与 sandboxes"
3
3
  sidebarTitle: "概览"
4
- description: "理解 NiceEval、Adapter 和 Sandbox backend 如何配合,用统一 API 评估任意 AI agent。"
4
+ description: "理解 NiceEval、Adapter 和 Sandbox Provider 如何配合,用统一 API 评估任意 AI Agent。"
5
5
  ---
6
6
 
7
- [NiceEval](https://niceeval.com/) 的核心设计是把“评测逻辑”与“如何连接被测对象”分开。[NiceEval](https://niceeval.com/) 负责发现、调度、评分和报告;Adapter 负责调用被测系统;Sandbox backend 负责隔离文件系统。
7
+ [NiceEval](https://niceeval.com/) 的核心设计是把“评测逻辑”与“如何连接被测对象”分开。[NiceEval](https://niceeval.com/) 负责发现、调度、评分和报告;Adapter 负责调用被测系统;Sandbox Provider 负责隔离文件系统。
8
8
 
9
9
  ## 四层架构
10
10
 
@@ -15,7 +15,7 @@ NiceEval
15
15
 
16
16
  Adapter
17
17
 
18
- Subject under test / Sandbox backend
18
+ Subject under test / Sandbox Provider
19
19
  ```
20
20
 
21
21
  ## NiceEval 负责什么
@@ -53,12 +53,12 @@ Subject under test / Sandbox backend
53
53
 
54
54
  <Tabs>
55
55
  <Tab title="Docker">
56
- 本地容器后端,适合开发和 CI 中的 coding-agent eval。
56
+ 本地容器 Provider,适合开发和 CI 中的 coding-agent eval。
57
57
  </Tab>
58
58
  <Tab title="Vercel Sandbox">
59
- 云端 sandbox 后端,适合更强隔离或更大的运行资源。
59
+ 云端 Sandbox Provider,适合更强隔离或更大的运行资源。
60
60
  </Tab>
61
- <Tab title="第三方后端">
61
+ <Tab title="第三方 Provider">
62
62
  只要实现 `Sandbox` 接口,就可以接入其他沙箱服务。
63
63
  </Tab>
64
64
  </Tabs>
@@ -102,8 +102,8 @@ Subject under test / Sandbox backend
102
102
 
103
103
  ## 相关阅读
104
104
 
105
- - [Evals](/zh/concepts/evals) — eval 是什么,以及生命周期细节。
106
- - [Adapter](/zh/concepts/adapter) — 如何写 adapter,并在 experiment 中引用它。
107
- - [Drive](/zh/concepts/drive) — `t.send()`、session 与 HITL:如何产出断言要读的 `Turn` 数据。
108
- - [Assert](/zh/concepts/assert) — 断言词汇和判定规则。
109
- - [Judge](/zh/concepts/judge) — LLM-as-judge,评开放式质量。
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,评开放式质量。
@@ -42,10 +42,11 @@ npx niceeval exp local --max-concurrency 8
42
42
  ## runs 与 early-exit
43
43
 
44
44
  ```bash
45
- npx niceeval exp local fixtures/button --runs 5 --early-exit
45
+ npx niceeval exp local fixtures/button --runs 5
46
+ npx niceeval exp local fixtures/button --runs 5 --no-early-exit
46
47
  ```
47
48
 
48
- `runs` 用于测 pass rate。`early-exit` 会在某个 attempt 通过后停止同一 eval 的剩余尝试。
49
+ `runs` 用于测 pass rate。首过即停默认开启:某个 Attempt 通过后,同一 eval 的剩余 Attempt 会被停止。想拿完整的通过率分布时,用 `--no-early-exit` 关闭,让每个 eval 跑满 `runs` 次。
49
50
 
50
51
  ## 缓存
51
52
 
@@ -57,26 +58,35 @@ npx niceeval exp local fixtures/button --runs 5 --early-exit
57
58
  npx niceeval exp local --timeout 300000 --budget 5
58
59
  ```
59
60
 
60
- 超时保护单个 eval,预算保护整次运行成本。
61
+ 超时保护单个 eval,预算保护整次运行成本。NiceEval 只有在 Attempt 已经发起 Agent Turn、却连续拿不到成本数据时,才提示预算无法执行。如果 Attempt 在 `sandbox.create` 或 setup 阶段就失败,Agent 尚未运行,CLI 只显示对应的结构化执行错误,不再追加容易误导排查方向的预算警告。
61
62
 
62
63
  ## Reporter
63
64
 
64
- runner eval 完成后把结果交给 reporters:
65
+ 运行中的反馈由 `--output` 选择消费者模型;Reporter 负责把完成后的结果写到其它目的地。两者不是同一层:
66
+
67
+ ```bash
68
+ npx niceeval exp local --output human # 人:TTY dashboard + 永久错误/诊断
69
+ npx niceeval exp local --output agent # AI:稳定 envelope + locator handoff
70
+ npx niceeval exp local --output ci # CI:单一有序 stdout 事件流
71
+ ```
72
+
73
+ 省略时使用 `auto`:TTY 选择 Human,CI 环境选择 CI,其它非 TTY 选择 Agent。输出模型只改变反馈,不改变调度、判定或 artifact。
74
+
75
+ Runner 在 Eval 完成后把结果交给 Reporters:
65
76
 
66
- - console reporter 提供实时反馈。
67
77
  - JSON artifacts 用于后续分析。
68
78
  - JUnit reporter 适合 CI。
69
79
  - Braintrust reporter 把一次运行作为实验上报,跨提交比较。
70
80
 
71
- 挂载方式和 Braintrust 配置见 [Reporter 上报](./reporters)。
81
+ 挂载方式和 Braintrust 配置见 [Reporter 上报](/zh/how-to/reporters)。
72
82
 
73
83
  ## 输出目录
74
84
 
75
- 每次运行会写入该实验的结果快照目录 `.niceeval/<experiment>/<快照>/`,包括快照级 `snapshot.json`,以及每个 attempt 的 `result.json`(判决与断言)和按需生成的 `events.json`、`sources.json`、`trace.json`、`o11y.json`、`diff.json` 等拆分 artifact
85
+ 每次运行会写入该实验的结果快照目录 `.niceeval/<experiment>/<快照>/`,包括快照级 `snapshot.json`,以及每个 Attempt 的 `result.json`(判定、断言、结构化错误、diagnostics)和按需生成的 `events.json`、`sources.json`、`trace.json`、`o11y.json`、`diff.json` 等拆分 artifact。瞬时 progress 不落盘。
76
86
 
77
87
  ## 推荐调试流程
78
88
 
79
89
  1. 先跑 `npx niceeval list` 确认发现结果。
80
90
  2. 用 `npx niceeval exp <实验> <ID 前缀>` 缩小到一个 eval。
81
- 3. 失败后运行 `npx niceeval view` 查看 transcript diff
91
+ 3. 失败后复制终端里的 locator,先运行 `npx niceeval show @<locator>` 看错误或断言摘要;需要 Agent 行为时再加 `--execution`,需要文件变化时加 `--diff`。
82
92
  4. 再扩大到完整 suite 或 experiment。
@@ -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/guides/connect-otel)。
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/concepts/experiment)。
37
+ 三级递进不互斥:先用 Tier 1 跑通基线和模型对比;要调用瀑布图,升 Tier 2;要对照应用内部变体,再升 Tier 3。每次升级都只是给 Adapter 或应用加东西,experiment 侧怎么组织对比见[实验](/zh/explanation/experiment)。
38
38
 
39
39
  ## 相关阅读
40
40
 
41
- - [接入你的 Agent](/zh/guides/connect-your-agent) — 接入全景:最小接入与参数通道。
42
- - [Adapter](/zh/concepts/adapter) — 契约本身:`send` 传入什么返回什么,`ctx.model` / `ctx.telemetry` / `ctx.flags` 按档位出现。
43
- - [OTel 接入](/zh/guides/connect-otel) — Tier 2 的完整走法。
44
- - [实验](/zh/concepts/experiment) — model / flags 对比在 experiment 侧怎么声明。
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/concepts/evals.mdx` |
29
- | 定义实验 | `docs-site/zh/guides/write-experiment.mdx` |
30
- | 连接被测 Agent | `docs-site/zh/concepts/adapter.mdx` |
31
- | 配置 Sandbox | `docs-site/zh/guides/sandbox-agent.mdx` |
32
- | 解释运行结果 | `docs-site/zh/guides/viewing-results.mdx` |
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
 
@@ -38,7 +38,7 @@ AI 通常按任务选择这些入口:
38
38
  <Steps>
39
39
  <Step title="运行实验">
40
40
  ```bash
41
- npx niceeval exp local
41
+ npx niceeval exp local --output agent
42
42
  ```
43
43
 
44
44
  先读取退出码:`0` 表示所有 Eval 通过;`1` 表示至少一个 Eval 失败或出错;`2` 表示 NiceEval 自身未能完成运行。退出码决定是否继续,控制台文本用于定位原因。
@@ -59,7 +59,7 @@ AI 通常按任务选择这些入口:
59
59
 
60
60
  `--execution` 合并 AI 输出与 trace:标准事件流提供消息、thinking、tool call/result 和 Skill load;OTel 在能够关联时给同一节点补开始时间、耗时、父子关系和错误状态。没有 OTel 时步骤仍完整,只不显示时间。
61
61
 
62
- 不带证据 flag 时,`show @<id>` 是失败诊断首页。它先列出失败断言的 group、matcher、expected、received、原因和源码位置,再给执行与文件变化摘要。AI 应该先读这一页;只有需要回答“为什么产生这个值”时,才继续打开对应证据。
62
+ 不带证据 flag 时,`show @<id>` 是失败诊断首页。它先列出失败断言的 group、matcher、expected、received、原因和源码位置,再给执行、生命周期阶段耗时与文件变化摘要。AI 应该先读这一页;只有需要回答“为什么产生这个值”时,才继续打开对应证据。
63
63
 
64
64
  ```text
65
65
  $ niceeval show @1k2m9qtr
@@ -89,20 +89,16 @@ AI 通常按任务选择这些入口:
89
89
  source: evals/memory/swelancer-manager-proposals.eval.ts:40:11
90
90
 
91
91
  execution: 3 events · 0 skill loads · 0 tool calls · 1 AI messages
92
- timing: OTel spans recorded for this attempt see --execution for per-step timing.
93
- agent run ▕████████████████████▏ 41.2s
94
- ├─ inference ▕█████░░░░░░░░░░░░░░░▏ 10.1s · "布鲁克林今天大约 24°C,晴。"
95
- ├─ inference ▕░░░░░█████████░░░░░░▏ 18.3s
96
- └─ inference ▕░░░░░░░░░░░░░░██████▏ 12.4s
97
- no tool calls
92
+ timing: eval.run 40.4s · scoring.evaluate 0.5s · teardown +0.2s
98
93
 
99
94
  changes · diff unavailable
100
95
  reason: this Attempt did not produce workspace file changes
101
96
 
102
- full eval source: …/weather/brooklyn/a2/eval-source.ts
97
+ full eval source: …/weather/brooklyn/a2/sources.json
103
98
  available:
104
99
  niceeval show @1k2m9qtr --eval
105
100
  niceeval show @1k2m9qtr --execution
101
+ niceeval show @1k2m9qtr --timing
106
102
  ```
107
103
 
108
104
  `--execution` 把 AI 消息、Skill load、工具调用和工具结果排成一棵执行树。它只展示 Agent 可理解的事件;没有关联到这些事件的 SDK / runtime span 不逐行输出,只报告省略数量并保留 `trace.json` 路径。下面的 Attempt 有 OTel,所以能关联的节点同时带相对时间与耗时:
@@ -175,9 +171,10 @@ AI 通常按任务选择这些入口:
175
171
 
176
172
  | 要回答的问题 | 入口 | 输出必须包含 |
177
173
  | --- | --- | --- |
178
- | 快速判断一次 Attempt 发生了什么 | `niceeval show @<id>` | Eval 断言、执行步骤、可选 OTel 时间、diff 摘要及各块可用性 |
174
+ | 快速判断一次 Attempt 发生了什么 | `niceeval show @<id>` | Eval 断言、执行步骤、生命周期阶段耗时摘要、diff 摘要及各块可用性 |
179
175
  | Eval 实际检查了什么,哪条 gate / soft 为什么通过或失败 | `niceeval show @<id> --eval` | 运行时 Eval 源码、源码哈希、断言所在行、严重度、分数与原因 |
180
- | AI 做了什么、调用了什么、时间花在哪里 | `niceeval show @<id> --execution` | 消息、thinking、Skill load、工具调用与结果;有 OTel 时在同一节点显示时间、父子关系和错误状态 |
176
+ | AI 做了什么、调用了什么 | `niceeval show @<id> --execution` | 消息、thinking、Skill load、工具调用与结果;有 OTel 时在同一节点附时间、父子关系和错误状态 |
177
+ | 整个 Attempt 的时间花在哪里 | `niceeval show @<id> --timing` | lifecycle → hook/turn → shell → OTel 的统一时间树;出错的 Attempt 标出已知的最深失败节点 |
181
178
  | Sandbox 工作区文件变成什么 | `niceeval show @<id> --diff` | 文件摘要、增删行数、具体补丁和原始 diff 路径;无文件工作区时明确 unavailable |
182
179
  </Step>
183
180
  <Step title="提出假设并修改">
@@ -195,7 +192,7 @@ AI 通常按任务选择这些入口:
195
192
  </Step>
196
193
  <Step title="局部重跑并验证假设">
197
194
  ```bash
198
- npx niceeval exp local weather/brooklyn --force
195
+ npx niceeval exp local weather/brooklyn --output agent --force
199
196
  npx niceeval show weather/brooklyn
200
197
  ```
201
198
 
@@ -203,7 +200,7 @@ AI 通常按任务选择这些入口:
203
200
  </Step>
204
201
  <Step title="全量确认没有回归">
205
202
  ```bash
206
- npx niceeval exp local --force
203
+ npx niceeval exp local --output agent --force
207
204
  npx niceeval show
208
205
  ```
209
206
 
@@ -213,19 +210,22 @@ AI 通常按任务选择这些入口:
213
210
 
214
211
  ## AI 应该从输出里读什么
215
212
 
216
- `exp` 运行结束后会给出三类信息:失败摘要、结果统计和结果快照目录。典型输出如下:
213
+ `--output agent` 运行中只向 stderr 追加低频 checkpoint(存活信号,不是结果数据源),结束时向 stdout 打印一个有界 handoff block——这才是 AI 应该解析的部分:
217
214
 
218
215
  ```text
219
- Failing:
220
- weather/brooklyn · @1k2m9qtr
221
- gate calledTool("get_weather"): tool was never called
222
-
223
- Results: 14 passed, 1 failed, 0 errored, 0 skipped
224
- Structured results: .niceeval/local/2026-07-09T10-00-00-000Z-x1f2/
225
- (snapshot.json + attempt 的 result.json / events.json / trace.json / diff.json)
216
+ NICEEVAL RESULT failed
217
+ summary: 14 passed, 1 failed, 0 errored (0 reused)
218
+ snapshots:
219
+ - .niceeval/local/2026-07-09T10-00-00-000Z-x1f2/
220
+ failures:
221
+ - @1k2m9qtr weather/brooklyn [local]
222
+ gate: tool was never called
223
+ next:
224
+ niceeval show @1k2m9qtr
225
+ niceeval show @1k2m9qtr --execution
226
226
  ```
227
227
 
228
- AI 应先从失败项选中 Attempt locator,再按证据位执行 `niceeval show @<id>` 或对应证据 flag,不要从头解析运行期间不断刷新的进度行。需要机器读取时,结果快照是事实来源:
228
+ AI 应先从 `failures` 选中 Attempt locator,再按证据位执行 `next` 给出的 `niceeval show @<id>` 或对应证据 flag,不要解析运行期间 stderr 上低频追加的 checkpoint 行——那些只用于判断进程是否存活。失败条数超过上限(默认 5 条)时,handoff 只展开前几条并给出总数,完整清单读结果快照。需要机器读取时,结果快照是事实来源:
229
229
 
230
230
  ```text
231
231
  .niceeval/<experiment>/<快照>/
@@ -238,7 +238,7 @@ AI 应先从失败项选中 Attempt locator,再按证据位执行 `niceeval sh
238
238
  ```
239
239
 
240
240
  - `snapshot.json` 记录实验身份、运行配置、格式版本和时间。
241
- - `result.json` 记录该 Attempt 的判定、断言、错误和用量。
241
+ - `result.json` 记录该 Attempt 的判定、断言、结构化错误、diagnostics 和用量;瞬时 progress 不落盘。
242
242
  - `events.json` 是对话与工具调用事件,`trace.json` 是调用链,`diff.json` 是 Sandbox 文件变化。
243
243
  - 某类证据不存在时,对应文件不会生成。先以 `show` 的提示为准,不要假设每个目录都有全部文件。
244
244
 
@@ -268,14 +268,16 @@ AI 应先从失败项选中 Attempt locator,再按证据位执行 `niceeval sh
268
268
 
269
269
  ```text
270
270
  读取 node_modules/niceeval/INDEX.md,再按索引读取与任务有关的文档。
271
- 运行 npx niceeval exp local,并根据退出码和失败摘要决定下一步。
271
+ 运行 npx niceeval exp local --output agent,并根据退出码和失败 locator 决定下一步。
272
272
  对每个失败的 Eval,从报告选择一个 Attempt locator;再运行 niceeval show @<id>
273
- 并按问题选择默认 Eval 源码面、--execution 或 --diff。写出失败原因的假设,并判断应该修改被测程序、
273
+ 并按问题选择 --eval、--execution、--timing 或 --diff;--timing 从 lifecycle 展开 setup/teardown
274
+ hook、shell 命令、每轮 send 与可关联的 OTel model/tool,回答整个 Attempt 的时间花在哪里。
275
+ 写出失败原因的假设,并判断应该修改被测程序、
274
276
  Eval,还是实验环境。修改后用 --force 重跑对应 Eval,比较新的判定和证据。
275
277
  同一问题连续三轮没有新证据或改善时停止并汇报,不要靠放宽断言碰绿。
276
- 全部局部失败清零后,用 npx niceeval exp local --force 全量验证;退出码 0 才完成。
278
+ 全部局部失败清零后,用 npx niceeval exp local --output agent --force 全量验证;退出码 0 才完成。
277
279
  ```
278
280
 
279
281
  真实 Agent 的运行可能产生费用。实验阶段可以加 `--budget <美元>` 限制本轮累计成本;预算只能限制单次命令,不能替代上面的停止条件。
280
282
 
281
- 人与 AI 随时可以接手同一轮工作。AI 用 `niceeval show` 读取的结果,也能由人运行 `npx niceeval view` 在网页中查看。两者读取同一批 artifact;完整的输出格式、历史选择和网页操作见[查看结果](/zh/guides/viewing-results)。
283
+ 人与 AI 随时可以接手同一轮工作。AI 用 `niceeval show` 读取的结果,也能由人运行 `npx niceeval view` 在网页中查看。两者读取同一批 artifact;完整的输出格式、历史选择和网页操作见[查看结果](/zh/how-to/viewing-results)。
@@ -18,6 +18,7 @@ export default defineEval({
18
18
  reporters?: Reporter[];
19
19
  timeoutMs?: number;
20
20
  metadata?: Record<string, unknown>;
21
+ async setup(sandbox, ctx) { /* task fixture + progress/diagnostic */ },
21
22
  async test(t) { /* interactions + assertions */ },
22
23
  });
23
24
  ```
@@ -90,7 +91,7 @@ export default rows.map((row) =>
90
91
  );
91
92
  ```
92
93
 
93
- 生成 ID 为 `sql/0000`、`sql/0001` 等。详见 [数据驱动测试](/zh/guides/dataset-fanout)。
94
+ 生成 ID 为 `sql/0000`、`sql/0001` 等。详见 [数据驱动测试](/zh/how-to/dataset-fanout)。
94
95
 
95
96
  ## Sandbox workspace
96
97
 
@@ -109,7 +110,39 @@ export default defineEval({
109
110
  });
110
111
  ```
111
112
 
112
- 详见 [Fixtures](/zh/guides/fixtures)。
113
+ 详见 [Fixtures](/zh/how-to/fixtures)。
114
+
115
+ ## 从 Eval 报告长步骤和诊断
116
+
117
+ `setup` 用于这条 Eval 的任务夹具。第二个参数绑定到 eval setup 阶段;`test(t)` 里的反馈绑定到 eval run 阶段:
118
+
119
+ ```ts
120
+ export default defineEval({
121
+ async setup(sandbox, ctx) {
122
+ ctx.progress({ message: "安装 fixture 依赖" });
123
+ await sandbox.runCommand("npm", ["install"]);
124
+ },
125
+
126
+ async test(t) {
127
+ t.progress({ message: "上传隐藏测试", current: 1, total: 2 });
128
+ await t.sandbox.uploadDirectory("../fixtures/project");
129
+
130
+ const preflight = await inspectFixture();
131
+ if (preflight.usedFallback) {
132
+ t.diagnostic({
133
+ code: "fixture-check-degraded",
134
+ level: "warning",
135
+ message: "Fixture 预检使用了备用检查器",
136
+ data: { checker: preflight.checker },
137
+ });
138
+ }
139
+
140
+ await t.send("完成任务");
141
+ },
142
+ });
143
+ ```
144
+
145
+ `progress` 只更新运行中的短期状态,不进入结果。`diagnostic` 会写进当前 Attempt 的 `result.json`,但不会代替断言或自动改变判定:业务结论仍用 `t.check` / `t.require` / gate;基础设施无法继续时抛出异常。
113
146
 
114
147
  ## 命名约定
115
148