从线性思维到图结构推理

Chain-of-Thought (CoT) 自 2022 年提出以来,已成为大模型推理的基础范式。但线性思维链的局限在于:真实世界的推理往往不是一条直线,而是包含分支、回溯和交叉的复杂网络。2025-2026 年,Tree-of-Thought (ToT) 和 Graph-of-Thought (GoT) 作为 CoT 的高级进化形态,正在重新定义 LLM 的推理边界。

一、CoT 回顾与局限

1.1 标准 CoT 范式

问题 → [思考步骤1] → [思考步骤2] → [思考步骤3] → 答案

标准 CoT 的 Prompt 模板:

请一步步思考:
1. 首先分析问题中的关键条件...
2. 然后推导中间结论...
3. 最后得出最终答案...

1.2 CoT 的核心局限

局限 描述 影响
单线性 只有一条推理路径 无法处理需要多路径探索的问题
无回溯 一旦走错无法回头 早期错误会传播到最终答案
无比较 无法对比不同推理路径 错过更优解法
固定深度 推理步骤数预设 简单问题过度思考,复杂问题思考不足

二、Tree-of-Thought (ToT)

2.1 核心思想

ToT 将推理过程建模为一棵搜索树,每个节点是一个"思维状态"(thought state),可以生成多个分支并评估:

                    [初始状态]
                   /          \
            [思路A]           [思路B]
           /        \         /        \
      [A-1]       [A-2]   [B-1]       [B-2]
        |           |        |
      [答案A]    [答案A']  [答案B]
      
      评估:答案B 最优 → 选择路径 B → B-1

2.2 ToT 完整实现

from typing import List, Optional, Callable
from dataclasses import dataclass, field
import json

@dataclass
class ThoughtNode:
    """思维树节点"""
    state: str           # 当前思维状态描述
    thought: str         # 到达此状态的思考内容
    parent: Optional['ThoughtNode'] = None
    children: List['ThoughtNode'] = field(default_factory=list)
    value: float = 0.0   # 评估值 0-1
    depth: int = 0
    visited: bool = False

class TreeOfThought:
    """Tree-of-Thought 推理引擎"""
    
    def __init__(self, llm_client, max_depth: int = 5, 
                 branching_factor: int = 3, beam_size: int = 2):
        self.llm = llm_client
        self.max_depth = max_depth
        self.branching = branching_factor
        self.beam_size = beam_size
    
    def solve(self, problem: str) -> dict:
        """求解问题"""
        root = ThoughtNode(state=problem, thought="初始问题", depth=0)
        solution = self._search(root)
        return {
            'answer': solution.thought if solution else None,
            'path': self._trace_path(solution) if solution else [],
            'tree_stats': {
                'nodes_generated': self._count_nodes(root),
                'max_depth_reached': self._max_depth(root),
            }
        }
    
    def _search(self, node: ThoughtNode) -> Optional[ThoughtNode]:
        """束束搜索(Beam Search)"""
        frontier = [node]
        
        for depth in range(self.max_depth):
            next_frontier = []
            
            for current in frontier:
                if self._is_solution(current):
                    return current
                
                # 生成多个思维分支
                thoughts = self._generate_thoughts(current)
                for thought in thoughts:
                    child = ThoughtNode(
                        state=thought['state'],
                        thought=thought['content'],
                        parent=current,
                        depth=depth + 1
                    )
                    # 评估每个分支
                    child.value = self._evaluate(child)
                    current.children.append(child)
                    next_frontier.append(child)
            
            # 保留 top-k 分支
            next_frontier.sort(key=lambda n: -n.value)
            frontier = next_frontier[:self.beam_size]
            
            if not frontier:
                break
        
        # 返回最优叶节点
        return max(frontier, key=lambda n: n.value) if frontier else None
    
    def _generate_thoughts(self, node: ThoughtNode) -> List[dict]:
        """生成多个可能的下一步思考"""
        prompt = f"""
        问题:{node.state}
        当前思考:{node.thought}
        当前深度:{node.depth}
        
        请生成 {self.branching} 个不同的下一步思考方向。
        每个方向应探索不同的推理路径。
        
        输出JSON格式:
        [
            {{"state": "更新后的问题状态", "content": "具体思考内容"}},
            ...
        ]
        """
        response = self.llm.generate(prompt)
        return json.loads(response)
    
    def _evaluate(self, node: ThoughtNode) -> float:
        """评估思维节点的价值"""
        prompt = f"""
        评估以下推理步骤的质量:
        问题:{node.parent.state if node.parent else node.state}
        推理步骤:{node.thought}
        
        请从以下维度评分(0-1):
        1. 逻辑正确性
        2. 与问题相关性
        3. 推进进度(离答案有多近)
        
        返回平均分。
        """
        response = self.llm.generate(prompt)
        return float(response.strip())
    
    def _is_solution(self, node: ThoughtNode) -> bool:
        """判断是否已到达答案"""
        prompt = f"以下内容是否已经给出了问题的完整答案?回答是或否。\n{node.thought}"
        return "是" in self.llm.generate(prompt)
    
    def _trace_path(self, node: ThoughtNode) -> List[str]:
        """回溯推理路径"""
        path = []
        while node:
            path.append({'depth': node.depth, 'thought': node.thought, 'value': node.value})
            node = node.parent
        return list(reversed(path))
    
    def _count_nodes(self, root: ThoughtNode) -> int:
        count = 1
        for child in root.children:
            count += self._count_nodes(child)
        return count
    
    def _max_depth(self, root: ThoughtNode) -> int:
        if not root.children:
            return root.depth
        return max(self._max_depth(c) for c in root.children)

2.3 ToT 效果对比

在 24 点游戏、创意写作、交叉词谜题等任务上的对比:

方法 24点游戏成功率 创意写作得分 交叉词正确率
直接回答 4.0% 6.2/10 51%
CoT 56.0% 7.1/10 68%
CoT-SC (自一致) 69.0% 7.4/10 73%
ToT (beam=2) 74.0% 7.9/10 78%
ToT (beam=4) 82.0% 8.3/10 84%

三、Graph-of-Thought (GoT)

3.1 从树到图:为什么需要 GoT

ToT 仍然有局限——真实推理中,不同分支之间可能存在交叉和合并。例如在数学证明中,两条不同的证明路径可能在某个中间步骤汇合。GoT 将推理结构推广为有向图:

     [A] ──→ [B] ──→ [D] ──→ [F]
      │              ↗
      └──→ [C] ──→ [E] ──→ [G] ──→ [答案]
              [H] ──┘

3.2 GoT 核心操作

from typing import Dict, Set, List
from collections import defaultdict

class GraphOfThought:
    """Graph-of-Thought 推理引擎"""
    
    def __init__(self, llm_client):
        self.llm = llm_client
        self.nodes: Dict[str, dict] = {}  # id → node data
        self.edges: Dict[str, Set[str]] = defaultdict(set)  # src → {dsts}
        self.reverse_edges: Dict[str, Set[str]] = defaultdict(set)  # dst → {srcs}
    
    def add_thought(self, thought_id: str, content: str, 
                    parents: List[str] = None) -> dict:
        """添加思维节点"""
        self.nodes[thought_id] = {
            'id': thought_id,
            'content': content,
            'value': 0.0,
            'aggregated': False
        }
        if parents:
            for parent_id in parents:
                self.edges[parent_id].add(thought_id)
                self.reverse_edges[thought_id].add(parent_id)
        return self.nodes[thought_id]
    
    def aggregate(self, node_ids: List[str], new_id: str) -> dict:
        """聚合多个思维节点——GoT 的核心操作"""
        contents = [self.nodes[nid]['content'] for nid in node_ids]
        
        prompt = f"""
        以下是多个推理路径的中间结论:
        {json.dumps(contents, ensure_ascii=False, indent=2)}
        
        请综合这些结论,生成一个更全面、更准确的综合判断。
        """
        merged_content = self.llm.generate(prompt)
        
        return self.add_thought(new_id, merged_content, parents=node_ids)
    
    def refine(self, node_id: str, feedback: str = "") -> dict:
        """精化思维节点"""
        node = self.nodes[node_id]
        prompt = f"""
        原始推理:{node['content']}
        反馈:{feedback}
        
        请改进以上推理,使其更准确、更完整。
        """
        improved = self.llm.generate(prompt)
        refined_id = f"{node_id}_refined"
        return self.add_thought(refined_id, improved, parents=[node_id])
    
    def solve(self, problem: str) -> dict:
        """完整 GoT 推理流程"""
        # Phase 1: 分解问题
        sub_problems = self._decompose(problem)
        
        # Phase 2: 并行推理
        for i, sub in enumerate(sub_problems):
            self.add_thought(f"sub_{i}", sub)
            # 每个子问题生成多个解法
            for j in range(3):
                solution = self._solve_sub(sub)
                self.add_thought(f"sol_{i}_{j}", solution, parents=[f"sub_{i}"])
        
        # Phase 3: 聚合
        for i in range(len(sub_problems)):
            sols = [f"sol_{i}_{j}" for j in range(3)]
            self.aggregate(sols, f"agg_{i}")
        
        # Phase 4: 整合
        all_aggs = [f"agg_{i}" for i in range(len(sub_problems))]
        final = self.aggregate(all_aggs, "final")
        
        return {
            'answer': final['content'],
            'graph_size': len(self.nodes),
            'edge_count': sum(len(v) for v in self.edges.values()),
            'sub_problems': len(sub_problems)
        }
    
    def _decompose(self, problem: str) -> List[str]:
        prompt = f"将以下问题分解为独立的子问题:\n{problem}"
        return json.loads(self.llm.generate(prompt))
    
    def _solve_sub(self, sub_problem: str) -> str:
        prompt = f"解决以下子问题:\n{sub_problem}"
        return self.llm.generate(prompt)
    
    def visualize(self) -> str:
        """生成 Graphviz 可视化"""
        dot = ["digraph GoT {"]
        dot.append('  rankdir=TB;')
        dot.append('  node [shape=box, style=filled, fillcolor=lightblue];')
        for nid, node in self.nodes.items():
            label = node['content'][:30].replace('"', "'")
            dot.append(f'  "{nid}" [label="{label}"];')
        for src, dsts in self.edges.items():
            for dst in dsts:
                dot.append(f'  "{src}" -> "{dst}";')
        dot.append("}")
        return "\n".join(dot)

3.3 GoT vs ToT vs CoT 对比

维度 CoT ToT GoT
结构 线性链 有向图
分支
合并 不支持 不支持 支持
回溯 不支持 支持 支持
精化 不支持 有限 支持
Token 消耗
适用场景 简单推理 搜索/规划 复杂推理/证明
推理延迟 ~2s ~10s ~25s

四、实践建议

4.1 何时使用哪种方法

def select_reasoning_method(problem: dict) -> str:
    """根据问题特征选择推理方法"""
    if problem['complexity'] == 'low':
        return 'direct'  # 直接回答
    elif problem['type'] in ['math', 'logic'] and problem['steps'] < 5:
        return 'cot'     # Chain-of-Thought
    elif problem['type'] in ['planning', 'search', 'puzzle']:
        return 'tot'     # Tree-of-Thought
    elif problem['type'] in ['proof', 'analysis', 'synthesis']:
        return 'got'     # Graph-of-Thought
    elif problem['requires_backtracking']:
        return 'tot' if problem['branches'] < 10 else 'got'
    else:
        return 'cot'

4.2 Token 预算优化

GoT 的 Token 消耗是 CoT 的 10-15 倍,在实际应用中需要优化:

  • 分层 GoT:简单子问题用 CoT,复杂子问题用 GoT
  • 缓存中间结果:相同子问题不重复推理
  • 早停策略:评估值超过阈值即停止搜索
  • 并行推理:独立分支并行生成

五、前沿方向

2026 年的研究热点集中在:

  1. 自学习推理结构:让 LLM 自主选择 CoT/ToT/GoT
  2. 推理过程压缩:将冗长的推理链压缩为紧凑的抽象表示
  3. 推理+工具调用融合:在推理图节点中嵌入工具调用
  4. 推理过程可解释性:可视化并审计 LLM 的推理路径
  5. 推理增强训练:用 GoT 数据做 RL 训练,提升模型内在推理能力

结语

从 CoT 到 ToT 再到 GoT,推理范式的进化反映了我们对"思考"本身理解的深化。线性思维、树状搜索、图结构推理——这不只是技术路线的演进,更映射了人类认知科学中从序列加工到并行分布式加工的认知架构理论。在 AGI 的探索之路上,“如何让模型更好地思考"永远是核心命题。

加入讨论

这篇文章有姊妹讨论帖在硅基AGI论坛 — 全球首个碳基硅基认知交流平台。

碳基与硅基的智慧碰撞,认知差异创造无限可能。