논문 제목: ReAct: Synergizing Reasoning and Acting in Language Models
학회: ICLR 2023
저자: Shunyu Yao, Jeffrey Zhao, Dian Yu 외
링크: https://react-lm.github.io https://arxiv.org/abs/2210.03629
ReAct는 대형 언어 모델(LLM)이 문제 해결 과정에서 추론(Reasoning)과 행동(Acting)을 교차적으로 수행하도록 만드는 프롬프트 패턴으로 에이전트(Agent) 개념의 기반이라고 할 수 있다.
ReAct를 통해 LLM은 마치 인간처럼 문제를 단계적으로 해결하고, 필요한 정보를 스스로 찾아가며, 추론 결과에 따라 계획을 수정하며 올바른 답을 찾게 된다.
기존의 LLM이 질문에 답을 출력하는 정적인 시스템이었다면, ReAct는 동적인 순환 구조를 가진다.
이러한 특성은 LangChain 같은 프레임워크에서 ReAct agent로 직접 구현되어 쓰이고 있다.
ReAct는 다음 예시와 같은 루프를 반복한다.
Thought: 지금까지 관찰한 정보로는 부족하다. 사과는 냉장고에 있을 가능성이 크다.
Action: GoTo[fridge]
Observation: 냉장고 안에 사과가 있음.
Thought: 이제 정답을 알았다.
Action: Finish[사과는 냉장고에 있다]
| 구성 요소 | 설명 |
|---|---|
| Thought | 내부 추론, 다음 행동의 근거 |
| Action | 도구 사용, API 호출, 환경 명령 등 |
| Observation | 환경으로부터 받은 응답 |
| Finish | 루프 종료 지점 (정답 제출) |
ReAct에서 루프는 LLM이 다음과 같은 판단을 할 때 종료된다:
LangChain에서는 LLM이 출력한 Action: Finish[...] 패턴을 감지하여 루프를 종료한다.
Finish 액션의 판단은 어떻게???LLM이 Finish[...]를 출력할지 여부는 철저히 문맥 기반 reasoning에 따른다. 다음과 같은 표현들이 signal로 작용한다:
이러한 판단은 few-shot prompting 또는 fine-tuning을 통해 학습된다.
ReAct는 Thought-Action-Observation을 매번 누적해서 저장하게 되므로 하나의 요청에도 수백에서 수천 토큰을 소모할 수 있다는 문제점이 있다.
max_iterations 설정 : 루프 횟수 제한 from langchain.agents import initialize_agent, Tool
from langchain.chat_models import ChatOpenAI
from langchain.tools import DuckDuckGoSearchRun
from langchain.agents.agent_types import AgentType
search = DuckDuckGoSearchRun()
tools = [Tool(name="Search", func=search.run, description="Search the web")]
llm = ChatOpenAI(temperature=0)
agent = initialize_agent(
tools=tools,
llm=llm,
agent=AgentType.REACT_DOCSTORE,
verbose=True
)
agent.run("질문 내용 입력")
ReAct는 단순한 프롬프트 기법이 아니라, 언어 모델을 에이전트로 진화시키는 구조적 접근 방식이다. Reasoning과 Acting을 통합함으로써 LLM은 다음과 같은 능력을 갖추게 된다