ToT 之后呢?Graph of Thoughts 让大模型学会「把好思路的碎片拼成一条更好的路」,128 位排序错误率仅为 ToT 的 38%

上一讲我们聊了 Tree of Thoughts(ToT,思维树):它让大模型从「一根筋写一条链」,进化到「想多条路、能试错、能回头」,把 24 点成功率从 4% 干到 74%。

那 ToT 是不是终点了?

不是。ToT 的树有一个结构性硬伤:每个节点只能有一个父节点 → 分支一旦分开,就永远不能汇合。

这听起来很学术,但后果极其反直觉。我用一个排序题让你秒懂。


〇、一个让 ToT 当场露怯的题

[8, 3, 5, 1, 9, 2, 7, 4] 从小到大排好。

用 ToT 的思路,先拆两半各自排:

  • 分支 A 把前半 [8,3,5,1] 排成了 [3,5,1,8](66% 已有序)
  • 分支 B 把后半 [9,2,7,4] 排成了 [2,7,4,9](66% 已有序)

关键来了:A 的前半里藏着正确顺序的碎片,B 的后半里也藏着。但 ToT 是「树」——它只能二选一,保留 A 或 B 里更好的那个,天花板死死卡在 66%

无法把「A 的前半 + B 的后半」拼起来——因为树没有「多父节点」这种边。

而真实世界里,大量好答案恰恰来自「把不同分支的好片段拼成一条更好的整体」:排序要 merge、集合要取交集、多份文档要合并、多源事实要汇总。

Graph of Thoughts(GoT,思维图,Besta et al., 2023)就是为这件事而生的:把推理建模成任意有向图(可带环),从而多出树做不到的两个原语——聚合(多→1 合并)细化(自环改进)

一句话点题三种范式:

CoT 是「想一条路」;ToT 是「想多条路、能回头」;GoT 是「想多条路、还能把好路的碎片拼成一条更好的路」。


一、GoT 是什么:从链到树再到图

GoT = 把 LLM 的推理建模成一张任意图

  • 顶点(vertex) = 一个「thought(思维)」,即一个中间推理产物(半成品答案、草稿、子结论)。
  • 边(edge) = thought 之间的依赖关系(这个想法由那个想法派生 / 聚合 / 细化而来)。

图被写成 G = (V, E, c):V 是 thought 集合,E 是依赖边,c 是节点类别标注 c ∈ {input, intermediate, output}(框架靠它识别哪个是最终答案、哪个要评估)。

三范式结构对比:

范式拓扑每个节点的父独有原语能否回溯能否聚合
CoT链(线性)1(前驱)
ToT1生成 / 评估 / 回溯
GoT任意图(可带环)可多个生成 / 评估 / 聚合 / 细化

关键结论:GoT 严格泛化(是超集)CoT 与 ToT。“chain < tree < graph” 应理解为「graph 包含前两者」,而非并列第三档。ToT 的 BFS/DFS 都能用「合适的图 + Reduce 算子」在 GoT 框架里表达。


二、GoT 不是什么(先排 4 个坑)

  • 不是模型内部能力:和 ToT 一样,是套在模型外面的编排框架,不是权重里焊死的功能(那是 o1 / Claude 思考这类「推理模型」)。模型永远只是被反复调用的「子程序」,图 / 聚合 / 细化全是外部代码在管。
  • 不是一句 prompt:你不能「加一句 Let’s think in a graph」就触发它,需要一段 Controller 代码维护状态图、循环调模型。
  • 不是 Workflow(工作流):二者都长「节点 + 边」,但语义相反(见第五节)。
  • 不是银弹:它调用数最多、最贵,只在「能分解且子结果需合并」的任务上才值。

三、核心机制:GoO / GRS 两层抽象 + 五大算子

3.1 架构总览

GoT 由 Controller 协调,包含两个核心元素:

元素全称性质何时构建职责
GoOGraph of Operations(操作蓝图)静态执行前构建一次声明用哪些算子、怎么连、图长啥拓扑(“图纸”)
GRSGraph Reasoning State(推理状态)动态执行中持续更新维护哪些操作已执行、所有 thought 的状态 / 有效性 / 分数

外加三个模块:Prompter(准备提示)、Parser(抽取信息)、Scoring(验证并打分)。

为什么这层分离重要:它让「换图结构」变成改配置(GoO),而不是改代码。不同任务就是不同的 GoO 图纸,运行时实例化出不同的 GRS。

3.2 五大算子(thought transformations)

