ToT 的 BFS/DFS 有个致命缺口:蒙特卡洛树搜索(MCTS)用「随机试错+统计」让大模型想得更深,小模型 + 它竟超过 GPT-4

ToT 的 BFS/DFS 有个致命缺口:蒙特卡洛树搜索(MCTS)用「随机试错+统计」让大模型想得更深,小模型 + 它竟超过 GPT-4

前面三篇我们走了一条清晰的线:CoT(链)→ ToT(树,能试错回头)→ GoT(图,能拼碎片)。你以为到图就到头了?

今天聊 MCTS(蒙特卡洛树搜索)------它和 ToT 跑在同一棵 thought 树上,但换了一套更聪明的搜索策略。

先抛一个反直觉结论:

一个更小的开源模型(LLaMA-33B)+ MCTS,在规划任务上超过了大得多的 GPT-4 + 普通 CoT。

这不是模型变大了,是「怎么用模型去想」变了。AlphaGo 靠 MCTS 战胜李世石,现在它也被用来让 LLM「想得更深」。


〇、ToT 的盲区:确定性剪枝会误杀好分支

回想 ToT 的剪枝逻辑:评估器说某状态 impossible,就永远丢掉

这有个致命前提------评估器必须永远判对。但前面讲过,评估器就是那个 LLM 自己,它会看走眼:

  • 本该保留的好分支 误判为 impossible永久误杀(这解永远丢了);
  • 死路 误判为 likely → 一直占着预算。

人类下棋不是这样想的。我们不会「一条路判死就永不回头」,也不会「每条路平均用力」。我们会在看起来有戏、但又没完全验证过的几步上多想几次 ,用多次试错后的统计结果来相信哪边更靠谱。

MCTS 正是把这种「用随机试错 + 统计对冲不确定性」形式化的算法。 它不是靠一次评估定生死,而是:多次随机推演(rollout)→ 统计哪条路赢的次数多 → 把搜索预算自动引向有希望的分支。

一句话定位:ToT 的 BFS/DFS 是「外部代码用穷举+贪心剪枝来搜树」;MCTS 是「外部代码用随机采样+价值统计来搜同一棵树」。树还在,搜索策略换了。


一、MCTS 是什么:在谱系里的位置

Monte Carlo Tree Search(蒙特卡洛树搜索) 是一类用于决策 / 规划问题 的启发式搜索算法。它在「可能动作空间极大、无法穷举」的场景里(围棋约 10^170 种局面、数学推理有无限多条证明路径),通过反复随机模拟来逼近最优解,而不必搜索整棵树。

它是所有现代围棋程序(AlphaGo / AlphaZero)的核心搜索算法。

回顾前面三篇的归属关系:

范式 结构 搜索策略 谁在管结构
CoT 链(线性) 无(一次生成) 模型内部
ToT BFS / DFS 外部框架
GoT BFS / DFS + 聚合细化 外部框架
MCTS UCT(UCB 选择)+ 随机 rollout 外部框架

关键认知 :MCTS 和 ToT 是同一层(外部编排)的两种搜索策略,不是递进关系 。MCTS 可以替换 ToT 里的 BFS/DFS,仍跑在同一棵 thought 树上;它和 GoT 也不冲突------图结构上同样能套 MCTS 选择。

澄清「不是什么」

  • ❌ 不是模型内部能力(不像 o1 的 hidden thinking),模型只是被反复调用的子程序。
  • ❌ 不是一句 prompt 能触发的,是一段算法代码(选择/扩展/模拟/回溯四步循环)。
  • ❌ 不是穷举,它有意不搜完整棵树,靠采样 + 统计把预算花在刀刃上。
  • ✅ 是一种「在树结构上做有偏采样的搜索算法」,核心是 UCB 选择公式

二、核心机制:四步循环

MCTS 把「搜索」建模成在树上反复跑同一个四步循环,直到预算(迭代次数)耗尽,再从统计结果里挑最优路径。

2.1 三个基本量

  • 状态(State):当前局面(如棋盘)。LLM 推理里 = 当前的部分推理轨迹 / 剩余数字集合。
  • 动作(Action):从某状态能走的合法一步。LLM 推理里 = 模型生成的「下一个 thought / 下一步运算」。
  • 奖励(Reward):走到终局后的结果信号(赢/输,或「是否凑出 24」)。

每个树节点维护两个统计量:n(被访问次数)、w(累计价值,如获胜次数)。节点的「平均价值」= w / n

