2강에서 작성한 첫번째 랭그래프 코드를 streamlit 형식에 넣어서 웹챗봇을 구현해 봅시다.
코드 작성
import streamlit as st
from typing import Annotated
from typing_extensions import TypedDict
from langgraph.graph import StateGraph, START, END
from langgraph.graph.message import add_messages
from langchain_openai import ChatOpenAI
import os
def LangGraph_run():
# Define the state for storing messages
class State(TypedDict):
messages: Annotated[list, add_messages]
graph_builder = StateGraph(State)
# session_state에 저장된 model_choice를 사용합니다.
st.session_state.model_choice == "OpenAI ChatGPT"
# OpenAI ChatGPT를 사용하는 코드
llm = ChatOpenAI(
model="gpt-4o-mini",
api_key=st.session_state.api_key
)
def chatbot(state: State):
return {"messages": [llm.invoke(state["messages"])]}
graph_builder.add_node("chatbot", chatbot)
graph_builder.add_edge(START, "chatbot")
graph_builder.add_edge("chatbot", END)
graph = graph_builder.compile()
try:
# Get the mermaid PNG as bytes
graph_bytes = graph.get_graph().draw_mermaid_png()
# 바이트를 이미지로 변환하고 Streamlit에 표시합니다.
st.image(graph_bytes, caption="Chatbot Graph")
except Exception as e:
st.error(f"Failed to display graph: {e}")
if "messages_01" not in st.session_state:
st.session_state.messages_01 = []
# 이전 메시지 모두 표시
for message in st.session_state.messages_01:
with st.chat_message(message["role"]):
st.markdown(message["content"])
# 새로운 사용자 입력을 받아 처리합니다.
if prompt := st.chat_input("무엇을 원하세요?"):
st.session_state.messages_01.append({"role": "user", "content": prompt})
with st.chat_message("user"):
st.markdown(prompt)
# 모델에 보낼 전체 채팅 기록을 준비합니다.
full_conversation = [(msg["role"], msg["content"]) for msg in st.session_state.messages_01]
# 전체 대화 기록이 포함된 모델을 사용하여 응답 생성
for event in graph.stream({"messages": full_conversation}):
for value in event.values():
# AIMessage 객체에서 직접 콘텐츠에 액세스
response = value["messages"][-1].content
st.session_state.messages_01.append({"role": "assistant", "content": response})
with st.chat_message("assistant"):
st.markdown(response)
def main():
# Sidebar to reset session state
with st.sidebar:
if st.button("초기화"):
st.session_state.clear()
# st.experimental_rerun() # Rerun the app to reflect the changes
if "model_choice" not in st.session_state:
st.session_state.model_choice = "OpenAI ChatGPT" # 기본 선택값 설정
# 모델 선택
model_choice = st.radio("모델을 선택하세요!", ["OpenAI ChatGPT"])
# 선택이 변경되었는지 확인하고, 변경되었다면 세션을 초기화
if model_choice != st.session_state.model_choice:
st.session_state.clear() # 현재 세션 정보 모두 초기화
st.session_state.model_choice = model_choice # 새로운 선택값을 세션에 저장
# Check if the API key has been submitted
if "api_key_submitted" not in st.session_state:
st.session_state.api_key_submitted = False
# API 키가 제출되지 않은 경우 입력 필드를 표시합니다.
if not st.session_state.api_key_submitted:
if st.session_state.model_choice == "OpenAI ChatGPT":
api_key = st.text_input("ChatGPT API Key:", type="password")
# API 키 제출 버튼
if st.button("제출"):
if api_key:
st.session_state.api_key = api_key
st.session_state.api_key_submitted = True
# Page title
st.title("LangGraph Chatbot!!")
# After API key submission, start the chatbot interaction
if st.session_state.api_key_submitted:
LangGraph_run()
if __name__ == "__main__":
main()
streamlit 실행 명령어로 웹화면 실행하기 streamlit run 파일명.py
초기화면
질문에 응답한 화면
한국어 텍스트가 포함된 페이지의 스크린샷
LLM이 학습 정보만을 기준으로 일반적인 응답을 하는 모습 입니다.
2. tavily검색tool을 적용한 챗봇 만들어 보기
2강에서 작성한 두번째 랭그래프 코드를 streamlit 형식에 넣어서 검색기능을 갖고 있는 웹챗봇을 구현해 봅시다.
(구현코드는 생략)
초기화면
Langgraph 챗봇 태피 도구 스크린샷 썸네일
질문에 대한 응답 화면
광주에서 금주 주말에 1일 여행계획을 작성해줘
한국어 텍스트가 포함된 페이지의 스크린샷
똑같은 질문을 했을때, 첫번째의 기본형 챗봇의 응답과 다르게 tavily 검색을 통해 2건의 최근 자료를 찾고 이를 바탕으로 LLM이 응답하는 형태를 볼 수 있다.
결과와 배운 점
랭그래프 코드를 streamlit 에 적용한 챗봇 구현을 쉽게 적용하여 구현해 볼 수 있다.