ReAct (인공지능)
더 많은 작업
- ReAct (Reasoning + Acting)
- 언어 모델이 생각(Thought), 행동(Action), 관찰(Observation)을 번갈아 쓰게 해서, 추론하며 외부 도구로 정보를 모으고 그 결과로 다시 추론하게 하는 프롬프팅 방식
ReAct는 추론(reasoning)과 행동(acting)을 합친 이름으로, 2022년 10월 프린스턴 대학교와 구글 연구진(Shunyu Yao 외)이 발표하고 ICLR 2023에 실린 대형 언어 모델 프롬프팅 방식이다. 모델이 자유 형식의 생각을 쓰고, 그 생각에 따라 검색 같은 행동을 지정하면, 실행 환경이 행동 결과를 관찰로 붙여 주고 모델이 다시 생각한다. 생각만 하는 사고 사슬(CoT)은 모르는 사실을 지어내기 쉽고, 행동만 하는 방식은 계획과 예외 처리가 약한데, 둘을 엮어 서로 보완하게 했다.[1]
이 생각, 행동, 관찰의 반복은 이후 LLM 에이전트의 기본 골격이 되었다. 에이전트 전반의 구성 요소와 역사는 에이전트 인공지능 문서에서 다루고, 이 문서는 ReAct의 프롬프트 형식, 실험 결과, 구현을 자세히 다룬다.
환경과 상호작용하는 에이전트가 시점 에 관찰 를 받고 행동 를 고른다고 하자. 지금까지의 맥락은 다. ReAct는 행동 공간을 로 넓힌다. 은 언어 공간이고, 여기서 고른 "행동"인 생각 는 환경을 바꾸지 않고 관찰도 받지 않는다. 대신 맥락에 덧붙어 가 되어 이후 추론과 행동을 돕는다.[1]
생각은 여러 역할을 한다. 논문은 질문 분해("x를 찾고, y를 찾고, z를 찾아야 한다"), 관찰에서 정보 뽑기("x는 1844년에 시작되었다"), 상식·산술 추론("1844 < 1989"), 검색어 바꾸기("대신 x를 찾아보자"), 최종 답 정리를 예로 든다.
ReAct는 별도 학습 없이 퓨샷 예시로 형식을 가르친다. HotpotQA는 6개, Fever는 3개의 사람이 쓴 궤적을 예시로 넣었고, 예시를 더 늘려도 성능이 오르지 않았다.[1] 지식 질의응답 실험의 행동 공간은 위키백과 API를 흉내 낸 세 가지다.
search[entity]: 해당 위키백과 문서의 첫 5문장을 돌려준다. 문서가 없으면 비슷한 제목 5개를 제안한다.lookup[string]: 현재 문서에서 그 문자열이 들어 있는 다음 문장을 돌려준다(브라우저의 찾기 기능).finish[answer]: 답을 내고 끝낸다.
논문 예시 하나를 우리말로 옮기면 다음과 같다(관찰은 환경이 채운 부분이다).
Question: 콜로라도 조산 운동의 동부 구역이 뻗어 들어가는 지역의 고도 범위는?
Thought 1: 콜로라도 조산 운동을 검색해 동부 구역이 어디로 뻗는지 찾고, 그 지역의 고도 범위를 찾아야 한다.
Action 1: Search[Colorado orogeny]
Observation 1: 콜로라도 조산 운동은 콜로라도와 주변 지역에서 일어난 조산 운동이다.
Thought 2: 동부 구역 이야기가 없다. 동부 구역을 찾아봐야 한다.
Action 2: Lookup[eastern sector]
Observation 2: (결과 1/1) 동부 구역은 하이플레인스로 뻗으며 센트럴 플레인스 조산 운동이라 불린다.
Thought 3: 동부 구역은 하이플레인스로 뻗는다. 하이플레인스의 고도 범위를 찾아야 한다.
Action 3: Search[High Plains]
Observation 3: 하이플레인스는 서로 다른 두 지역 중 하나를 가리킨다.
Thought 4: 미국의 하이플레인스를 검색해야 한다.
Action 4: Search[High Plains (United States)]
Observation 4: 하이플레인스는 그레이트플레인스의 하위 지역이다. 동쪽에서 서쪽으로 약 1,800피트에서 7,000피트까지 높아진다.
Thought 5: 고도 범위는 1,800~7,000피트다.
Action 5: Finish[1,800 to 7,000 ft]
지식 과제에서는 매 단계 생각을 쓰는 조밀한(dense) 형식을, 수십 단계가 걸리는 의사 결정 과제(ALFWorld)에서는 필요할 때만 생각을 끼우는 성긴(sparse) 형식을 썼다.
| 방법 | HotpotQA(EM) | Fever(정확도) |
|---|---|---|
| 표준(답만) | 28.7 | 57.1 |
| 사고 사슬(CoT) | 29.4 | 56.3 |
| CoT 자기 일관성(CoT-SC, 21개 표본) | 33.4 | 60.4 |
| 행동만(Act) | 25.7 | 58.9 |
| ReAct | 27.4 | 60.9 |
| CoT-SC → ReAct | 34.2 | 64.6 |
| ReAct → CoT-SC | 35.1 | 62.0 |
- 생각을 넣은 ReAct는 행동만 하는 Act보다 두 과제 모두 좋았다.
- ReAct 단독은 Fever에서 CoT보다 좋고 HotpotQA에서는 조금 낮았다. 그래서 논문은 둘을 섞는 규칙을 제안했다. ReAct가 정해진 단계(HotpotQA 7단계, Fever 5단계) 안에 답하지 못하면 CoT-SC로 넘어가고(ReAct → CoT-SC), CoT-SC 표본 개 중 최다 답이 번 미만으로 나오면(내부 지식이 불확실하면) ReAct로 넘어간다(CoT-SC → ReAct). 이 조합은 표본 3~5개로 CoT-SC 21개 표본의 성능에 도달했다.
ReAct 형식의 궤적 3,000개로 미세 조정하면 작은 모델에서도 효과가 컸다. 미세 조정한 PaLM-8B ReAct가 PaLM-62B의 모든 프롬프팅 방법을, 미세 조정한 PaLM-62B ReAct가 PaLM-540B의 모든 프롬프팅 방법을 앞섰다. 표준·CoT 형식으로 미세 조정하면 사실을 외우게 되지만, ReAct 형식은 정보를 찾는 방법을 가르치므로 더 잘 일반화한다는 해석이다.[1]
텍스트 형식 그대로 구현하면 다음과 같다. llm(prompt, stop)은 문자열을 이어 쓰는 아무 언어 모델 호출 함수다. 핵심은 관찰을 모델이 쓰지 못하게 멈춤 문자열을 거는 것이다. 이를 빼면 모델이 관찰까지 지어낸다.
import re
def react(question, llm, tools, examples, max_steps=7):
"""llm(prompt, stop) -> str, tools: {"search": 함수, "lookup": 함수}"""
prompt = examples + f"\nQuestion: {question}\n"
for i in range(1, max_steps + 1):
out = llm(prompt + f"Thought {i}:", stop=[f"\nObservation {i}:"])
prompt += f"Thought {i}:{out}\n"
m = re.search(rf"Action {i}:\s*(\w+)\[(.*?)\]", out)
if not m: # 형식 오류도 관찰로 돌려준다
prompt += f"Observation {i}: Invalid action.\n"
continue
act, arg = m.group(1).lower(), m.group(2)
if act == "finish":
return arg, prompt
obs = tools[act](arg) if act in tools else f"Unknown action {act}."
prompt += f"Observation {i}: {obs}\n"
return None, prompt # 단계 한도 초과
OpenAI 호환 API라면 llm은 client.completions.create(model=..., prompt=p, stop=stop, temperature=0)의 결과 텍스트를 돌려주면 된다. 논문 실험도 탐욕 디코딩을 썼다. 단계 한도에 걸려 None이 나오면 논문처럼 CoT-SC로 넘어가게 할 수 있다.
상용 모델과 프레임워크는 ReAct의 구조를 유지하면서 형식만 바꿨다.
- 텍스트 파싱 대신 도구 호출: 모델이
Action: search[...]를 문장으로 쓰는 대신, API가 도구 이름과 JSON 인자를 구조화된 필드로 돌려주고, 결과는 도구 결과 메시지로 넣는다. 정규식 파싱 오류가 사라지고 구조화된 출력으로 인자 형식을 강제할 수도 있다. 도구 연결 표준으로는 모델 컨텍스트 프로토콜이 있다. - 생각의 위치: 추론 모델은 도구를 부르기 전후에 내부 추론을 하므로, Thought를 프롬프트로 유도하지 않아도 같은 효과를 낸다.
- 종료와 안전장치: 최대 단계 수, 같은 행동 반복 감지, 비용 한도, 위험한 도구의 사람 승인 같은 장치를 루프 밖에 둔다. 관찰에 들어온 외부 텍스트가 지시를 몰래 바꾸는 프롬프트 인젝션도 막아야 한다.
| 방식 | 외부 정보 | 계획 | 주된 약점 |
|---|---|---|---|
| 사고 사슬(CoT) | 없음 | 한 줄의 추론 | 사실 환각 |
| 행동만(Act) | 있음 | 암묵적 | 목표 추적, 예외 처리 부족 |
| ReAct | 있음 | 단계마다 다시 계획 | 반복 루프, 검색 실패에 흔들림, 단계마다 호출이라 느림 |
| 계획 후 실행(Plan-and-Execute) | 있음 | 처음에 전체 계획 | 중간 결과가 계획과 어긋나면 다시 계획해야 함 |
| Reflexion | 있음 | 실패 뒤 언어적 반성을 기억에 남겨 재시도 | 여러 번 시도할 수 있는 과제에 한정 |
| 생각의 나무 | 보통 없음 | 여러 갈래를 탐색·평가 | 호출 수가 많아 비쌈 |