
오늘은 ChatGPT API를 사용해서 여행 계획을 작성해 주는 챗봇을 만들어 보자!

OpenAI > assistants에서 챗봇의 기본 정보를 넣어주자. 이름은 '여행 계획 작성봇'이고, 프롬프트는 '너는 세계 곳곳의 여행 정보를 잘 알고 있어서 어디든 시간과 예산에 맞춰서 여행 계획을 잘 짜줘. 원하는 여행지와, 여행 기간, 예산을 말하면 여행 계획과 일정을 날짜별로 짜줘. 또, 항공권이나 기차 예매는 어떻게 하는지도 알려줘. 또, 특정 날짜에 전시나 공연 행사가 있다면 그 행사가 포함된 일정을 짜줘. '라고 넣었다.

그리고 왼쪽에서 assistants id, 오른쪽에서 thread id를 복사한다.
import openai
from dotenv import load_dotenv
import time
import logging
from datetime import datetime
load_dotenv()
client = openai.OpenAI()
assistant_id = "asst_WBJHxUaCHCBheZWNA1yYMJUf"
thread_id = "thread_U3wPxZxDgg0wnJTRFkyLWiTz"
message = "나 중국 여행 가고 싶은데 계획 좀 짜줄래? 여행 기간은 3일, 예산은 300만 원이야."
message = client.beta.threads.messages.create(
thread_id=thread_id, role="user", content=message
)
instructions = """너는 세계 곳곳의 여행 정보를 잘 알고 있어서 어디든 시간과 예산에 맞춰서 여행 계획을 잘 짜줘. 원하는 여행지와, 여행 기간, 예산을 말하면 여행 계획과 일정을 날짜별로 짜줘. 또, 항공권이나 기차 예매는 어떻게 하는지도 알려줘. """
이와 같이 코드에 id와 프롬프트를 넣어준다.
run = client.beta.threads.runs.create(
assistant_id=assistant_id,
thread_id=thread_id,
# instructions=instructions
)
def wait_for_run_completion(client, thread_id, run_id, sleep_interval=5):
"""
Waits for a run to complete and prints the elapsed time.:param client: The OpenAI client object.
:param thread_id: The ID of the thread.
:param run_id: The ID of the run.
:param sleep_interval: Time in seconds to wait between checks.
"""
while True:
try:
run = client.beta.threads.runs.retrieve(thread_id=thread_id, run_id=run_id)
if run.completed_at:
elapsed_time = run.completed_at - run.created_at
formatted_elapsed_time = time.strftime(
"%H:%M:%S", time.gmtime(elapsed_time)
)
print(f"Run completed in {formatted_elapsed_time}")
logging.info(f"Run completed in {formatted_elapsed_time}")
# Get messages here once Run is completed!
messages = client.beta.threads.messages.list(thread_id=thread_id)
last_message = messages.data[0]
response = last_message.content[0].text.value
print(f"Assistant Response: {response}")
break
except Exception as e:
logging.error(f"An error occurred while retrieving the run: {e}")
break
logging.info("Waiting for run to complete...")
time.sleep(sleep_interval)
# === Run ===
wait_for_run_completion(client=client, thread_id=thread_id, run_id=run.id)
# ==== Steps --- Logs ==
run_steps = client.beta.threads.runs.steps.list(thread_id=thread_id, run_id=run.id)
print(f"Steps---> {run_steps.data[0]}")
그리고 위와 같이 코드를 작성하고, 터미널에 python 파일이름.py를 입력해 실행시켜 보면,



이렇게 답변을 받을 수 있다.
이번에는 여행지 추천 블로그를 넣으면 그에 맞게 여행 계획을 짤 수 있도록, 블로그를 크롤링하는 코드를 작성해 보자.

예를 들어 이렇게 부산의 여행지 추천 글을 넣어보자.
import trafilatura as tf
html = tf.fetch_url("https://kr.hotels.com/go/south-korea/kr-best-busan-locals-things-to-do")
result = tf.extract(html)
print(result)
그리고 해당 파일을 실행시키면,

위와 같이 크롤링 해 준다.