2.2 四步详解

  1. Selection(选择) :从根出发,按 UCB1 公式递归选子节点,一路向下直到某个未完全展开的节点。UCB1 自动平衡「利用高价值节点」和「探索少访问节点」。
  2. Expansion(扩展) :到达叶节点后,生成它的一个或多个子节点(尝试几个候选动作),挑一个作为新节点 C
  3. Simulation / Rollout(模拟 / 推演) :从 C 出发,用随机(或默认)策略一直走到终局 ,得到结果。这一步不记录进搜索树 ,只是一次"快速试完"来估计 C 的价值。
  4. Backpropagation(回溯更新) :把模拟结果沿 C → 根 反向传回,更新路上每个节点的 n(+1) 和 w(+本次结果)。让"好路径"的统计价值慢慢累积。

四步跑完 = 一次迭代。重复成千上万次后,根节点各子树统计趋于稳定,选 w/n 最高的分支即为答案。

2.3 UCB1 公式(MCTS 的灵魂)

选择子节点 i 时:

复制代码
UCB1(i) = w_i / n_i  +  c · √(ln N / n_i)
           └─利用项─┘     └───探索项───┘
  • w_i / n_i(利用项):该节点目前的平均胜率,越大越值得走。
  • √(ln N / n_i)(探索项):父节点总访问 N 越大、本节点访问 n_i 越小,该项越大,越"值得去试探"。
  • c(探索常数):理论上取 √2,实践常凭经验调(1~2),越大越爱探索冷门分支。

直觉 :一个"赢了很多次但试得也多"的节点,和一个"只试了一次但赢了"的节点------UCB1 会让后者也有机会被选中,避免算法过早认定某路"最好"而错过其他潜力分支。这就是探索-利用权衡的数学实现。

2.4 伪代码

python 复制代码
def mcts(root, budget):
    for _ in range(budget):                 # 迭代预算
        node = selection(root)              # ① UCB1 选到叶
        child = expansion(node)             # ② 扩展出新节点
        reward = simulation(child)          # ③ 随机 rollout 到终局
        backpropagation(child, reward)      # ④ 沿路径更新 n, w
    return best_child(root)                 # 选 w/n 最高分支

三、统一案例:Game of 24 的 MCTS 走查

题目和 ToT 篇一致:用 4、9、10、13 凑 24。

  • 状态 = 剩余数字集合,如 {4,9,10,13}
  • 动作 = 选两数做一次运算,如 13-9=4,新状态 {4,4,10}
  • 奖励 = 走到只剩一个数时,若 =24 则 reward=1,否则 0。
  • rollout = 从某状态随机选两数随机运算,一路算到剩一个数,看是否=24。

一次迭代的明细(带数字) :初始根 {4,9,10,13},假设已有统计。本次迭代:

  1. Selection :根下有两个候选 A{4,4,10}(n=5, w=3 → 均值0.6)和 B{6,9,13}(n=2, w=1 → 均值0.5)。算 UCB1(设 N=7, c=1.4):
    • A:0.6 + 1.4·√(ln7/5) ≈ 0.6 + 0.61 = 1.21
    • B:0.5 + 1.4·√(ln7/2) ≈ 0.5 + 1.21 = 1.71B 被选中(虽均值略低,但访问少,探索项更高)
  2. Expansion :在 B 下生成子节点 B1{6,4,13} 作为新节点 C。
  3. Simulation:从 C 随机 rollout 到终局,假设这次没凑出 24 → reward=0。
  4. Backpropagation :路径 C→B→根n 各 +1,w 不变。B 的均值略降。

注意:这次 B 被"探索"了一次,即便结果不好,下次它的探索项会变小,算法自然回归到更稳的 A。这正是 UCB 的奥妙------不靠一次评估定生死,而靠多次统计收敛

对比 ToT(BFS) :ToT 会让 LLM 评估 B「impossible 就剪掉」。若 LLM 误判,B 里其实藏着的解就永远丢了。MCTS 不剪,只是"少去" ,靠 rollout 统计自然降权------对评估噪声更鲁棒


四、MCTS 在 LLM 推理中的适配(RAP)

MCTS 原本为博弈设计(终局胜负明确)。用到 LLM 推理,关键是怎么定义「状态/动作/奖励」。代表工作是 RAP(Reasoning via Planning,Hao et al., 2023)

4.1 把推理建模成 MDP(马尔可夫决策过程)