论文定义了作用在 thought 上的算子,前四个是核心、第五个 Reduce 常被遗漏

算子作用是否 GoT 独有
Generate(生成)从一个 thought 产出多个候选否(CoT/ToT 都有)
Score(评分)给 thought 打分 / 验证否(ToT 有)
Aggregate(聚合)多个 thought 融合成一个全新的(内容合并)是 ★
Refine(细化)一个 thought 自己改进自己(自环)是 ★
Reduce(缩减)把 N 个 thought 压成 k 个保留(不合并内容)是(论文常写 KeepBest(N))

Aggregate vs Reduce 易混,必须分清

  • Aggregate = 「合多为一(内容融合)」——结果是一个新 thought,内容来自多个父。
  • Reduce = 「从多里挑少(集合缩减)」——结果还是那几个 thought 本身,只是数量变少。
  • 例:排序里「把 8 段各排好的分支 Reduce 成 top-2 进入下一轮合并」是 Reduce;「把两段已排序序列 merge 成一个更长有序序列」是 Aggregate

四、实战:排序案例完整走查

题目:把 [8,3,5,1,9,2,7,4] 从小到大排好。GoT 用 merge-based sorting(分治排序)

① Generate:外部代码把任务拆成「先各排一半」,调模型两次:

  • A = [3,5,1,8](前半,66% 有序)
  • B = [2,7,4,9](后半,66% 有序)

② Score:给 A、B 各打分(这里用「已有序比例」:66% / 66%)。

停在这里,如果只用 ToT(树),算法只能二选一,天花板卡在 66%——因为树不能汇合。

③ Aggregate(聚合,GoT 独有)★:外部代码把 A 和 B 合并成一个新 thought

  • merge(A, B)[2,3,5,1,7,4,8,9],Score 升到 71%

关键点:没有任何一条分支单独含着全部正确顺序。是「合并」把两半的好片段出来的——树做不到,只有图能汇合。

④ Refine(细化,GoT 独有):让模型拿合并结果自己改进自己(图里 Refine 框的自环箭头):做一次相邻交换打磨 → 得到 100% 排好的最终结果(标记为 output 节点)。

⑤ 终止:遇到 output 类别节点,或达到 max-depth,Controller 停止并输出。

同题对比(为什么 GoT 更强):论文在 128 位数字排序上,GoT 错误率仅为 ToT 的 38%(即相对改进 62%),同时成本还降了 >31%——因为「聚合」复用了各分支的好片段,不必重复生成。

代价:每次聚合 / 细化都要额外调模型,调用数比 ToT 还多。原则是 chain < tree < graph,用最小够用的结构。纯数学用 SC、要试错回溯用 ToT、要「拼碎片」才上 GoT。


五、最容易误解的点:模型根本不知道自己在「图」里

很多人以为 GoT 是模型「自己画出一张图在思考」——。和 ToT 一样,模型每次只接到一段 prompt,吐出一段文字,然后外部代码把结果存进自己的数据结构,决定下一步再喂给它什么。

框架结构在哪模型被调用几次
CoT输出 token 序列里(一次生成)1 次
ToT外部 Python 代码的树N 次
GoT外部 Python 代码的图N 次(更多)

核心澄清:GoT/ToT 里,模型根本不知道自己在「树」或「图」里,它只是一个被反复调用的子程序。树 / 图、剪枝、回溯、聚合——全是你写的代码在管。

而真正的「模型内部」是推理模型(o1 / Claude 思考 / Gemini thinking):权重在 RL 训练时被改过,"先想后答"焊进模型本身——但那内部也没有显式的树或图结构,只是默认多生成一串隐藏推理 token。

一句话:CoT 是模型「内部」最轻量的推理增强(一句话提示就自己写链);ToT/GoT 是「系统层面」的外部编排(得写代码)。 三者里只有 CoT 是模型自己一次生成的。


六、GoT 与 Workflow 的关系(同形不同义)

很多人以为「GoT 是基于 Workflow 的」——。两者是两层正交结构,只是视觉上都长「节点 + 边」。

