Plan-and-Solve: 모델이 계산하기 전에 단계를 계획하도록 만들기
요약
LLM의 다단계 추론 과정에서 발생하는 단계 누락 및 계산 오류를 해결하기 위한 Plan-and-Solve(PS) 프롬프팅 기법을 소개합니다. 모델이 실행 전 계획을 먼저 세우도록 유도하여 추론의 정확도를 높이는 방법을 다룹니다.
핵심 포인트
- CoT의 한계인 단계 누락 및 계산 오류를 해결하는 프롬프팅 전략
- 계획 수립 단계를 통해 모델의 실행 과정을 강제하는 '약속 장치' 역할
- PS+ 기법을 통해 변수 추출 및 산술 정확도까지 개선 가능
일반 언어 모델에게 다단계(multi-step)의 서술형 문제를 내면, 모델은 종종 틀린 자신감 있는 숫자를 뱉어냅니다. 이는 모델이 어리석어서가 아니라, 조용히 한 단계를 건너뛰거나 산술 계산을 실수했기 때문입니다. '단계별로 생각해보자(Let's think step by step)' (제로샷 체인-오브-쏘트, zero-shot chain-of-thought)가 큰 도움이 되지만, 같은 두 가지 실수는 여전히 발생합니다. Plan-and-Solve (PS) 프롬프팅은 이 두 가지 실패 모드를 정확히 겨냥하는 한 줄 업그레이드입니다: 먼저 모델이 하위 작업의 계획을 세우게 하고, 그다음 순서대로 그 계획을 수행하게 합니다. 예시도 없고 추가 호출도 필요 없습니다. 단지 더 나은 트리거 구문만 있으면 됩니다.
추론이 깨지는 두 가지 방식
CoT가 생성하는 추론 과정을 연구한 연구자들은 오류가 두 개의 범주로 군집화되는 것을 발견했습니다:
- 단계 누락 오류 (Missing-step error) — 체인(chain)이 필요한 연산을 아예 수행하지 않는 경우입니다. 유창하게 읽히고 완전해 보이지만, 한 단계가 사라진 것입니다.
- 계산 오류 (Calculation error) — 한 단계가 올바른 연산을 하지만 틀린 숫자를 산출하는 경우입니다.
일반 프롬프팅은 여러 연산을 하나의 도약으로 압축하기 때문에 최악이며, 따라서 단계 누락이 거의 기본값처럼 발생합니다. CoT는 작업을 분산시키고 도움을 주지만, 여전히 실수가 발생합니다.
이를 노출하는 문제
한 가게에 사과 120개가 있습니다. 아침에 40%를 팔고, 오후에 15개를 더 팝니다. 남은 사과는 몇 개입니까?
정답은 120 − 48 − 15 = 57입니다. 일반 프롬프팅이 무엇을 하는지 지켜보세요: '120의 40%는 48이므로, 120 − 48 = 72.' 아침 판매량을 계산하고 빼고 멈춥니다. 오후에 팔린 15개는 그냥 사라집니다. 이것은 전형적인 단계 누락 오류이며, '단계별로 생각해보자'도 아무것도 마지막 연산이 존재하도록 강제하지 않기 때문에 종종 같은 함정에 빠집니다.
Plan-and-Solve 트리거
'단계별로 생각해보자(let's think step by step)'를 추가하는 대신, 이것을 추가하세요:
Let's first understand the problem and devise a plan to solve it.
Then, let's carry out the plan and solve the problem step by step.
마법은 먼저 계획(plan first) 부분에 있습니다. 숫자를 건드리기 전에, 모델은 하위 작업들을 열거해야 합니다:
- 오전에 판매된 수량 찾기 (120의 40%).
- 시작 수량에서 오전 판매량을 뺌.
- 오후에 판매된 15를 뺌.
- 남은 수량을 보고함.
단계 3이 계획(plan)에 기록되고 나면, 실행(execution) 단계에서 이를 그냥 지나치기가 훨씬 어려워집니다. 계획은 약속 장치 (commitment device) 역할을 합니다. 모델이 스스로에게 오후 뺄셈 작업이 존재함을 알렸기 때문에, 이를 수행하게 됩니다. 계획을 실행하면 48 → 72 → 57이라는 결과가 곧바로 도출됩니다.
PS+ : 산술적 실수도 해결하기
순수 PS는 누락된 단계는 해결하지만 잘못된 산술 (arithmetic)은 해결하지 못합니다. 그래서 저자들은 두 가지 지침을 더 추가했습니다. 이것이 바로 **PS+**입니다:
먼저 문제를 이해하고, 관련 변수와 그에 해당하는 숫자들을 추출한 다음, 계획을 세워봅시다. 그런 다음, 계획을 수행하고, 중간 결과들을 계산하십시오 (계산과 상식에 주의를 기울이십시오...
여기에는 두 가지 구절이 실질적인 역할을 하고 있습니다. **"관련 변수와 숫자들을 추출하라 (Extract relevant variables and numerals)"**는 morning_sold = 48, after_morning = 72와 같이 숫자들을 고정합니다. 이를 통해 모델은 매 줄마다 기억에서 값을 다시 유도하는 대신, 구체적이고 이름이 붙여진 값들을 바탕으로 추론하게 됩니다. 그리고 괄호 안의 **"계산과 상식에 주의를 기울여라 (pay attention to calculation and commonsense)"**는 각 연산을 재확인하고 불가능한 결과(사과 개수가 음수일 수 없으며, 평균 속도가 가장 빠른 구간의 속도를 초과할 수 없음)를 거부하도록 유도합니다. 논문에서 PS+는 순수 PS를 능가했으며, 예시(worked examples)가 전혀 없는 상태에서도 Few-shot CoT와의 격차를 대부분 좁혔습니다.
피할 수 있는 두 번째 함정
기차가 2시간 동안 시속 60km로 달리고, 그다음 3시간 동안 시속 90km로 달렸습니다. 평균 속도는 얼마입니까?
유혹적인 오답은 (60 + 90) / 2 = 75입니다. 평균 속도는 두 속도의 평균이 아니라, 총 거리를 총 시간으로 나눈 값입니다. PS는 계획(leg-1 거리, leg-2 거리, 총 거리, 총 시간, 나누기)을 강제하므로, (120 + 270) / 5 = 78 km/h라는 올바른 값을 계산합니다. 수정 방식은 동일합니다. 계획이 "시간에 따른 가중치 부여"라는 누락된 단계를 건너뛰는 것을 불가능하게 만듭니다.
PS의 위치와 한계
Plan-and-Solve는 "선 분해(decompose first)" 계열 중 가장 비용이 저렴한 방식입니다. Least-to-most prompting 또한 문제를 순서가 있는 하위 문제들로 분해하지만, 대개 예시(examples)와 여러 번의 호출(multiple calls)이 필요합니다. 반면, 완전한 작업 분해(full task-decomposition) 프레임워크는 하위 작업들을 서로 다른 도구(tools)나 에이전트(agents)로 전달합니다. Plan-and-Solve는 계획과 그 실행을 단일 제로샷 호출(single zero-shot call) 안에 담아냅니다. 즉, 분해를 통한 이점은 대부분 챙기면서도, 복잡한 메커니즘은 거의 사용하지 않습니다.
하지만 이것이 완벽한 보장을 의미하지는 않습니다. 동일한 모델이 여전히 단 한 번의 생성(generation) 과정에서 스스로 세운 계획을 실행하기 때문에, 결함이 있는 계획은 확신에 찬 오답을 만들어낼 수 있으며, 매우 길거나 기호적인(symbolic) 문제들은 여전히 모델을 무너뜨릴 수 있습니다. Plan-and-Solve+를 강력하고 거의 비용이 들지 않는 1차 방어선으로 취급하되, 더 높은 정확도가 필요할 때는 다음과 같은 방식으로 격상(escalate)시키십시오: self-consistency (많은 PS 체인을 샘플링하여 다수결 원칙 적용), 깊은 의존성을 위한 least-to-most, 또는 모델이 계획에만 집중할 수 있도록 실제 산술 연산을 계산기나 코드 도구(code tool)로 오프로딩(offloading)하는 방식입니다.
대화형 버전을 시도해 보세요 — 동일한 문제에 대해 일반 방식(plain) vs CoT vs Plan-and-Solve를 실행하여, 오직 계획 경로(plan path)만이 모든 단계를 유지하는 것을 확인할 수 있습니다: https://dev48v.infy.uk/prompt/day24-plan-and-solve.html
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기