1 ReAct Agent란?
ReAct(Reasoning and Acting)는 대규모 언어 모델(LLM)이 추론(Reasoning)과 행동(Acting)을 결합하여 문제를 해결하는 패턴이다.
1.1 ReAct의 핵심 개념
전통적인 방식의 한계: - Chain-of-Thought: 추론만 수행 (외부 정보 접근 불가) - Tool-only: 도구 사용만 수행 (추론 과정 부재)
ReAct의 장점: - 추론 + 행동: 각 단계에서 “왜 이 행동을 하는가?”를 생각하고 실행 - 반복적 개선: 결과를 보고 다음 행동을 결정 - 투명성: 추론 과정이 명시적으로 드러남
1.2 ReAct 작동 원리
1. Thought (생각): "이 문제를 해결하려면 최신 정보가 필요하다"
2. Action (행동): 웹 검색 도구 실행
3. Observation (관찰): 검색 결과 확인
4. Thought (생각): "이 정보로 답변할 수 있다"
5. Final Answer: 최종 답변 생성
1.3 LangGraph의 ReAct 구현
LangGraph의 create_react_agent는 ReAct 패턴을 쉽게 구현할 수 있게 해주는 사전 구축된 에이전트다.
주요 특징: - 자동 루프: Thought → Action → Observation 반복 - 메모리 지원: 이전 대화 기억 - 멀티 도구: 여러 도구를 동시에 사용 가능 - 스트리밍: 실시간 응답 생성
2 환경 설정
2.1 기본 구성 요소
ReAct Agent는 세 가지 핵심 요소가 필요하다:
- LLM 모델: 추론을 담당
- 도구(Tools): 외부 작업 수행
- 메모리(Memory): 대화 이력 저장