그리고 크롤링 된 글과 함께 이번에는 부산 여행 계획 글을 짜달라고 보내면,



이런식으로 체계적으로 답변을 보내준다.
만든 챗봇을 웹에서 사용할 수 있게 만들어 보자.

앞에서 작성한 코드를 streamlit 코드로 바꿔달라고 ChatGPT에게 보낸다.

ChatGPT가 변환한 코드는 파일로 저장한다.
그 다음 pip install streamlit으로 패키지를 설치해 주고, streamlit run 파일이름.py로 파일을 실행시켜 보자.


그러면 이렇게 웹으로도 동작되는 것을 확인할 수 있다.

ui를 바꿔달라고 하면 이렇게 더 이쁘게도 바꿀 수 있다.

여행 지역 / 기간 / 예산을 입력받고, 크롤링하여 참고할 웹 페이지 또한 사용자에게 입력받을 수 있도록 위와 같이 바꿔줬다.
import streamlit as st
import openai
from dotenv import load_dotenv
import time
from datetime import datetime
import trafilatura as tf
load_dotenv()
# OpenAI API 설정
client = openai.OpenAI()
assistant_id = "asst_WBJHxUaCHCBheZWNA1yYMJUf"
thread_id = "thread_U3wPxZxDgg0wnJTRFkyLWiTz"
# 여행 계획 생성 함수
def generate_travel_plan(destination, duration, budget, blog_url):
try:
# 사용자 입력 정보 전송
user_input = f"여행 지역: {destination}, 여행 기간: {duration} 일, 예산: {budget} 원, 참고 웹 페이지: {blog_url}"
client.beta.threads.messages.create(thread_id=thread_id, role="user", content=user_input)
# 여행 계획 생성 요청
run = client.beta.threads.runs.create(assistant_id=assistant_id, thread_id=thread_id)
run_id = run.id
# 실행 완료 대기
while True:
run = client.beta.threads.runs.retrieve(thread_id=thread_id, run_id=run_id)
if run.completed_at:
# 실행 완료 시간 계산
elapsed_time = run.completed_at - run.created_at
formatted_elapsed_time = time.strftime("%H:%M:%S", time.gmtime(elapsed_time))
st.success(f"여행 계획 생성 완료 ({formatted_elapsed_time})")
# 최종 메시지 확인
messages = client.beta.threads.messages.list(thread_id=thread_id)
last_message = messages.data[0]
travel_plan = last_message.content[0].text.value
return travel_plan
time.sleep(5) # 5초마다 확인
except Exception as e:
st.error(f"An error occurred: {e}")
return None
# Streamlit 애플리케이션 시작
def main():
# 페이지 설정
st.set_page_config(
page_title="Travel Planner Assistant",
page_icon="🌍",
layout="centered",
initial_sidebar_state="expanded",
)
# 사이드바
with st.sidebar:
st.title("Travel Planner Assistant")
st.image("https://pbs.twimg.com/media/E-LYlnoVIAMxx0P.jpg", use_column_width=True)
st.markdown("""
### 기능 설명
- 원하는 여행지와 기간, 예산에 맞춘 여행 계획 짜기
- 항공권이나 기차 예매 방법 안내
""")
# 메인 페이지
st.title("🌍 Travel Planner Assistant")
st.subheader("여행 계획을 세워보세요!")
# 사용자 입력 받기
destination = st.text_input("여행 지역")
duration = st.number_input("여행 기간(일)", min_value=1, step=1)
budget = st.number_input("여행 예산(원)", min_value=1, step=1)
blog_url = st.text_input("참고할 웹 페이지 URL")
html = tf.fetch_url(blog_url)
result = tf.extract(html)
if st.button("계획 짜기"):
if destination and duration and budget and blog_url:
with st.spinner("여행 계획을 세우고 있습니다..."):
travel_plan = generate_travel_plan(destination, duration, budget, result)
if travel_plan:
st.markdown(f"### 여행 계획:\n{travel_plan}")
else:
st.warning("모든 정보를 입력해주세요.")
if __name__ == "__main__":
main()