返回 AICAP-180
B4 · Day 34reasoning/planning/multi-agent + 何时不用 agent

self-consistency 机制

Day 33 立了非确定性的统计底座(pass@k / pass^k / variance),并建了 runNTimes 复跑封装。今天把这个封装用起来,落地第一个降方差技术:self-consistency——同 prompt 多采样再多数投票。它在能力曲线上的位置是「方差控制」:不是让模型更聪明,而是把偶发错误样本稀释掉。最小可判定产出:用 DeepSeek-V3 对 8 任务跑 single

阶段: B4 · reasoning/planning/multi-agent + 何时不用 agent(Day 31-40) 标签: #self-consistency #majority-vote #variance-reduction #cost-curve

今日导引(由浅入深)

Day 33 立了非确定性的统计底座(pass@k / pass^k / variance),并建了 runNTimes 复跑封装。今天把这个封装用起来,落地第一个降方差技术:self-consistency——同 prompt 多采样再多数投票。它在能力曲线上的位置是「方差控制」:不是让模型更聪明,而是把偶发错误样本稀释掉。最小可判定产出:用 DeepSeek-V3 对 8 任务跑 single-shot vs k=5 self-consistency,记 Δaccuracy 与成本曲线(数字待 key)。

1. 机理精读

self-consistency 是方差缩减,不是能力提升。 机制三步:(1) 对同一 prompt 在温度>0 下采样 k 次,得到 k 个可能不同的答案;(2) 把答案归一化(数值/分类/是否);(3) 多数投票取众数作为最终答案。直觉来自 Self-Consistency (arXiv:2203.11171):正确答案往往是「多条不同推理路径的共同终点」,而错误是分散的偶发样本——投票把分散的错稀释、把集中的对放大。

为什么有效,依赖什么前提。 它成立的前提是「单次正确率 > 随机」且「错误彼此独立分散」。在这个前提下,多数票的准确率高于单次,且随 k 上升。但它只对可投票的输出有效——数值(reasoning-numeric-sum 答 $29,000)、分类(structuring/layering/integration)、是/否(restraint 类「是否 flag」)能投票;开放式长文(aml-sar-5w1h 的叙事)不能直接多数投票,需先抽取可比较的关键字段再投。

代价是 token×k 与延迟。 k=5 意味着 5 倍生成 token 和(若串行)约 5 倍延迟。准确率随 k 边际递减:从 1→3 提升明显,3→5、5→7 收益迅速变小。因此必须把 accuracy 和 cost 一起画成成本曲线找拐点——这正是 Karpathy Zero-to-Hero 里「采样直觉」的工程化:采样是有价的随机性,要为收益付费而非无脑堆 k。

关键权衡与边界。 self-consistency 是「用更多 token 换更低方差」的经典基线。它和 Day 33 的 variance 是一体两面:variance 大的任务,self-consistency 收益大;variance 已经很小(模型每次都对或每次都错)的任务,投票几乎无用。重要边界(2026 现实):带 extended thinking 的推理模型在内部已经走了多条路径并自洽,外部再叠 self-consistency 的边际收益变小——对 reasoning model 要先验证收益是否还在,不能照搬 2022 的经验。这条会进 Day 38(成本/延迟多维度量)和 Day 40(gate)的取舍。

与 Day 33 的接力。 Day 33 把 variance 量化成 per-task std;今天 self-consistency 正是「对高 std 任务定向投药」——只对那些 std 大、单次不稳的任务开 k 采样,对 std≈0 的稳定任务保持 single-shot 省钱。换句话说,self-consistency 不该全量开,而该按 Day 33 的 std 列有选择地开,这本身就是一条成本优化策略。

2. 推导 / 手算 / 代码走读

为什么这一步对 AISA 重要。 self-consistency 是「可靠性可以花钱买」的最直接证据——它把「准确率不够」翻译成「再花 k 倍 token 能买回多少 pp」,让可靠性和成本进同一张账。架构评审里你能据此回答「为什么这条链路用 k=3 投票」:因为它的 std 大(Day 33)、k=3 把 Δaccuracy 抬到 CI 不跨 0(Day 35),且 token 成本仍在预算内(Day 38)。这比「加一层投票更稳」的空话能落到数字上。

