Tree-of-Thoughts (ToT)
Yao et al., Tree of Thoughts: Deliberate Problem Solving with Large Language Models, NeurIPS 2023
- https://arxiv.org/pdf/2305.10601
 
1. Motivation
Chain-of-Thought (CoT):
- 
    
핵심: LLM이 reasoning할 때 한 줄(linear)로 생각의 흐름을 이어감.
 - 
    
문제: Greedy/linear reasoning은 중간에 잘못된 단계가 나오면 되돌리기 어렵고, 탐색 공간을 충분히 활용하지 못함
 
해결책: Tree-of-Thoughts (ToT)
- 
    
핵심: Reasoning을 tree 구조로 확장
→ 다양한 thought candidates를 분기(branch)시켜 탐색
 

2. Background
Notation:
- Pretrained LM: \(p_\theta\)
 - 입력 \(x\), 출력 \(y\)
 
Prompting
- IO prompting:
    
- \[y \sim p_\theta(y\mid \text{prompt}_{IO}(x))\]
 - 가장 단순한 입출력 방식
 
 - Chain-of-Thought (CoT):
    
- 중간 추론 조각 \(z_i\)를 순차 생성해 최종 답에 도달.
 - \([z_{1\ldots n}, y] \sim p_\theta^{\text{CoT}}(\cdot \mid x)\).
 
 - Self-Consistency (CoT-SC):
    
- CoT 경로를 k개 i.i.d. 샘플링 후 다수결로 최종 답 선택
 - 한 경로 안에서의 국소 탐색이 없고, 출력공간이 넓을 때는 다수결의 한계 O
 
 
3. Review: Self-Consistency (CoT-SC)
(1) CoT-SC 방식이란?
Procedure
- Step 1) 여러 개의 CoT 추론 경로를 독립적으로 샘플링합니다.
 - Step 2) 마지막 정답을 다수결로 뽑음
 
Example) (Q) 1,2,3,4 조합해서 8 만들기
- 경로 A: “1+2=3, 3+4=7 → 답=7”
 - 경로 B: “2+2=4, 4+4=8 → 답=8”
 - 경로 C: “3+3=6, 6+4=10 → 답=10 ✅”
 
→ 정답은 C에 있지만, 다수결은 7이나 8을 뽑아버릴 수 있음.
(2) 한계점
“한 경로 안에서 국소 탐색(local search)이 없다”**
- 
    
CoT-SC는 (경로를 여러 개 뽑기는 하지만) 경로 내부에서 분기하거나 되돌아보며 탐색은 X
\(\rightarrow\) 즉, 하나의 reasoning line이 잘못 가면 그대로 끝까지 잘못 가는 것
 - 
    
그래서 이 방식은 경로 내부(local level)에서 오류 수정이나 backtracking이 불가능
 
“출력공간이 넓을 때 다수결의 한계”
- 
    
만약 가능한 정답 후보가 (1개가 아니라) 다양한 경우 (= 출력 공간이 넓다)
 - 
    
정답이 소수 branch에서만 나오는 경우라면, 다수결은 쉽게 틀릴 수 있음
 
3. Tree-of-Thoughts
ToT는 문제를 Tree 탐색 문제로 재정의
3.1 문제의식과 상태 정의
- 사람은 부분해(Partial solution) 들을 잇는 Tree를 휴리스틱으로 탐색
 - 기존 LLM 추론의 두 한계
    
- 로컬: 한 단계(thought) 안에서 여러 분기를 탐색하지 않음
 - 글로벌: 계획, lookahead, backtracking이 없음
 
 - ToT의 상태(state): \(s = [x, z_{1\ldots i}]\).
    
- (1) 입력 \(x\)
 - (2) 지금까지의 thought 시퀀스 \(z_{1\ldots i}\)로 구성된 부분해 노드.
 
 
3.2 ToT를 구성하는 4가지 질문
- Thought Decomposition
 - Thought Generator
 - State Evaluator
 - Search Algorithm
 
(1) Thought Decomposition
Q) Thought 단위는?
- 한 thought \(z_i\)는 의미 있는 중간 단위(단어/구/문장/문단 등)여야
 - 너무 작으면(토큰 단위) 평가가 어렵고
 - 너무 크면(책 한 권) 다양 샘플링이 어려움
 
(2) Thought Generator \(G(p_\theta, s, k)\)
Q) 다음 thought 후보 \(k\)개를 어떻게 낼까?
(“현재 상태 s에서 다음에 전개할 생각 조각(thought) 후보 k개를 어떻게 뽑을까?”)
두 전략
- i.i.d. sampling from CoT prompt
 - Sequential propose prompt
 
a) i.i.d. sampling from CoT prompt
아이디어: 같은 프롬프트(=현재 상태 \(s=[x, z_{1..i}]\))로부터 독립적으로 k번 샘플링
- \(z^{(j)} \sim p_\theta^{\text{CoT}}(z_{i+1}\mid x, z_{1..i}),\quad j=1..k\).
 
장점
- 병렬로 쉽게 뽑음.
 - 후보 간 다양성(diversity) 을 크게 확보하고 싶을 때
    
