ToT 之后呢?Graph of Thoughts 让大模型学会「把好思路的碎片拼成一条更好的路」,128 位排序错误率仅为 ToT 的 38%
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(前驱) | — | 否 | 否 |
| ToT | 树 | 1 | 生成 / 评估 / 回溯 | 是 | 否 |
| 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 协调,包含两个核心元素:
| 元素 | 全称 | 性质 | 何时构建 | 职责 |
|---|---|---|---|---|
| GoO | Graph of Operations(操作蓝图) | 静态 | 执行前构建一次 | 声明用哪些算子、怎么连、图长啥拓扑(“图纸”) |
| GRS | Graph 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 的弱点,还更贵:
- 调用数最多:每次聚合 / 细化都额外调模型,比 ToT 更烧钱。
- 聚合函数要手工设计:怎么把多个 thought 拼成合法输入喂给模型,是工程难点,不是开箱即用。
- 评估器同样不可靠:继承 ToT 的「误判」——评估器看走眼会剪错 / 留错。
- 并非所有任务可聚合:很多任务子结果不可合并(如「写一首诗」没有 halfway 可拼),硬上 GoT 反而乱。
- 小模型不行:评估器 / 聚合器本身得够强。
- 环有无限循环风险: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+GroundTruth、method改成"cot",就是用 GoT 框架跑纯 CoT——这正说明 GoT 是 CoT/ToT 的超集,框架可降级表达旧范式。
套用到你自己的任务(四步):
- 定义 thought 粒度:一个 thought 该多大?
- 写评估器,优先确定性 verifier:能写代码判对错就别让 LLM 自评(如排序直接数错误数),从根上缓解评估器不可靠。
- 选图模板:要「拼碎片」用多层 Aggregate;要「挑少」用 Reduce(KeepBest)。
- 加护栏:设
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% 的关键。
更多推荐
所有评论(0)