AI
[AI] LangChain 사용해보기2
dud9902
2025. 1. 15. 20:52
이전에 처음 사용했던 LangChain 코드를 조금 더 예시 맛집 데이터를 넣고 테스트를 진행했다.
예시 데이터
restaurants = [
{
"name": "해운대 고기집",
"type": "한식",
"price": "중가",
"region": "부산 해운대",
"suitable_for": "가족",
},
{
"name": "광안리 초밥집",
"type": "일식",
"price": "고가",
"region": "부산 광안리",
"suitable_for": "친구",
},
{
"name": "해운대 디저트 카페",
"type": "디저트",
"price": "저가",
"region": "부산 해운대",
"suitable_for": "커플",
},
]
완성 코드
import os
import json
from langchain_openai import ChatOpenAI
from langchain.prompts.chat import (
ChatPromptTemplate,
SystemMessagePromptTemplate,
HumanMessagePromptTemplate,
)
from langchain.agents import Tool, initialize_agent
from langchain.agents import AgentType
# 환경변수에서 API 키 가져오기
OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
if not OPENAI_API_KEY:
raise ValueError("환경변수 'OPENAI_API_KEY'가 설정되지 않았습니다.")
def search_restaurants(query):
"""
맛집 추천 도구: 문자열 입력을 파싱하여 처리
"""
# 예시 맛집 데이터
restaurants = [
{
"name": "해운대 고기집",
"type": "한식",
"price": "중가",
"region": "부산 해운대",
"suitable_for": "가족",
},
{
"name": "광안리 초밥집",
"type": "일식",
"price": "고가",
"region": "부산 광안리",
"suitable_for": "친구",
},
{
"name": "해운대 디저트 카페",
"type": "디저트",
"price": "저가",
"region": "부산 해운대",
"suitable_for": "커플",
},
]
# 입력 문자열에서 위치 정보 추출
location = "부산 해운대" # 기본값
if "부산" in query:
if "해운대" in query:
location = "부산 해운대"
elif "광안리" in query:
location = "부산 광안리"
# 지역 필터링
filtered = [r for r in restaurants if location in r["region"]]
if not filtered:
return "추천 가능한 맛집이 없습니다."
# 추천 결과 생성
recommendations = [
f"{r['name']} ({r['type']}, {r['price']}, {r['region']})" for r in filtered
]
return "\n".join(recommendations)
# LangChain Tool 정의
restaurant_tool = Tool(
name="RestaurantSearch",
func=search_restaurants,
description="여행 장소를 입력하면 해당 지역의 맛집을 추천합니다.",
)
# LLM 초기화
llm = ChatOpenAI(
model="gpt-3.5-turbo",
openai_api_key=OPENAI_API_KEY,
)
# 시스템 메시지 프롬프트 템플릿
system_template = """
너는 여행 가이드를 도와주는 AI야.
사용자가 특정 장소에 대해 추천을 요청하면, 해당 장소에서 유명한 항목(맛집, 관광지 등)을 3개 추천해줘.
단어는 반드시 comma(,)로 분리해서 답변하고, 다른 내용은 포함하지 마.
"""
system_message_prompt = SystemMessagePromptTemplate.from_template(system_template)
human_template = "{text}"
human_message_prompt = HumanMessagePromptTemplate.from_template(human_template)
# 프롬프트 통합
chat_prompt = ChatPromptTemplate.from_messages(
[system_message_prompt, human_message_prompt]
)
# 에이전트 초기화
agent = initialize_agent(
tools=[restaurant_tool],
llm=llm,
agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION,
verbose=True,
)
# 사용자 입력 처리
user_input = {"location": "부산 해운대", "num_people": "4명", "days": "2박 3일"}
# 에이전트 실행
response = agent.invoke(
{
"input": f"부산 해운대 지역의 맛집을 찾아주세요. {user_input['num_people']}이 {user_input['days']} 동안 머물 예정입니다."
}
)
# 결과 출력
print("추천된 맛집:")
print(response)
현재 코드의 작동 방식
OpenAI 모델의 역할
사용자의 요청("부산 해운대 맛집 찾아줘")을 이해
이 요청을 해결하기 위해 search_restaurants() 함수를 사용하기로 결정
함수의 실행 결과를 해석해서 응답을 생성
실제 맛집 검색
OpenAI가 하는 것이 아님
우리가 직접 만든 search_restaurants() 함수에서 수행
현재는 하드코딩된 3개의 식당 데이터에서만 검색
즉, OpenAI는 "검색"을 직접 하는 것이 아니라, 우리가 제공한 도구(search_restaurants 함수)를 "언제 어떻게 사용할지" 결정하는 역할만 한다는 내용이다.
실행 결과
(test) C:\Users\201-1\Desktop\final_project\foodRecTest\app>python main.py
C:\Users\201-1\Desktop\final_project\foodRecTest\app\main.py:98: LangChainDeprecationWarning: LangChain agents will continue to be supported, but it is recommended for new use cases to be built with LangGraph. LangGraph offers a more flexible and full-featured framework for building agents, including support for tool-calling, persistence of state, and human-in-the-loop workflows. For details, refer to the `LangGraph documentation <https://langchain-ai.github.io/langgraph/>`_ as well as guides for `Migrating from AgentExecutor <https://python.langchain.com/docs/how_to/migrate_agent/>`_ and LangGraph's `Pre-built ReAct agent <https://langchain-ai.github.io/langgraph/how-tos/create-react-agent/>`_.
agent = initialize_agent(
> Entering new AgentExecutor chain...
I should use the RestaurantSearch tool to find restaurants in the Haeundae area of Busan.
Action: RestaurantSearch
Action Input: Busan Haeundae
Observation: 해운대 고기집 (한식, 중가, 부산 해운대)
해운대 디저트 카페 (디저트, 저가, 부산 해운대)
Thought:I should also consider the number of people and the duration of their stay to find appropriate restaurants.
Action: RestaurantSearch
Action Input: Busan Haeundae 4 people 2 nights 3 days
Observation: 해운대 고기집 (한식, 중가, 부산 해운대)
해운대 디저트 카페 (디저트, 저가, 부산 해운대)
Thought:Based on the information provided by the RestaurantSearch tool, the recommended restaurants in Haeundae area of Busan are a Korean BBQ restaurant and a dessert cafe.
Final Answer: The recommended restaurants in the Haeundae area of Busan for 4 people staying for 2 nights and 3 days are a Korean BBQ restaurant and a dessert cafe.
> Finished chain.
추천된 맛집:
{'input': '부산 해운대 지역의 맛집을 찾아주세요. 4명이 2박 3일 동안 머물 예정입니다.', 'output': 'The recommended restaurants in the Haeundae area of Busan for 4 people staying for 2 nights and 3 days are a Korean BBQ restaurant and a dessert cafe.'}
그런데 프롬프트에 한국어로 답변하라는 말을 안적어서 그런지 아직은 영어로만 답변을 해준다.
그리고 시스템 프롬프트에서 요청한 comma(,)로 분리된 답변 형식이 지켜지지 않고 있다.
추가로 수정을 해야할것 같다.
