dsh-llm-verifier 0.4.0 → 0.4.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/README.md +3 -3
- package/lib/index.js +30 -0
- package/lib/index.js.map +1 -1
- package/lib/types/index.d.ts.map +1 -1
- package/lib/types/index.js +12 -3
- package/lib/types/index.js.map +1 -1
- package/package.json +1 -1
- package/src/index.test.ts +71 -0
- package/src/index.ts +12 -3
package/README.md
CHANGED
|
@@ -338,7 +338,7 @@ node scripts/eval-replay.mjs --dir <话题目录> --thresholds 0.5,0.65,0.8
|
|
|
338
338
|
1. **阈值扫描**:每条 `verifier_current_session` 记录都存有会话分数、空工作基线、胜者与逐项判据分数——也就是门控看过的全部信息——因此可以用**当前生效的验收规则**在每个阈值上重新判定,并区分"均分不够""逐项不达标""输给基线""无法解析"四种落选原因。
|
|
339
339
|
2. **解析器回放**:决策快照保存了判官原始回答,脚本用当前解析器重新解析并报告 drift——提示词或解析逻辑的回归会在**没有模型调用**的情况下暴露出来。`top-logprobs` 通道的分数是 token 分布上的期望,快照不保存分布,因此其文本通道重解析出现 drift 属预期,仅供参考。
|
|
340
340
|
|
|
341
|
-
> 在本仓库作者机器上的真实数据里,14 次验收在 0.5–0.9 的所有阈值下**全部通过**:判官给每次会话都打了 1.00。这正是这个工具要暴露的事实——阈值调参的前提是判官能区分候选,详见
|
|
341
|
+
> 在本仓库作者机器上的真实数据里,14 次验收在 0.5–0.9 的所有阈值下**全部通过**:判官给每次会话都打了 1.00。这正是这个工具要暴露的事实——阈值调参的前提是判官能区分候选,详见 `.agents/notes/implemented/feature/2026-09-13-best-of-n-generation-side-selection.md` 记录的判别探针结论与当前通道现状。
|
|
342
342
|
|
|
343
343
|
## 关键交付物的 best-of-N
|
|
344
344
|
|
|
@@ -363,9 +363,9 @@ task ─┬─ 生成 N 份候选(会话模型,temperature 1.0,maxTokens 4
|
|
|
363
363
|
| 明显质量差(一方漏验需求) | 10/10 | 0.544 | 63.3% |
|
|
364
364
|
| 难分(都通过任务列出的用例,差别在 `.strip()` 的覆盖范围与证据) | 10/10 | 0.018 | 50.4% |
|
|
365
365
|
|
|
366
|
-
方向是可靠的(A/B 换槽后完全一致),但**效果量随难度塌缩**:explicit-tag 一次只采一个字母,量化下限就是 1/19 ≈ 0.053,0.018 的中位差意味着 3 条判据里只有 1 条动了一档。真机上已经看到它的直接后果:一个三份草稿**都合格**的长任务被锦标赛判成 **0.5 / 0.5 / 0.5 全平**,排名没有任何信息量;那一次真正救场的是**绝对分**——`passesThreshold: false` 且点名 `output_match` 未达标(生成侧无法提供真实跑过的 stdout/stderr),于是 agent 不会拿着一个平局排名去发货。**这正是「相对最优 ≠
|
|
366
|
+
方向是可靠的(A/B 换槽后完全一致),但**效果量随难度塌缩**:explicit-tag 一次只采一个字母,量化下限就是 1/19 ≈ 0.053,0.018 的中位差意味着 3 条判据里只有 1 条动了一档。真机上已经看到它的直接后果:一个三份草稿**都合格**的长任务被锦标赛判成 **0.5 / 0.5 / 0.5 全平**,排名没有任何信息量;那一次真正救场的是**绝对分**——`passesThreshold: false` 且点名 `output_match` 未达标(生成侧无法提供真实跑过的 stdout/stderr),于是 agent 不会拿着一个平局排名去发货。**这正是「相对最优 ≠ 够好」,也是基线比较不可省的原因。** **所以「让插件起草」只在预期候选之间有明显质量差时才划算**(不同思路、不同实现正是这种情形);如果候选很可能都「做了真实工作」,先花钱买判官质量(换成能走概率期望通道的判官)而不是把 N 调大。设置页的「判官自检」会回报当前实际通道。
|
|
367
367
|
|
|
368
|
-
|
|
368
|
+
探针数据与结论另见 Agent Notes:`.agents/notes/implemented/feature/2026-09-13-best-of-n-generation-side-selection.md`(含三份草稿全合格时锦标赛全平的真机案例)。
|
|
369
369
|
|
|
370
370
|
- **不新增配置项**:起草模型取自 `agent.session.requestHeader().config`(就是当前会话模型),温度固定 1.0——判官的默认 0.2 会让 N 份几乎相同,工具就失去意义。
|
|
371
371
|
- **每份输出上限 16384 token,且「被上限截断」不算失败**:这个数字是实测的,不是拍的——第一次真机端到端验收里,4096 让**三份草稿全部截断**、工具一份都没返回;原因写在返回值的 `stats.reasoningTokens` 里:一次只有两份短草稿的运行,会话模型(`deepseek-official/deepseek-flash`)输出了 17254 token,其中 **16363 是推理 token**(约 8k/份),4096 在答案开始前就被吃光。16384 既是该实测值的约 2 倍,也是「两份草稿 + 任务」仍留在插件 24 万字符显式证据上限内的最大取值;`maxTokens` 是上限而非预留,短草稿的代价没有变化。**仍被截断的草稿会被保留并列入 `truncated`**:判官自己看得到文本没写完、会相应扣分,而直接丢弃等于白付一次生成。真正的长答案超出本工具适用范围。
|
package/lib/index.js
CHANGED
|
@@ -2081,6 +2081,29 @@ const criterionResultSchema = {
|
|
|
2081
2081
|
}
|
|
2082
2082
|
}
|
|
2083
2083
|
};
|
|
2084
|
+
/**
|
|
2085
|
+
* The per-criterion row `verifySession` reports: the compare engine's rows reduced to the
|
|
2086
|
+
* acceptance-facing `{id, name, score}` shape (`score` is compare's `scoreA`).
|
|
2087
|
+
*
|
|
2088
|
+
* Deliberately NOT {@link criterionResultSchema}: that one declares compare's `{scoreA, scoreB}`
|
|
2089
|
+
* rows, and the host rejects any key a tool's declared output schema does not mention — declaring
|
|
2090
|
+
* the wrong criterion shape here is exactly how the explicit session verifier broke.
|
|
2091
|
+
*/
|
|
2092
|
+
const acceptanceCriterionResultSchema = {
|
|
2093
|
+
type: "object",
|
|
2094
|
+
additionalProperties: false,
|
|
2095
|
+
properties: {
|
|
2096
|
+
id: {
|
|
2097
|
+
type: "string",
|
|
2098
|
+
required: true
|
|
2099
|
+
},
|
|
2100
|
+
name: { type: "string" },
|
|
2101
|
+
score: {
|
|
2102
|
+
type: "number",
|
|
2103
|
+
required: true
|
|
2104
|
+
}
|
|
2105
|
+
}
|
|
2106
|
+
};
|
|
2084
2107
|
const commonParams = {
|
|
2085
2108
|
criteria: {
|
|
2086
2109
|
type: "array",
|
|
@@ -3308,6 +3331,7 @@ function apply(ctx, config = {}) {
|
|
|
3308
3331
|
items: criterionResultSchema,
|
|
3309
3332
|
required: true
|
|
3310
3333
|
},
|
|
3334
|
+
identical: { type: "boolean" },
|
|
3311
3335
|
agreement: {
|
|
3312
3336
|
type: "number",
|
|
3313
3337
|
required: true
|
|
@@ -3394,6 +3418,7 @@ function apply(ctx, config = {}) {
|
|
|
3394
3418
|
type: "string",
|
|
3395
3419
|
required: true
|
|
3396
3420
|
},
|
|
3421
|
+
identical: { type: "boolean" },
|
|
3397
3422
|
scores: {
|
|
3398
3423
|
type: "array",
|
|
3399
3424
|
items: { type: "number" },
|
|
@@ -3729,6 +3754,11 @@ function apply(ctx, config = {}) {
|
|
|
3729
3754
|
],
|
|
3730
3755
|
required: true
|
|
3731
3756
|
},
|
|
3757
|
+
criteria: {
|
|
3758
|
+
type: "array",
|
|
3759
|
+
items: acceptanceCriterionResultSchema,
|
|
3760
|
+
required: true
|
|
3761
|
+
},
|
|
3732
3762
|
fromSeq: {
|
|
3733
3763
|
type: "integer",
|
|
3734
3764
|
required: true
|