전통 RAG의 한계 (Retrieval-Augmented Generation의 한계)
RAG(Retrieval-Augmented Generation)는 대형 언어 모델(LLM)이 응답을 생성할 때, 외부 지식베이스에서 관련 정보를 검색하여 활용하는 기법입니다. 예를 들어 질문에 답하기 위해 벡터 DB 등에서 관련 문서를 찾아와 LLM의 프롬프트에 포함시키는 방식이죠. 이러한 전통적인 RAG 파이프라인은 질문 → 키워드 기반 벡터 검색 → 상위 문서 반환 → 답변 생성의 단순 구조로 이루어집니다.
하지만 이 방식에는 큰 한계가 있습니다. 질문 자체가 여러 단계를 거쳐야 풀리는 경우(멀티홉 추론)에는 한 번의 벡터 검색으로는 충분한 정보를 얻기 어렵습니다 (genui.com). 다시 말해, 질문에 필요한 단서들이 서로 다른 문서에 분산되어 있고, 각 단서를 연결해야 답이 나오는 경우에는 단순한 벡터 유사도 검색만으로 답을 찾기 어렵습니다 (genui.com).
예시 질문을 통해 살펴보겠습니다. “2025년 기준 Apple의 소프트웨어 엔지니어링 담당 수석부사장(SVP)은 어디서 공학 학위를 받았나요?”라는 질문이 있다고 해보죠. 이 질문은 두 단계의 추론이 필요합니다.
- 2025년 기준 Apple의 소프트웨어 엔지니어링 담당 SVP가 누구인지 알아내기 (1단계).
- 그 사람이 어느 대학에서 공학 학위를 받았는지 찾기 (2단계).
전통적인 RAG 접근으로 1단계와 2단계를 한꺼번에 해결하려 하면 어려움이 있습니다. 우선 질문에 등장하는 키워드로 벡터 DB에 검색을 해봅니다. 예를 들어 “Apple SVP Software Engineering”이라는 키워드로 Weaviate와 같은 벡터 데이터베이스를 조회한다고 가정해보죠. 그러면 여러 관련 문서(JSON 형태)가 검색되어 나오지만, 원하는 답(학위를 받은 곳)은 직접적으로 보이지 않을 수 있습니다. 왜 그럴까요? 해당 결과들은 Apple의 임원 목록이나 조직 정보일 수 있지만, 질문에 답하려면 먼저 SVP의 이름을 알아낸 뒤, 다시 그 사람의 학력 정보를 찾아야 하기 때문입니다. 기존 RAG 파이프라인은 한 번의 검색 질의로 이 모든 단계를 수행하기 어렵습니다.
결국 사용자가 수동으로 결과를 읽고 “아, Apple 소프트웨어 엔지니어링 SVP는 크레이그 페더리기(Craig Federighi)구나”를 알아낸 뒤, 다시 “Craig Federighi academic background”와 같이 두 번째 검색을 해야 원하는 답을 찾게 됩니다. 이처럼 멀티홉 질문에 대해 전통 RAG는 사용자가 직접 검색과 추론을 여러 번 반복해야 한다는 한계를 보입니다. 요약하자면, 질문 자체에 필요한 중간 정보가 명시되지 않은 경우 기존 방식으로는 곧바로 답을 얻기 어렵다는 점입니다.
Tool-Using 에이전트 (ReAct Agent)
위 문제를 해결하기 위해 등장한 개념이 툴 사용 에이전트(Tool-Using Agent)입니다. 이는 LLM 스스로가 도구를 활용하여 단계적인 검색과 추론을 수행하는 에이전트 방식입니다. 특히 ReAct 라고 불리는 프롬프트 기법을 통해 구현되는데, ReAct(Reasoning + Acting)는 말 그대로 LLM이 “추론”과 “행동”을 번갈아 가며 수행하도록 만드는 패턴입니다(promptingguide.ai). 추론 단계에서는 모델이 다음에 무엇을 해야 할지 생각을 전개하고, 행동 단계에서는 실제로 정해진 도구(예: 검색 함수)를 호출하여 외부 정보를 가져옵니다.(promptingguide.aipromptingguide.ai.) 이렇게 함으로써 LLM은 필요한 경우 여러 번 외부 지식을 조회하면서 마치 사람처럼 복잡한 문제를 풀어나갈 수 있게 됩니다.
앞서 예로 든 Apple SVP 학위 질문을 툴 사용 에이전트로 접근하면 다음과 같은 흐름으로 해결됩니다:
- 질문 분석 (LLM 생각): LLM이 사용자 질문을 읽고, 바로 답을 모르겠으면 우선 “Apple의 소프트웨어 엔지니어링 담당 SVP가 누구인지 찾아봐야겠군” 하고 추론합니다. (내부적으로 이런 Thought를 가정합니다.)
- 도구 호출 (1단계 검색): LLM이 사전에 등록된 검색 툴(예: 위키백과 검색 함수)을 호출하도록 응답을 생성합니다. 예를 들어 "search_wikipedia"라는 도구를 {"keyword": "Apple SVP Software Engineering"} 인자로 실행하라는 Action을 내놓습니다.
- 시스템은 이 툴 호출을 받아 실제로 위키백과나 지식베이스에서 해당 키워드로 검색을 수행합니다.
- 검색 결과로 “Craig Federighi가 Apple 소프트웨어 엔지니어링 SVP”라는 정보를 얻어옵니다. 이를 LLM에게 Observation으로 전달합니다.
- 추론 계속 (LLM 생각): LLM은 방금 얻은 결과를 읽고, 이제 인물의 이름을 알았으니 “Craig Federighi의 학위 정보를 찾아보자”고 다음 행동을 계획합니다.
- 도구 호출 (2단계 검색): LLM이 다시 "search_wikipedia" 툴을 {"keyword": "Craig Federighi engineering degree"} 등의 인자로 두 번째 호출합니다.
- 시스템은 이 요청을 받아 Craig Federighi에 대한 학력 정보를 검색하고, “UC 버클리에서 컴퓨터공학 석사 학위를 받았다”는 등의 결과를 찾습니다.
- 해당 내용을 다시 LLM에게 Observation으로 제공하게 됩니다.
- 최종 답변 생성: LLM은 이제 필요한 정보를 모두 얻었으므로, 사용자에게 “Apple의 소프트웨어 엔지니어링 SVP인 크레이그 페더리기는 UC 버클리(캘리포니아 대학교 버클리)에서 공학 학위를 취득했습니다.”라는 최종 답변을 만들어냅니다.
위 과정을 보면, LLM 에이전트는 사람처럼 생각(Thought) → 검색(Action) → 결과 확인(Observation)을 반복하며 문제를 해결합니다. 이러한 ReAct Agent는 멀티홉으로 이어진 복잡한 질의에 대해 전통 RAG보다 훨씬 자연스럽게 답을 찾아낼 수 있습니다. LLM이 필요한 만큼 여러 번 도구를 호출해 정보를 수집하고, 그동안의 추론 맥락을 유지하면서 최종 결론을 도출하기 때문입니다. (참고로 이러한 접근은 핫팟QA(HotpotQA) 같은 멀티홉 QA 데이터셋 문제를 해결하기 위해 고안되었고, 기존의 단일 단계 검색보다 뛰어난 성능을 보였습니다.)
OpenAI Agent SDK로 간편하게 구현하기
앞서 살펴본 Tool-Using 에이전트의 논리를 조금 더 쉽게 구현할 수 있는 방법으로, OpenAI에서 제공하는 에이전트 SDK(프레임워크)를 활용하는 것이 있습니다. 이를 사용하면 일일이 메시지를 관리하며 함수 호출을 처리하는 대신, 에이전트 객체를 생성해 간편하게 멀티홉 질의응답을 수행할 수 있습니다.
OpenAI 에이전트 SDK를 사용하면 기본적으로 ReAct 스타일의 실행 흐름이 내장되어 있습니다. 간단한 설정으로 우리가 원하는 도구(tool)와 LLM을 엮어 에이전트를 만들 수 있죠. 예를 들어, 앞서 사용한 지식베이스 검색 함수를 툴로 등록하고 GPT-4 모델을 연결하여 에이전트를 생성해보겠습니다:
from openai_api import Agent, OpenAIChatCompletionsModel, function_tool# 가상의 모듈 예시# 1. 에이전트 생성 및 설정
wikipedia_agent = Agent(
name="Wikipedia Agent",
instructions=REACT_INSTRUCTIONS,# ReAct 스타일로 행동하도록 지시하는 시스템 프롬프트
tools=[ function_tool(async_knowledgebase.search_knowledgebase) ],
model=OpenAIChatCompletionsModel(
model=AGENT_LLM_NAME,# 예: "gpt-4"
openai_client=async_openai_client
),
)
위 코드에서 Agent 객체를 초기화하면서:
- instructions에는 에이전트에게 줄 시스템 역할의 메시지를 넣습니다. 여기에 ReAct 프롬프트(예: “너는 똑똑한 에이전트이며, 주어진 도구를 사용해서 질문에 답할 수 있다...” 등)를 명시해 LLM이 적절히 생각과 행동을 하도록 유도합니다.
- tools에는 에이전트가 사용할 수 있는 도구 목록을 넣습니다. 여기서는 우리가 정의한 search_knowledgebase 함수를 간단히 function_tool로 래핑하여 전달했습니다.
- model에는 사용할 LLM과 API 클라이언트를 지정합니다.
이렇게 에이전트를 설정해두면, 이후에는 wikipedia_agent.run("<사용자 질문>") 등의 형태로 간편하게 질문에 답변할 수 있습니다. SDK 내부에서 LLM의 함수 호출 및 도구 실행, 여러 턴에 걸친 추론을 자동으로 처리해주므로 개발자는 세부 로직보다는 결과 활용에 집중할 수 있습니다.
※ 참고: 본 예시는 OpenAI의 에이전트 기능을 직접 SDK 형태로 사용한 것입니다. 이와 비슷한 기능을 하는 오픈소스 프레임워크로 LangChain도 널리 쓰입니다. LangChain을 사용하면 다양한 도구 연동과 에이전트 프롬프트 템플릿을 지원하므로 손쉽게 멀티스텝 Q&A 에이전트를 구축할 수 있습니다. 다만 개념 자체는 동일하게 ReAct 스타일로 동작합니다.
요약
전통적인 RAG 방식은 한 번의 검색으로 답을 찾는 단순 질의응답에 적합하지만, 여러 단계를 거쳐야 하는 복잡한 질문에는 한계가 있습니다. 이러한 한계를 극복하기 위해 ReAct 스타일의 Tool-Using 에이전트가 등장했고, LLM이 스스로 검색 등의 도구를 활용하여 단계적으로 답을 찾아내는 똑똑한 방법을 가능하게 했습니다. 오픈AI의 SDK나 LangChain 같은 프레임워크를 활용하면 비교적 쉽게 이러한 에이전트를 구현할 수 있으며, Langfuse 등의 도구로 에이전트의 추론 과정을 모니터링하면서 개선해나갈 수 있습니다. LLM 시대의 새로운 질의응답 패러다임으로서, Tool-Using 에이전트는 앞으로 더욱 중요해질 것입니다.
참고
'AI engineering > AI agent' 카테고리의 다른 글
심층 리서치 구현: OpenAI Agent SDK를 활용해서 Deep Research Agent 만들기 (8) | 2025.08.03 |
---|---|
Cursor보다 좋고 싸다: Mac에서 Gemini CLI 사용하기 (3) | 2025.07.06 |
노코딩으로 초간단 chatGPT 창작 작문 AI 에이전트 만들기 - FlowiseAI (0) | 2025.01.31 |
FlowiseAI 설치방법: 코딩 없이 쉽게 나만의 챗봇, 추천 시스템을 만드는 툴 (1) | 2025.01.01 |