第1章:思维图(Graph-of-Thoughts)进阶:从链到网的认知跃迁

说实话,我第一次接触GoT时,脑子里冒出的第一个念头是——这不就是把思维链(CoT)和思维树(ToT)揉在一起吗?

后来踩了几个坑才明白,事情远没那么简单。GoT不是简单的"升级版",而是一种全新的认知架构范式。它把推理过程从线性链条、树状分支,真正变成了网状结构。

嗯,咱们今天就来聊聊这个。

1.1 GoT的核心思想:思维即节点,推理即路径

先问个问题:你平时做复杂推理时,大脑是怎么运作的?

我自己的经验是——不会一条路走到黑。往往是先冒出几个想法,然后来回比较、合并、修正,最后才形成结论。这个过程,本质上就是一张图。

GoT的核心思想说白了就一句话:把每个思维单元看作图中的一个节点,推理过程就是在这张图上遍历、合并、剪枝

关键概念拆解:

  • 思维节点(Thought Node):一个完整的推理步骤或中间结论。可以是一句话、一段代码、一个数学公式。
  • 思维边(Thought Edge):节点之间的逻辑关系。比如"支持"、"反驳"、"细化"、"合并"。
  • 思维图(Graph of Thoughts):由节点和边构成的有向/无向图,代表整个推理过程。
  • 推理路径(Reasoning Path):从初始节点到目标节点的一条或多条路径。

我在项目中遇到过一种典型场景:让LLM写一个复杂的数据处理pipeline。如果用CoT,它经常写到一半就忘了前面的约束。用ToT好一些,但分支太多时容易发散。后来改用GoT,把每个处理步骤、每个约束条件都作为节点,让模型在图上自由组合——效果出奇的好。

1.2 思维图构建方法:从零开始搭一张推理网

构建思维图,我习惯分三步走。你想想看,这其实跟搭乐高差不多。

第一步:节点生成

把问题拆解成原子化的思维单元。每个单元要足够小,小到不能再拆为止。

# 伪代码示例:节点生成
def generate_thought_nodes(problem):
    nodes = []
    # 分解问题为子问题
    sub_problems = decompose(problem)
    for sp in sub_problems:
        # 为每个子问题生成多个候选思维
        candidates = llm.generate(sp, n=5)
        for c in candidates:
            nodes.append(ThoughtNode(content=c, parent=sp))
    return nodes

我的小技巧:节点粒度要适中。太粗了,图就退化成链;太细了,图会变得难以管理。我一般控制在"一个节点对应一个完整的推理步骤"这个粒度。

第二步:边连接

节点之间怎么连?不是随便连的。我总结了三种常见连接模式:

  • 顺序连接:A推导出B,形成因果链
  • 并行连接:多个节点共同支持一个结论
  • 合并连接:两个节点合并产生新节点(这是GoT独有的能力)

第三步:图结构优化

图建好了,还得优化。我踩过的坑是——图太密了,推理时根本跑不动。

优化策略:

  • 剪掉孤立节点(跟主路径无关的思维)
  • 合并冗余节点(表达相同意思的节点)
  • 限制图深度(一般不超过5层,否则LLM会迷失)

1.3 图遍历与推理路径优化

图建好了,怎么走?这是个好问题。

我试过几种遍历策略,各有优劣:

遍历策略 适用场景 我的评价
深度优先(DFS) 需要深入探索单一分支 容易钻牛角尖,慎用
广度优先(BFS) 需要全面覆盖所有可能性 计算量大,但结果全面
最佳优先(Best-First) 有明确的评价标准 我最常用的策略
蒙特卡洛树搜索(MCTS) 不确定性高的场景 效果好,但实现复杂

避坑指南:我曾经在项目中直接用DFS遍历整个图,结果模型陷入了死胡同,反复生成无意义的中间节点。后来改用Best-First + 剪枝,效率提升了3倍。

路径优化的核心是找到最短、最可靠的推理路径。我常用的方法是:

  1. 给每条边赋予权重(表示推理的可信度)
  2. 用Dijkstra或A*算法找最优路径
  3. 对找到的路径做二次验证
# 路径优化示例
def optimize_path(graph, start, end):
    # 计算每条边的置信度
    for edge in graph.edges:
        edge.weight = compute_confidence(edge)
    # 使用A*搜索最优路径
    path = astar_search(graph, start, end, heuristic)
    # 路径验证
    if validate_path(path):
        return path
    else:
        return fallback_path(graph, start, end)

1.4 GoT与ToT的对比分析

很多人问我:GoT和ToT到底有什么区别?

我一般这么回答:ToT是树,GoT是网。树有层级,网有回路。

对比维度 ToT(思维树) GoT(思维图)
结构 树状,有严格层级 图状,允许任意连接
节点关系 父子关系,单向 多对多,可双向
合并能力 不支持 支持节点合并
回溯能力 只能回溯到父节点 可回溯到任意相关节点
适用场景 层次分明的决策问题 复杂、多依赖的推理问题
计算复杂度 O(b^d) O(n^2) ~ O(n^3)

说白了,ToT适合"选哪个"的问题,GoT适合"怎么组合"的问题。

我记得有一次做代码生成任务,用ToT时模型总是生成一些语法正确但逻辑矛盾的结果。换成GoT后,它能把不同模块的约束条件作为节点,自动检测冲突并合并——效果立竿见影。

我的选择建议:

  • 如果问题可以分解为独立的子问题 → 用ToT
  • 如果子问题之间有复杂的依赖关系 → 用GoT
  • 如果拿不准 → 先用ToT快速验证,再升级到GoT

1.5 知识体系总览

最后,我用一张图把本章的核心逻辑串起来。这张图是我自己画的,希望能帮你建立整体认知。

GoT知识体系总览 思维图(GoT) 图构建 图遍历 路径优化 节点生成 边连接 DFS/BFS Best-First 剪枝策略 A*搜索 对比:ToT(树) vs GoT(图) 核心差异:GoT支持节点合并与多路径回溯 适用场景:复杂依赖关系的推理问题

这张图把GoT的核心要素都串起来了。你仔细看,从中心节点出发,三个支柱分别对应构建、遍历、优化。每个支柱下面又有具体的技术手段。最下面是和ToT的对比,以及适用场景总结。

嗯,第一章的内容就到这儿。GoT是个好东西,但别急着上手。先把这些基础概念吃透,后面几章我们会深入具体的实现细节和实战案例。


公众号:蓝海资料掘金营,微信deep3321