MCTS 通用概念 LLM 推理中的对应(RAP)
状态 State 部分推理轨迹(已生成的 thought 序列)
动作 Action LLM 生成的下一个推理步骤
奖励 Reward **世界模型(也是 LLM)**给的信号:「这步多大可能导向正确解」
终局 得到最终答案 / 达到目标状态

4.2 RAP 的核心创新:LLM 当「双角色」

RAP 把同一个 LLM 复用成两个角色:

  • Agent(策略):给定当前状态,生成候选「下一步推理动作」。
  • World Model(世界模型):给定「状态+动作」,预测「执行后的下一个状态」,并给该状态打分("这有多可能通向正确答案")。

这解决了 LLM 推理的一大短板:没有内部世界模型去预判"这一步走了会怎样",只能自回归一路写下去、撞了南墙不回头。RAP 让模型在脑子里"先模拟几步再决定"。

4.3 真实实验结果(LLaMA-33B 设置下)

任务 基线(CoT) RAP(MCTS) 说明
Blocksworld(6 步规划) 近乎 0% 42%(20 轮迭代) 四步内难题平均 64% ;LLaMA-33B+RAP 比 GPT-4+CoT 相对 +33%
GSM8K(数学) 29.4% 48.8%(RAP-Aggregate ≈51.8%) 同一 LLaMA-33B,远超 CoT
PrOntoQA(逻辑证明) 证明准确率 64.8% 78.8%(预测准确率 94.2%) 显著超越 CoT 与 Least-to-Most

最关键的一条 :一个更小的开源模型(LLaMA-33B)+ RAP ,能在规划任务上超过大得多的 GPT-4 + 普通 CoT 。这印证了全系列反复强调的主题------"怎么用模型的推理能力"和"模型本身多大"同样重要


五、MCTS vs BFS/DFS(ToT)vs 其他搜索

MCTS 和 ToT 跑在同一棵树上,差别只在搜索策略:

