Agent 기능의 기반이 되는 ReAct에 대해 알아보자

Kitkat·2025년 4월 14일

논문 제목: 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


1. ReAct란

ReAct는 대형 언어 모델(LLM)이 문제 해결 과정에서 추론(Reasoning)행동(Acting)교차적으로 수행하도록 만드는 프롬프트 패턴으로 에이전트(Agent) 개념의 기반이라고 할 수 있다.

ReAct를 통해 LLM은 마치 인간처럼 문제를 단계적으로 해결하고, 필요한 정보를 스스로 찾아가며, 추론 결과에 따라 계획을 수정하며 올바른 답을 찾게 된다.


2. ReAct와 Agent

기존의 LLM이 질문에 답을 출력하는 정적인 시스템이었다면, ReAct는 동적인 순환 구조를 가진다.

ReAct의 구조적 특성

  • 목표 기반 행동: 문제 해결이라는 목표를 향해 여러 단계를 거침
  • 상태 인식: Observation(환경 피드백)을 받아 상태 업데이트
  • 결정 및 실행: Thought에서 Action을 도출
  • 환경 상호작용: Wikipedia API나 웹사이트, 시뮬레이터 등 외부와 상호작용 가능

이러한 특성은 LangChain 같은 프레임워크에서 ReAct agent로 직접 구현되어 쓰이고 있다.


3. ReAct의 구조: 루프 기반 추론과 행동

ReAct는 다음 예시와 같은 루프를 반복한다.

Thought: 지금까지 관찰한 정보로는 부족하다. 사과는 냉장고에 있을 가능성이 크다.
Action: GoTo[fridge]
Observation: 냉장고 안에 사과가 있음.
Thought: 이제 정답을 알았다.
Action: Finish[사과는 냉장고에 있다]
구성 요소설명
Thought내부 추론, 다음 행동의 근거
Action도구 사용, API 호출, 환경 명령 등
Observation환경으로부터 받은 응답
Finish루프 종료 지점 (정답 제출)

4. 루프는 언제, 어떻게 종료되는가?

ReAct에서 루프는 LLM이 다음과 같은 판단을 할 때 종료된다:

종료 조건

  1. 문제 해결에 충분한 정보가 수집되었을 때
  2. Observation이 명확한 답을 제공할 때
  3. 질문이 단일 사실 기반일 때
  4. 추론 루프가 반복되거나 의미 없는 상태일 때

LangChain에서는 LLM이 출력한 Action: Finish[...] 패턴을 감지하여 루프를 종료한다.


5. Finish 액션의 판단은 어떻게???

LLM이 Finish[...]를 출력할지 여부는 철저히 문맥 기반 reasoning에 따른다. 다음과 같은 표현들이 signal로 작용한다:

  • Thought: "I now know the answer."
  • Thought: "That directly answers the question."
  • Thought: "So the final answer must be..."

이러한 판단은 few-shot prompting 또는 fine-tuning을 통해 학습된다.


6. 문제점

ReAct는 Thought-Action-Observation을 매번 누적해서 저장하게 되므로 하나의 요청에도 수백에서 수천 토큰을 소모할 수 있다는 문제점이 있다.

해결책

  • max_iterations 설정 : 루프 횟수 제한
  • Observation 요약 : 긴 문장을 짧게 요약
  • LangChain Memory 사용 : 이전 컨텍스트 압축 또는 델타 방식 유지
  • 대형 context 모델 사용

7. LangChain ReAct agent 구현 예제

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("질문 내용 입력")

8. 결론

ReAct는 단순한 프롬프트 기법이 아니라, 언어 모델을 에이전트로 진화시키는 구조적 접근 방식이다. Reasoning과 Acting을 통합함으로써 LLM은 다음과 같은 능력을 갖추게 된다

  • 외부 지식 활용 기반의 추론
  • 동적 계획 수립 및 수정
  • 결정 근거가 드러나는 설명력
  • 학습 없이도 새로운 문제에 대응

0개의 댓글