ReAct: 추론과 행동의 결합
Reasoning + Acting - 생각한 후 도구를 사용하고, 결과를 관찰하는 순환 구조
Reasoning + Acting
개념
ReAct는 추론(Reasoning)과 행동(Acting)을 결합한 에이전트 프레임워크이다. 생각한 후 외부 도구를 사용하고, 결과를 관찰하는 순환 구조를 가진다.
동작 구조
- Thought -- 현재 상황을 분석하고 다음 단계를 계획한다
- Action -- 외부 도구를 호출한다 (검색, 계산 등)
- Observation -- 행동 결과를 수신한다
- 목표를 달성할 때까지 1-3 단계를 반복한다
예시
질문: "롯데월드타워의 높이는?"
Thought: 롯데월드타워 높이를 알아야 함. 검색 필요. Action: [Search] "롯데월드타워 높이" Observation: 554.5미터
Thought: 정보를 얻었음. 답변 가능. Answer: 554.5미터
다단계 추론 예시
질문: "한국에서 가장 높은 건물과 두 번째로 높은 건물의 높이 차이는?"
Thought: 먼저 가장 높은 건물을 알아야 한다. Action: [Search] "한국 가장 높은 건물" Observation: 롯데월드타워 (554.5m)
Thought: 두 번째로 높은 건물도 알아야 한다. Action: [Search] "한국 두 번째로 높은 건물" Observation: 해운대 LCT 더샵 (411.6m)
Thought: 이제 차이를 계산할 수 있다. Action: [Calculate] 554.5 - 411.6 Observation: 142.9
Answer: 142.9미터
장점
| 장점 | 설명 |
|---|---|
| 검증 가능성 | 어떤 도구를 사용했는지 투명 |
| 최신 정보 | 검색으로 실시간 정보 접근 |
| 투명성 | 추론 과정이 명확 |
| 확장성 | 새로운 도구 쉽게 추가 |
CoT만으로는 해결할 수 없는 문제
질문: "오늘 서울 날씨는?"
CoT만 사용: Thought: 서울은 한국의 수도이고... Answer: 서울은 사계절이 뚜렷하여... (할루시네이션)
ReAct 사용: Thought: 실시간 날씨 정보가 필요하다 Action: [Search] "오늘 서울 날씨" Observation: 맑음, 기온 -2°C Answer: 오늘 서울은 맑고, 기온은 영하 2도이다.
성능
| 벤치마크 | 기존 | ReAct |
|---|---|---|
| HotpotQA | 29% | 36.4% |
| FEVER | 45% | 79% |
FEVER는 팩트 검증 작업으로, ReAct가 특히 강점을 보이다.
사용 가능한 도구들
| 도구 | 용도 | 예시 |
|---|---|---|
| Search | 정보 검색 | 최신 뉴스, 사실 확인 |
| Calculate | 수학 계산 | 복잡한 연산 |
| Wikipedia | 백과사전 조회 | 개념 설명 |
| Code | 코드 실행 | 프로그래밍 작업 |
| Calendar | 날짜 계산 | 요일, 기간 계산 |
한계
-
복잡한 다단계 도구 사용 시 실패 가능
- 도구 사용 순서가 복잡해지면 오류 증가
-
잘못된 경로에서 회복 어려움
- 한 번 잘못된 방향으로 가면 되돌리기 어려움
-
도구 의존성
- 적절한 도구가 없으면 해결 불가
Reflexion과의 결합
ReAct의 한계를 극복하기 위해 Reflexion과 결합할 수 있다:
1차 시도 Thought: 검색하자 Action: [Search] "잘못된 검색어" Observation: 관련 없는 결과 -- 실패
Reflexion: "검색어가 너무 모호했다. 더 구체적으로 검색해야 한다."
2차 시도 Thought: 더 구체적인 검색어 사용 Action: [Search] "구체적인 검색어" Observation: 정확한 결과 -- 성공
구현 패턴
def react_loop(question, max_iterations=5):
context = f"Question: {question}\n"
for i in range(max_iterations):
# Thought 생성
thought = llm.generate(context + "Thought:")
context += f"Thought: {thought}\n"
# Action 결정
action = llm.generate(context + "Action:")
if action.startswith("[Search]"):
result = search(action.query)
elif action.startswith("[Calculate]"):
result = calculate(action.expression)
else:
break
context += f"Action: {action}\n"
context += f"Observation: {result}\n"
# 최종 답변 생성
answer = llm.generate(context + "Answer:")
return answer관련 개념
- Chain of Thought (CoT): 기반 기술 (추론만)
- Reflexion: 실패 복구 추가
- LATS: 트리 탐색 결합
- Toolformer: 도구 사용 자동 학습