# dsh-llm-verifier 使用手册 本手册面向**已安装** dsh-llm-verifier 的用户。安装与发布流程见 [SOP](SOP.md)。 ## 目录 1. [快速开始](#1-快速开始) 2. [验证后端](#2-验证后端) 3. [三个工具详解](#3-三个工具详解) 4. [配置参考](#4-配置参考) 5. [token 计量](#5-token-计量) 6. [算法原理速览](#6-算法原理速览) 7. [故障排查](#7-故障排查) 8. [安全说明](#8-安全说明) ## 1. 快速开始 ```sh # 1) 安装 dsh plugin --profile web add dsh-llm-as-a-verifier # 2) 配置验证模型凭证(二选一) export DEEPSEEK_API_KEY=sk-xxx # DeepSeek 官方 API # export OPENAI_BASE_URL=http://localhost:8000/v1 # 本地 vLLM/SGLang # 3) 重启 dsh web(或等待 HMR 自动加载) dsh web ``` 然后在对话中直接说: ```text 用 verify_compare 比较这两个实现哪个正确性更高: A: def rev(s): return s[::-1] B: def rev(s): return s ``` 智能体会自动调用工具,返回形如: ```text Fine-grained rewards on criteria correctness: candidate A: 0.7310 candidate B: 0.3845 Winner: candidate A (margin 0.3465) 3 verifier call(s), input 4123 tokens (cached 0, 0.0% hit), output 96 tokens (reasoning 48) ``` ## 2. 验证后端 验证模型必须是**返回 token 级 logprobs 的 OpenAI 兼容服务**。支持三类: | 后端 | 配置方式 | 备注 | |---|---|---| | DeepSeek 官方 API | `export DEEPSEEK_API_KEY=sk-...` | 自动启用 thinking、32k 输出预算;推荐 `deepseek-v4-flash` | | 本地 vLLM / SGLang | `export OPENAI_BASE_URL=http://localhost:8000/v1` | 需要模型支持 logprobs(如 `Qwen/Qwen3.5-9B`);本插件会自动做评分标签 prefill,读分布更稳 | | 其他 OpenAI 兼容服务 | config 里写 `baseUrl` + `apiKey` | 必须返回 `logprobs.content[].top_logprobs` | 凭证解析顺序:**插件 config → `OPENAI_BASE_URL`+`OPENAI_API_KEY` → `DEEPSEEK_API_KEY`**。全部缺失时工具仍会注册,调用时才抛 `MissingAPIKeyError`(不影响智能体其他工作)。 ### 推荐的模型与预算 - **DeepSeek**:`deepseek-v4-flash`(上游默认),thinking 开启、32k 输出预算。可用环境变量微调: - `DEEPSEEK_EFFORT=off|low|high|max`(默认 `high`) - `DEEPSEEK_MAX_TOKENS=32768`(默认) - **本地开源模型**:`vllm serve Qwen/Qwen3.5-9B` 之类;若服务不支持 `continue_final_message` 预填充,评分会自动退化为 0.5/0.5 平局并在结果中体现,不影响流程。 ## 3. 三个工具详解 ### 3.1 verify_compare — 成对细粒度打分 对两个候选做**有向**比较(A 在槽位 A、B 在槽位 B),按评价标准逐条打分,返回 [0,1] 的期望奖励。 | 参数 | 必填 | 说明 | |---|---|---| | `problem` | ✅ | 任务描述 | | `candidateA` / `candidateB` | ✅ | 两个候选(代码、方案、轨迹文本均可) | | `criteria` | ✅ | `{名称: 描述}` 映射,逐条打分后平均 | | `nEvaluations` | | 每条标准的重复验证次数,默认 1 | | `groundTruthNote` | | 验证器总会看到的备注(如基准补丁位置) | **注意**:单次有向比较**不消除槽位偏置**(上游语义)。要消除偏置请用 `verify_select`(其环赛会轮换槽位、奇数次重复交换槽位)。 ### 3.2 verify_select — N 选一(Probabilistic Pivot Tournament) - 阶段 1 **环赛**:在随机哈密顿环上对相邻候选做 N 次有向比较,每个候选在 A/B 槽各出现一次 → 槽位偏置在环上抵消; - 阶段 2 **枢纽选择**:按环赛平均偏好 `w/c` 取 top-k 作为枢纽; - 阶段 3 **枢纽轮**:非枢纽 vs 枢纽 + 枢纽 vs 枢纽 全部比较,聚合成最终偏好,返回 argmax。 总比较数 = `N + k(N−k) + C(k,2)`,对固定 k 线性于 N。 | 参数 | 必填 | 说明 | |---|---|---| | `problem` | ✅ | 任务描述 | | `candidates` | ✅ | N 个候选 | | `criteria` | ✅ | 评价标准 | | `nEvaluations` | | 每条标准每对比较的重复次数,默认 4 | | `pivots` | | 枢纽数 k,默认 2;越大越准、越贵 | | `seed` | | 环赛随机种子,默认 0;同 seed 同输入 → 完全相同的锦标赛 | | `groundTruthNote` | | 验证器备注 | 返回:`index`(胜者下标)、`best`(胜者内容)、`scores`(各候选平均偏好)、`ranking`(降序排名)、`nComparisons`、`usage`。 ### 3.3 verify_track — 逐步进度追踪 把轨迹的每一步编号喂给「严格、怀疑」的验证器,逐 checkpoint 判断「按当前状态是否已经满足隐藏评分器」,答案字母 A(0%)..T(100%) 从 logprob 分布解码成连续曲线。 | 参数 | 必填 | 说明 | |---|---|---| | `problem` | ✅ | 任务指令 | | `steps` | ✅ | 每步一行(动作 + 观察到的输出) | | `checkpoints` | | 要评分的步骤号;默认内部步骤 2..T−1(<3 步则全部) | | `nEvaluations` | | 独立重复次数,默认 1 | 返回:`steps`、`scores`(各 checkpoint 进度)、`final`(最后 checkpoint 的分数)。典型用法:判断「修到哪一步真的起效了」「要不要放弃这条轨迹」。 ## 4. 配置参考 写入 profile 配置(`~/.dsh/profiles//cordis.patch.yml` 或 `~/.dsh/cordis.patch.yml`): ```yaml - id: llm-verifier config: model: deepseek-v4-flash # 验证模型名(可选) baseUrl: https://api.deepseek.com apiKey: '' # 建议留空走环境变量 timeoutMs: 60000 # 单请求超时 maxConcurrency: 8 # 最大并发验证调用 deepseek: false # 强制/禁用 DeepSeek 调用路径(默认按 baseUrl 推断) prefill: true # 非 DeepSeek 服务器评分标签预填充 compare: true # 注册 verify_compare select: true # 注册 verify_select track: true # 注册 verify_track ``` ## 5. token 计量 每次工具调用返回 `usage` 快照(与上游 `llm_verifier.token_usage()` 同构): ```json { "calls": 6, "inputTokens": 41230, "cachedInputTokens": 35000, "uncachedInputTokens": 6230, "outputTokens": 512, "reasoningTokens": 256, "cacheHitRate": 0.849 } ``` 成对提示词把任务/轨迹放在前缀、标准放在尾部,刻意放大前缀缓存命中(上游 0.2.0 的 prefix-cache 优化)。 ## 6. 算法原理速览 1. **20 级字母尺度**:A=20(最好)…T=1(最差),大小写同义;进度追踪反过来 A=0%…T=100%。 2. **期望打分**:找到回复末尾 ``/`` 标签后的 top-logprobs 分布,`E = Σ v·p(v) / Σ p(v)`,归一化到 [0,1];读不到分布时按文本标签回退,再不行取 0.5(不硬崩)。 3. **槽位偏置消除**:环赛让每个候选各坐一次 A/B 槽;`nEvaluations ≥ 2` 时奇数次重复交换槽位、分数按候选顺序记回。 4. **Bradley-Terry 软胜负**:`p(a 胜 b) = sigmoid(R_a − R_b)`,聚合进 `w/c` 平均偏好。 5. **进度解码**:`..` 标签后答案位置的字母分布做 softmax 重归一化取期望。 6. **确定性**:环赛用 mulberry32 种子 PRNG,同 seed 同输入必得同一场锦标赛。 ## 7. 故障排查 | 症状 | 原因与处理 | |---|---| | 调用报 `MissingAPIKeyError` | 未配置凭证;`export DEEPSEEK_API_KEY=...` 或写 config | | 所有分数都是 0.5 | 后端没返回可用 logprobs;确认服务开了 `logprobs`/`top_logprobs`,本地模型确认支持;DeepSeek 若报 `no answer logprobs`,调大 `DEEPSEEK_MAX_TOKENS` 或调低 `DEEPSEEK_EFFORT` | | 调用超时 | `timeoutMs` 过小;验证类调用建议 ≥60s,`verify_select` 工具预算 360s | | 比较「看似随机」 | 单次 `verify_compare` 有槽位偏置;改用 `verify_select` 或提高 `nEvaluations` | | 安装后没有新工具 | 确认 dsh ≥ 0.1.0-rc.6;`dsh plugin --profile web ls` 看是否在依赖里;重启 `dsh web` | ## 8. 安全说明 - 验证调用会把你的任务与候选内容发给配置的验证后端,**注意敏感信息**; - `apiKey` 建议始终走环境变量,不要写进 patch 文件后提交; - 本插件只做只读模型调用,不写文件、不执行代码;`isConcurrencySafe` 已声明,可与其他工具并行。