维度GoT(推理图)Workflow(执行图 / DAG)
节点一个 thought(中间推理产物)一个操作算子(调 API、跑工具、存库)
推理依赖:「这想法从那想法派生 / 聚合 / 细化」控制 / 数据流:「做完 A 然后做 B」
拓扑谁定运行时由搜索算法发现(你只写连边规则)开发时由你写死(DAG 骨架每次一样)
目的在未知推理空间里搜索好答案(提升质量)把已知流程可靠跑完(提升可靠性)
确定性非确定:每次结果图不同确定:给定输入走法基本固定
  • GoT 的图是「搜索出来的推理地图」,Workflow 的图是「你设计的操作说明书」。
  • 真实关系:正交、可嵌套。你可以在 Workflow 的某个节点内部跑 GoT:[读取需求] → [规划节点(内部跑 GoT)] → [执行节点] → [检查]。外层 Workflow,里层 GoT,各管一层。

七、思想级并行:为什么 GoT「调用多却还能省」

GoT 每次聚合 / 细化都额外调模型,调用数比 ToT 还多——但论文说成本反而降 >31%。秘密是并行

  • CoT/ToT 的 DFS 往往串行(一条分支走死才换下一条)。
  • GoT 的图天然可并行:不同分支的 thought 可以同时批量发给模型。延迟被摊薄,整体 wall-clock 反而短。
  • 这不是「更少调用」,是「并行摊薄」——ToT(树)很难做到的隐藏优势。

论文还提出 「思想的体积」(Volume of a thought) 指标:定义为「给定 thought 可以从多少个先行 thought 到达」,用来刻画某个推理结果汇聚了多少信息广度。从侧面印证 GoT 的核心价值——让信息跨分支汇聚


八、任务 → 图模板映射(GoO 配置表)

不同任务,GoO 图纸不一样。论文给了四类真实用例:

任务图结构模板(GoO)关键算子
Sorting(排序)分治 + 多步 Aggregate(merge-sort 式)Generate → Score → Aggregate(k) → Refine
Set operations(集合运算)单次 Aggregate拆分子集 → 各自求交 → Aggregate
Document merge(文档合并)层级 Aggregate(两两合并再合并)多源抽取 → 分层 Aggregate
Keyword counting(关键词计数)分治 Reduce分段处理 → Reduce 聚合计数

九、局限性与不适用场景(必读,否则 GoT 显得无敌)

GoT 完整继承了 ToT 的弱点,还更贵

  1. 调用数最多:每次聚合 / 细化都额外调模型,比 ToT 更烧钱。
  2. 聚合函数要手工设计:怎么把多个 thought 拼成合法输入喂给模型,是工程难点,不是开箱即用。
  3. 评估器同样不可靠:继承 ToT 的「误判」——评估器看走眼会剪错 / 留错。
  4. 并非所有任务可聚合:很多任务子结果不可合并(如「写一首诗」没有 halfway 可拼),硬上 GoT 反而乱。
  5. 小模型不行:评估器 / 聚合器本身得够强。
  6. 环有无限循环风险:Refine 自环必须配 max-depth / output 类别 终止条件,否则会一直「改进自己」到刷爆账单。

适用边界一句话:只有「能分解、且子结果需要合并成更好整体」的任务才值——排序、集合运算、文档合并、多源事实整合。其余别炫技。


十、论文实测结果(已核对原论文 Besta et al., 2023)

任务GoT 表现
Sorting(排序)质量比 ToT 高 62%,同时成本 降 >31%;128 元素时中位数误差比 ToT 减约 62%
规模效应改进随问题规模增大而显著:32 元素微不足道,64 元素约 61%,128 元素约 69%
相对 CoT / IO排序质量比 CoT 高约 70%、比 IO 高约 83%
Set intersection(集合交集)错误元素数显著少于其他方法
Keyword counting(关键词计数)错误率显著降低,且成本合理
Document merge(文档合并)得分高于基线,能结合部分重叠信息、最小化冗余

规律:GoT 的优势随问题复杂度上升而放大——越需要「分解 + 聚合」的复杂任务,越该用图而非链 / 树。


十一、怎么用 GoT(官方库)

GoT 也不是「换个提示词」,而是用框架代码跑。官方实现是 spcl/graph-of-thoughts(GitHub),配置驱动:你写一份 GoO 配置(用哪些算子、什么拓扑),它实例化跑 GoT。

安装(Python 3.8+):

pip install graph_of_thoughts
# 或开发者从源码可编辑安装:
git clone https://github.com/spcl/graph-of-thoughts.git
cd graph-of-thoughts && pip install -e .

最小用法(排序 32 个数,来自官方 README,真实可用)

from examples.sorting.sorting_032 import SortingPrompter, SortingParser, got, utils
from graph_of_thoughts import controller, language_models, operations