- (temperature/top-p 등을 조절해 다양성↑)
 
 
단점
- 
    
출력 단위가 짧거나 제약적일 때(예: “다음 칸에 올 한 단어”), 중복 후보가 많이 나올 수 있음.
 - 
    
같은 맥락이라 상위 확률 후보가 반복적으로 뽑히는 mode collapse 위험.
 
예시
- 
    
상태: 1–2문단까지 썼고, 3문단을 다양한 흐름으로 이어가고 싶을 때
 - 
    
프롬프트(요지): “다음 단락 후보를 1문단 분량으로 생성하라.”
 - 
    
샘플링: temperature=0.8, top-p=0.9로 5개 i.i.d. 샘플 →
- \(z^{(1)}\): 주인공이 과거의 트라우마 회상
 - \(z^{(2)}\): 조력자 등장으로 방향 전환
 - \(z^{(3)}\): 내적 독백 심화
 - \(z^{(4)}\): 외부 사건(정전) 발생
 - \(z^{(5)}\): 반전 사실 드러남
 
→ 각각을 state evaluator가 점수 매기고, 상위 후보만 다음 깊이로 전개(beam/best-first).
 
b) Sequential propose prompt
아이디어: 한 번의 forward에서 순서 있는 후보 묶음 [z^{(1)}, …, z^{(k)}]을 직접 나열하도록 LLM에 시킴
- 
    
(“중복 금지, 서로 다른 유형, 간결한 포맷” 등을 명시적으로 강제)
 - 
    
\([z^{(1)},\ldots,z^{(k)}] \sim p_\theta^{\text{propose}}(z_{i+1}^{(1\ldots k)} \mid s)\).
 
장점
- thought가 짧고 제약적일 때 (한 단어/한 식/하나의 그리드 단서) 좋음
 - 한 호출에서 다양하고 비중복 후보를 “리스트”로 뽑도록 유도
 - 포맷/제약(길이, 품사, 사전 제약 등)을 프롬프트로 엄격히 통제 가능.
 
단점
- 한 호출에 많은 내용을 요구하니 맥락폭/토큰 비용이 커질 수 있음.
 - 나열 순서 편향이 생길 수 있어 후속 평가 모듈이 중요.
 
Summary
| 항목 | i.i.d. sampling | sequential propose | 
|---|---|---|
| 목적 | 자유도 큰 thought에서 다양성 확보 | 짧고 제약적 thought에서 비중복·커버리지 확보 | 
| 호출 방식 | k회 독립 샘플 | 1회 호출에 k개 후보 나열 | 
| 중복 방지 | 약함(샘플링 편향) | 강함(프롬프트로 강제) | 
| 제약/포맷 통제 | 비교적 약함 | 강함(번호, 길이, 품사, 사전 등) | 
| 예시 | 창작 문단, 전략 설명 | 24게임 한 수, 크로스워드 단어, 코드 한 줄 | 
def gen_iid(model, state, k, **decoding):
    return [ model.sample_next_thought(state, **decoding) for _ in range(k) ]
def gen_propose(model, state, k):
    prompt = build_propose_prompt(state, k, rules=...)
    items = model.generate_list(prompt)  # "1) ... 2) ... 3) ..."
    return parse_numbered_items(items)[:k]
(3) State Evaluator \(V(p_\theta, S)\)
Q) 어떤 상태가 유망한가?
- 핵심 아이디어: LM 스스로가 상태의 장단을 숙고(deliberate)하여 휴리스틱처럼 점수화.
 
두 방식:
- (1) Independent value: 각 상태 s를 독립적으로 평가
    
- \(V(s) \sim p_\theta^{\text{value}}(v \mid s)\).
 - (예: “이 상태에서 문제를 풀 수 있을 가능성(0–10)?”)
 
 - (2) Pairwise / comparative: 상태들을 서로 비교해 랭킹/선택
    
- \(p_\theta^{\text{vote}}(s^\star \mid \{s\in S\})\).
 - (예: “다음 중 가장 유망한 진행은?”)
 
 
(4) Search Algorithm
Q) Tree를 어떻게 탐색할까?
본문에서는 두 가지를 사용:
- (1) BFS with beam \(b\) (Algorithm 1): 각 깊이에서 상위 \(b\) 상태만 유지/전개.
    
- 깊이가 얕고(\(T\le 3\)), 초반 pruning이 잘 먹히는 곳에서!
 - e.g., Game of 24, Creative Writing에 사용
 
 - (2) DFS + pruning/backtracking (Algorithm 2): 가장 유망한 경로를 깊게 탐색하다가
    
- 상태값이 임계 이하 (\(V(s)\le v_{\text{th}}\))면 서브Tree 가지치기
 - 해에 도달하거나 막히면 부모로 backtrack.
 - e.g., Mini Crosswords(깊은 탐색)
 
 
종료/기록: 깊이 \(t>T\) 도달 시 출력을 기록; 임계값 기반 pruning으로 탐색 효율 개선.

4. Experiments
