Skip to main content

체인 오브 소트, 트리 오브 소트, 그래프 오브 소트: 프롬프트 기법 설명

이 글에서는 체인 오브 소트(Chain-of-Thought, CoT)에서 시작해 트리 오브 소트(Tree-of-Thought, ToT)로 확장하여 트리 탐색을 가능하게 하고, 마지막으로 그래프 오브 소트(Graph-of-Thought, GoT) 프롬프팅으로 일반화하는 일련의 프롬프팅 기법을 간략히 소개합니다. 이 글은 AI 번역본입니다. 오역이 있을 경우 댓글로 알려주세요.
Created on September 15|Last edited on September 15

체인 오브 소트(CoT)는 간단하지만 자주 더 정확한 LLM 출력을 이끄는 프롬프팅 기법입니다. 간단히 말해, 체인 오브 소트 프롬프트는 모델이 정답을 성급히 제시하지 않고 단계별로 논리적으로 사고(하나의 생각 사슬)하도록 지시합니다.
이 보고서에서는 CoT와 몇 가지 관련 프롬프팅 기법을 살펴보며, 그것들이 어떻게 작동하는지와 이후 기법들이 CoT에서 어떻게 발전해 왔는지를 이해하겠습니다.

목차





체인 오브 소트 프롬프팅

저자들은 체인 오브 소트(Chain-of-Thought, CoT) (2201.11903) 아주 단순한 동기가 있었다. LLM을 단순히 키우는 것은 복잡한 추론 과제에서 기대한 성능 향상을 가져오지 못했다. 이 방법은 두 가지 핵심 아이디어에 의존한다:
  • 복잡한 산술 과제는 자연어 지시문 형태의 작은 중간 단계로 나누면 더 효과적으로 해결할 수 있다.
  • 프롬프팅(컨텍스트 내 퓨샷 러닝)은 각 과제마다 파인튜닝을 하지 않고, 메인 프롬프트에 입력–출력 예시를 제공함으로써 모델을 다른 작업에 맞게 적응시키는 데 사용할 수 있다.
체인 오브 소트 기법은 모델에 삼중항으로 구성된 프롬프트를 제공하여, 이 두 단계를 하나로 결합하는 방식에 의존한다. <input, chain of thought, output>, 여기서:
A 연쇄 추론 최종 출력에 이르는 중간 단계의 자연어 추론 과정 일련
💡
그림 1에서 이 기법으로 프롬프트할 경우 모델이 서로 다른 두 출력을 어떻게 낼 수 있는지 확인할 수 있다. 제시된 입출력 예시는 이 경우 필요한 연산이 덧셈임을 판별하는 간단한 추론 단계로 이루어져 있다. (5 + 2 × 3 = 11) 그러나 실제로 요구된 문제는 중간에 한 번의 뺄셈 단계가 추가로 포함되어 있다. (23 − 20 + 6 = 9)
  • 에서 표준 프롬프팅 (왼쪽)에서는 추론 단계를 전혀 포함하지 않은 입력–출력 예시만 제공합니다. 그 결과 모델은 두 번째 문제가 다르다는 사실을 인지하지 못한 채 같은 연산 과정을 반복하려고 하여, 최종 답을 27로 잘못 산출합니다.
  • 하지만 우리가 사용하면 Chain-of-Thought 프롬프팅 (오른쪽)에서는 추론 과정을 명시적으로 제시합니다. “로저는 공 5개로 시작했다. 테니스공 3개짜리 캔 2개는 총 6개다. 5 + 6 = 11”처럼요(그림 1의 파란색 강조). 이처럼 구성하면 최종 응답은 9로 정확하게 산출됩니다.
다음 코드 스니펫은 graph_of_thoughts CoT 파이프라인을 생성하는 패키지:"
def cot() -> operations.GraphOfOperations:
operations_graph = operations.GraphOfOperations()

