详细解释
Tree of Thoughts(ToT,思维树) 是普林斯顿 + Google DeepMind 2023 年论文《Tree of Thoughts: Deliberate Problem Solving with Large Language Models》的成果,也是当前 Agent 框架做复杂规划时默认采用的推理结构之一。
它直接针对 CoT(Chain-of-Thought 思维链)的天生短板——CoT 是线性的,一步错步步错,没法回头。举个例子:解 24 点(4 个数字用加减乘除凑 24),人类会”试一条路 → 发现走不通 → 回溯 → 换一条路”,这是树状搜索;CoT 是”赌一次从头到尾的推理对不对”,不对就没了。
ToT 的三要素:
- 思维状态(State,即树的节点):对 24 点来说 State = “当前已用了哪些数,得到哪些中间值”;对创意写作 State = “已经写好的前 3 段故事大纲”。每个节点都能继续”生长”。
- 思维生成器(Thought Generator):给定当前节点,让 LLM 生成 B 个候选下一步(Branch Factor B = 3 至 5 常用)。
- 状态评估器(State Evaluator / Value Function):给定 K 个候选节点,让 LLM 打分(1 分 至 10 分,或”投票打分”),分数低的剪枝剪掉(别再往下走,省 token)。
- 搜索算法(Search):常见是 BFS(广度优先,每层保留 Top-N)/ DFS + 回溯 / MCTS(蒙特卡洛树搜索,AlphaGo 同款)。
和其他推理范式的对比:
| 范式 | 形状 | 能否回溯/剪枝 | 适合任务 | 每问题 token 消耗 |
|---|---|---|---|---|
| 标准 Prompt | 点(1 步) | ❌ | 简单分类/抽取 | 最少 |
| CoT(思维链) | 线(1 条线性链) | ❌ 错了只能重来 | 中等数学/代码 | 少 |
| SC(自洽性) | 星型(K 条独立链 + 投票) | ⚠️ 间接(靠多样性) | 唯一答案类 | K × CoT |
| ToT(思维树) | 树(多层分支 + 剪枝 + 搜索) | ✅ 剪枝 + 回溯 | 规划/组合/24点/创意大纲 | 中 至 多(取决于剪枝效果) |
| ReAct | 链 + 工具调用 | ✅ 每一步能调用工具观察新信息 | Agent 任务(搜索+计算) | 工具调用相关 |
| Graph of Thoughts | 图(允许节点合并/分叉) | ✅ 合并 | 更复杂的可组合任务 | 多 |
典型 ToT 落地场景(真实工程上哪些真的有用)
| 场景 | ToT 的 State 设计 | 提升效果(经验值) |
|---|---|---|
| 数学竞赛/24点/逻辑谜题 | 状态 = “当前推导到的中间式子 + 已用变量集合” | CoT 基线 50% → ToT 85%+ |
| 创意大纲 / 产品 PRD 撰写 | 状态 = “已写完的章节草稿”,每层生成 5 条候选分节 | 大纲满意度提升 30%,减少返工 |
| 多步代码重构 | 状态 = “重构后的部分代码 diff + 通过的测试用例数” | 代码通过率 +15%,更不容易引入 Bug |
| Agent 任务规划(预订机票+酒店+打车 三件事) | 状态 = “已完成的子任务集合”,BFS 保留 Top-5 计划 | 单链 Agent 成功率 40% → ToT 80%+ |
| RAG 多跳问答(“某公司创始人在创办前就读于哪所大学”) | 状态 = “已检索到的中间事实”,评估器 = “这条路径离最终答案近不近” | 多跳准确率 +20% |
注意:普通 1 步抽取 / 摘要 / 翻译不要上 ToT,纯浪费 Token,CoT 或 Zero-Shot 就够了。ToT 只适合”需要反复尝试+回溯”的多步决策类任务。
最小可运行 ToT 伪代码
# 用 BFS 做 3 层 ToT:每层保留 Top-N 高分状态
def tree_of_thoughts(problem, N_per_level=5, depth=3):
frontier = [initial_state(problem)] # 初始节点
for level in range(depth):
candidates = []
for state in frontier:
# 每个状态用 LLM 生成 B=3 个下一步思维
thoughts = llm_generate_thoughts(state, branch=3)
candidates.extend(thoughts)
# 让 LLM 对每个候选打分 1-10(或让多 LLM 投票)
scored = [(c, llm_score(problem, c)) for c in candidates]
# 剪枝:只保留 Top-N 高分
scored.sort(key=lambda x: x[1], reverse=True)
frontier = [s[0] for s in scored[:N_per_level]]
# 最后从叶子层选最高分 / 结合 SC 做最终答案抽取
return extract_best_answer(frontier)
工程上可配合 唯元智创 做三件事进一步压成本:
- Thought Generator 用便宜模型(如 gpt-4o-mini、Qwen2.5 14B)——“写点子”对模型大小不敏感;
- Evaluator 用强模型(如 Claude 3.5 Sonnet、GPT-4o)——“判好坏”很吃智商;
- 高并发异步化:N_per_level=5, branch=3, depth=3 共有 45 次 LLM 调用,全异步能在 3 至 5 秒内跑完(不是 45 秒)。
常见问题
ToT 和 Agent 框架(LangGraph / AutoGen)是什么关系?
是底层范式 vs 上层框架的关系。ToT 是一种”推理结构”(树 + 评分 + 剪枝),不管是纯 LLM 推理还是带工具的 Agent 都能用。LangGraph、CrewAI、AutoGen 这些 Agent 框架是”执行引擎”,你在引擎里定义的”条件边 + 状态机 + 评分节点”本质就是实现了一棵 ToT。大多数 2025 年的 Agent 产品:规划层用 ToT / 执行层用 ReAct + Tools 是标准搭配。
State Evaluator 打分不准怎么办?
LLM 当 Judge 打分确实有噪声,业界三个补丁:(1)Multi-Judge 投票——让 3 至 5 个不同 System Fingerprint 或不同模型独立打分,取均值/中位数;(2)强制给出打分理由 + 结构化——先输出 3 条打分的 Pros/Cons 再给分,打分稳定性 +15%;(3)用真实信号做 Evaluator——代码场景用单测通过率、游戏场景用游戏得分、搜索场景用检索命中数,这些客观信号比 LLM 主观打分靠谱得多,能上客观就别用主观。
MCTS(蒙特卡洛)和 BFS 在 ToT 里该选哪个?
90% 业务场景 BFS + 每步 Top-N 剪枝就够了,实现简单、可预测、可解释。MCTS(经典 AlphaGo 做法)适合”树非常大(棋盘状态空间)、单步评价很不可靠、可以允许探索-利用权衡”的场景——比如科研探索、长规划任务、生成对抗。MCTS 的实现复杂度是 BFS 的 5 至 10 倍,除非你明确知道你要它,否则从 BFS 开始。