Tree of Thoughts:当LLM学会“分叉思考“——从线性接龙到树状搜索的推理革命
Tree of Thoughts:当LLM学会"分叉思考"——从线性接龙到树状搜索的推理革命
阅读导航:这篇文章会从一道让CoT也束手无策的"24点游戏"开始,先让你看到Tree of Thoughts(ToT)的全貌(宏观),再逐层剥开"思维节点"、"评估函数"和"搜索算法"的内部结构(中观),最后落到单个token如何在分支间流转(微观)。如果你已经熟悉CoT的线性链条、Zero-shot-CoT的触发句,或者OPAR循环的反馈控制,我们会不断用它们作为锚点。准备好了吗?我们出发。
0. 从一个让CoT也头疼的问题开始
来看一道经典题:
用 4、9、10、13 这四个数字,通过加减乘除和括号,得到 24。
如果你用标准的Chain-of-Thought(CoT),模型会生成一条漂亮的线性推理链:
“First, try 13 - 9 = 4. Then 4 × 4 = 16. Then 16 + 10 = 26. Not 24. Hmm…”
然后呢?然后CoT就卡住了。因为它只有一条路,一旦开头选了"13-9",后面就只能在这条路上修修补补,没法回头。这就像你走进一条死胡同,但墙上的油漆还没干——你只能继续往前蹭。
但如果模型能像人类一样分叉思考呢?
“Option A: 13 - 9 = 4… Option B: 10 - 4 = 6… Option C: 13 + 9 = 22…”
然后在每个分叉口都竖一块路牌:“此路不通"或"前景看好”。最终沿着最有希望的分支走到终点。
这就是本文的主角——Tree of Thoughts(ToT, Yao et al., 2023)。别急,这个名字听起来像数据结构课,对吧?但如果我们把它画成图,你会发现它其实很像你在陌生城市里找餐厅的过程。让我们先站在山顶,看看全貌。
1. 宏观视角:ToT的全貌——如果画成一张交通地图
如果我们把模型解决问题的过程画成一张交通地图,会有三条并行的道路:
如果画成图会是什么样子? CoT像一条单行道,一旦开上去就只能踩油门或刹车,不能掉头。Zero-shot-CoT是在单行道入口加了一个导航语音,告诉你"请保持直行",但本质上还是单行道。ToT则像一座立交桥——在每个路口都有多个匝道,而且每个匝道入口都有红绿灯(评估函数),告诉你"此路畅通"或"前方施工"。
关键认知:ToT不是"教"模型生成更多token,而是给模型一个"决策空间",让它能像人类一样在多个中间想法之间比较、选择、回溯。 它把LLM从"接龙选手"升级为"棋手"——每步都考虑多种走法。
2. 中观拆解:四个核心组件里究竟在发生什么?
现在我们已经了解了ToT的全貌,接下来看看它内部的四个核心组件。每节只解决一个认知疑点。
2.1 Thought Node:什么是"思维节点"?——不只是文本片段
我们先问一个直觉问题:在ToT里,“一个想法”(thought)到底是什么?是像CoT里的一句话,还是更像某种数据结构?
别急,答案是:一个thought节点是一个"状态"(state),它封装了从问题开始到当前步骤的所有历史。 用Yao等人的符号表示:
s = [x, z1, z2, …, zi]
其中x是原始问题,z1到zi是到目前为止生成的中间推理步骤。这个节点不是孤立的字符串,而是部分解的完整快照。
锚定已知概念:这很像RNN中的隐藏状态ht。在RNN里,ht编码了从时间步1到t的所有输入历史。ToT中的thought节点si就是推理时间步i的"隐藏状态"——只不过它是显式的文本形式,而不是压缩的向量。不同之处在于,RNN的下一步只由ht决定,而ToT的下一步可以从同一个父节点生出多个子节点——就像RNN突然学会了"平行宇宙"分裂。
听起来抽象对吧?让我们看一个toy example。假设我们的问题极简到只有两个操作:
问题:从数字 2 开始,经过两步运算得到 8。
可用操作:×2 或 +3
根节点 s0 = [“从2开始”]。
第一层展开:
- s1(1) = [“从2开始”, “×2 → 4”]
- s1(2) = [“从2开始”, “+3 → 5”]
第二层从s1(1)展开:
- s2(1,1) = […, “×2 → 4”, “×2 → 8”] ✅ 目标达成!
- s2(1,2) = […, “×2 → 4”, “+3 → 7”] ❌ 未达成
很简单对吧?但在真实规模中,每个节点可能包含数百个token的上下文,而分支因子(branching factor)k可能达到5-10。原理一样,只是规模爆炸了。
2.2 Thought Generation:从"接龙"到"分叉"——Actor的角色
现在我们已经了解了节点结构,接下来看看一个关键疑点:模型怎么知道要生成哪些分支?是随机瞎猜吗?
别急,ToT把LLM当作一个Actor(行动者),通过特定的prompt让它生成候选thoughts。具体来说,有两种生成策略:
- i.i.d.采样:对同一个父节点,独立采样k次,每次生成一个候选thought。就像让模型"头脑风暴",快速列出k个想法。
- Propose Prompt:设计一个专门的prompt,明确要求模型"列出k个不同的下一步"。
视觉化描述:想象Actor是一位厨师,父节点是"当前已切好的食材"。厨师不看菜谱(不依赖确定性规则),而是凭经验和创意(概率生成)提出k种不同的下一步切法。每种切法都是一个候选thought。
这和全连接层有什么关系?如果把LLM的输出层看作一个巨大的Softmax分布,标准CoT只取argmax(贪婪解码)或top-p采样(一条路径)。ToT的Actor则在这个分布上独立采样k次,相当于从同一个概率云里提取k个不同的"量子态"。
渐进披露:先理解小词表的情况——模型只是从{×2, +3}中采样两次。再推广到真实规模:在Game of 24中,模型需要从当前四个数字的状态中,生成所有合法的加减乘除组合作为候选thoughts。分支因子k通常设为3-5,由计算预算决定。
2.3 State Evaluation:谁来做"路牌"?——Critic的角色
现在我们已经了解了如何生成分支,接下来看看一个更微妙的疑点:如果每个节点都生5个分支,深度为5层,那就有55 = 3125个叶节点。模型不可能全部算完。谁来决定哪些分支值得继续探索?
答案是:评估函数(Evaluation Function),也就是ToT中的**Critic(评论家)**角色。它给每个thought节点打分,决定这盏路灯是绿的(继续)还是红的(剪枝)。
问题驱动:评估函数怎么打分?Yao等人提出了几种方案:
- LLM自评(Value Prompt):把thought丢回LLM,问"这个想法离解决目标有多近?请打分1-10"。这听起来像自己给自己看病,但 surprisingly 有效——因为LLM在预训练中见过大量"评估-反馈"文本。
- 投票评估:对同一个thought采样多次评估,取多数决。这利用了Self-Consistency的思想。
- 学习验证器(Learned Verifier):训练一个独立的模型V(s) → ℝ,专门评估thought质量。类似AlphaGo中的价值网络。
锚定已知概念:如果你熟悉神经网络中的分类器,评估函数就像一个二分类器(保留 vs 剪枝),只不过它的输入是一个文本状态s,输出是一个标量值。在强化学习的视角下,这个值就是状态价值函数V(s)——评估从当前状态出发,最终达成目标的期望概率。
在继续之前,让我们回到toy example。假设评估函数是一个简单的规则:“当前数字能否在剩余步数内到达8?”
- s1(1) = […, “×2 → 4”]:还剩一步,4可以×2到8。评估 = promising
- s1(2) = […, “+3 → 5”]:还剩一步,5无法通过×2或+3到达8。评估 = dead end
于是s1(2)被剪枝,模型不会继续探索它的子节点。这就是主动剪枝的力量——它把指数级爆炸的搜索空间压缩到可管理的范围。
2.4 Search Algorithm:BFS vs DFS——导航策略的选择
现在我们已经了解了节点生成和评估,接下来看看最后一个中观疑点:有了节点和评估函数,模型到底怎么遍历这棵树?是像排队买票一样一层层来(BFS),还是像钻地洞一样一条道走到黑再回头(DFS)?
别急,ToT框架提供了两种经典搜索策略,适用于不同类型的任务:
视觉化描述:
- BFS像排队安检。所有人先过第一层安检,合格的进入第二层,再全部过第二层安检… 每层只保留最 promising 的b个节点(beam width)。Yao等人在Game of 24中使用BFS,因为树的深度很浅(通常3-4步就能完成24点),而且需要比较不同开局的优劣。
- DFS像钻地洞。选一个洞一直钻到底,如果发现是死胡同,就退回到上一个分叉口,换另一个洞钻。在Mini Crosswords中,ToT使用DFS,因为填字游戏需要连续填10个以上的词,BFS会在中间层爆炸(每层的候选词太多)。
渐进披露:先理解极简情况——我们的"2到8"问题只有两层,BFS和DFS没区别。再推广到真实规模——Game of 24的BFS在每层评估5个候选,保留Top-3,深度3层,总共只探索约33 = 27个节点,而不是53 = 125个。这就是beam search的思想:用评估函数做概率剪枝。
3. 微观视角:Token与概率如何在树中流转?
现在我们已经了解了中观层面的四个组件,接下来看看最微观的层面:当模型生成一个thought节点时,token级别的概率流到底发生了什么变化?别急,这部分我们从一个toy example开始,再推广到真实规模。
3.1 Toy Example:极简算术树的概率展开
问题:用 2, 3 通过两步运算得到 10。可用操作:×2, +3, ×3。
不加ToT时,CoT的解码是一条直线:
输入: [Q, "Step 1:"]
→ "2 + 3 = 5" (P=0.4)
→ "Step 2: 5 × 2 = 10" (P=0.3 | 上一步)
→ 答案: 10 ✅
但如果第一步模型不幸采样到"2 × 3 = 6"(P=0.35),第二步就卡死了:
→ "2 × 3 = 6" (P=0.35)
→ "Step 2: 6 + 3 = 9" (P=0.5 | 上一步)
→ 答案: 9 ❌
CoT没有后悔药。ToT则不同。在ToT中,第一步不是只采样一个thought,而是并行采样k=3个候选:
从根节点 s0 = ["用2,3得到10"] 展开:
候选 z<sup>(1)</sup>: "2 + 3 = 5" P(z<sup>(1)</sup>|s0) = 0.40
候选 z<sup>(2)</sup>: "2 × 3 = 6" P(z<sup>(2)</sup>|s0) = 0.35
候选 z<sup>(3)</sup>: "3 × 3 = 9" P(z<sup>(3)</sup>|s0) = 0.15
评估函数(这里用一个简单规则:“当前结果能否在一步内到10?”)打分:
- v(s1(1)) = 0.9(5可以×2到10)
- v(s1(2)) = 0.2(6无法一步到10)
- v(s1(3)) = 0.1(9无法一步到10)
BFS策略保留Top-b=1(只保留s1(1)),然后继续展开:
从 s1<sup>(1)</sup> = [..., "2+3=5"] 展开:
候选 z<sup>(1,1)</sup>: "5 × 2 = 10" P = 0.80
候选 z<sup>(1,2)</sup>: "5 + 3 = 8" P = 0.15
评估:v(s2(1,1)) = 1.0(目标达成!),终止搜索,输出10。
啊哈时刻:注意概率的变化!在标准CoT中,正确答案路径的整体概率是 P(z(1)) × P(z(1,1)|z(1)) = 0.40 × 0.80 = 0.32。但ToT通过显式展开和评估,确保即使某条路径的初始概率不是最高(比如0.40 vs 0.35),只要评估认为它promising,就会深入探索。这就像一个概率放大镜:把局部概率高但全局死胡同的路径过滤掉,把全局有希望的路径放大。
3.2 推广到真实规模:注意力头的"分叉"与"评估"
在真实LLM中,上述过程涉及数百亿参数。研究表明,ToT的"分叉生成"可能激活了Transformer中的特定机制:
- 生成阶段:模型对同一个父节点做k次独立前向传播(或一次batch forward),每次用不同的随机种子或temperature。这相当于在解码空间的局部区域做蒙特卡洛采样。
- 评估阶段:当LLM作为Critic评估自身生成的thought时,它实际上在做条件概率判断:P(“yes” | “Is this thought promising?” + thought_text)。这个概率被用作价值分数。
锚定已知概念:如果你熟悉束搜索(Beam Search),ToT-BFS本质上就是一种带有LLM评估器的自适应Beam Search。标准Beam Search用序列概率(log-likelihood)作为评分,ToT用LLM的语义评估作为评分。后者更灵活,但也更昂贵(需要额外的LLM调用)。
4. 结构化伪代码:ToT的精确描述
好了,现在我们已经了解了直觉和微观概率流,接下来看看如果用结构化伪代码描述ToT,会是什么样子。
4.1 ToT 通用主框架
算法 1: Tree of Thoughts 通用框架
输入: 问题 x, LLM Actor ℳ<sub>actor</sub>, LLM Critic ℳ<sub>critic</sub>,
分支因子 k, 保留宽度 b, 最大深度 D<sub>max</sub>, 搜索策略 𝒮 ∈ {BFS, DFS}
输出: 最终答案 A, 最优路径 z<sup>*</sup>
1: procedure TREE_OF_THOUGHTS(x, ℳ<sub>actor</sub>, ℳ<sub>critic</sub>, k, b, D<sub>max</sub>, 𝒮)
2: s<sub>0</sub> ← INITIALIZE_STATE(x) ▷ 根节点仅包含问题
3: 𝒯 ← {s<sub>0</sub>} ▷ 初始化搜索树
4:
5: if 𝒮 = BFS then
6: return BFS_SEARCH(𝒯, ℳ<sub>actor</sub>, ℳ<sub>critic</sub>, k, b, D<sub>max</sub>)
7: else if 𝒮 = DFS then
8: return DFS_SEARCH(𝒯, ℳ<sub>actor</sub>, ℳ<sub>critic</sub>, k, D<sub>max</sub>)
9: end if
10: end procedure
4.2 BFS 变体(广度优先+束剪枝)
算法 2: ToT-BFS 搜索
输入: 搜索树 𝒯, ℳ<sub>actor</sub>, ℳ<sub>critic</sub>, k, b, D<sub>max</sub>
输出: 最终答案 A
1: procedure BFS_SEARCH(𝒯, ℳ<sub>actor</sub>, ℳ<sub>critic</sub>, k, b, D<sub>max</sub>)
2: 𝒬 ← {s<sub>0</sub>} ▷ 初始化队列,含根节点
3:
4: for d ← 1 to D<sub>max</sub> do
5: 𝒬<sub>next</sub> ← ∅
6:
7: ▷ ====== 第一步: 展开所有当前节点 ======
8: for each s ∈ 𝒬 do
9: if IS_TERMINAL(s) then
10: return EXTRACT_ANSWER(s)
11: end if
12:
13: ▷ 从Actor生成k个候选thoughts
14: 𝒞 ← ℳ<sub>actor</sub>.GENERATE_CANDIDATES(s, k)
15:
16: for each z ∈ 𝒞 do
17: s<sub>child</sub> ← EXTEND_STATE(s, z)
18: 𝒬<sub>next</sub> ← 𝒬<sub>next</sub> ∪ {s<sub>child</sub>}
19: end for
20: end for
21:
22: ▷ ====== 第二步: 评估与剪枝 ======
23: 𝒱 ← ∅
24: for each s<sub>cand</sub> ∈ 𝒬<sub>next</sub> do
25: v ← ℳ<sub>critic</sub>.EVALUATE(s<sub>cand</sub>)
26: 𝒱 ← 𝒱 ∪ {(s<sub>cand</sub>, v)}
27: end for
28:
29: ▷ 保留Top-b个最有希望的节点
30: 𝒬 ← TOP_B(𝒱, b)
31:
32: ▷ 可选: 将剪枝信息写回上下文
33: LOG_PRUNING_INFO(𝒬<sub>next</sub> \ 𝒬)
34: end for
35:
36: ▷ 达到最大深度,从队列中选最优
37: s<sub>best</sub> ← argmax<sub>s ∈ 𝒬</sub> ℳ<sub>critic</sub>.EVALUATE(s)
38: return EXTRACT_ANSWER(s<sub>best</sub>)
39: end procedure
注意看第30行。TOP_B操作是BFS的核心——它把指数增长的候选空间压缩到固定宽度b。这就像水库的闸门,只允许b股水流通过,其余全部截流。
4.3 DFS 变体(深度优先+回溯)
算法 3: ToT-DFS 搜索
输入: 搜索树 𝒯, ℳ<sub>actor</sub>, ℳ<sub>critic</sub>, k, D<sub>max</sub>
输出: 最终答案 A
1: procedure DFS_SEARCH(𝒯, ℳ<sub>actor</sub>, ℳ<sub>critic</sub>, k, D<sub>max</sub>)
2: s<sub>current</sub> ← ROOT(𝒯) ▷ 从根节点开始
3:
4: while NOT_EMPTY(STACK) do
5: if IS_TERMINAL(s<sub>current</sub>) then
6: if VERIFY_ANSWER(s<sub>current</sub>) then
7: return EXTRACT_ANSWER(s<sub>current</sub>)
8: else
9: ▷ 答案错误,回溯
10: s<sub>current</sub> ← BACKTRACK(STACK)
11: CONTINUE
12: end if
13: end if
14:
15: if DEPTH(s<sub>current</sub>) ≥ D<sub>max</sub> then
16: s<sub>current</sub> ← BACKTRACK(STACK)
17: CONTINUE
18: end if
19:
20: ▷ ====== 生成与评估 ======
21: 𝒞 ← ℳ<sub>actor</sub>.GENERATE_CANDIDATES(s<sub>current</sub>, k)
22:
23: ▷ 按评估值降序排列,优先探索高分分支
24: for each z ∈ 𝒞 do
25: s<sub>child</sub> ← EXTEND_STATE(s<sub>current</sub>, z)
26: v ← ℳ<sub>critic</sub>.EVALUATE(s<sub>child</sub>)
27: PUSH(STACK, (s<sub>child</sub>, v))
28: end for
29:
30: ▷ 选择栈顶最有希望的分支深入
31: s<sub>current</sub> ← POP_MOST_PROMISING(STACK)
32: end while
33:
34: return FAILURE
35: end procedure
注意看第10行的BACKTRACK。这是DFS的灵魂——当一条路径走到死胡同时,模型不是放弃整个任务,而是弹出栈顶,回到上一个分叉口。这和OPAR循环中的Reflect触发REPLAN非常相似,但ToT的REPLAN是结构化的、通过栈实现的,而不是通过上下文窗口的文本重写。
4.4 评估函数:LLM-as-Critic 的实现
算法 4: LLM-as-Critic 评估
输入: 候选状态 s, 评估提示模板 P<sub>eval</sub>, 阈值 θ<sub>prune</sub>
输出: 价值分数 v ∈ [0, 1], 决策标签 label ∈ {PROMISING, DEAD_END, TERMINAL}
1: procedure LLM_CRITIC_EVALUATE(s, P<sub>eval</sub>, θ<sub>prune</sub>)
2: prompt ← RENDER_TEMPLATE(P<sub>eval</sub>, s)
3: ▷ 例如: "Evaluate if the following thought is promising to solve the problem.
Thought: {s}
Answer yes or no, then rate 1-10."
4:
5: response ← ℳ.GENERATE(prompt, temperature=0.0)
6:
7: ▷ 方法A: 从文本响应解析分数
8: if CONTAINS(response, "yes") then
9: v ← EXTRACT_NUMBER(response) / 10.0
10: else
11: v ← 0.0
12: end if
13:
14: ▷ 方法B: 使用logits概率(更精确)
15: ▷ v ← P<sub>ℳ</sub>("yes" | prompt) ▷ 下一个token为"yes"的概率
16:
17: ▷ 决策逻辑
18: if IS_COMPLETE_SOLUTION(s) then
19: label ← TERMINAL
20: else if v ≥ θ<sub>prune</sub> then
21: label ← PROMISING
22: else
23: label ← DEAD_END
24: end if
25:
26: return (v, label)
27: end procedure
注意看第15行被注释掉的方法B。这是RAP(Hao et al., 2023)论文中使用的高级技巧:不解析文本,而是直接看LLM输出"yes"的logit概率作为连续值评分。这比离散打分更细粒度,也更稳定。
5. 与已知概念的对话:ToT站在谁的肩膀上?
5.1 ToT vs CoT/Zero-shot-CoT:从单行道到立交桥
现在我们已经了解了ToT的内部机制,接下来看看一个关键的对比疑点:如果Zero-shot-CoT已经能让模型"逐步思考",为什么还需要ToT?
因为Zero-shot-CoT解决的是"怎么一步步想",ToT解决的是"想错了怎么回头"。这是两个维度的问题。
锚定已知概念:如果你熟悉有限状态机(FSM),CoT就像一个确定性有限自动机(DFA)——每个状态只有一个出边。ToT像一个非确定性有限自动机(NFA)——每个状态有多个出边,搜索算法负责"模拟"NFA到DFA的转换。GoT则更进一步,允许状态之间有循环边(比如把两个子问题的答案聚合后再精炼)。
5.2 ToT vs OPAR循环:树搜索 vs 闭环控制
如果你读了OPAR循环的文章,你可能会问:OPAR有Observe-Plan-Act-Reflect的循环,ToT有树搜索,它们是什么关系?
答案是:OPAR是"时间维度"的循环,ToT是"空间维度"的展开。
视觉化描述:想象你在玩一个复杂的RPG游戏。OPAR是你的"宏观策略循环"——观察地图、制定战略、执行动作、反思战果。ToT是你打开背包后,面对"如何合成最强武器"时的内部配方搜索——你脑子里展开了一棵树:“用A+B合成C?不行,材料不够。用A+D合成E?评估一下, promising。继续深入…”
在生产级Agent中,这种混合架构已经出现:OPAR负责"做什么"(任务级),ToT负责"怎么做"(推理级)。
6. 边界与成本:ToT不是免费的午餐
6.1 组合爆炸:评估开销的隐藏账单
现在我们已经了解了ToT的强大,接下来看看它的致命弱点:如果每个节点生5个分支,深度5层,BFS每步评估所有候选,总共需要多少次LLM调用?
算一笔账:
- Actor调用:每层每个保留节点生成k个候选。BFS中,第1层1个节点→5个候选,第2层保留b=3个→3×5=15个候选… 总Actor调用 ≈ O(bd-1 × k)。
- Critic调用:每个候选都要评估。总Critic调用 ≈ O(bd-1 × k)。
- 总成本:假设k=5, b=3, d=4,总调用 ≈ 33 × 5 × 2 ≈ 270次LLM前向传播。
对比CoT的1次调用,ToT贵了两个数量级。
渐进披露:先理解极简情况——我们的"2到8"问题只有两层,总调用 = 1(根) + 2(第一层Actor) + 2(第一层Critic) + 1(第二层Actor) = 6次。再推广到真实规模:Game of 24的论文中,ToT的成功率从CoT的7.3%提升到74%,但代价是数百倍的API调用。这就是**测试时计算(test-time compute)**的经典权衡:用计算换准确率。
6.2 评估的脆弱性:Critic也会犯错
另一个隐蔽的约束:如果Critic评估错了怎么办?
假设Critic给一条正确路径打了低分(假阴性),或者给错误路径打了高分(假阳性)。在BFS中,假阴性意味着正确路径被提前剪枝,永远找不到答案。在DFS中,假阳性意味着模型会沿着死胡同一路钻到底,浪费大量计算。
这和全连接层的分类误差完全类似。Critic本质上是一个二分类器(保留/剪枝),它的准确率直接决定了搜索效率。Yao等人的实验表明,即使使用LLM自评,Critic的评估也不是完美的——它只是比随机好得多,但仍有约10-20%的误判率。
7. 生产环境中的ToT:这到底意味着什么?
好了,原理和边界都讲完了。但"这在训练/实际使用中意味着什么?"
7.1 在训练时意味着什么
ToT是纯推理时技术(inference-time technique),但它创造了独特的训练机会:
-
过程监督数据(Process Supervision):ToT生成的完整搜索树——包括被剪枝的失败路径和保留的成功路径——是训练**过程奖励模型(PRM)**的绝佳数据。OpenAI的论文(Lightman et al., 2024)证明,用PRM替代最终答案奖励,能显著提升推理准确率。
-
策略蒸馏(Policy Distillation):用大模型(GPT-4)运行ToT生成的高质量推理路径,蒸馏到小模型(Llama-3-8B)中。让小模型学会"一步生成正确的thought",而不需要显式搜索。
-
验证器训练(Verifier Training):用ToT的评估日志训练一个轻量级验证器,替代昂贵的LLM-as-Critic。这类似于AlphaGo训练价值网络来替代昂贵的蒙特卡洛 rollout。
7.2 在实际使用中的最佳实践
如果你明天就要在生产环境部署ToT,这里有几个硬核建议:
| 生产要素 | 具体含义 | 最佳实践 |
|---|---|---|
| 任务选择 | 不是每个问题都需要ToT | 简单算术用Zero-shot-CoT,创意写作用ToT-BFS,填字游戏用ToT-DFS。 |
| 预算控制 | Token和API调用爆炸 | 设置全局调用上限Nmax;使用学习验证器替代LLM-Critic;启用缓存。 |
| 早期终止 | 找到答案后继续搜索是浪费 | 在DFS中,一旦VERIFY_ANSWER返回true,立即终止。 |
| 自适应束宽 | 不同深度需要不同粒度 | 浅层用宽束(b=5)探索多样性,深层用窄束(b=2)聚焦精细搜索。 |
| 评估一致性 | Critic的随机性导致结果波动 | 对关键节点做多次评估取平均(类似Self-Consistency)。 |
| 与Agent集成 | ToT作为子模块嵌入OPAR | 在OPAR的Plan阶段调用ToT搜索子计划,Act阶段执行最优路径。 |
8. 闭环总结与延伸阅读
让我们回到开头那个Game of 24的问题。现在你应该能看懂了:
模型不是"更聪明了"——它的权重一点没变。而是更会"逛街"了。CoT像一条直线商业街,你只能从街头走到街尾,遇到死胡同就傻站着。ToT像一座购物中心——每层都有多个店铺(thought节点),你在每个路口都看指示牌(评估函数),只进最有希望的店,遇到关门马上就退出来换一家(回溯)。
如果画成一张最终的总结图,ToT就像一台带有"多重宇宙导航仪"的推理引擎:Actor负责"制造平行宇宙",Critic负责"评估哪个宇宙有前途",Search算法负责"决定先探索哪个宇宙"。
而是给模型一个"可以后悔"的 -----------------------^ Expecting 'SQE', 'DOUBLECIRCLEEND', 'PE', '-)', 'STADIUMEND', 'SUBROUTINEEND', 'PIPE', 'CYLINDEREND', 'DIAMOND_STOP', 'TAGEND', 'TRAPEND', 'INVTRAPEND', 'UNICODE_TEXT', 'TEXT', 'TAGSTART', got 'STR'
延伸阅读
如果你想深入这个领域,以下国外文献是极佳的起点:
-
Yao et al., 2023, “Tree of Thoughts: Deliberate Problem Solving with Large Language Models” (NeurIPS 2023) —— ToT的奠基论文。核心贡献:将LLM推理建模为组合搜索空间上的树搜索,提出Actor-Critic-Search三元架构,在Game of 24上将成功率从CoT的7.3%提升到74%。必读。
-
Wei et al., 2022, “Chain-of-Thought Prompting Elicits Reasoning in Large Language Models” (NeurIPS) —— 理解ToT的最佳背景。看清CoT的线性局限,才能理解ToT为何必要。
-
Besta et al., 2024, “Graph of Thoughts: Solving Elaborate Problems with Large Language Models” —— ToT的直接进化版。将树结构扩展为有向图,支持聚合(Aggregation)、精炼(Refining)和循环(Cyclic)操作,适合需要多路径融合的任务。
-
Hao et al., 2023, “Reasoning with Language Model is Planning with World Model” (RAP) —— 用蒙特卡洛树搜索(MCTS)替代BFS/DFS,LLM同时作为世界模型和推理Agent。展示了更高效的搜索策略。
-
Lightman et al., 2024, “Let’s Verify Step by Step” (OpenAI) —— 过程监督的里程碑论文。证明用PRM(过程奖励模型)评估每一步比只评估最终答案更有效,为ToT的Critic设计提供了理论支撑。
-
Long, 2023, “Large Language Model Guided Tree-of-Thought” —— 引入强化学习训练的"ToT Controller"动态调整搜索策略,而非固定使用BFS或DFS。
-
Sel et al., 2024, “Algorithm of Thoughts” —— 探索在单次LLM调用中模拟算法搜索,试图用上下文内的"思维算法"替代显式的多轮API调用,是ToT的轻量化方向。
写在最后:Tree of Thoughts提醒我们一个深刻的道理——智能的本质不总是"知道更多",有时候是"知道如何尝试更多,并知道何时放弃"。ToT给LLM的礼物不是知识,而是选择的自由和评估的智慧。下次当你面对一个复杂问题时,不妨也学学ToT:不要急着一条路走到黑,先在脑子里展开几棵树枝,看看哪片叶子最绿。
本文架构图使用 Mermaid 绘制,伪代码遵循结构化算法描述规范。数学上下标使用 HTML 标签(sub/sup)以确保跨平台兼容。如有错误,欢迎指出。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐


所有评论(0)