operations_graph.append_operation(operations.Generate(1, 1))
operations_graph.append_operation(operations.Score(1, False, utils.num_errors))
operations_graph.append_operation(operations.GroundTruth(utils.test_sorting))

return operations_graph

Tree-of-Thought 프롬프팅

CoT 직후 곧바로, Tree-of-Thoughts (2305.10601) ToT 기법은 모든 추론 과제를 트리 탐색 문제로 구성하는 접근으로 제안되었습니다. 여기서 트리의 중간 상태는 부분 해를 가리키며, 모델은 분기와 백트래킹 같은 표준 트리 순회 기법을 사용해 주요 문제의 해를 찾는 동안 이 부분 해들을 참조하고 활용할 수 있습니다. 이제 이 기법을 단계별로 살펴보겠습니다:
  • 중간 과정을 단계로 나눕니다: ToT에서는 각 분기마다 주어진 문제를 중간 단계로 분해하려고 시도합니다. 각 단계에서 CoT 방식으로 다양한 생각을 샘플링하거나, 생성기를 사용해 새로운 생각을 제안할 수 있습니다.
  • 생성된 다양한 상태를 평가합니다: 여러 서로 다른 상태가 주어지면, 전체 문제에 대한 휴리스틱으로 작동하도록 각 상태를 평가하는 평가자를 사용합니다. 다만 고정된 공식 대신, 모델이 각 상태에 대해 추론하도록 합니다. 각 상태별로 값을 계산해 독립적으로 평가할 수도 있고, 특정 레벨/깊이에 있는 모든 상태를 대상으로 투표하여 결합 방식으로 평가할 수도 있습니다.
  • 평가된 상태 전반을 탐색합니다: 이제 가능한 다음 상태들을 생성하고 그 가치까지 평가했으므로, 알고리즘 이론의 표준 기법을 활용해 다음에 탐색할 분기를 결정할 수 있습니다. 관련 논문에서는 깊이 우선 탐색과 너비 우선 탐색을 두 가지 유효한 기법으로 검토했습니다.
CoT와 마찬가지로 예시를 하나 살펴보겠습니다. 논문에서는 24 게임 문제를 다룹니다. 24 게임은 수학적 추론 과제로, 네 개의 숫자와 기본 산술 연산(+ − × ÷)을 사용해 24를 만드는 것이 목표입니다. 그림 2에서 시작 상태로 “4 9 10 13”을 사용했을 때, 모델이 다음 단계로 일부 가능한 선택지를 생성한 것을 볼 수 있습니다. 이후 단계들은 Value 프롬팅 또는 Propose 프롬팅을 사용해 계속 생성할 수 있으며, 각 점수에 기반해 다음에 탐색할 분기를 결정합니다.
이 예시에서는 프롬프트 "Possible next steps: "를 사용해 언어 모델이 가능한 다음 단계를 제안하도록 했습니다. 모델은 (10 − 4 = 6) 또는 (4 + 9 = 13)을 제안했습니다. 이어서 프롬프트 "Evaluate if the given numbers can reach 24(sure/likely/impossible) <...>"로 각 상태를 평가하도록 다시 언어 모델을 사용했고, 그 출력에 따라 주어진 탐색 전략(DFS/BFS)을 이용해 다음 상태를 선택했습니다.
다음 코드 스니펫은 graph_of_thoughts ToT 파이프라인을 생성하는 패키지입니다.
def tot() -> operations.GraphOfOperations:
operations_graph = operations.GraphOfOperations()

operations_graph.append_operation(operations.Generate(1, 20))
operations_graph.append_operation(operations.Score(1, False, utils.num_errors))
keep_best_1 = operations.KeepBestN(1, False)
operations_graph.append_operation(keep_best_1)

for _ in range(1):
operations_graph.append_operation(operations.Generate(1, 20))
operations_graph.append_operation(operations.Score(1, False, utils.num_errors))
keep_best_2 = operations.KeepBestN(1, False)
keep_best_2.add_predecessor(keep_best_1)
operations_graph.append_operation(keep_best_2)
keep_best_1 = keep_best_2

