AI 에이전트로 구현하는 RAG 01
AI 에이전트로 구현하는 RAG 시스템(w. LangGraph)를 듣고 요약 정리한 내용입니다.
1. 들어가며
최근 LLM 기반의 RAG(Retrieval-Augmented Generation)가 챗봇, 검색 서비스, 문서 요약 등 다양한 영역에서 활용되고 있다. 하지만 기본적인 RAG 방식에는 몇 가지 한계가 있다.
단일 질문-응답 구조로는 복잡한 요구사항 처리에 한계가 있다. 검색된 문서를 그대로 사용할 뿐, 문서의 품질이나 적합성을 평가하지 않는다. 다단계 추론이나 도구 호출을 필요로 하는 경우, 일관된 컨트롤 흐름을 유지하기 어렵다. LangGraph는 이러한 문제를 해결하기 위해 고안된 구조다. LangChain 생태계를 기반으로 상태(state), 흐름(flow), 조건 분기(branching) 등을 지원하여 에이전트 기반의 RAG 시스템을 유연하게 설계할 수 있게 해준다.
2. LangChain ToolCalling 개념과 활용
2-1. ToolCalling이란?
ToolCalling은 LLM이 외부 도구(검색, 계산, API 등)를 호출해 결과를 활용하는 방식이다.
LLM의 한계인 실시간 정보 부족, 정확한 계산 불가, 전문적인 도메인 지식 부재 등을 보완하는 핵심 기능이다.
2-2. LangChain의 내장 도구 예시
tavily_search_results_json: 실시간 웹 검색 API (Tavily) 검색 키워드를 입력하면, 신뢰도 높은 웹 검색 결과를 반환한다.
도구 직접 실행
1
2
3
4
from langchain_community.tools import TavilySearchResults
web_search = TavilySearchResults(max_results=2)
search_results = web_search.invoke("스테이크에 어울리는 와인 추천")
2-3. LLM과 도구 바인딩
Tool Calling
1
2
3
4
5
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(model="gpt-4o-mini")
llm_with_tools = llm.bind_tools(tools=[web_search])
response = llm_with_tools.invoke("스테이크에 어울리는 와인 추천")
1
2
{'url': 'https://m.blog.naver.com/wineislikeacat/223096696241', 'content': '등심 스테이크, 채끝 스테이크와 어울리는 와인 품종은? 카베르네 소비뇽, 시라 등!\n\n등심은 소의 등뼈를 둘러싸고 있는 부위입니다.... 중략
{'url': 'https://mashija.com/%EC%8A%A4%ED%85%8C%EC%9D%B4%ED%81%AC%EC%99%80-%EC%96%B4%EC%9A%B8%EB%A6%AC%EB%8A%94-%EC%B5%9C%EA%B3%A0%EC%9D%98-%EC%99%80%EC%9D%B8-%EB%AC%B4%EC%97%87%EC%9D%84-%EA%B3%A0%EB%A5%BC-%EA%B2%83%EC%9D%B8/', 'content': 'Bora Kim 2022년 1월 27일\n카베르네 소비뇽(Cabernet Sauvignon) 및 말벡(Malbec)과 같은 전형적인 선택부터 더 가벼운 레드 와인, ... 중략}
도구 호출 결과는 tool_calls 필드에 포함된다. 해당 도구를 수동 또는 자동으로 실행한 뒤, 결과를 다시 LLM에 전달하면 응답 생성에 활용된다.
2-4 사용자 정의 도구
사용자가 직접 도구를 정의하여 사용할 수도 있다. 가장 대표적인 방법으로는 @tool
데코레이터 가 있다.
• 함수를 LangChain 도구로 변환하는 방법
• 도구 함수 작성 가이드라인: 명확한 입출력 정의, 단일 책임 원칙 준수
• 도구 설명(description) 작성: LLM이 도구의 기능을 정확히 이해하고 사용하도록 작성
-> description을 명확하게 작성해야 LLM이 효과적으로 도구를 선택할 수 있다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
from langchain_community.tools import TavilySearchResults
from langchain_core.tools import tool
from typing import List
# Tool 정의
@tool
def search_web(query: str) -> str:
"""Searches the internet for information that does not exist in the database or for the latest information."""
tavily_search = TavilySearchResults(max_results=2)
docs = tavily_search.invoke(query)
formatted_docs = "\n---\n".join([
f'<Document href="{doc["url"]}"/>\n{doc["content"]}\n</Document>'
for doc in docs
])
if len(formatted_docs) > 0:
return formatted_docs
return "관련 정보를 찾을 수 없습니다."
query = "스테이크와 어울리는 와인을 추천해주세요."
search_result = search_web.invoke(query)
print(search_result)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<Document href="https://m.blog.naver.com/wineislikeacat/223096696241"/>
등심 스테이크, 채끝 스테이크와 어울리는 와인 품종은? 카베르네 소비뇽, 시라 등!
등심은 소의 등뼈를 둘러싸고 있는 부위입니다.
육질이 연하고 지방이 많아서 두꺼운 스테이크 구이용으로 최적이죠.
채끝은 등뼈에서 허리를 감싸는 뼈로 내려오는 쪽의 살인데요,
... 중략
</Document>
---
<Document href="https://mashija.com/%EC%8A%A4%ED%85%8C%EC%9D%B4%ED%81%AC%EC%99%80-%EC%96%B4%EC%9A%B8%EB%A6%AC%EB%8A%94-%EC%B5%9C%EA%B3%A0%EC%9D%98-%EC%99%80%EC%9D%B8-%EB%AC%B4%EC%97%87%EC%9D%84-%EA%B3%A0%EB%A5%BC-%EA%B2%83%EC%9D%B8/"/>
Bora Kim 2022년 1월 27일
카베르네 소비뇽(Cabernet Sauvignon) 및 말벡(Malbec)과 같은 전형적인 선택부터 더 가벼운 레드 와인, 심지어 화이트 와인과 맛있는 스테이크를 페어링하는 방법까지, 우리의 아카이브에서 가져온 최고의 조언과 최근 디캔터 전문가가 추천한 와인을 소개한다. [...] <스테이크를 곁들인 레드 와인을 위한 5가지 전형적인 선택>
• 카베르네 소비뇽(Cabernet Sauvignon)
... 중략
</Document>
3. LangChain Agent 이해하기
3-1. LangChain Agent란?
LangChain Agent는 LLM이 어떤 도구를 언제 어떻게 사용할지 스스로 결정하도록 하는 구조다.
Agent는 단순히 답을 출력하는 것이 아니라, 생각(Reasoning) 하고, 행동(Acting) 하며, 그 결과를 기반으로 다음 단계를 선택하는 과정을 반복한다.
3-2. 구성 요소
create_tool_calling_agent: 에이전트 초기화 함수
AgentExecutor: 에이전트 실행을 담당
1
2
3
4
5
6
7
8
from langchain.agents import create_tool_calling_agent, AgentExecutor
tools = [search_web, wiki_summary, search_wine, search_menu]
agent = create_tool_calling_agent(llm, tools)
agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
query = "시그니처 스테이크의 가격과 특징은 무엇인가요? 그리고 스테이크와 어울리는 와인 추천도 해주세요."
response = agent_executor.invoke({"input": query})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
> Entering new AgentExecutor chain...
Invoking: `search_menu` with `{'query': '시그니처 스테이크'}`
[Document(metadata={'menu_name': '시그니처 스테이크', 'menu_number': 1, 'source': './data/restaurant_menu.txt'}, page_content='1. 시그니처 스테이크\n • 가격: ₩35,000\n • 주요 식재료: 최상급 한우 등심, 로즈메리 감자, 그릴드 아스파라거스\n • 설명: 셰프의 특제 시그니처 메뉴로, 21일간 건조 숙성한 최상급 한우 등심을 사용합니다. 미디엄 레어로 조리하여 육즙을 최대한 보존하며, 로즈메리 향의 감자와 아삭한 그릴드 아스파라거스가 곁들여집니다. 레드와인 소스와 함께 제공되어 풍부한 맛을 더합니다.'), Document(metadata={'menu_name': '안심 스테이크 샐러드', 'menu_number': 8, 'source': './data/restaurant_menu.txt'}, page_content='8. 안심 스테이크 샐러드\n • 가격: ₩26,000\n • 주요 식재료: 소고기 안심, 루꼴라, 체리 토마토, 발사믹 글레이즈\n • 설명: 부드러운 안심 스테이크를 얇게 슬라이스하여 신선한 루꼴라 위에 올린 메인 요리 샐러드입니다. 체리 토마토와 파마산 치즈 플레이크로 풍미를 더하고, 발사믹 글레이즈로 마무리하여 고기의 풍미를 한층 끌어올렸습니다.')]
Invoking: `search_wine` with `{'query': '스테이크'}`
[Document(metadata={'menu_name': '그랜지 2016', 'menu_number': 10, 'source': './data/restaurant_wine.txt'}, page_content='10. 그랜지 2016\n • 가격: ₩950,000\n • 주요 품종: 시라\n • 설명: 호주의 대표적인 아이콘 와인입니다. 블랙베리, 자두, 블랙 올리브의 강렬한 과실향과 함께 유칼립투스, 초콜릿, 가죽의 복잡한 향이 어우러집니다. 풀바디이며 강렬한 타닌과 산도가 특징적입니다. 놀라운 집중도와 깊이, 긴 여운을 자랑하며, 수십 년의 숙성 잠재력을 가집니다.'), Document(metadata={'menu_name': '사시카이아 2018', 'menu_number': 3, 'source': './data/restaurant_wine.txt'}, page_content='3. 사시카이아 2018\n • 가격: ₩420,000\n • 주요 품종: 카베르네 소비뇽, 카베르네 프랑, 메를로\n • 설명: 이탈리아 토스카나의 슈퍼 투스칸 와인입니다. 블랙베리, 카시스의 강렬한 과실향과 함께 허브, 가죽, 스파이스 노트가 복잡성을 더합니다. 풀바디이지만 우아한 타닌과 신선한 산도가 균형을 잡아줍니다. 오크 숙성으로 인한 바닐라, 초콜릿 향이 은은하게 느껴집니다.')]
**시그니처 스테이크 정보**:
- **가격**: ₩35,000
- **주요 재료**: 쇠고기 등심, 로즈마리, 흑후추
- **조리 방법**: 생소금에 21일간 숙성된 최상급 쇠고기를 사용하여 미디엄 레어로 조리합니다. 고소한 맛의 로즈마리와 향긋한 흑후추를 곁들여 풍미를 더했습니다.
**스테이크와 어울리는 와인 추천**:
1. **그란지 2016**
- **가격**: ₩950,000
- **특징**: 호주산으로 강렬한 과일 맛과 탄닌이 잘 어우러진 와인입니다. 스테이크의 풍미를 보완하며, 깊은 맛을 제공합니다.
2. **사스까이 2018**
- **가격**: ₩420,000
- **특징**: 카베르네 소비뇽과 멜롯의 조화로 부드러운 맛과 풍부한 과일향이 특징입니다. 스테이크와의 조화가 훌륭하여 고기의 맛을 더욱 돋보이게 합니다.
이 두 와인은 시그니처 스테이크와 잘 어울리며, 각각의 풍미가 스테이크의 맛을 더욱 강조해 줄 것입니다. 즐거운 식사 되세요! 🍷🥩
> Finished chain.
에이전트는 주어진 질문을 해석한 뒤, 필요한 도구를 호출하고, 그 결과에 따라 다음 행동을 선택한다. 여러 도구를 조합하거나, 반복적으로 질문을 재구성하는 방식도 가능하다.