input_to_be_sorted = "[0, 2, 6, 3, 8, 7, 1, 1, 6, 7, 7, 7, 7, 9, 3, 0, 1, 7, 9, 1, 3, 5, 1, 3, 6, 4, 5, 4, 7, 3, 5, 7]"
gop = got()                                   # 预置 GoO 图纸(merge-sort 式图)
lm = language_models.ChatGPT("config.json", model_name="chatgpt")
ctrl = controller.Controller(
    lm, gop, SortingPrompter(), SortingParser(),
    {"original": input_to_be_sorted, "current": "", "phase": 0, "method": "got"},
)
ctrl.run()
ctrl.output_graph("output_got.json")          # 最终 thought 的分数 = 排序错误数

同样的库,把 gop 换成 operations.GraphOfOperations() + Generate + Score + GroundTruthmethod 改成 "cot",就是用 GoT 框架跑纯 CoT——这正说明 GoT 是 CoT/ToT 的超集,框架可降级表达旧范式。

套用到你自己的任务(四步)

  1. 定义 thought 粒度:一个 thought 该多大?
  2. 写评估器,优先确定性 verifier:能写代码判对错就别让 LLM 自评(如排序直接数错误数),从根上缓解评估器不可靠。
  3. 选图模板:要「拼碎片」用多层 Aggregate;要「挑少」用 Reduce(KeepBest)。
  4. 加护栏:设 max-depth、总 LLM 调用上限,防环和树爆炸刷爆账单。

十二、为什么你现在该把这条线串起来

推理结构的演进主线很清楚:

CoT(链)→ SC(多链投票)→ ToT(树 + 回溯)→ GoT(图 + 聚合 / 细化),从「模型一次生成」到「外部树编排」再到「外部图编排」。

GoT 还能接更强搜索:外层不限于 BFS/DFS,可上 MCTS 做探索-利用权衡。而它真正的价值,不在「图」这个花活,而在于一句话——

当问题的答案来自「把不同思路的好碎片拼起来」,你就该用图,而不是链或树。


最后

我把 GoT 从「为什么 ToT 的树不够用」,到「五大算子怎么搭」、排序实战走查、模型到底知不知道自己在图里、GoT 与 Workflow 的同形不同义、思想级并行、四类任务配图、适用边界,再到官方库用法——

整理成了一份 10 章的《Graph of Thoughts (GoT) 学习指南》完整版。里面还附了:

  • GoO / GRS 架构图 + 五大算子对照
  • ✅ 排序 / 集合 / 文档合并 / 关键词计数 四类真实案例配图
  • ✅ 官方库 graph_of_thoughts 可运行代码 + 四步迁移法
  • ✅ 与 CoT / ToT 的衔接和方法版图(含两篇同名 ToT 论文的命名澄清)

📱 关注看后续

在这里插入图片描述

🛠 顺手推荐一个开源工具

deepSeekHarenss Desktop —— DeepSeekHarenss 的客户端工具,用来一键安装 DeepSeekHarenss,省去手动配置环境的麻烦。

📦 下载地址:https://github.com/qweqe417/dsh-desktop

有兴趣的朋友可以去下一个玩玩,顺便点个 ⭐ Star 支持作者 🙏


📊 一张图看懂:链 → 树 → 图(三范式递进)

① CoT(链) —— 一根筋走到底:

  问题 → 步骤1 → 步骤2 → 步骤3 → 答案
                              (错了只能错到底)

② ToT(树) —— 多路并行,能回头,但分支一旦分开就合不拢:

                    ┌─→ 候选 A ─┐
                    │            │
  问题 ── 生成 ──┬─→├─→ 候选 B ─┼─→ 评估 → 剪枝/保留 → 答案
                 │  │            │
                 │  └─→ 候选 C ─┘
                 │
                 └── 回溯换路(分支之间不能合并)

③ GoT(图) —— 多路并行 + 能回头 + 能把好碎片拼起来(聚合):

                    ┌─→ 候选 A ─┐
                    │            ├─→ Aggregate ─→ 新 thought ─┐
  问题 ── 生成 ──┬─→├─→ 候选 B ─┤  (多→1 合并)             ├─→ Refine(自环) ─→ 答案
                 │  │            ├─→                          │
                 │  └─→ 候选 C ─┘                              │
                 │                                             │
                 └──────── 回溯换路 ────────────────────────────┘

一句话:链「一根筋」;树「多路能回头,但分了就合不拢」;图「多路能回头,还能把好碎片拼成更好的整体」——这就是 GoT 把排序错误率压到 ToT 的 38% 的关键。

更多推荐