operations_graph.append_operation(operations.KeepBestN(1, False))
operations_graph.append_operation(operations.GroundTruth(utils.test_sorting))

return operations_graph

Graph-of-Thought 프롬팅

이제 이 접근을 나무 구조에 제한되지 않도록 더 일반화할 수 있을까요? Graph-of-Thoughts (2308.09687) GoT 기법은 정보 흐름을 임의의 그래프 구조로 모델링하는 하나의 해법을 제안합니다. 전체 흐름은 ToT와 동일합니다. 즉, 가능한 단계를 제안하는 생각 생성기, 다양한 생각에 점수를 매기는 평가자, 그리고 다음 생각을 선택하는 데 사용하는 순위 결정자로 구성됩니다.
그림 3: Graph-of-Thought 프롬팅과 다른 기법들의 비교 from Graph of Thoughts: 대규모 언어 모델로 복잡한 문제 해결하기 (2308.09687)
다음 코드 스니펫은 graph_of_thoughts GoT 파이프라인을 만들기 위한 패키지.
def got() -> operations.GraphOfOperations:
operations_graph = operations.GraphOfOperations()

plans = operations.Generate(2, 1)
operations_graph.append_operation(plans) # generate the sublists
for i in range(1, 3):
list_id = f"List {i}"
sub_list = operations.Selector(
lambda thoughts, list_id=list_id: [
thought for thought in thoughts if thought.state["part"] == list_id
]
)
sub_list.add_predecessor(plans)
operations_graph.add_operation(sub_list)
sort_sub_list = operations.Generate(1, 5)
sort_sub_list.add_predecessor(sub_list)
operations_graph.add_operation(sort_sub_list)
score_sub_list = operations.Score(1, False, utils.num_errors)
score_sub_list.add_predecessor(sort_sub_list)
operations_graph.add_operation(score_sub_list)
keep_best_sub_list = operations.KeepBestN(1, False)
keep_best_sub_list.add_predecessor(score_sub_list)
operations_graph.add_operation(keep_best_sub_list)

final_aggregate = operations.Aggregate(10)
operations_graph.append_operation(final_aggregate)
operations_graph.append_operation(operations.Score(1, False, utils.num_errors))
keep_best_aggregate_final = operations.KeepBestN(1, False)
operations_graph.append_operation(keep_best_aggregate_final)

operations_graph.append_operation(operations.Generate(1, 10))
score_aggr_3 = operations.Score(1, False, utils.num_errors)
score_aggr_3.add_predecessor(keep_best_aggregate_final)
operations_graph.append_operation(score_aggr_3)
operations_graph.append_operation(operations.KeepBestN(1, False))

operations_graph.append_operation(operations.GroundTruth(utils.test_sorting))

return operations_graph

결론

이 글에서는 사고 프롬팅에 관한 일련의 논문을 간략히 살펴보고, 이를 어떻게 활용할 수 있는지에 대해 알아보았습니다. Weights & Biases 학습 과정을 탐구하고, 그 과정에서 어떻게 가치 있는 인사이트를 도출할 수 있는지 살펴보기 위해.
Weights & Biases의 전체 기능 모음을 확인하려면 다음을 참고하세요 짧은 5분 가이드수학과 “처음부터 직접 구현한” 코드에 대한 보고서를 더 보고 싶다면, 아래 댓글이나 저희의 포럼 ✨!
다음 주제에 관한 다른 보고서도 확인해 보세요 완전 연결 다른 주제를 다루는 대규모 언어 모델모델 적응과 같은 관련 주제.


이 글은 AI 번역본입니다. 오역이 있을 수 있으니 댓글로 알려 주세요. 원문 보고서는 아래 링크에서 확인하실 수 있습니다: 원문 보고서 보기