from langchain_openai import ChatOpenAI
from langchain_teddynote.tools.tavily import TavilySearch
from langchain_core.messages import HumanMessage
from langgraph.checkpoint.memory import MemorySaver
from langgraph.prebuilt import create_react_agent
# 메모리 설정 (대화 이력 저장)
memory = MemorySaver()
# 모델 설정 (GPT-4o-mini 사용)
model = ChatOpenAI(model_name="gpt-4o-mini")MemorySaver: - 대화 컨텍스트를 메모리에 저장 - 이전 대화를 기억하여 연속적인 대화 가능 - Thread ID로 세션 관리
3 도구 설정
ReAct Agent는 다양한 도구를 사용하여 복잡한 작업을 수행한다.
3.1 웹 검색 도구
Tavily Search: 실시간 웹 검색을 위한 도구
from langchain_teddynote.tools.tavily import TavilySearch
# 웹 검색 도구 생성
web_search = TavilySearch(
topic="general", # 뉴스 주제 (general 또는 news)
max_results=5, # 최대 검색 결과 수
include_answer=False, # Tavily의 답변 포함 여부
include_raw_content=False, # 원본 HTML 포함 여부
include_images=False, # 이미지 포함 여부
format_output=False, # 결과 포맷팅 여부
)
# 도구 이름 및 설명 설정 (LLM이 도구를 선택할 때 사용)
web_search.name = "web_search"
web_search.description = (
"Use this tool to search on the web for any topic other than news."
)웹 검색 테스트:
왜 웹 검색이 필요한가? - LLM의 지식 컷오프 날짜 이후의 최신 정보 획득 - 실시간 데이터 (뉴스, 주가, 날씨 등) 조회 - 팩트 체크 및 검증
3.2 파일 관리 도구
FileManagementToolkit: 로컬 파일 시스템 작업
from langchain_community.agent_toolkits import FileManagementToolkit
# 'tmp'라는 이름의 디렉토리를 작업 디렉토리로 설정
working_directory = "tmp"
# FileManagementToolkit 객체를 생성
file_management_tools = FileManagementToolkit(
root_dir=str(working_directory),
).get_tools()포함된 도구들:
주요 기능: - write_file: 파일 쓰기 - read_file: 파일 읽기 - list_directory: 디렉토리 목록 조회 - copy_file: 파일 복사 - move_file: 파일 이동 - delete_file: 파일 삭제
사용 예시: 1. 웹에서 정보 수집 2. 보고서 작성 3. 파일로 저장
4 Retriever 도구
PDF 문서 검색: RAG 시스템과 통합
4.1 PDF 문서 로드 및 벡터화
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_community.vectorstores import FAISS
from langchain_openai import OpenAIEmbeddings
from langchain.document_loaders import PDFPlumberLoader
# PDF 파일 로드. 파일의 경로 입력
loader = PDFPlumberLoader("data/SPRI_AI_Brief_2023년12월호_F.pdf")
# 텍스트 분할기를 사용하여 문서를 분할
text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=100)
# 문서를 로드하고 분할
split_docs = loader.load_and_split(text_splitter)
# VectorStore를 생성 (FAISS 사용)
vector = FAISS.from_documents(split_docs, OpenAIEmbeddings())
# Retriever를 생성
pdf_retriever = vector.as_retriever()처리 과정: 1. PDF 로드: PDFPlumberLoader로 텍스트 추출 2. 청크 분할: 1000자 단위로 분할 (100자 오버랩) 3. 임베딩: OpenAI Embeddings로 벡터 변환 4. 벡터 저장: FAISS에 저장 5. Retriever 생성: 유사도 검색 가능한 객체
4.2 Retriever를 도구로 변환
from langchain_core.tools.retriever import create_retriever_tool
from langchain_core.prompts import PromptTemplate
# PDF 문서를 기반으로 검색 도구 생성
retriever_tool = create_retriever_tool(
pdf_retriever,
"pdf_retriever",
"Search and return information about SPRI AI Brief PDF file. It contains useful information on recent AI trends. The document is published on Dec 2023.",
document_prompt=PromptTemplate.from_template(
"<document><context>{page_content}</context><metadata><source>{source}</source><page>{page}</page></metadata></document>"
),
)도구 설명 작성 팁: - LLM이 언제 이 도구를 사용할지 명확히 기술 - 문서 내용 및 출판 날짜 명시 - 검색 가능한 주제 힌트 제공
4.3 전체 도구 목록
도구 조합의 장점: - 웹 검색: 최신 정보 - 파일 관리: 결과 저장 및 관리 - PDF 검색: 내부 문서 지식
5 에이전트 생성
5.1 create_react_agent
LangGraph의 사전 구축된 ReAct Agent를 생성한다.
from langgraph.prebuilt import create_react_agent
agent_executor = create_react_agent(model, tools, checkpointer=memory)파라미터: - model: 사용할 LLM - tools: 도구 목록 - checkpointer: 메모리 저장소 (대화 이력)
내부 동작: 1. 사용자 입력 받기 2. LLM이 추론 (어떤 도구를 사용할지) 3. 도구 실행 4. 결과 관찰 5. 다음 행동 결정 (반복) 6. 최종 답변 생성
5.2 에이전트 시각화
그래프 구조: - agent 노드: LLM이 추론 및 도구 선택 - tools 노드: 선택된 도구 실행 - 순환 구조: agent ↔︎ tools 반복
6 실행 함수 정의
6.1 스트리밍 출력
실시간으로 에이전트의 사고 과정을 확인할 수 있다.
stream_graph 함수: - 에이전트 실행을 스트리밍으로 출력 - 각 노드의 출력을 실시간 확인 - 디버깅 및 모니터링에 유용
7 사용 예시
7.1 예시 1: 기본 대화 (메모리 테스트)
# Config 설정 (Thread ID로 세션 관리)
config = {"configurable": {"thread_id": "abc123"}}
inputs = {"messages": [("human", "안녕? 내 이름은 테디야")]}
# 그래프 스트림
stream_graph(agent_executor, inputs, config, node_names=["agent"])메모리 확인:
config = {"configurable": {"thread_id": "abc123"}}
inputs = {"messages": [("human", "내 이름이 뭐라고?")]}
# 그래프 스트림
stream_graph(agent_executor, inputs, config, node_names=["agent"])기대 결과: - “테디”라고 기억하고 답변 - 이전 대화를 참조하여 연속적인 대화
7.2 예시 2: PDF 문서 검색
config = {"configurable": {"thread_id": "abc123"}}
inputs = {
"messages": [
("human", "AI Brief 보고서에서 Anthropic 투자 관련된 정보를 요약해줘.")
]
}
stream_graph(agent_executor, inputs, config, node_names=["agent", "tools"])실행 흐름: 1. Thought: “PDF 문서를 검색해야겠다” 2. Action: pdf_retriever 실행 3. Observation: Anthropic 투자 관련 문서 청크 반환 4. Thought: “이 정보로 요약을 작성할 수 있다” 5. Final Answer: 요약 생성
7.3 예시 3: 웹 검색
config = {"configurable": {"thread_id": "abc123"}}
inputs = {
"messages": [
(
"human",
"한강 작가의 노벨상 수상 관련된 뉴스를 검색하고 보고서 형식에 맞게 작성해줘",
)
]
}
stream_graph(agent_executor, inputs, config, node_names=["agent", "tools"])실행 흐름: 1. Thought: “최신 뉴스를 검색해야 한다” 2. Action: web_search 실행 3. Observation: 검색 결과 확인 4. Thought: “보고서 형식으로 정리해야 한다” 5. Final Answer: 보고서 작성
7.4 예시 4: 복합 작업 (검색 + 작성 + 저장)
instruction = """
당신의 임무는 `보도자료`를 작성하는 것이다.
----
다음의 내용을 순서대로 처리해 주세요.
1. `한강 작가의 노벨상 수상` 관련된 뉴스를 검색해 주세요.
2. 노벨상 수상 관련 뉴스를 바탕으로 보고서 / 보드자료 작성해 주세요.
3. 단, 중간에 요점 정리를 위한 markdown 테이블 형식 요약을 적극 활용해 주세요.
4. 출력 결과를 파일로 저장해 주세요. (파일 이름은 "agent_press_release.md")
"""config = {"configurable": {"thread_id": "abc123"}}
inputs = {"messages": [("human", instruction)]}
stream_graph(agent_executor, inputs, config, node_names=["agent", "tools"])실행 흐름: 1. 웹 검색: web_search 도구로 최신 뉴스 검색 2. 보고서 작성: 검색 결과를 바탕으로 markdown 보고서 작성 3. 파일 저장: write_file 도구로 파일 저장
멀티 도구 사용: - 하나의 작업에서 여러 도구를 순차적으로 사용 - 각 도구의 결과를 다음 단계의 입력으로 활용 - 복잡한 워크플로우를 자동화
8 ReAct Agent 활용 팁
8.1 도구 선택 최적화
명확한 도구 설명 작성:
tool.name = "specific_tool_name"
tool.description = "Use this tool when [specific condition]. It returns [output format]."도구 우선순위 힌트: - 시스템 프롬프트에 도구 사용 가이드 추가 - 도구 설명에 사용 시기 명시
8.2 에러 처리
일반적인 문제: 1. 무한 루프: 최대 반복 횟수 설정 2. 잘못된 도구 선택: 도구 설명 개선 3. 메모리 부족: Thread ID 정리
해결 방법:
8.3 성능 최적화
모델 선택: - 빠른 응답: GPT-4o-mini - 복잡한 추론: GPT-4o
도구 개수: - 너무 많은 도구 → 선택 혼란 - 권장: 3-7개 도구
메모리 관리: - 긴 대화 → 토큰 소비 증가 - 주기적으로 Thread 초기화
9 ReAct vs 다른 패턴
| 패턴 | 추론 | 도구 사용 | 반복 | 투명성 |
|---|---|---|---|---|
| ReAct | ✅ | ✅ | ✅ | 높음 |
| Chain-of-Thought | ✅ | ❌ | ❌ | 높음 |
| Tool-only | ❌ | ✅ | ❌ | 낮음 |
| Plan-and-Execute | ✅ | ✅ | 제한적 | 중간 |
ReAct의 장점: - 각 단계에서 “왜”를 설명 - 실패 시 재시도 가능 - 디버깅이 쉬움
단점: - 토큰 소비가 많음 - 느린 실행 속도
10 참고 자료
11 다음 단계
ReAct Agent의 기본을 익혔다면, 다음 주제들을 살펴보자:
- 커스텀 도구 개발: 특화된 도구 만들기
- Plan-and-Execute Agent: 더 복잡한 작업 계획
- Multi-Agent 시스템: 여러 에이전트 협업