手算多数投票降错的直觉(设单次正确率 p=0.6,错误均匀分散到 2 个错误答案各 0.2,k=5 投票):

  • 5 次里正确答案的期望出现次数 = 5×0.6 = 3,往往是众数 → 投票后正确概率明显 > 0.6。
  • 直觉公式(二选一简化版,单次 p>0.5 时):多数票正确率 = Σ_{i>k/2} C(k,i) p^i (1-p)^(k-i),p=0.6、k=5 时 ≈ 0.683 > 0.6。提升约 +8pp,但 k 再加到 7、9 提升迅速收窄——这就是边际递减,要在曲线拐点停。

代码走读(本日复用/挂接):

  • 复用 Day 33 的 runNTimes(task, n):对每任务采样 k=5,拿到 k 个输出。
  • 多数投票聚合器(本日新增逻辑):对 k 个输出按可比较字段归一化后取众数;single-shot 则取 k=1。两者都过同一 judge/codeCheck 算 accuracy。
  • 投票逻辑用 fake 输出离线单测(如喂 ['A','A','B','A','B'] 验证众数=A),离线单测绿,不触网。
  • 脚本挂到 scripts/run-agent-eval.ts:该 runner 现状是 --provider deepseek 默认、读 EVAL_TASKS、无 key 时打印 dry-run 并 exit 0(见文件 68-89 行 main())。本日要做的是让它支持「k-run + 投票」模式跑真实 DeepSeek-V3(OpenRouter),但无 key 时仍走 dry-run,与现有行为一致。
  • 真实模型经 makeModelGenerate 计 token 与(若 modelNameMODEL_PRICES)真实 cost,成本曲线的 token 数据由此而来。

makeModelGenerate 的成本细节(走读 agentEval.ts 150-165 行):

  • 它对每个 task 调 generateText,从 r.usageinputTokens/outputTokens(兼容 promptTokens/completionTokens 旧字段名)。
  • 仅当 opts.modelName 存在且命中 MODEL_PRICES 且 in/out token 都是数字时,才用 estimateCost(modelName, inTok, outTok)costUsd;否则 costUsdundefined——绝不静默记 0。这保证成本曲线里没有「假装免费」的点。
  • 因此 self-consistency 的真实 token 成本 = k 次每次的 inTok+outTok 累加,可直接从 per-call 结果聚合,无需另估。

多数投票聚合的伪代码(本日新增逻辑,离线可单测):

function majorityVote(outputs):           # outputs = k 个被测输出
    keys = outputs.map(normalize)         # 抽可比较字段(数值/分类/是否)
    return mode(keys)                      # 取众数;平票按预设 tiebreak
# single-shot = majorityVote([outputs[0]]);k=5 = majorityVote(全部 5 个)

测试:喂 ['structuring','structuring','layering','structuring','layering'] → 众数 structuring,离线断言即可,不触网

成本曲线读法速查表

k相对 token 成本accuracy 走势何时停
1基线稳定任务(std≈0)停在此
3提升明显多数任务的甜点区
5提升收窄高方差任务可到此
7+7×+边际趋平几乎不值得,除非任务极脆弱

口诀:accuracy 抬升边际递减、token 成本线性上涨,拐点(通常 k=3~5)就是该停的地方;reasoning model 上拐点更靠前(内部已多路径)。

3. 今日实战

  1. 用 DeepSeek-V3(OpenRouter provider,runner 默认 provider 可切到 openrouter)对 8 任务跑 single-shot
  2. 同 8 任务跑 k=5 self-consistency:复用 Day 33 runNTimes 采样 + 本日多数投票聚合。
  3. 记两组 accuracyΔ(k=5 − single-shot)。
  4. 把投票模式脚本挂到 scripts/run-agent-eval.ts
  5. 画 accuracy-vs-k 成本曲线(k=1,3,5),找边际递减拐点。
  6. 离线 fixture 模式:喂确定性 fake 输出验证投票聚合 + completion% 能产出并 commit;真实 single vs k=5 的 Δaccuracy 留待 key。
  7. 把每任务的 token 成本(k 次累加)并列记入,作为 Day 38 成本/延迟矩阵的输入之一。

