Chain-of-Thought (CoT)
Chain-of-Thought는 AI가 최종 답변에 도달하기 전에 사고 과정을 단계별로 표시하도록 하는 프롬프팅 기법입니다. 복잡한 추론, 수학 문제, 다단계 분석에서 정확도를 크게 향상시킵니다.
"단계별 사고 과정 표시" - AI가 답을 내기 전에 중간 추론 단계를 명시하도록 유도하는 기법입니다.
3가지 핵심 개념:
- Zero-shot CoT: "단계별로 생각해봅시다" 한 문장 추가
- Few-shot CoT: 예제에 추론 과정 포함
- Self-Consistency: 여러 추론 경로 생성 → 가장 일관된 답 선택
언제 사용? "복잡한 문제를 단계별로 풀어야 할 때" - 수학 문제, 다단계 분석, 코드 디버깅, 의사결정 등
마법의 문구: 단계별로 생각해봅시다 (Let's think step by step)
CoT란?
Chain-of-Thought는 2022년 Google Research가 발표한 기법으로, LLM이 중간 추론 단계를 명시적으로 출력하도록 유도합니다. 이는 인간이 복잡한 문제를 풀 때 단계별로 생각하는 것과 유사합니다.
CoT 유무 비교
질문: 사과 15개를 3명이 똑같이 나눈 후, 각자 2개씩 더 받았습니다. 한 명당 몇 개인가요?
답변: 7개입니다.
# 추론 과정 없음 → 오답 가능성 높음
질문: 사과 15개를 3명이 똑같이 나눈 후, 각자 2개씩 더 받았습니다. 한 명당 몇 개인가요?
단계별 풀이:
1. 처음 15개를 3명이 나눔: 15 ÷ 3 = 5개씩
2. 각자 2개씩 더 받음: 5 + 2 = 7개
3. 최종 답: 한 명당 7개
답변: 7개입니다.
# 추론 과정 명시 → 정확도 향상
그림 1: Chain-of-Thought 적용 전후 비교 - 단계별 추론으로 정확도 향상
CoT 기법 종류
1. Zero-shot CoT
예제 없이 간단한 프롬프트만으로 CoT를 유도합니다.
마법의 문구: "단계별로 생각해봅시다" (Let's think step by step)
문제: 한 달에 30일이 있고, 매일 3페이지씩 책을 읽으면 450페이지 책을 다 읽는 데 며칠 걸리나요?
단계별로 생각해봅시다:
# Claude가 자동으로 단계를 생성
1. 총 페이지 수: 450페이지
2. 하루에 읽는 페이지: 3페이지
3. 필요한 일수: 450 ÷ 3 = 150일
4. 따라서 150일이 걸립니다.
2. Few-shot CoT
예제에 추론 과정을 포함시켜 Claude가 패턴을 학습하게 합니다.
다음 문제를 단계별로 풀어주세요:
예시 1:
문제: 연필 12자루를 4명이 나눕니다. 한 명당 몇 자루인가요?
풀이:
1. 총 연필 수: 12자루
2. 나눌 사람 수: 4명
3. 계산: 12 ÷ 4 = 3자루
답: 한 명당 3자루
예시 2:
문제: 사탕 20개를 5명이 나누고, 각자 3개씩 더 받습니다. 한 명당 몇 개인가요?
풀이:
1. 처음 나눔: 20 ÷ 5 = 4개씩
2. 추가로 받음: 4 + 3 = 7개
3. 최종 답: 한 명당 7개
답: 한 명당 7개
이제 다음 문제를 풀어주세요:
문제: 초콜릿 36개를 6명이 나누고, 각자 2개씩 덜 줍니다. 한 명당 몇 개인가요?
풀이:
3. Self-Consistency CoT
여러 추론 경로를 생성하고 가장 일관된 답을 선택합니다.
from anthropic import Anthropic
from collections import Counter
client = Anthropic()
problem = "사과 18개를 3명이 나누고, 각자 3개씩 더 받습니다. 한 명당 몇 개?"
prompt = f"{problem}\n\n단계별로 생각해봅시다:"
# 여러 번 실행하여 다양한 추론 경로 생성
answers = []
for _ in range(5):
message = client.messages.create(
model="claude-" ,
max_tokens=512,
temperature=0.7, # 다양성 확보
messages=[{"role": "user", "content": prompt}]
)
response = message.content[0].text
# 최종 답만 추출 (예: "9개")
answer = extract_final_answer(response)
answers.append(answer)
# 가장 많이 나온 답 선택
most_common = Counter(answers).most_common(1)[0][0]
print(f"최종 답: {most_common}")
print(f"모든 답: {answers}")
언제 CoT를 사용하나요?
| 작업 유형 | CoT 필요성 | 예시 |
|---|---|---|
| 수학/논리 문제 | ✅ 필수 | 계산, 추론, 증명 |
| 다단계 분석 | ✅ 강력 권장 | 데이터 분석, 의사결정 |
| 디버깅 | ✅ 유용 | 코드 오류 분석 |
| 복잡한 질문 | ✅ 유용 | "왜?", "어떻게?" 질문 |
| 간단한 사실 질문 | ❌ 불필요 | "수도는?" "색깔은?" |
| 분류 작업 | ⚠️ 선택적 | 감정 분석, 태깅 |
실전 예시
예시 1: 수학 문제
문제:
한 상점에서 티셔츠를 개당 15,000원에 팔고 있습니다.
오늘은 20% 할인 행사를 하고, 3개 이상 구매 시 추가로 10% 할인을 해줍니다.
5개를 구매하면 총 얼마를 지불해야 하나요?
단계별로 계산해주세요:
1단계: 원가 계산
- 개당 가격: 15,000원
- 5개 가격: 15,000 × 5 = 75,000원
2단계: 첫 번째 할인 (20%)
- 할인액: 75,000 × 0.2 = 15,000원
- 할인 후: 75,000 - 15,000 = 60,000원
3단계: 추가 할인 (3개 이상 구매 시 10%)
- 조건 충족: 5개 > 3개 ✓
- 추가 할인액: 60,000 × 0.1 = 6,000원
- 최종 가격: 60,000 - 6,000 = 54,000원
답: 54,000원
예시 2: 코드 디버깅
다음 코드의 버그를 단계별로 분석하세요:
```python
def calculate_average(numbers):
total = 0
for num in numbers:
total += num
return total / len(numbers)
data = [10, 20, 30, 40, 50]
result = calculate_average(data)
print(result) # 예상: 30, 실제: 오류
```
단계별 분석:
1단계: 함수 로직 검토
- total 초기화: 0 ✓
- 루프로 합산: ✓
- 평균 계산: total / len(numbers) ✓
→ 로직 자체는 정상
2단계: 예외 상황 확인
- numbers가 빈 리스트일 때?
- len([]) = 0
- total / 0 → ZeroDivisionError 발생 ❌
3단계: 테스트 케이스 분석
- data = [10, 20, 30, 40, 50]
- len(data) = 5 (≠ 0)
- 이 경우는 오류 없음
→ 하지만 빈 리스트 입력 시 문제 발생
4단계: 버그 정리
- **버그:** 빈 리스트 처리 부재
- **심각도:** MEDIUM
- **발생 조건:** len(numbers) == 0
5단계: 수정 방안
```python
def calculate_average(numbers):
if not numbers: # 빈 리스트 체크
return 0 # 또는 None, 또는 예외 발생
total = 0
for num in numbers:
total += num
return total / len(numbers)
```
최종 결론:
- 원래 코드는 주어진 데이터에서 작동하지만, 빈 리스트 입력 시 예외 발생
- 방어 코드 추가로 안정성 확보
예시 3: 의사결정
상황:
- 스타트업 초기 단계 (팀 3명)
- MVP 웹 애플리케이션 개발
- 개발 기간: 2개월
- 팀 기술 스택: JavaScript 능숙, Python 기본
선택지: React vs Vue vs Angular
단계별 분석:
1단계: 각 프레임워크 특징 정리
React:
- 장점: 생태계 풍부, 구인 용이, 유연성 높음
- 단점: 학습 곡선 중간, 추가 라이브러리 필요
Vue:
- 장점: 학습 곡선 낮음, 문서 훌륭, 빠른 개발
- 단점: 생태계 작음, 대기업 지원 약함
Angular:
- 장점: 완전한 프레임워크, TypeScript 기본
- 단점: 학습 곡선 높음, 무거움
2단계: 요구사항 우선순위
1) 빠른 개발 속도 (2개월 마감) - 최우선
2) 팀 학습 시간 최소화 (이미 JS 숙련) - 중요
3) 향후 확장성 및 유지보수 - 중요
3단계: 각 선택지 평가
React:
- 개발 속도: ⭐⭐⭐ (생태계 덕분에 빠름)
- 학습: ⭐⭐⭐ (JS 숙련자에게 적합)
- 확장성: ⭐⭐⭐⭐⭐ (매우 우수)
총점: 11/15
Vue:
- 개발 속도: ⭐⭐⭐⭐⭐ (가장 빠름)
- 학습: ⭐⭐⭐⭐⭐ (가장 쉬움)
- 확장성: ⭐⭐⭐ (괜찮음)
총점: 13/15
Angular:
- 개발 속도: ⭐⭐ (설정 복잡)
- 학습: ⭐⭐ (어려움)
- 확장성: ⭐⭐⭐⭐ (우수)
총점: 8/15
4단계: 리스크 평가
Vue 선택 시:
- 리스크: 나중에 대규모 팀 확장 시 구인 어려움
- 완화 방안: MVP 성공 후 React 마이그레이션 고려 가능
React 선택 시:
- 리스크: 초기 설정과 라이브러리 선택에 시간 소요
- 완화 방안: Create React App, Next.js 같은 보일러플레이트 사용
5단계: 최종 결정
**추천: Vue**
근거:
1. 2개월 마감이 최우선 → Vue가 가장 빠름
2. 팀이 작고 JS 숙련 → Vue의 간결함이 효율적
3. MVP 단계 → 대규모 생태계는 현재 불필요
4. 학습 곡선 최소 → 즉시 생산성 확보
5. 향후 마이그레이션 가능 → 리스크 관리 가능
단, 향후 팀 규모 확장 시 React 전환 검토 권장
고급 패턴
1. Least-to-Most Prompting
복잡한 문제를 작은 하위 문제로 분해한 후 순차적으로 해결합니다.
문제: 웹 애플리케이션 성능을 50% 향상시키세요.
먼저 이 문제를 작은 하위 문제들로 나누겠습니다:
하위 문제 1: 현재 성능 병목 지점 식별
→ 해결: 프로파일링 도구 사용, 네트워크 탭 분석, Lighthouse 실행
하위 문제 2: 프론트엔드 최적화
→ 해결: 코드 스플리팅, 이미지 최적화, lazy loading
하위 문제 3: 백엔드 최적화
→ 해결: 데이터베이스 인덱스, 캐싱, 쿼리 최적화
하위 문제 4: 네트워크 최적화
→ 해결: CDN 사용, HTTP/2, Gzip 압축
하위 문제 5: 측정 및 검증
→ 해결: A/B 테스트, 성능 지표 모니터링
각 하위 문제를 순차적으로 해결하면 전체 50% 향상 목표 달성 가능
2. Tree of Thoughts
여러 추론 경로를 트리 구조로 탐색하고 최적 경로를 선택합니다.
문제: "GAME"이라는 단어에서 한 글자씩 바꿔서 "PLAY"로 만드세요. 각 단계는 유효한 영단어여야 합니다.
추론 트리 탐색:
경로 1:
GAME → GALE (✓ 유효) → PALE (✓ 유효) → PALY (✗ 유효하지 않음) → 막힘
경로 2:
GAME → CAME (✓ 유효) → CALE (✗ 유효하지 않음) → 막힘
경로 3:
GAME → GAPE (✓ 유효) → PAPE (✗ 유효하지 않음) → 막힘
경로 4:
GAME → GATE (✓ 유효) → PATE (✓ 유효) → LATE (✓ 유효) → LATY (✗ 유효하지 않음) → 막힘
경로 5:
GAME → TAME (✓ 유효) → TALE (✓ 유효) → PALE (✓ 유효) → PALY (✗ 유효하지 않음) → 막힘
...
최적 경로:
GAME → NAME → LAME → LAMB → PLAN (불가능)
# 여러 경로를 탐색하여 실현 가능성 평가
베스트 프랙티스
1. 명시적 지시
"단계별로", "차근차근", "먼저...그 다음..." 같은 명확한 지시를 사용하세요.
✅ 좋은 예시
"다음 문제를 단계별로 풀어주세요. 각 단계를 명확히 표시하세요."
"먼저 A를 분석하고, 그 다음 B를 평가한 후, 마지막으로 결론을 도출하세요."
❌ 나쁜 예시
"문제를 풀어주세요." # 너무 모호
2. 구조화된 출력
단계 번호, 제목, 구분선을 사용하여 추론 과정을 명확히 하세요.
다음 형식으로 답변하세요:
## 단계 1: [단계명]
[내용]
## 단계 2: [단계명]
[내용]
## 단계 3: [단계명]
[내용]
## 최종 답변
[요약 및 결론]
3. 자가 검증 추가
Claude가 자신의 추론을 검증하도록 요청하세요.
문제: [수학 문제]
단계별로 풀이한 후, 다음을 수행하세요:
1. 풀이 과정 작성
2. 답 도출
3. 답을 문제에 대입하여 검증
4. 검증 결과 명시
예시:
## 풀이
...
## 답
x = 5
## 검증
문제에 x = 5를 대입:
2x + 3 = 13
2(5) + 3 = 10 + 3 = 13 ✓
검증 성공
CoT 성능 개선 팁
1. temperature 조정
복잡한 추론에는 낮은 temperature(0.2~0.5)를 사용하여 일관성을 높이세요.
message = client.messages.create(
model="claude-" ,
max_tokens=2048,
temperature=0.3, # 낮은 온도 → 일관된 추론
messages=[{"role": "user", "content": cot_prompt}]
)
2. 충분한 max_tokens
CoT는 출력이 길므로 max_tokens를 충분히 설정하세요 (최소 1024, 권장 2048+).
3. Few-shot + CoT 조합
예제에 추론 과정을 포함시켜 패턴을 학습시키면 더욱 효과적입니다.
한계와 주의사항
1. 비용 증가
CoT는 출력 토큰이 많아 비용이 증가합니다. 필요한 경우에만 사용하세요.
2. 지연 시간
단계별 추론으로 응답 시간이 길어집니다. 실시간 대화에는 부적합할 수 있습니다.
3. 환각 위험
CoT가 항상 정확한 것은 아닙니다. 그럴듯하지만 잘못된 추론을 할 수 있으므로 중요한 결정에는 검증이 필요합니다.
다음 단계
CoT를 마스터했다면 실전에 적용해보세요:
핵심 정리
- Chain-of-Thought (CoT)의 핵심 개념과 흐름을 정리합니다.
- CoT란?를 단계별로 이해합니다.
- 실전 적용 시 기준과 주의점을 확인합니다.
실무 팁
- 입력/출력 예시를 고정해 재현성을 확보하세요.
- Chain-of-Thought (CoT) 범위를 작게 잡고 단계적으로 확장하세요.
- CoT란? 조건을 문서화해 대응 시간을 줄이세요.