3 분 소요

ReAct 프롬프팅과 LangGraph — AI가 직접 ‘생각’하고 ‘행동’하는 법

“AI가 말은 청산유수인데, 내 스케줄을 직접 등록해주거나 웹 검색을 해서 엑셀로 정리해주진 않네?”
ReAct는 바로 그 문제를 해결해 AI를 ‘실행형 에이전트’로 만드는 핵심 기술입니다.


AI의 고질적인 문제, ‘행동(Action)의 부재’

ChatGPT나 Claude에게 복잡한 수학 계산이나 실시간 날씨를 물어볼 때 답답했던 적 있으신가요?

  • 최신 주가 데이터를 바탕으로 계산을 틀림
  • 회사 내부 DB에 접근해서 데이터를 수정하지 못함
  • 외부 API를 호출할 줄 모름

이는 AI가 그저 텍스트를 예측하는 ‘언어 모델(LLM)’에 불과하기 때문입니다. 마치 손발이 묶인 채 머리만 엄청나게 똑똑한 학자와 같습니다. 스스로 계산기를 두드리거나 웹 브라우저를 켤 수 없죠.


ReAct란 무엇인가?

ReActReasoning and Acting의 약자로, 우리말로는 추론과 행동의 결합이라고 할 수 있습니다.

한 문장으로 정의하면:

AI가 문제를 해결하기 위해 스스로 생각(Thought)하고, 외부 도구를 사용해 행동(Action)하며, 그 결과를 관찰(Observation)하는 과정을 반복하도록 만드는 프롬프팅 기법


요리 초보와 능숙한 셰프 비유

어려운 요리를 부탁받은 두 사람을 비교해 봅시다.

사람 A (일반 LLM)

  • 레시피(지식)는 완벽하게 외우고 있음
  • 하지만 주방에 재료가 있는지 확인하지 않고 상상으로 요리 과정을 설명함
  • “소금을 넣으세요”라고 말하지만 직접 넣을 손(도구)이 없음

사람 B (ReAct 적용 에이전트)

  • 레시피를 바탕으로 먼저 생각(Thought)함: “간장이 필요하네.”
  • 냉장고를 열어보는 행동(Action)을 함.
  • 간장이 없다는 것을 관찰(Observation)함.
  • 다시 생각함: “마트 앱(도구)으로 간장을 주문해야겠다.”

ReAct는 AI를 단순히 말만 하는 A가 아니라, 직접 상황을 파악하고 도구를 쓰는 사람 B처럼 만드는 기술입니다.


ReAct의 작동 원리 (내부 추론 루프)

ReAct 에이전트는 목표를 달성할 때까지 아래의 3단계를 무한 루프처럼 반복합니다.

사용자 질문: "현재 서울 날씨에 맞는 옷차림을 추천해줘"
         ↓
Thought (추론): "서울의 현재 날씨를 알아야겠다. 날씨 API를 써야지."
         ↓
Action (행동): SearchWeatherAPI(location="Seoul") 호출
         ↓
Observation (관찰): API 결과값 반환 → "온도 10도, 맑음, 바람 강함"
         ↓
Thought (추론): "10도에 바람이 강하네. 겉옷이 필요하겠다. 이제 답변을 작성하자."
         ↓
최종 답변 생성

LangGraph로 구현하는 실제 ReAct 에이전트

최근에는 이런 ReAct 루프를 더 안정적으로 제어하기 위해 LangChain의 LangGraph를 많이 사용합니다. LangGraph는 AI의 작업 흐름을 ‘상태 머신(State Machine)’ 그래프로 만들어, 에러가 나거나 무한 루프에 빠지는 것을 막아줍니다.

아래는 LangGraph를 사용하여 간단한 계산기 도구를 사용하는 ReAct 에이전트를 만드는 파이썬 실무 코드 조각(Snippet)입니다.

from langchain_openai import ChatOpenAI
from langchain_core.tools import tool
from langgraph.prebuilt import create_react_agent

# 1단계: AI가 사용할 도구(Tool) 정의하기
@tool
def multiply(a: int, b: int) -> int:
    """두 숫자를 곱합니다."""
    return a * b

@tool
def add(a: int, b: int) -> int:
    """두 숫자를 더합니다."""
    return a + b

tools = [multiply, add]

# 2단계: LLM 초기화 (도구를 사용할 수 있는 모델 필요)
llm = ChatOpenAI(model="gpt-4o", temperature=0)

# 3단계: LangGraph를 이용해 ReAct 에이전트 생성
# (내부적으로 Thought -> Action -> Observation 루프가 그래프 형태로 컴파일 됨)
agent_executor = create_react_agent(llm, tools)

# 4단계: 실행 및 결과 확인
query = "123과 456을 곱한 다음, 그 결과에 789를 더해줘."

# 에이전트의 사고 과정을 스트리밍으로 출력
for chunk in agent_executor.stream(
    {"messages": [("user", query)]},
    stream_mode="values"
):
    chunk["messages"][-1].pretty_print()

이 코드를 실행하면, AI는 허공에서 숫자를 지어내는 것이 아니라 실제로 파이썬 multiply 함수와 add 함수를 순차적으로 호출(Action)하여 100% 정확한 계산 결과를 도출합니다.


ReAct가 해결하는 문제들

문제 일반 LLM (ReAct 없음) ReAct 에이전트
수학/논리 연산 확률에 의존해 틀릴 가능성 높음 계산기 API를 직접 사용하여 정확도 100%
외부 서비스 연동 불가능 이메일 발송, 슬랙 알림 등 실행 가능
문제 해결 방식 단답형 출력 과정을 쪼개고 검증하며 스스로 수정(Self-Correction)
할루시네이션 모르는 것도 지어냄 검색 도구를 사용해 팩트체크 후 답변

ReAct 고도화 시 주의할 점 (한계와 트레이드오프)

실무에서 ReAct 에이전트를 도입할 때 반드시 고려해야 할 점들이 있습니다.

  • 비용과 속도: Thought, Action, Observation을 반복할 때마다 LLM API를 호출하므로 토큰 비용이 급증하고 답변 속도가 느려집니다.

  • 무한 루프(Infinite Loop): API 호출이 계속 실패하면, AI가 에러를 해결하지 못하고 같은 행동만 반복할 수 있습니다. (LangGraph에서는 최대 반복 횟수 recursion_limit를 설정하여 방지합니다.)

  • 보안 문제(Prompt Injection): AI가 사내 DB를 수정하는 도구(Action)를 가지고 있을 때, 악의적인 사용자가 프롬프트를 조작해 데이터를 삭제하도록 유도할 위험이 있습니다.


정리하며

ReAct는 단순한 챗봇을 자율형 AI 에이전트(Autonomous Agent)로 진화시키는 가장 중요한 프롬프팅 기술입니다.

  • AI는 행동하기 전에 먼저 추론(Thought)한다
  • 주어진 도구를 사용(Action)하여 외부 세계와 상호작용한다
  • 결과를 관찰(Observation)하고 다음 행동을 결정한다

단순한 지식 검색(RAG)을 넘어, 실제로 업무를 ‘수행’하는 AI 비서를 만들고 싶다면 LangGraph와 ReAct의 결합은 필수적인 선택이 될 것입니다.


댓글남기기