维度 ToT-BFS ToT-DFS MCTS
遍历方式 逐层、每层留 top-b 一条路深探、死就回溯 UCB1 有偏采样
是否穷举 近似穷举(受 b 限) 单链深探 有意不穷举
剪枝依据 评估器打分 同左 rollout 统计价值
是否需要价值估计 是(一次性) 是(多次累积
对评估器噪声 敏感(误判即误剪) 敏感 更鲁棒(统计对冲)
预算分配 平均/固定宽度 单链 自动集中于有希望分支
参数 b, max_depth max_depth 迭代次数, c(探索常数)

MCTS 的三大相对优势

  1. 预算自动分配:不用手设 b,UCB 自己把算力引向高价值区。
  2. 从早期错误恢复:rollout 统计让"曾被冷落的好分支"仍有机会被翻出。
  3. 对噪声鲁棒:不依赖单次评估定生死。

代价:每次 rollout 都要把轨迹"跑完",LLM 调用数可能比 BFS 还多;且 rollout 质量依赖 World Model / 评估器------评估器烂,统计再多边也是"在烂信号上收敛"。

后续变体(图谱)

  • LATS(Zhou et al., 2023):MCTS 统一到「推理+行动+规划」,用环境反馈引导,HumanEval 达 92.7% Pass@1。
  • LLM-MCTS(Zhao et al., 2023):LLM 当常识世界模型 + 启发式策略。
  • MCTSr / rStar(2024):小模型靠 MCTS 自 refine / 策略-价值互增强。
  • AlphaLLM / AlphaGeometry:MCTS + 自对弈训练,搜出来的树同时当训练信号(类 AlphaZero)。

六、局限性(必读)

MCTS 完整继承了 ToT「外部框架、多次调用」的代价,还多了自己的坑

  1. 必须有可模拟 / 可评估的奖励信号 。围棋有胜负,24 点有"是否=24"。但开放式生成(写文章、闲聊)没有清晰终局奖励,rollout 无从谈起------这类任务 MCTS 用不上。
  2. 评估器 / World Model 不可靠 = 系统性偏差。rollout 和奖励都靠 LLM 自评。若模型对"哪步对"的判断本身错,MCTS 只是在错误信号上越收敛越自信。连回 ToT 第 6 章"评估器致命弱点"。
  3. 计算成本高。每次迭代含 expansion(调 LLM)+ rollout(再调 LLM 跑完)+ 评估,调用数比 ToT-BFS 只多不少。
  4. 探索不足会陷局部。c 太小或预算不够,可能过早锁定非最优分支。
  5. 实现复杂度高于 BFS/DFS。需维护 n/w 统计、UCB 计算、rollout 策略。

适用边界一句话 :只在「有清晰终局奖励、状态可模拟、且需要规划/试错」的任务上才值------数学谜题、规划、逻辑推理、代码生成(编译即免费验证)。其余别上。


七、关键参数怎么选

参数 含义 经验值 怎么调
迭代次数 (budget) 跑多少轮四步循环 几百~几千 越大越准越慢;先小后大找拐点
c(探索常数) UCB 探索项权重 理论 √2,实践 1~2 噪声大→调大;评估准→调小
rollout 策略 模拟时随机还是有引导 随机最省,引导更准 有 cheap verifier 就用确定性 rollout
奖励设计 reward 怎么给 终局对错 / World Model 置信度 最影响成败,优先用确定性 verifier
状态/动作定义 thought 粒度 同 ToT:一步运算 / 一个子问题 太粗搜不动,太细爆炸

经验法则:先用确定性奖励(能代码验证就别让 LLM 自评)+ 适中 c(1.4)+ 迭代次数调到准确率不再涨为止。奖励设计比迭代次数更关键。


八、怎么用(实现)

和 ToT 一样,MCTS 是外部框架,需一段代码驱动。

现成库

  • RAP 官方实现https://github.com/maitrix-org/llm-reasoners(含 Blocksworld / GSM8K / PrOntoQA 的 MCTS 配置)。
  • LATShttps://github.com/ZhangYihan1/LATS(MCTS + 环境反馈统一框架)。

最小骨架(教学版,需接你的 LLM API)

python 复制代码
# 教学骨架:MCTS 四步循环(call_llm / world_model 需接你的 LLM)
def mcts(root_state, budget=500, c=1.4):
    root = Node(root_state)
    for _ in range(budget):
        node = root
        while node.children and not node.to_expand():
            node = max(node.children, key=lambda n: ucb(n, c))   # ① Selection
        if not node.is_terminal():
            thought = call_llm(f"从状态 {node.state} 给出下一步推理:")
            child = Node(thought); node.children.append(child); node = child  # ② Expansion
        reward = rollout(node.state)        # ③ Simulation(最好用确定性 verifier)
        while node:                        # ④ Backpropagation
            node.n += 1; node.w += reward; node = node.parent
    return best_leaf(root)

def ucb(node, c):
    if node.n == 0:
        return float('inf')
    return node.w / node.n + c * (log(node.parent.n) / node.n) ** 0.5

要点:① ucb() 即 UCB1 公式;② rollout 最好用确定性 verifier(如 24 点直接算剩余数是否=24),避免 LLM 自评噪声;③④ 回传即 Backpropagation。


九、为什么这条线值得你串起来

「LLM 推理搜索谱系」四篇到这就闭环了:

CoT(链,模型内部一次生成)→ SC(多链投票)→ ToT(树,BFS/DFS 外部编排)→ GoT(图,聚合/细化)→ MCTS(树,UCB 有偏采样)

一条越来越清晰的规律浮现:

模型「想得对」的上限,不只在模型多大,更在「你用什么结构去组织它的思考」。 链 → 树 → 图 → 带统计的树,本质上是让模型从「一根筋写答案」进化到「会试错、会回头、会拼碎片、会用概率对冲不确定性」。

MCTS 是这条线上把「不确定性」处理得最优雅的一环------它不假装评估器永远对,而是用多次试错 + 统计把噪声对冲掉。


相关推荐
万法若空2 小时前
CSP-J/S 排序算法完整专题训练题单
数据结构·算法·排序算法
凉茶钱2 小时前
【数据结构】排序(快排,选择,直接插入,希尔)
数据结构·算法·排序算法
weixin_446260852 小时前
拆解再复用:大模型智能体的跨任务技能迁移
人工智能·深度学习·算法
Brilliantwxx2 小时前
【Linux】 进程(4)七大进程状态深度解析
linux·运维·算法
青少儿编程课堂2 小时前
用图形化编程做一个“少年探险闯关”小游戏:方向键控制、碰撞检测与多关卡串起完整项目
c++·python·算法·bfs·信息学竞赛
CQU_JIAKE3 小时前
8.22【A】
算法
大熊背4 小时前
ISP图像处理中大数乘法溢出处理(一)
人工智能·python·算法·溢出处理
wabs6664 小时前
关于栈【力扣1047. 删除字符串中的所有相邻重复项的思考】
数据结构·c++·算法·leetcode··代码随想录
疯狂打码的少年4 小时前
【数据结构】选择类排序:简单选择与堆排序
java·数据结构·笔记·算法