4. 今日实测 / 产出

  • 「待跑(需 OPENROUTER_API_KEY);可先用离线 fixture 跑通 harness 出 completion%+commit」
  • 将产出 Δaccuracy(k=5 − single-shot)数字 + 成本曲线
  • 投票逻辑离线单测绿
  • 状态:投票聚合器+离线单测属可建/可验;Δaccuracy 与成本曲线的真实数字属待跑(需 key),不臆造数值。

与 Day 33/35 的接力

  • 输入来自 Day 33runNTimes + per-task std:std 大的任务才是 self-consistency 的投药对象。
  • 输出交给 Day 35:single vs k=5 的两组 accuracy 喂 pairedBootstrap,判 Δ 的 95% CI 是否跨 0——只有 CI 不跨 0,才有统计依据说「投票真的更好、值这 k 倍 token」。
  • token 成本列再喂 Day 38 的 cost/latency/variance 三维矩阵。

5. 常见误区 / 陷阱

  1. 对不可投票输出硬投票:开放式叙事(SAR narrative)直接投票无意义,需先抽取可比较字段再投。
  2. 无脑堆大 k:准确率边际递减但 token×k 线性涨,不画成本曲线就会在 k=9 付 9 倍钱换 +1pp。
  3. 对 reasoning model 照搬收益:extended thinking 模型已内化多路径,外叠 self-consistency 收益变小,要先测再上。
  4. 把离线投票单测绿当真实 Δ:fixture 只验众数逻辑,真实 Δaccuracy 仍需 key——状态不可升级。
  5. 全量开 self-consistency:对 std≈0 的稳定任务也投票纯属浪费;应按 Day 33 的 std 列定向只对高方差任务开。
  6. 平票无 tiebreak:偶数 k 或多分类下可能平票,聚合器必须有确定性 tiebreak(如按 codeCheck 或保守取「更安全」选项),否则结果不可复现。

自测题(面试演练)

  • Q:self-consistency 提升的是能力还是方差? A:方差。它不让模型更聪明,而是把分散的偶发错误样本投票稀释掉;前提是单次正确率 > 随机且错误彼此独立分散。
  • Q:为什么不能无脑把 k 调大? A:accuracy 随 k 边际递减,但 token×k 与(串行)延迟×k 线性上涨;不画成本曲线就会在 k=9 付 9 倍钱换 +1pp。要在拐点(常 k=3~5)停。
  • Q:reasoning model 上还要叠 self-consistency 吗? A:先测。extended thinking 模型内部已走多路径并自洽,外叠收益变小甚至接近 0,要用实测确认收益是否还在,别照搬 2022 经验。
  • Q:开放式 SAR 叙事怎么投票? A:不能直接投。先从每次输出抽出可比较的关键字段(典型学标签、是否含 5W1H facet、风险结论),对字段投票,而非对整段文本投票。

6. 学习资源(每条带 YYYY-MM)

  • Self-Consistency Improves Chain of Thought Reasoning, Wang et al. (arXiv:2203.11171, 2022-03) — 多采样投票降方差原始论文。
  • Karpathy《Neural Networks: Zero to Hero》(2023, 持续更新) — 采样/温度直觉的教学黄金路径。
  • 本仓代码 scripts/run-agent-eval.ts + src/agent/eval/agentEval.tsmakeModelGenerate 计 token/cost)— 真实跑与成本数据来源。
  • 本仓代码 src/agent/eval/stats.ts — accuracy 聚合的统计原语。

SOTA检查 (2026-06 更新)

  • 当前主流:self-consistency 仍是降方差基线,现行有效。
  • 重要折扣:2026 推理模型(带 extended thinking)部分内化了多路径,需注意对 reasoning model 收益变小——上线前先验证收益是否仍在。
  • 版本核对DeepSeek-V3 版本号执行当周复验(OpenRouter slug 可能变更)。
  • 下次复查点:是否有 self-consistency 的「自适应 k」方法(按 variance 动态决定采样数)成为新基线。

衔接

  • 昨天:Day 33 — 非确定性统计基础(pass@k/pass^k/variance + runNTimes 封装)。
  • 今天:self-consistency 多采样投票降方差,single-shot vs k=5 对比 + 成本曲线。
  • 明天:Day 35 — bootstrap 置信区间(给今天两组 single vs k=5 结果算 Δ 的 95% CI,判是否跨 0)。